summaryrefslogtreecommitdiffstats
path: root/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
diff options
context:
space:
mode:
Diffstat (limited to 'docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C')
-rw-r--r--docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C1
1 files changed, 1 insertions, 0 deletions
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
new file mode 100644
index 0000000..b319f77
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
@@ -0,0 +1 @@
+************************************************************************** ************************************************************************** ** ** ** MAIN IRQ Entry point ** ** ** ** ** ************************************************************************** ************************************************************************** ;ON ENTRY STACK contains STATUS REGISTER,PCH,PCL ; DC1C STA &FC ;save A DC1E PLA ;get back status (flags) DC1F PHA ;and save again DC20 AND #&10 ;check if BRK flag set DC22 BNE &DC27 ;if so goto DC27 DC24 JMP (&0204) ;else JMP (IRQ1V) ************************************************************************* * * * BRK handling routine * * * ************************************************************************* DC27 TXA ;save X on stack DC28 PHA ; DC29 TSX ;get status pointer DC2A LDA &0103,X ;get Program Counter lo DC2D CLD ; DC2E SEC ;set carry DC2F SBC #&01 ;subtract 2 (1+carry) DC31 STA &FD ;and store it in &FD DC33 LDA &0104,X ;get hi byte DC36 SBC #&00 ;subtract 1 if necessary DC38 STA &FE ;and store in &FE DC3A LDA &F4 ;get currently active ROM DC3C STA &024A ;and store it in &24A DC3F STX &F0 ;store stack pointer in &F0 DC41 LDX #&06 ;and issue ROM service call 6 DC43 JSR &F168 ;(User BRK) to roms ;at this point &FD/E point to byte after BRK ;ROMS may use BRK for their own purposes DC46 LDX &028C ;get current language DC49 JSR &DC16 ;and activate it DC4C PLA ;get back original value of X DC4D TAX ; DC4E LDA &FC ;get back original value of A DC50 CLI ;allow interrupts DC51 JMP (&0202) ;and JUMP via BRKV (normally into current language) ************************************************************************* * * * DEFAULT BRK HANDLER * * * ************************************************************************* DC54 LDY #&00 ;Y=0 to point to byte after BRK DC56 JSR &DEB1 ;print message DC59 LDA &0267 ;if BIT 0 set and DISC EXEC error DC5C ROR ;occurs DC5D BCS &DC5D ;hang up machine!!!! DC5F JSR OSNEWL ;else print two newlines DC62 JSR OSNEWL ; DC65 JMP &DBB8 ;and set tape speed before entering current ;language ; ACIA IRQ, RxRDY but both Serial and Printer buffers empty ; --------------------------------------------------------- DC68 SEC DC69 ROR &024F ; Set b7 of RS423 busy flag DC6C BIT &0250 ;check bit 7 of current ACIA control register DC6F BPL &DC78 ;if interrupts NOT enabled DC78 DC71 JSR &E741 ;else E741 to check if serial buffer full DC74 LDX #&00 ; X=&00 to set RTS low DC76 BCS &DC7A ;if carry set goto DC7A to transfer data DC78 LDX #&40 ; X=&40 to set RTS high DC7A JMP &E17A ; Jump to set ACIA control register ; Serial IRQ and RxRDY - Get byte and store in serial buffer ; ---------------------------------------------------------- DC7D LDY &FE09 ; Read data from ACIA DC80 AND #&3A ; Check PE:RO:FE:DCD DC82 BNE &DCB8 ; If any set, jump to generate Serial Error Event ; Serial IRQ and RxRDY, no errors ; ------------------------------- DC84 LDX &025C ; Read RS423 input suppression flag DC87 BNE &DC92 ; If not 0, jump to ignore DC89 INX ; X=1, serial input buffer DC8A JSR &E4F3 ; Put byte in buffer DC8D JSR &E741 ; Check if serial buffer almost full DC90 BCC &DC78 ; If almost full, jump to set RTS high DC92 RTS ; Return ************************************************************************* * * * Main IRQ Handling routines, default IRQ1V destination * * * ************************************************************************* DC93 CLD ; Clear decimal flag DC94 LDA &FC ; Get original value of A DC96 PHA ; Save it DC97 TXA ; Save X DC98 PHA ; DC99 TYA ; and Y DC9A PHA ; DC9B LDA #&DE ; Stack return address to &DE82 DC9D PHA DC9E LDA #&81 DCA0 PHA DCA1 CLV ; Clear V flag DCA2 LDA &FE08 ; Read ACIA status register DCA5 BVS &DCA9 ; b6 set, jump with serial parity error DCA7 BPL &DD06 ; b7=0, no ACIA interrupt, jump to check VIAs ; ACIA Interrupt or ACIA Parity Error ; ----------------------------------- DCA9 LDX &EA ; Get RS423 timeout counter DCAB DEX ; Decrement it DCAC BMI &DCDE ; If 0 or <0, RS423 owns 6850, jump to DCDE DCAE BVS &DCDD ; If &41..&80, nobody owns 6850, jump to exit DCB0 JMP &F588 ; CFS owns 6850, jump to read ACIA in CFS routines ; ACIA Data Carrier Detect ; ------------------------ DCB3 LDY &FE09 ; Read ACIA data DCB6 ROL A ; DCB7 ASL A ; Rotate ACIA Status back DCB8 TAX ; X=ACIA Status DCB9 TYA ; A=ACIA Data DCBA LDY #&07 ; Y=07 for RS423 Error Event DCBC JMP &E494 ; Jump to issue event ; ACIA IRQ, TxRDY - Send a byte ; ----------------------------- DCBF LDX #&02 DCC1 JSR &E460 ; Read from Serial output buffer DCC4 BCC &DCD6 ; Buffer is not empty, jump to send byte DCC6 LDA &0285 ; Read printer destination DCC9 CMP #&02 ; Is it serial printer?? DCCB BNE &DC68 ; Serial buffer empty, not Serial printer, jump to ... DC68 DCCD INX ; X=3 for Printer buffer DCCE JSR &E460 ; Read from Printer buffer DCD1 ROR &02D2 ; Copy Byte Fetched/Not fetched into Printer Buffer full flag DCD4 BMI &DC68 ; Printer buffer was empty, so jump to ... DC68 DCD6 STA &FE09 ; Send byte to ACIA DCD9 LDA #&E7 ; Set timeout counter to &E7 DCDB STA &EA ; Serial owns 6850 for 103 more calls DCDD RTS ; Exit IRQ ; RS423 owns 6850, PE or RxRDY interupt occured ; --------------------------------------------- ; On entry, A contains ACIA status ; DCDE AND &0278 ; AND with ACIA IRQ mask (normally &FF) DCE1 LSR A ; Move RxRDY into Carry DCE2 BCC &DCEB ; If no RxData, jump to check DCD and TxRDY ; ; Data in RxData, check for errors ; DCE4 BVS &DCEB ; If IRQ=1 (now in b6) RxIRQ must have occured, so jump to DCEB ; ; RxData but no RxIRQ, check that IRQs are actually disabled ; DCE6 LDY &0250 ; Get ACIA control setting DCE9 BMI &DC7D ; If bit 7=1, IRQs enabled so jump to read byte and insert into buffer ; ; DCE9 -> RxData, no RxIRQ, IRQs disabled ; DCE4 -> RxData and RxIRQ ; DCE2 -> No RxData ; ; Check TxRDY and DCD, if neither set, send a Serial Error Event ; -------------------------------------------------------------- DCEB LSR A ; Move TxRDY into Carry DCEC ROR A ; Rotate TxRDY into b7 and DCD into Carry DCED BCS &DCB3 ; If Data Carrier Detected, jump to DCB3 DCEF BMI &DCBF ; If TxRDY (now in b7) jump to to DCBF to send a byte DCF1 BVS &DCDD ; b6 should always be zero by now, but if set, then jump to exit ; Issue Unknown Interupt service call ; =================================== DCF3 LDX #&05 DCF5 JSR &F168 ; Issue service call 5, 'Unknown Interrupt' DCF8 BEQ &DCDD ; If claimed, then jump to exit DCFA PLA ; Otherwise drop return address from stack DCFB PLA ; DCFC PLA ; And restore registers DCFD TAY ; DCFE PLA ; DCFF TAX ; DD00 PLA ; DD01 STA &FC ; Store A in IRQA DD03 JMP (&0206) ; And pass the IRQ in to IRQ2V ************************************************************************* * * * VIA INTERUPTS ROUTINES * * * ************************************************************************* DD06 LDA &FE4D ; Read System VIA interrupt flag register DD09 BPL &DD47 ; No System VIA interrupt, jump to check User VIA ; System VIA interupt ; DD0B AND &0279 ; Mask with System VIA bit mask DD0E AND &FE4E ; and interrupt enable register DD11 ROR ; Rotate to check for CA1 interupt (frame sync) DD12 ROR ; DD13 BCC &DD69 ; No CA1 (frame sync), jump to check speech ; System VIA CA1 interupt (Frame Sync) ; DD15 DEC &0240 ;decrement vertical sync counter DD18 LDA &EA ;A=RS423 Timeout counter DD1A BPL &DD1E ;if +ve then DD1E DD1C INC &EA ;else increment it DD1E LDA &0251 ;load flash counter DD21 BEQ &DD3D ;if 0 then system is not in use, ignore it DD23 DEC &0251 ;else decrement counter DD26 BNE &DD3D ;and if not 0 go on past reset routine DD28 LDX &0252 ;else get mark period count in X DD2B LDA &0248 ;current VIDEO ULA control setting in A DD2E LSR ;shift bit 0 into C to check if first colour DD2F BCC &DD34 ;is effective if so C=0 jump to DD34 DD31 LDX &0253 ;else get space period count in X DD34 ROL ;restore bit DD35 EOR #&01 ;and invert it DD37 JSR &EA00 ;then change colour DD3A STX &0251 ;&0251=X resetting the counter DD3D LDY #&04 ;Y=4 and call E494 to check and implement vertical DD3F JSR &E494 ;sync event (4) if necessary DD42 LDA #&02 ;A=2 DD44 JMP &DE6E ;clear interrupt 1 and exit ************************************************************************* * * * PRINTER INTERRUPT USER VIA 1 * * * ************************************************************************* DD47 LDA &FE6D ; Read User VIA interrupt flag register DD4A BPL &DCF3 ; No User VIA interrupt, jump to pass to ROMs ; User VIA interupt ; DD4C AND &0277 ;else check for USER IRQ 1 DD4F AND &FE6E ; DD52 ROR ; DD53 ROR ; DD54 BCC &DCF3 ;if bit 1=0 the no interrupt 1 so DCF3 DD56 LDY &0285 ;else get printer type DD59 DEY ;decrement DD5A BNE &DCF3 ;if not parallel then DCF3 DD5C LDA #&02 ;reset interrupt 1 flag DD5E STA &FE6D ; DD61 STA &FE6E ;disable interrupt 1 DD64 LDX #&03 ;and output data to parallel printer DD66 JMP &E13A ; ************************************************************************* * * * SYSTEM INTERRUPT 5 Speech * * * ************************************************************************* DD69 ROL ; Rotate bit 5 into bit 7 DD6A ROL ; DD6B ROL ; DD6C ROL ; DD6D BPL &DDCA ; Not a Timer 2 interrupt, jump to check timers ; System VIA Timer 2 interupt - Speech interupt ; DD6F LDA #&20 ; Prepare to clear VIA interupt DD71 LDX #&00 DD73 STA &FE4D ; Clear VIA interupt DD76 STX &FE49 ; Zero high byte of T2 Timer DD79 LDX #&08 ; X=8 for Speech buffer DD7B STX &FB ; Prepare to loop up to four times for Speak from RAM ; DD7D JSR &E45B ; Examine Speech buffer DD80 ROR &02D7 ; Shift carry into bit 7 DD83 BMI &DDC9 ; Buffer empty, so exit DD85 TAY ; Buffer not empty, A=first byte waiting DD86 BEQ &DD8D ; Waiting byte=&00 (Speak, no reset), skip past DD88 JSR &EE6D ;control speech chip DD8B BMI &DDC9 ;if negative exit DD8D JSR &E460 ; Fetch Speech command byte from buffer DD90 STA &F5 ; Store it DD92 JSR &E460 ; Fetch Speech word high byte from buffer DD95 STA &F7 ; Store it DD97 JSR &E460 ; Fetch Speech word low byte from buffer DD9A STA &F6 ; Store it, giving &F6/7=address to be accessed DD9C LDY &F5 ; Y=Speech command byte DD9E BEQ &DDBB ; SOUND &FF00 - Speak from RAM, no reset DDA0 BPL &DDB8 ; SOUND &FF01-&FF7F - Speak from RAM, with reset DDA2 BIT &F5 ; Check bit 6 of Speech command DDA4 BVS &DDAB ; SOUND &FFC0-&FFFF - Speak word number ; SOUND &FF80-&FFBF - Speak from absolute address ; &F5=command &80-&BF (b0-b3=PHROM number), &F6/7=address ; DDA6 JSR &EEBB ; Write address to speech processor DDA9 BVC &DDB2 ; Skip forward to speak from selected address ; SOUND &FFC0-&FFFF - Speak word number ; &F5=command &C0-&FF (b0-b3=PHROM number), &F6/7=word number ; DDAB ASL &F6 ; Multiply address by 2 to index into word table DDAD ROL &F7 ; DDAF JSR &EE3B ; Read address from specified PHROM ; Speak from PHROM address ; By now, the address in the PHROM specified in Command b0-b3 has been set ; to the start of the speech data to be voiced. ; DDB2 LDY &0261 ; Fetch command code, usually &50=Speak or &00=Nop DDB5 JMP &EE7F ; Jump to send command to speak from current address ; SOUND &FF01-&FF7F - Speak from RAM with reset ; Y=Speech command byte, &F6/7=Speech data ; Use SOUND &FF60 to send Speak External command ; DDB8 JSR &EE7F ; Send command byte to Speech processor ; SOUND &FF00 - Speak from RAM without reset ; &6/7=Speech data ; DDBB LDY &F6 DDBD JSR &EE7F ; Send Speech data low byte DDC0 LDY &F7 DDC2 JSR &EE7F ; Send Speech data high byte DDC5 LSR &FB ; Shift loop counter DDC7 BNE &DD7D ; Loop to send up to four byte-pairs DDC9 RTS *********************************************************************** * * * SYSTEM INTERRUPT 6 10mS Clock * * * ************************************************************************* DDCA BCC &DE47 ;bit 6 is in carry so if clear there is no 6 int ;so go on to DE47 DDCC LDA #&40 ;Clear interrupt 6 DDCE STA &FE4D ; ;UPDATE timers routine, There are 2 timer stores &292-6 and &297-B ;these are updated by adding 1 to the current timer and storing the ;result in the other, the direction of transfer being changed each ;time of update. This ensures that at least 1 timer is valid at any call ;as the current timer is only read. Other methods would cause inaccuracies ;if a timer was read whilst being updated. DDD1 LDA &0283 ;get current system clock store pointer (5,or 10) DDD4 TAX ;put A in X DDD5 EOR #&0F ;and invert lo nybble (5 becomes 10 and vv) DDD7 PHA ;store A DDD8 TAY ;put A in Y ;Carry is always set at this point DDD9 LDA &0291,X ;get timer value DDDC ADC #&00 ;update it DDDE STA &0291,Y ;store result in alternate DDE1 DEX ;decrement X DDE2 BEQ &DDE7 ;if 0 exit DDE4 DEY ;else decrement Y DDE5 BNE &DDD9 ;and go back and do next byte DDE7 PLA ;get back A DDE8 STA &0283 ;and store back in clock pointer (i.e. inverse previous ;contents) DDEB LDX #&05 ;set loop pointer for countdown timer DDED INC &029B,X ;increment byte and if DDF0 BNE &DDFA ;not 0 then DDFA DDF2 DEX ;else decrement pointer DDF3 BNE &DDED ;and if not 0 do it again DDF5 LDY #&05 ;process EVENT 5 interval timer DDF7 JSR &E494 ; DDFA LDA &02B1 ;get byte of inkey countdown timer DDFD BNE &DE07 ;if not 0 then DE07 DDFF LDA &02B2 ;else get next byte DE02 BEQ &DE0A ;if 0 DE0A DE04 DEC &02B2 ;decrement 2B2 DE07 DEC &02B1 ;and 2B1 DE0A BIT &02CE ;read bit 7 of envelope processing byte DE0D BPL &DE1A ;if 0 then DE1A DE0F INC &02CE ;else increment to 0 DE12 CLI ;allow interrupts DE13 JSR &EB47 ;and do routine sound processes DE16 SEI ;bar interrupts DE17 DEC &02CE ;DEC envelope processing byte back to 0 DE1A BIT &02D7 ;read speech buffer busy flag DE1D BMI &DE2B ;if set speech buffer is empty, skip routine DE1F JSR &EE6D ;update speech system variables DE22 EOR #&A0 ; DE24 CMP #&60 ; DE26 BCC &DE2B ;if result >=&60 DE2B DE28 JSR &DD79 ;else more speech work DE2B BIT &D9B7 ;set V and C DE2E JSR &DCA2 ;check if ACIA needs attention DE31 LDA &EC ;check if key has been pressed DE33 ORA &ED ; DE35 AND &0242 ;(this is 0 if keyboard is to be ignored, else &FF) DE38 BEQ &DE3E ;if 0 ignore keyboard DE3A SEC ;else set carry DE3B JSR &F065 ;and call keyboard DE3E JSR &E19B ;check for data in user defined printer channel DE41 BIT &FEC0 ;if ADC bit 6 is set ADC is not busy DE44 BVS &DE4A ;so DE4A DE46 RTS ;else return ; ************************************************************************* * * * SYSTEM INTERRUPT 4 ADC end of conversion * * * ************************************************************************* DE47 ROL ;put original bit 4 from FE4D into bit 7 of A DE48 BPL &DE72 ;if not set DE72 DE4A LDX &024C ;else get current ADC channel DE4D BEQ &DE6C ;if 0 DE6C DE4F LDA &FEC2 ;read low data byte DE52 STA &02B5,X ;store it in &2B6,7,8 or 9 DE55 LDA &FEC1 ;get high data byte DE58 STA &02B9,X ;and store it in hi byte DE5B STX &02BE ;store in Analogue system flag marking last channel DE5E LDY #&03 ;handle event 3 conversion complete DE60 JSR &E494 ; DE63 DEX ;decrement X DE64 BNE &DE69 ;if X=0 DE66 LDX &024D ;get highest ADC channel preseny DE69 JSR &DE8F ;and start new conversion DE6C LDA #&10 ;reset interrupt 4 DE6E STA &FE4D ; DE71 RTS ;and return ************************************************************************* * * * SYSTEM INTERRUPT 0 Keyboard * * * ************************************************************************* ; DE72 ROL ;get original bit 0 in bit 7 position DE73 ROL ; DE74 ROL ; DE75 ROL ; DE76 BPL &DE7F ;if bit 7 clear not a keyboard interrupt DE78 JSR &F065 ;else scan keyboard DE7B LDA #&01 ;A=1 DE7D BNE &DE6E ;and off to reset interrupt and exit DE7F JMP &DCF3 ; ************** exit routine ********************************************* DE82 PLA ;restore registers DE83 TAY ; DE84 PLA ; DE85 TAX ; DE86 PLA ; DE87 STA &FC ;store A ************************************************************************* * * * IRQ2V default entry * ************************************************************************* DE89 LDA &FC ;get back original value of A DE8B RTI ;and return to calling routine ************************************************************************* * * * OSBYTE 17 Start conversion * * * ************************************************************************* ; DE8C STY &02BE ;set last channel to finish conversion DE8F CPX #&05 ;if X<4 then DE91 BCC &DE95 ;DE95 DE93 LDX #&04 ;else X=4 DE95 STX &024C ;store it as current ADC channel DE98 LDY &024E ;get conversion type DE9B DEY ;decrement DE9C TYA ;A=Y DE9D AND #&08 ;and it with 08 DE9F CLC ;clear carry DEA0 ADC &024C ;add to current ADC DEA3 SBC #&00 ;-1 DEA5 STA &FEC0 ;store to the A/D control panel DEA8 RTS ;and return ; DEA9 LDA #&C3 ;point to start of string @&C300 DEAB STA &FE ;store it DEAD LDA #&00 ;point to lo byte DEAF STA &FD ;store it and start loop@ DEB1 INY ;print character in string DEB2 LDA (&FD),Y ;pointed to by &FD/E DEB4 JSR OSASCI ;print it expanding Carriage returns DEB7 TAX ;store A in X DEB8 BNE &DEB1 ;and loop again if not =0 DEBA RTS ;else exit *********** OSBYTE 129 TIMED ROUTINE ****************************** ;ON ENTRY TIME IS IN X,Y DEBB STX &02B1 ;store time in INKEY countdown timer DEBE STY &02B2 ;which is decremented every 10ms DEC1 LDA #&FF ;A=&FF to flag timed wait DEC3 BNE &DEC7 ;goto DEC7 ************************************************************************** ************************************************************************** ** ** ** OSRDCH Default entry point ** ** ** ** RDCHV entry point read a character ** ** ** ************************************************************************** ************************************************************************** DEC5 LDA #&00 ;A=0 to flag wait forever DEC7 STA &E6 ;store entry value of A DEC9 TXA ;save X and Y DECA PHA ; DECB TYA ; DECC PHA ; DECD LDY &0256 ;get *EXEC file handle DED0 BEQ &DEE6 ;if 0 (not open) then DEE6 DED2 SEC ;set carry DED3 ROR &EB ;set bit 7 of CFS active flag to prevent clashes DED5 JSR OSBGET ;get a byte from the file DED8 PHP ;push processor flags to preserve carry DED9 LSR &EB ;restore &EB DEDB PLP ;get back flags DEDC BCC &DF03 ;and if carry clear, character found so exit via DF03 DEDE LDA #&00 ;else A=00 as EXEC file empty DEE0 STA &0256 ;store it in exec file handle DEE3 JSR OSFIND ;and close file via OSFIND DEE6 BIT &FF ;check ESCAPE flag, if bit 7 set Escape pressed DEE8 BMI &DF00 ;so off to DF00 DEEA LDX &0241 ;else get current input buffer number DEED JSR &E577 ;get a byte from input buffer DEF0 BCC &DF03 ;and exit if character returned DEF2 BIT &E6 ;(E6=0 or FF) DEF4 BVC &DEE6 ;if entry was OSRDCH not timed keypress, so go back and ;do it again i.e. perform GET function DEF6 LDA &02B1 ;else check timers DEF9 ORA &02B2 ; DEFC BNE &DEE6 ;and if not zero go round again DEFE BCS &DF05 ;else exit DEF0 .. BCC &DF03 DEF2 $æ BIT &E6 DEF4 Pð BVC &DEE6 DEF6 ­±. LDA &02B1 DEF9 .². ORA &02B2 DEFC Ðè BNE &DEE6 DEFE °. BCS &DF05 DF00 8 SEC DF01 ©. LDA #&1B DF03 .æ STA &E6 DF05 h PLA DF06 ¨ TAY DF07 h PLA DF08 ª TAX DF09 ¥æ LDA &E6 DF0B ` RTS \ No newline at end of file