PTR = $06 PTRL = $06 PTRH = $07 SPINIDX = $07 BASEL = $28 CSWL = $36 CSWH = $37 KSWL = $38 KSWH = $39 RNDL = $4E RNDH = $4F MOUROM = $C4 MOUINDEX = $04 MOUSLOT = $40 CEVL = $3CE CEVH = $3CF OUTVECT0 = $BE10 OUTVECT3 = $BE16 INVECT0 = $BE20 INVECT3 = $BE26 VECTOUT = $BE30 VECTIN = $BE32 WARMDOS = $BE00 TEXTSCRN = $0400 WAIT = $FCA8 BELL1 = $FBD9 COUT1 = $FDF0 KEYBD = $C000 KBCLR = $C010 ANYKEY = $C010 ;--------------------------------------------------------- ; Apple IIgs SCC Z8530 registers and constants ;--------------------------------------------------------- GSCMDB = $C038 GSDATAB = $C03A GSCMDA = $C039 GSDATAA = $C03B RESETB = %01010001 ; constant to reset Channel B WR11A = %11010000 ; init wr11 in Ch A WR11BXTAL = %00000000 ; init wr11 in Ch B - use external clock WR11BBRG = %01010000 ; init wr11 in Ch B - use baud rate generator .org $9600 CLD ; ; SLOTS FOR MOUSE AND SERIAL ON IIGS ARE WELL KNOWN ; ; ; RESET ENTRYPOINT ; ENTRY: CLI ; ; INIT MOUSE ; INITMOU: LDY #$19 ; INIT MOUSE JSR CALLMOU LDY #$12 ; SET MOUSE LDA #$01 ; TRANSPARENT MODE JSR CALLMOU LDA #$00 STA $478 STA $4F8 LDA #$C0 STA $578 LDA #$3F STA $5F8 LDY #$17 ; CLAMP MOUSE LDA #$00 ; X AXIS JSR CALLMOU LDY #$17 ; CLAMP MOUSE LDA #$01 ; Y AXIS JSR CALLMOU ; ; INIT SCC MODEM PORT FOR 115K BAUD ; INITSCC: SEI ; No interruptions here! LDA GSCMDB ; Hit rr0 once to sync up LDY #$00 SCCREGS: LDA SCCTAB,Y STA GSCMDB INY LDA SCCTAB,Y STA GSCMDB INY CPY SCCTABLEN BNE SCCREGS CLI ; we're done! ; ; SYNCHRONIZE WITH PI ; SYNC: LDA #$80 JSR SENDACC INC SPINIDX LDA SPINIDX AND #$03 TAX LDA SPINNER,X STA TEXTSCRN LDA #$FF JSR WAIT LDA KEYBD BPL CHKACK JMP EXIT CHKACK: ; Read a byte from SCC LDA GSCMDB ; dummy read to reset SCC pointer to 0 SYNCLUP: BIT $C0E0 ; attempt to slow down accelerators by referencing slot 6 ($C080 + $60) LDA GSCMDB ; read SCC register 0 AND #$01 ; bit 0 means receive available CMP #$01 BNE SYNC SYNCRDY: LDA #$01 ; set pointer to rr1 STA GSCMDB LDA GSCMDB ; read SCC register 1 AND #$20 ; check for bit 5=rx overrun BEQ SYNCOK LDX #$30 ; clear overrun STX GSCMDB LDX #$00 STX GSCMDB SYNCOK: LDA #$08 ; get ready to read rr8 (our SCC byte) STA GSCMDB LDA GSCMDB ; read it CMP #$81 BNE SYNC LDY #$20 ; Tell 'em about slot 2 STY $301 ; TELL CALLING PROGRAM SYNC OK LDA #$A0 STA TEXTSCRN ; Clear the spinner out LDA #$87 JSR BELL1 LDA ANYKEY STA KEYSTAT ; ; GET COUT/CIN VECTORS ; JSR $C300 LDA CSWL STA CHAINOUT+1 LDA CSWH STA CHAINOUT+2 JSR HOOK ; ; SET VECTOR FOR CHKEVENT ; ; LDX #CHKEVENT ; STX CEVH ; ; SET UP RESET VECTOR ; LDA RESET+1 BNE ISRESET LDA $3F2 STA RESET LDA $3F3 STA RESET+1 LDA #ENTRY STA $3F3 EOR #$A5 STA $3F4 RTS ISRESET: LDX #$FF TXS JMP WARMDOS ; ; CHAR OUT HOOK - CHECK ONCE FOR A2PI EVENTS ; COUTPI: PHP CLI PHA STX SAVEX STY SAVEY LDA #$98 JSR SENDACC PLA PHA JSR SENDACC JSR SENDACC LDA CHRIN BNE COUTNXT ; SKIP IF INPUT CHAR PENDING LDA KEYBD CMP #$83 ; SKIP CTRL-C BEQ COUTNXT CMP #$93 ; SKIP CTRL-S BEQ COUTNXT LDA #$01 STA WAITEV JSR CHKEVENT ; CHECK ON EVENTS BCC COUTNXT STA CHRIN COUTNXT: PLA LDY SAVEY LDX SAVEX PLP STA SAVEY CHAINOUT: JSR COUT1 ; ; SET INPUT/OUTPUT VECTORS ; HOOK: STX SAVEX LDX #COUTPI STX CSWH LDX #CINPI STX KSWH LDX SAVEX RTS ; ; CHAR IN HOOK - EVENT LOOP FOR A2PI DAEMON ; CINPI: STA (BASEL),Y ; RESTORE CURSOR LDA CHRIN BNE CINPIEX STX SAVEX LDA #$5F ; PRINT _ JSR CHAINOUT LDA #$88 ; BACKSAPCE JSR CHAINOUT PHP CLI EVENTLP: INC RNDL ; UPDATE RND LIKE ANY PROPER RDKEY BNE EVENTLP1 INC RNDH EVENTLP1: JSR CHKEVENT BCC EVENTLP PLP ; HAVE CHAR FROM A2PI DAEMON LDX SAVEX CINPIEX: LDY #$00 STY CHRIN RTS ; ; SEND MODIFIER (OPEN & CLOSED APPLE) KEYS/PADDLE BUTTONS ; SENDMOD: LDA $C062 ASL LDA $C061 ROR AND #$C0 ; FALL THROUGH ; ; ACIA SEND BYTE IN ACCUMULATOR ; SENDACC: STA SAVEY STX SAVEX SCCSEND: LDA GSCMDB TAX AND #%00000100 ; test bit 2 (hardware handshaking) BEQ SCCSEND TXA AND #%00100000 ; test bit 5 (ready to send?) BEQ SCCSEND LDA SAVEY ; ready... get the byte to send STA GSDATAB ; send the byte LDX SAVEX LDA SAVEY RTS ; ; SCC RECEIVE BYTE IN ACCUMULATOR ; RECVACC: LDA GSCMDB ; dummy read to reset SCC pointer to 0 RECVLUP: BIT $C0E0 ; attempt to slow down accelerators by referencing slot 6 ($C080 + $60) LDA GSCMDB ; read SCC register 0 AND #$01 ; bit 0 means receive available CMP #$01 BNE RECVLUP RECVRDY: LDA #$01 ; set pointer to rr1 STA GSCMDB LDA GSCMDB ; read SCC register 1 AND #$20 ; check for bit 5=rx overrun BEQ RCVOK LDX #$30 ; clear overrun STX GSCMDB LDX #$00 STX GSCMDB RCVOK: LDA #$08 ; get ready to read rr8 (our SCC byte) STA GSCMDB LDA GSCMDB ; read it CLC RTS ; ; CHECK INPUT STATE FOR CHANGE ; CHKEVENT: LDA ANYKEY ; CHECK FOR KEY PRESS/RELEASE CMP KEYSTAT BNE SENDKEY LDA GSCMDB BIT $C0E0 LDA GSCMDB AND #$01 CMP #$01 BNE CHKMOU ; no data; check for mouse JSR RECVRDY JMP HOSTREQ CHKMOU: DEC WAITEV ; CHECK FOR MOUSE UPDATE BEQ UPDTMOU EXEVENT: CLC RTS ; ; KEYBOARD EVENT ; SENDKEY: TAX BPL SENDKBEV LDA #$80 ; DEBOUNCE KEYPRESS JSR WAIT LDX ANYKEY CPX #$FF BNE SENDKBEV LDA $C062 BPL SENDKBEV LDA $C061 BPL SENDKBEV UNHOOK: JSR EXIT LDA #$00 STA RESET STA RESET+1 LDA #$0D SEC RTS SENDKBEV: STX KEYSTAT LDA #$82 ; KBEVENT CODE JSR SENDACC JSR SENDMOD TXA CLC JMP SENDACC ; ; MOUSE EVENTS ; UPDTMOU: LDY #$14 ; READ MOUSE LDA #$80 JSR CALLMOU BCC EXMOU LDY #MOUINDEX LDA $478,Y STA MOUXSTAT LDA $4F8,Y STA MOUYSTAT LDA $778,Y PHA LDY #$15 ; CLEAR MOUSE LDA #$80 JSR CALLMOU LDA MOUXSTAT ORA MOUYSTAT BEQ CHKBTTN LDA #$84 ; SEND MOUSE POSITION JSR SENDACC LDA MOUXSTAT JSR SENDACC LDA MOUYSTAT JSR SENDACC CHKBTTN: LDY #MOUINDEX PLA STA $778,Y ; GS CLEARS THIS IN CLEAR MOUSE CALL AND #$80 CMP BTTNSTAT BEQ EXMOU SENDBTTN: STA BTTNSTAT LDA #$86 JSR SENDACC JSR SENDMOD LDA BTTNSTAT JSR SENDACC EXMOU: CLC RTS ; ; CALL MOUSE FIRMWARE ; CALLMOU: LDX #MOUROM PHA LDA PTRL ; SAVE ZERO PAGE LOCATIONS STA SAVEZP LDA PTRH STA SAVEZP+1 LDA #$00 STA PTRL STX PTRH LDA (PTR),Y STA PTRL PLA LDX #MOUROM LDY #MOUSLOT PHP SEI JSR IJMP PLP LDA SAVEZP ; RESTORE ZERO PAGE LOCATIONS STA PTRL LDA SAVEZP+1 STA PTRH SEC ; MOUSE PRESENT FLAG RTS ; ; HOST REQUEST/RESPONSE HANDLING ; RECVADDR: JSR SENDACC ; ECHO REQUEST JSR SENDACC ; DUMMY VALUE JSR SENDACC ; DUMMY VALUE JSR RECVACC STA PTRL TXA ; ACK JSR SENDACC JSR RECVACC STA PTRH TXA ; ACK JMP SENDACC RECVCNT: JSR RECVACC STA CNTL TXA ; ACK JSR SENDACC JSR RECVACC STA CNTH ; INC FOR LOOP CONTROL INC CNTH TXA ; ACK JMP SENDACC HOSTREQ: LDX PTRL ; SAVE ZERO PAGE LOCATIONS STX SAVEZP LDX PTRH STX SAVEZP+1 READREQ: CMP #$90 ; READ BYTES BNE WRITEREQ LDX #$91 JSR RECVADDR JSR RECVCNT LDX #$00 READLP: LDA (PTR,X) JSR SENDACC INC PTRL BNE READDEC INC PTRH READDEC: DEC CNTL BNE READLP DEC CNTH BNE READLP BEQ OKREQ WRITEREQ: CMP #$92 ; WRITE BYTES BNE CALLREQ SEI ; DISABLE INTERRUPTS LDX #$93 JSR RECVADDR JSR RECVCNT LDX #$00 WRITELP: JSR RECVACC STA (PTR,X) INC PTRL BNE WRITEDEC INC PTRH WRITEDEC: DEC CNTL BNE WRITELP DEC CNTH BNE WRITELP BEQ OKREQ CALLREQ: CMP #$94 BEQ CALLREQ1 CMP #$9A BNE CINREQ CALLREQ1: TAX INX JSR RECVADDR JSR IJMP OKREQ: LDX #$9E ; REQ COMPLETE OK SENDCOMP: CLI ; ENABLE INTERRUPTS PHP PHA TXA JSR SENDACC PLA JSR SENDACC ; ACCUM VALUE PLA JSR SENDACC ; FLAGS VALUE LDA SAVEZP ; RESTORE ZERO PAGE LOCATIONS STA PTRL LDA SAVEZP+1 STA PTRH EXREQ: CLC RTS CINREQ: CMP #$96 BNE RESYNC LDX #$97 JSR RECVADDR LDA #$9E ; REQ COMPLETE OK JSR SENDACC LDA PTRL LDX SAVEZP ; RESTORE ZERO PAGE LOCATIONS STX PTRL LDX SAVEZP+1 STX PTRH JSR SENDACC ; ECHO VALUE JSR SENDACC ; ECHO VALUE SEC ; RETURN CHAR TO RDKEY RTS RESYNC: CMP #$80 ; RESYNC WITH HOST BNE BADREQ JSR SENDACC ; ECHO JSR RECVACC CMP #$81 BEQ EXREQ ; JMP UNHOOK BNE RESYNC BADREQ: LDX #$9F ; REQ BAD BNE SENDCOMP ; ; CLEANUP ; EXIT: LDA KBCLR JSR $C300 LDA RESET+1 BEQ EX1 STA $3F3 EOR #$A5 STA $3F4 LDA RESET STA $3F2 EX1: LDY #$12 ; SET MOUSE LDA #$00 ; DISABLE MOUSE STA RESET STA RESET+1 JMP CALLMOU IJMP: JMP (PTR) MOUXSTAT: .byte 0 MOUYSTAT: .byte 0 BTTNSTAT: .byte 0 KEYSTAT: .byte 0 WAITEV: .byte 0 CNTL: .byte 0 CNTH: .byte 0 RESET: .word 0 SAVEZP: .word 0 SAVEX: .byte 0 SAVEY: .byte 0 CHRIN: .byte 0 SPINNER: .byte $af, $ad, $dc, $fc ; "/-\|" (i.e. rotate clockwise) SCCTABLEN: .byte 24 ; Number of bytes to follow SCCTAB: .byte 9, RESETB .byte 3, %11000000 .byte 5, %01100010 .byte 14, %00000000 .byte 4, %10000100 .byte 11, WR11BXTAL .byte 3, %11000001 .byte 5, %01101010 .byte 15, %00000000 .byte 0, %00010000 ; Need this twice .byte 0, %00010000 ; Need this twice .byte 1, %00000000