; ********************************************** ; ** ** ; ** OPERATING SYSTEM ROM PART 1: C000-CBFF ** ; ** ** ; ********************************************** .org $C000 .segment "C000CBFF" .include "atari.inc" .include "gtia.inc" .include "pokey.inc" .include "antic.inc" .include "pia.inc" .import E510,E55C,E716,E89E,E7DE,E971 .import SLFTSV,SIOV,CSOPIV,RBLOKV,DISKINV .import E49B,DISKIV,INTIV,INTINV,SIOINV .import CIOINV,E40C,E41C,E42C,E43C,E44C .import BFF0,ISRTD,ISRODN,ISRSIR,KIR .import KEYBDV,SCRENV,EDITRV,CASETV,PRINTV .import BFFE,BFFA,PHR,CIOV,BFFC,V003,CHARSET1 .import VSR,VFR,SELFS .export C000,C018,C02C,C0CE,C2AA,C745,C90C,C991,C996 .export C99B,C9A0,C9A5,C9AA,CA29,CA57,CA61,CB56 .export DISKI,DISKIN,SIO,SETVBL,VBLKI,VBLKD,INTIN,WARMS,COLDS ; C000-C00C 13 ROM identification ; C00D-C017 11 init interrupys ; C018-C02B 20 6502 NMI handler ; C02C-C02F 4 6502 IRQ handler ; C030-C0DE 175 default IRQ handler ; C0DF-C0E1 3 halt computer ; C0E2-C271 400 vblank stage 1 ; C272-C289 24 set vblank ; C28A-C28F 6 end-vblank ; C290-C2A9 26 warmstart code ; C2AA-C2C9 32 6502 RESET handler: coldstart code ; C2CA-C42D 356 warm/coldstart continuation ; C42E-C470 67 boot process data ; C471-C6A2 562 boot code ; C6A3-C932 656 floppy disk code ; C933-C96D 59 SIO code ; C96E-CA56 233 parallel handler code ; CA57-CB55 255 selftest data ; CB56-CB64 15 checksum code ; CB65-CBFF 155 unused (zeros) ; CC00-CFFF 1024 character set 2 ; 5000-57FF 2048 selftest ROM ; D800-DFFF 2048 floating point package ; ************************************* ; ** ** ; ** Computer & ROM identification ** ; ** ** ; ************************************* C000: .word $9211 ; checksum .byte $10,$05,$83 ; revision date: October 5th, 1983 .byte 0 ; option byte .byte 'B','B',0,0,1 ; part number: BB001 .byte 2 ; revision number ; ********************** ; ** ** ; ** Init Interrupts ** ; ** ** ; ********************** INTIN: lda #%01000000 ; enable VBI only sta NMIEN lda TRIG3 sta GINTLK rts ; ************************************************* ; ** ** ; ** 6502 Non-Maskable Interrupt (NMI) handler ** ; ** ** ; ************************************************* C018: bit NMIST ; check NMI status bpl C020 ; determine NMI type ; display list interrupt detected jmp (VDSLST) ; engage DLI handler ; vertical blank interrupt detected C020: cld ; clear decimal flag pha ; save A register txa ; save X register pha tya ; save Y register pha sta NMIRES ; reset NMI status jmp (VVBLKI) ; engage VBLANK immediate handler ; ******************************************** ; ** ** ; ** 6502 Interrupt Request (IRQ) handler ** ; ** ** ; ******************************************** C02C: cld ; clear decimal flag jmp (VIMIRQ) ; engage immediate IRQ handler ; ************************************ ; ** ** ; ** Default Immediate IRQ handler ** ; ** ** ; ************************************ IMIRQ: pha ; save A register lda IRQST ; check IRQ status and #%00100000 ; serial input data ready? bne @1 ; no - other IRQ! ; serial input ready IRQ lda #%11011111 ; disable interrupt notification sta IRQEN lda POKMSK ; enable interrupts sta IRQEN jmp (VSERIN) ; engage SERIN IRQ handler ; other IRQ @1: txa ; save X register pha lda PDVS ; check parallel bus IRQ and PDMSK beq @2 ; no - other IRQ! ; parallel bus IRQ jmp (VPIRQ) ; engage Parallel IRQ handler ; other IRQ @2: ldx #6 @3: lda IRQMSK,X cpx #5 bne @4 and POKMSK beq @5 @4: bit IRQST beq @6 @5: dex bpl @3 jmp C0A0 @6: eor #$FF sta IRQEN lda POKMSK sta IRQEN cpx #0 bne @7 lda KEYDIS bne C0A0 @7: lda IRQOFS,X ; setup correct handler jump vector tax lda $200,X sta JVECK lda $201,X sta JVECK+1 pla ; restore X register tax jmp (JVECK) ; ***************************** ; ** ** ; ** break key IRQ Handler ** ; ** ** ; ***************************** BRKKY: lda #0 sta BRKKEY sta SSFLAG sta CRSINH sta ATRACT pla rti C0A0: pla tax bit PACTL bpl @1 lda PORTA jmp (VPRCED) @1: bit PBCTL bpl @2 lda PORTB jmp (VINTER) @2: pla sta JVECK pla pha and #%00010000 beq @3 lda JVECK pha jmp (VBREAK) @3: lda JVECK pha PLARTI: pla C0CE: rti ; *************************** ; ** ** ; ** IRQ Dispatcher Data ** ; ** ** ; *************************** ; Bit masks for IRQ interrupts IRQMSK: .byte %10000000 ; break key LO PRIORITY .byte %01000000 ; keyboard | .byte %00000100 ; timer 4 | .byte %00000010 ; timer 2 | .byte %00000001 ; timer 1 | .byte %00001000 ; serial output complete | .byte %00010000 ; serial output ready | .byte %00100000 ; serial input ready HI PRIORITY ; Offsets from $200 of IRQ interrupt handler vectors IRQOFS: .byte VBRKKY - $200 ; break key LO PRIORITY .byte VKEYBD - $200 ; keyboard | .byte VTIMR4 - $200 ; timer 4 | .byte VTIMR2 - $200 ; timer 2 | .byte VTIMR1 - $200 ; timer 1 | .byte VSEROC - $200 ; serial output complete | .byte VSEROR - $200 ; serial output ready | .byte VSERIN - $200 ; serial input ready HI PRIORITY ; ********************* ; ** ** ; ** HALT PROCESSOR ** ; ** ** ; ********************* HALT: jmp HALT ; ********************** ; ** ** ; ** VBLANK STAGE 1 ** ; ** ** ; ********************** VBLKI: inc RTCLOK+2 ; increase RTCLOK bne @1 inc ATRACT inc RTCLOK+1 bne @1 inc RTCLOK @1: lda #$FE ; manage ATRACT mode ldx #0 ldy ATRACT bpl @2 sta ATRACT ldx RTCLOK+1 lda #%11110110 @2: sta DRKMSK stx COLRSH lda COLOR1 eor COLRSH and DRKMSK sta COLPF1 ldx #0 ; decrement countdown timer 1 jsr C255 bne @3 jsr @16 ; JSR (CDTMA1) @3: lda CRITIC bne @4 ; BNE VBLKD tsx lda $104,X and #4 beq @5 @4: jmp VBLKD @5: lda TRIG3 ; crash purposely if (TRIG3!=GINTLK) cmp GINTLK bne HALT lda PENV ; light pen hardware -> shadow sta LPENV lda PENH sta LPENH lda SDLSTH ; dlist shadow -> hardware sta DLISTH lda SDLSTL sta DLISTL lda SDMCTL ; dma control shadow -> hardware sta DMACTL lda GPRIOR ; GTIA priority shadow -> hardware sta PRIOR lda VSFLAG ; do vertical scrolling beq @6 dec VSFLAG lda #8 sec sbc VSFLAG and #%00000111 sta VSCROL @6: ldx #8 ; reset console keys stx CONSOL @7: cli ; copy shadow colors -> GTIA lda $2C0,X eor COLRSH and DRKMSK sta $D012,X dex bpl @7 lda CHBAS ; character base shadow -> hardware sta CHBASE lda CHACT ; character control shadow -> hardware sta CHACTL ldx #2 ; decrement countdown timer 2 jsr C255 bne @8 jsr @17 ; JSR (CDTMA2) @8: ldx #2 ; decrement timer 3,4,5 & set flags @9: inx inx lda $218,X ora $219,X beq @10 jsr C255 sta $226,X @10: cpx #8 bne @9 lda SKSTAT and #%00000100 beq @11 lda KEYDEL beq @11 dec KEYDEL @11: lda SRTIMR beq @13 lda SKSTAT and #%00000100 bne @12 dec SRTIMR bne @13 lda KEYDIS bne @13 lda KEYREP sta SRTIMR lda KBCODE ; KBCODE in [$9F,$83,$84,$94,$11,$51,$91,$D1] ? cmp #$9F ; ... skip beq @13 cmp #$83 beq @13 cmp #$84 beq @13 cmp #$94 beq @13 and #$3F cmp #$11 beq @13 lda KBCODE sta CH jmp @13 @12: lda #0 sta SRTIMR @13: lda PORTA ; set stick() values lsr A lsr A lsr A lsr A sta STICK1 sta STICK3 lda PORTA and #%00001111 sta STICK0 sta STICK2 lda TRIG0 ; set STRIG() from TRIG() values sta STRIG0 sta STRIG2 lda TRIG1 sta STRIG1 sta STRIG3 ldx #3 ; set PADDLE() from POT() values @14: lda $D200,X sta $270,X sta $274,X dex bpl @14 sta POTGO ; paddles have been read; initiate new "POTGO"! ldx #2 ; set PTRIG() values ldy #1 @15: lda $278,Y lsr A lsr A lsr A sta $27D,X sta $281,X lda #0 rol A sta $27C,X sta $280,X dex dex dey bpl @15 jmp (VVBLKD) @16: jmp (CDTMA1) @17: jmp (CDTMA2) ; ********************************* ; ** ** ; ** DECREMENT COUNTDOWN TIMER ** ; ** ** ; ********************************* C255: ldy $218,X bne @1 ldy $219,X beq @2 dec $219,X @1: dec $218,X bne @2 ldy $219,X bne @2 lda #0 rts @2: lda #$FF rts ; ************************************ ; ** ** ; ** SET VERTICAL BLANK INTERRUPT ** ; ** ** ; ************************************ ; subroutine to set vertical blank vectors and timers ; entry X=hi, Y=lo byte to set ; A= 1-5 TIMERS 1-5 ; 6 IMM VBLANK ; 7 DEF VBLANK SETVBL: asl A ; mul by 2 sta INTEMP txa ldx #5 sta WSYNC ; waste 20 CPU cycles @1: dex ; to allow VBLANK to happen bne @1 ; if this is line "7C" ldx INTEMP sta $217,X tya sta $216,X rts ; ****************************************** ; * ** ; * END-VBLANK & DEFAULT VBLANK STAGE 2 ** ; * ** ; ****************************************** ; exit rom vertical blank VBLKD: pla ; unstack Y tay pla ; unstack X tax pla ; unstack A rti ; and go back from whence ; ****************** ; ** ** ; ** WARM START ** ; ** ** ; ****************** WARMS: sei lda TRIG3 cmp GINTLK bne COLDS ror A bcc @1 jsr C4C9 bne COLDS @1: lda COLDST bne COLDS lda #$FF bne C2CA ; ******************************** ; ** ** ; ** 6502 Reset (RST) handler ** ; ** ** ; ******************************** C2AA: sei ; disable interrupts ldx #140 ; wait about 0@1 second ... @1: dey bne @1 dex bne @1 lda PUPBT1 ; check $33D..$33F = $5C,$93,$25? cmp #$5C bne COLDS lda PUPBT2 cmp #$93 bne COLDS lda PUPBT3 cmp #$25 beq WARMS COLDS: lda #0 ; Warm- and cold-start continuation C2CA: sta WARMST sei cld ldx #$FF txs jsr C471 lda #1 ; default: memory OK! sta NGFLAG lda WARMST bne @6 ; This part: cold start only! lda #0 ldy #8 sta RAMLO sta RAMLO+1 @1: lda #$FF sta (RAMLO),Y cmp (RAMLO),Y beq @2 lsr NGFLAG ; signal memory bad! @2: lda #0 sta (RAMLO),Y cmp (RAMLO),Y beq @3 lsr NGFLAG ; signal memory bad! @3: iny bne @1 inc RAMLO+1 ldx RAMLO+1 cpx TRAMSZ bne @1 lda #SELFS sta DOSVEC+1 lda PORTB ; Verify ROMs and #%01111111 ; enable self test ROM sta PORTB jsr VFR bcs @4 jsr VSR bcc @5 @4: lsr NGFLAG @5: lda PORTB ; disable self test ROM ora #%10000000 sta PORTB lda #$FF sta COLDST bne @10 ; this part: Warm start only! @6: ldx #0 lda DERRF beq @7 .byte $8E ; force absolute addr. mode for STX APPMHI .word APPMHI .byte $8E ; force absolute addr. mode for STX APPMHI+1 .word APPMHI+1 txa ; clear $200-$33C @7: sta $200,X cpx #$ED bcs @8 sta $300,X @8: dex bne @7 ldx #$10 ; reset $10..$7F to zero @9: sta 0,X inx bpl @9 ; Warm- and cold-start continuation @10: ldx #0 ; init BASICF lda PORTB and #%00000010 beq @11 inx @11: stx BASICF lda #$5C ; init power-up bytes sta PUPBT1 lda #$93 sta PUPBT2 lda #$25 sta PUPBT3 lda #2 ; init left margin sta LMARGN lda #39 ; init right margin sta RMARGN lda PAL ; init keyboard timing & PALNTS flag and #%00001110 bne @12 lda #5 ; PAL ldx #1 ldy #40 bne @13 @12: lda #6 ; NTSC ldx #0 ldy #48 @13: sta KEYREP stx PALNTS sty KRPDEL ldx #$25 ; init 19 vectors from $200 to $225 @14: lda C44B,X sta $200,X dex bpl @14 ldx #14 ; init 5 3-byte device driver entries @15: lda C42E,X sta HATABS,X dex bpl @15 jsr C535 cli lda NGFLAG ; check if memory is ok bne @16 lda PORTB ; NO: enable SELFTEST ROM! and #%01111111 sta PORTB lda #2 ; ...and go for self-test! sta CHACT lda #>CHARSET1 sta CHBAS jmp V003 @16: ldx #0 ; memory ok. stx TRAMSZ ldx RAMSIZ cpx #>$B000 bcs @17 ldx BFFC bne @17 inc TRAMSZ jsr C4C9 jsr @22 ; JSR ($BFFE) @17: lda #3 ; open #0,12,0,"E:" ldx #0 sta ICCOM,X lda #EDITOR sta ICBAH,X lda #12 sta ICAX1,X jsr CIOV bpl @18 jmp C2AA ; no go -- hardware reset! @18: inx ; all ok -- settle down bne @18 iny bpl @18 jsr C66E lda TRAMSZ beq @19 lda BFFC+1 ror A bcc @20 @19: jsr C58B jsr PHR @20: lda #0 sta COLDST lda TRAMSZ beq @21 ; BEQ (DOSVEC) lda BFFC+1 and #%00000100 beq @21 ; BEQ (BFFE) jmp (BFFA) @21: jmp (DOSVEC) @22: jmp (BFFE) clc rts ; BOOT PROCESS DATA! C42E: .byte "P" ; initial device driver entries .word PRINTV .byte "C" .word CASETV .byte "E" .word EDITRV .byte "S" .word SCRENV .byte "K" .word KEYBDV BT_ERR: .byte "BOOT ERROR",$9B EDITOR: .byte "E:",$9B ; Editor device specification C44B: .word C0CE ; VDSLST -> RTI .word PLARTI ; VPRCED -> PLA,RTI .word PLARTI ; VINTER -> PLA,RTI .word PLARTI ; VBREAK -> PLA,RTI .word KIR ; VKEYBD .word ISRSIR ; VSERIN .word ISRODN ; VSEROR .word ISRTD ; VSEROC .word PLARTI ; VTIMR1 -> PLA,RTI .word PLARTI ; VTIMR2 -> PLA,RTI .word PLARTI ; VTIMR4 -> PLA,RTI .word IMIRQ ; VIMIRQ -> Immediate IRQ .word 0 ; CDTMV1 -> 0 .word 0 ; CDTMV2 -> 0 .word 0 ; CDTMV3 -> 0 .word 0 ; CDTMV4 -> 0 .word 0 ; CDTMV5 -> 0 .word VBLKI ; VVBLKI -> VBLANK Immediate .word VBLKD ; VVBLKD -> VBLANK Deferred C471: lda TRIG3 ror A bcc @1 lda BFFC bne @1 lda BFFC+1 bpl @1 jmp (BFFE) @1: jsr C4DA lda PORTB ora #%00000010 sta PORTB lda WARMST beq @2 lda BASICF bne @4 beq @3 @2: lda CONSOL ; option key pressed? and #%00000100 beq @4 ; no -- skip enable BASIC @3: lda PORTB ; enable BASIC and #%11111101 sta PORTB @4: lda #<$2800 ; search 1st byte of ROM from $2800 up tay sta RAMLO+1 lda #>$2800 sta TRAMSZ @5: lda (TRAMSZ-1),Y eor #$FF sta (TRAMSZ-1),Y cmp (TRAMSZ-1),Y bne @6 eor #$FF sta (TRAMSZ-1),Y cmp (TRAMSZ-1),Y bne @6 inc TRAMSZ bne @5 @6: rts C4C9: lda #0 tax clc @1: adc BFF0,X inx bne @1 cmp CARTCK sta CARTCK rts C4DA: lda #0 ; clear all of $D000..$D4FF, except $D301. tax sta PBCTL @1: sta $D000,X sta $D400,X sta $D200,X cpx #1 beq @2 sta $D300,X @2: inx bne @1 lda #%00111100 sta PBCTL lda #%11111111 sta PORTB lda #%00111000 sta PACTL sta PBCTL lda #0 sta PORTA lda #%11111111 sta PORTB lda #%00111100 sta PACTL sta PBCTL lda PORTB lda PORTA lda #%00100010 sta SKCTL lda #160 sta $D205 sta $D207 lda #%00101000 sta AUDCTL lda #$FF sta SEROUT rts C535: dec BRKKEY lda #BRKKY sta VBRKKY+1 lda TRAMSZ sta RAMSIZ sta HIMEM+1 lda #0 sta HIMEM lda #<$700 ; MEMLO = $700 sta MEMLO lda #>$700 sta MEMLO+1 jsr E40C ; init devices jsr E41C jsr E42C jsr E43C jsr E44C jsr CIOINV ; init cassette I/O jsr SIOINV ; init serial I/O jsr INTINV ; init ehhh... jsr DISKIV ; init disk I/O lda #PIRQ sta VPIRQ+1 jsr E49B lda CONSOL and #1 eor #1 sta CKEY rts C58B: lda WARMST beq @1 lda BOOTQ and #1 beq C5C8 jmp C63B ; JMP (DOSINI) @1: lda #1 sta DUNIT lda #'S' ; status sta DCOMND jsr DISKINV bmi C5C8 C5A7: lda #0 sta DAUX2 lda #1 sta DAUX1 lda #<$400 sta DBUFLO lda #>$400 sta DBUFHI C5BB: jsr C659 bpl C5C9 C5C0: jsr C63E lda CASSBT beq C5A7 C5C8: rts C5C9: ldx #3 @1: lda $400,X sta $240,X dex bpl @1 lda BOOTAD sta RAMLO lda BOOTAD+1 sta RAMLO+1 lda $404 sta DOSINI lda $405 sta DOSINI+1 C5E8: ldy #$7F ; copy lower half page 4 @1: lda $400,Y sta (RAMLO),Y dey bpl @1 clc ; RAMLO += 128 lda RAMLO adc #<$80 sta RAMLO lda RAMLO+1 adc #>$80 sta RAMLO+1 dec DBSECT beq @3 ; we have read last sector! inc DAUX1 ; go for next sector... @2: jsr C659 bpl C5E8 jsr C63E lda CASSBT bne C5C0 beq @2 @3: lda CASSBT beq @4 jsr C659 @4: jsr @5 bcs C5C0 jsr C63B ; JSR (DOSINI) inc BOOTQ rts @5: clc ; [RAMLO] = BOOTAD+6 lda BOOTAD adc #6 sta RAMLO lda BOOTAD+1 adc #0 sta RAMLO+1 jmp (RAMLO) C63B: jmp (DOSINI) ; display "BOOT ERROR" message C63E: ldx #BT_ERR txa ldx #0 sta ICBAL,X tya sta ICBAH,X lda #9 sta ICCOM,X lda #$FF sta ICBLL,X jmp CIOV C659: lda CASSBT beq @1 jmp RBLOKV @1: lda #'R' ; read sector sta DCOMND lda #1 sta DUNIT jmp DISKINV C66E: lda WARMST beq @1 lda BOOTQ and #2 beq @2 ; RTS jmp @3 ; JMP (CASINI) @1: lda CKEY beq @2 ; RTS lda #$80 sta FTYPE inc CASSBT jsr CSOPIV jsr C5BB lda #0 sta CASSBT sta CKEY asl BOOTQ lda DOSINI ; copy DOSINI -> CASINI sta CASINI lda DOSINI+1 sta CASINI+1 @2: rts @3: jmp (CASINI) DISKI: lda #160 ; 171-second timeout sta DSKTIM lda #<$80 ; 128-byte disk sectors sta DSCTLN lda #>$80 sta DSCTLN+1 rts DISKIN: lda #'1' sta DDEVIC lda DSKTIM ; time-out for FORMAT ldx DCOMND cpx #'!' beq @1 lda #7 ; otherwise: 7 seconds @1: sta DTIMLO ldx #%01000000 ; set bit 7 if WRITE, otherwise bit 6 lda DCOMND cmp #'P' ; "put" command? (WRITE/NO VERIFY) beq @2 cmp #'W' ; "write" command? bne @3 @2: ldx #%10000000 @3: cmp #'S' ; "status" command? bne @4 ; STATUS command: lda #DVSTAT sta DBUFHI ldy #<4 lda #>4 beq @5 ; JMP @5 @4: ldy DSCTLN lda DSCTLN+1 @5: stx DSTATS sty DBYTLO sta DBYTHI jsr SIOV bpl @6 rts @6: lda DCOMND cmp #'S' bne @7 jsr C73A ldy #2 lda (BUFADR),Y sta DSKTIM @7: lda DCOMND cmp #'!' bne @10 jsr C73A ldy #$FE @8: iny iny @9: lda (BUFADR),Y cmp #$FF bne @8 iny lda (BUFADR),Y iny cmp #$FF bne @9 dey dey sty DBYTLO lda #0 sta DBYTHI @10: ldy DSTATS rts C73A: lda DBUFLO sta BUFADR lda DBUFHI sta BUFADR+1 rts C745: ldx #5 @1: lda #0 sta $2C9,X dex bpl @1 @2: lda #0 sta LCOUNT jsr C7CF ; JSR (GBYTEA) ldy #$9C bcs @4 ; RTS sta HIBYTE jsr C7CF ; JSR (GBYTEA) ldy #$9C bcs @4 ; RTS sta RECLEN lda HIBYTE cmp #11 beq C795 rol A tax lda C8E4,X sta RUNADR lda C8E4+1,X sta RUNADR+1 @3: lda RECLEN cmp LCOUNT beq @2 jsr C7CF ; JSR (GBYTEA) ldy #$9C bcs @4 ; RTS jsr C7D2 ; JSR (RUNADR) inc LCOUNT bne @3 @4: rts C795: jsr C7CF ; JSR (GBYTEA) ldy #$9C bcs @3 sta RUNADR jsr C7CF ; JSR (GBYTEA) ldy #$9C bcs @3 sta RUNADR+1 lda RECLEN cmp #1 beq @2 bcc @4 clc lda RUNADR adc LOADAD tay lda RUNADR+1 adc $2D2 @1: sty RUNADR sta RUNADR+1 @2: ldy #1 @3: rts @4: ldy #0 lda #0 beq @1 C7CF: jmp (GBYTEA) C7D2: jmp (RUNADR) C7D5: ldy LCOUNT cpy #1 beq @1 bcs @9 sta RELADR sta NEWADR bcc @8 ; RTS @1: sta RELADR+1 sta NEWADR+1 ldx #0 lda HIBYTE beq @2 cmp #10 beq @3 ldx #2 @2: clc lda RELADR adc $2D1,X sta NEWADR lda RELADR+1 adc $2D2,X sta NEWADR+1 @3: clc lda NEWADR adc RECLEN pha lda #0 adc NEWADR+1 tay pla sec sbc #2 bcs @4 dey @4: pha tya cmp $2CC,X pla bcc @6 bne @5 cmp $2CB,X bcc @6 @5: sta $2CB,X pha tya sta $2CC,X pla @6: ldx HIBYTE cpx #1 beq @8 ; RTS cpy HIMEM+1 bcc @8 ; RTS bne @7 cmp HIMEM bcc @8 ; RTS @7: pla pla ldy #$9D @8: rts @9: sec pha lda LCOUNT sbc #2 clc adc NEWADR sta LTEMP lda #0 adc NEWADR+1 sta LTEMP+1 pla ldy #0 sta (LTEMP),Y jmp @8 ; RTS C86D: clc adc NEWADR sta LTEMP lda #0 adc NEWADR+1 sta LTEMP+1 ldy #0 lda (LTEMP),Y clc adc LOADAD sta (LTEMP),Y inc LTEMP bne @1 inc LTEMP+1 @1: lda (LTEMP),Y adc LOADAD+1 sta (LTEMP),Y rts C892: ldx #0 ldy HIBYTE cpy #4 bcc @1 ldx #2 @1: clc adc NEWADR sta LTEMP lda #0 adc NEWADR+1 sta LTEMP+1 ldy #0 lda (LTEMP),Y clc adc LOADAD,X sta (LTEMP),Y rts C8B5: pha lda LCOUNT ror A pla bcs @2 clc adc NEWADR sta LTEMP lda #0 adc NEWADR+1 sta LTEMP+1 ldy #0 lda (LTEMP),Y sta HIBYTE @1: rts @2: clc adc LOADAD lda #0 adc LOADAD+1 adc HIBYTE ldy #0 sta (LTEMP),Y beq @1 ; RTS ; Peripheral Device Handlers? C8E4: .word C7D5,C7D5,C892,C892,C892,C892 .word C86D,C86D,C8B5,C8B5,C7D5,C795 ; Unused code? lda #$FF ; start self test! sta COLDST lda PORTB and #%01111111 sta PORTB jmp SLFTSV C90C: lda #1 sta SHPDVS @1: lda SHPDVS sta PDVS lda $D803 ; ID number cmp #$80 bne @2 lda $D80B ; ID number cmp #$91 bne @2 jsr $D819 ; JMP addr @2: asl SHPDVS bne @1 lda #0 sta PDVS rts ; ****************** ; ** ** ; ** SERIAL I/O ** ; ** ** ; ****************** ; !!! patched by XL-IT! !!! SIO: lda #1 ; start of critical timing region .byte $8D ; STA CRITIC (absolute) .word CRITIC lda DUNIT ; save DUNIT pha lda PDVMSK beq @2 ldx #8 @1: jsr C9AF beq @2 txa ; save X pha jsr $D805 ; JMP instruction pla tax ; restore X bcc @1 lda #0 sta SHPDVS sta PDVS beq @3 ; skip to end-of-sio ; "normal" SIO command @2: jsr E971 @3: pla ; restore DUNIT sta DUNIT lda #0 ; end of critical timing region .byte $8D ; STA CRITIC (absolute) .word CRITIC sty DSTATS ldy DSTATS rts ; **************************** ; ** ** ; ** PARALLEL IRQ HANDLER ** ; ** ** ; **************************** PIRQ: ldx #8 @1: ror A bcs @2 dex bne @1 @2: lda SHPDVS pha lda BARREL-1,X sta SHPDVS sta PDVS jsr $D808 ; 'JMP' pla sta SHPDVS sta PDVS pla tax pla rti C991: ldy #1 jmp C9DC C996: ldy #3 jmp C9DC C99B: ldy #5 jmp C9DC C9A0: ldy #7 jmp C9DC C9A5: ldy #9 jmp C9DC C9AA: ldy #11 jmp C9DC C9AF: dex bpl @1 lda #0 sta SHPDVS sta PDVS rts @1: lda PDVMSK and BARREL,X beq C9AF sta SHPDVS sta PDVS rts C9CA: lda $D80D,Y ; open vector pha dey lda $D80D,Y ; open vector pha lda PPTMPA ldx PPTMPX ldy #146 rts C9DC: sta PPTMPA stx PPTMPX .byte $AD ; absolute addr. mode for LDA CRITIC .word CRITIC pha lda #1 .byte $8D ; absolute addr. mode for STA CRITIC .word CRITIC ldx #8 @1: jsr C9AF beq @2 txa pha tya pha jsr C9CA bcc @4 sta PPTMPA pla pla jmp @3 @2: ldy #130 @3: lda #0 sta SHPDVS sta PDVS pla .byte $8D ; absolute addr. mode for STA CRITIC .word CRITIC lda PPTMPA sty PPTMPX ldy PPTMPX rts @4: pla tay pla tax bcc @1 ; JMP @1 ; Barrel Shifter :-) BARREL: .byte %10000000 .byte %01000000 .byte %00100000 .byte %00010000 .byte %00001000 .byte %00000100 .byte %00000010 .byte %00000001 CA29: .byte $AE ; absolute addr mode for LDX ICAX5Z .word ICAX5Z lda $34D,X jsr E7DE bcs @1 ; BCS E510 clc jsr E89E bcs @1 .byte $AE ; absolute addr. mode for LDX ICAX5Z .word ICAX5Z lda $34C,X jsr E716 bcs @1 .byte $AE ; absolute addr. mode for LDX ICAX5Z .word ICAX5Z sta IOCB,X sta ICHIDZ lda #3 sta ICCOMT jmp E55C @1: jmp E510 ; Some data, seems to be used by SELFTEST ROMS. CA57: .byte $00,$13,$16,$D1,$E4,$E4,$E8,$29,$EB,$EE CA61: .byte $00,$00,$2D,$25,$2D,$2F,$32,$39 ; ' MEMORY TEST ' .byte $00,$34,$25,$33,$34,$00,$00,$00 .byte $32,$2F,$2D ; 'ROM' .byte $32,$21,$2D ; 'RAM' .byte $00,$00,$2B,$25,$39,$22,$2F,$21 ; ' KEYBOARD TEST ' .byte $32,$24,$00,$34,$25,$33,$34,$00 .byte $00,$00,$B2,$91,$00,$92,$00,$93 .byte $00,$94,$00,$A8,$00,$A1,$00,$A2 .byte $00,$00,$00,$5B,$00,$11,$00,$12 .byte $00,$13,$00,$14,$00,$15,$00,$16 .byte $00,$17,$00,$18,$00,$19,$00,$10 .byte $00,$1C,$00,$1E,$00,$A2,$80,$B3 .byte $00,$00,$00,$FF,$FF,$00,$31,$00 .byte $37,$00,$25,$00,$32,$00,$34,$00 .byte $39,$00,$35,$00,$29,$00,$2F,$00 .byte $30,$00,$0D,$00,$1D,$00,$B2,$B4 .byte $00,$00,$00,$80,$DC,$80,$00,$21 .byte $00,$33,$00,$24,$00,$26,$00,$27 .byte $00,$28,$00,$2A,$00,$2B,$00,$2C .byte $00,$1B,$00,$0B,$00,$0A,$00,$A3 .byte $00,$00,$00,$80,$B3,$A8,$80,$00 .byte $3A,$00,$38,$00,$23,$00,$36,$00 .byte $22,$00,$2E,$00,$2D,$00,$0C,$00 .byte $0E,$00,$0F,$00,$80,$B3,$A8,$80 .byte $00,$00,$00,$00,$00,$00,$00,$00 .byte $80,$B3,$80,$B0,$80,$A1,$80,$A3 .byte $80,$A5,$80,$80,$80,$A2,$80,$A1 .byte $80,$B2,$80,$00,$33,$00,$30,$00 .byte $21,$00,$23,$00,$25,$00,$00,$00 .byte $22,$00,$21,$00,$32,$00,$00,$33 .byte $28,$00,$22,$00,$33,$00,$5C,$00 .byte $36,$2F,$29,$23,$25 ; 'VOICE' .byte $00,$03 ; 18-byte checksum! CB56: ldy #17 lda #0 clc @1: adc (ZCHAIN),Y dey bpl @1 adc #0 eor #$FF rts ; 155 zero bytes: .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 0,0,0,0,0 .end