diff options
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/DC1C | 1 |
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 |