From 7112146a0d2bf31835801d1b44528dcc994eaad7 Mon Sep 17 00:00:00 2001 From: jgharston Date: Sun, 16 Oct 2022 00:54:55 +0100 Subject: [PATCH] Character input loop enables IRQs Character input loop enables IRQs. Fixed bug where cursor keys all returned TAB if *FX4,2 active. --- auxmem.chario.s | 352 ++++++++++++++++++++++++------------------------ 1 file changed, 177 insertions(+), 175 deletions(-) diff --git a/auxmem.chario.s b/auxmem.chario.s index 6c67cac..c0d6177 100644 --- a/auxmem.chario.s +++ b/auxmem.chario.s @@ -1,5 +1,5 @@ * AUXMEM.CHARIO.S -* (c) Bobbi 2021 GPLv3 +* (c) Bobbi 2021,2022 GPLv3 * * AppleMOS Character I/O @@ -9,7 +9,7 @@ * Character read and write * * 14-Aug-2021 Flashing cursor and INKEY sync'd to frame rate -* with VBLK. Ensured cursor turned on straightaway. +* with VBLK. Ensured cursor turned on straight away. * 15-Aug-2021 Cursor keys move copy cursor, copy reads char. * Copy cursor not visible yet. * 16-Aug-2021 Copy cursor and Edit cursor visible. @@ -27,11 +27,18 @@ * 12-Sep-2021 COPY calls new VDU entry point. * 15-Sep-2021 INKEY(0) tests once and returns immediately. * 30-Nov-2021 With *FX4,<>0 TAB returns $09, allows eg VIEW to work. -* 13-Sep-2022 Fix bug in INKEY with misbalanced stack when Escape pressed -* TO DO: CHKESC should go through translations before testing. +* 15-Oct-2022 Replace calling KBDCHKESC with ESCPOLL, does translations, etc. +* Fixed bug with cursor keys after *FX4,2. OSRDCH enables IRQs. -FLASHER EQU BYTEVARBASE+176 ; VSync counter for flashing cursor +* Hardware locations +KBDDATA EQU $C000 ; Read Keyboard data +KBDACK EQU $C010 ; Acknowledge keyboard data +KBDAPPLFT EQU $C061 ; Left Apple key +KBDAPPRGT EQU $C062 ; Right Apple key +IOVBLNK EQU $C019 ; VBLNK pulse + +FLASHER EQU BYTEVARBASE+176 ; VSync counter for flashing cursor FXEXEC EQU BYTEVARBASE+198 FXSPOOL EQU BYTEVARBASE+199 @@ -56,23 +63,23 @@ WRCHHND PHA PHX PHY PHA - JSR OUTCHAR - * TO DO Check any output redirections * TO DO Check any printer output -* BCC WRCHHND3 -* PLA + JSR OUTCHAR ; Send to VDU driver +* BCC WRCHHND3 ; VDU driver says skip printer +* PLA ; Get character back * PHA -* JSR PRNCHAR +* JSR PRNCHAR ; Send to printer * WRCHHND3 - - LDY FXSPOOL ; See if *SPOOL is in effect - BEQ WRCHHND4 +* Check FX3VAR +* Bxx WRCHHND4 ; Spool disabled + LDY FXSPOOL ; See if *SPOOL is in effect + BEQ WRCHHND4 ; No, skip sending to spool file PLA PHA - JSR OSBPUT ; Write char to spool file -WRCHHND4 PLA - PLY + JSR OSBPUT ; Write character to spool file +WRCHHND4 PLA ; Drop stacked character + PLY ; Restore everything PLX PLA RTS @@ -81,32 +88,32 @@ WRCHHND4 PLA * Character Input ***************** * Default keyboard OSBYTE variables -*DEFBYTELOW EQU 219 ; First default OSBYTE value -*DEFBYTE DB $09,$1B ; Default key codes -* DB $01,$D0,$E0,$F0 ; Default key expansion -* DB $01,$80,$90,$00 ; Default key expansion +*DEFBYTELOW EQU 219 ; First default OSBYTE value +*DEFBYTE DB $09,$1B ; Default key codes +* DB $01,$D0,$E0,$F0 ; Default key expansion +* DB $01,$80,$90,$00 ; Default key expansion *DEFBYTEEND * TEMP as no *KEY * Default keyboard OSBYTE variables -DEFBYTELOW EQU 219 ; First default OSBYTE value -DEFBYTE DB $09,$1B ; Default key codes - DB $C0,$D0,$E0,$F0 ; Default key expansion - DB $80,$90,$A0,$B0 ; Default key expansion +DEFBYTELOW EQU 219 ; First default OSBYTE value +DEFBYTE DB $09,$1B ; Default key codes + DB $C0,$D0,$E0,$F0 ; Default key expansion + DB $80,$90,$A0,$B0 ; Default key expansion DEFBYTEEND KBDINIT LDX #DEFBYTEEND-DEFBYTE-1 -:KBDINITLP LDA DEFBYTE,X ; Initialise KBD OSBYTE variables +:KBDINITLP LDA DEFBYTE,X ; Initialise KBD OSBYTE variables STA BYTEVARBASE+DEFBYTELOW,X DEX BPL :KBDINITLP LDX #$C0 - STX FX254VAR ; b7-b4=default KBD map, b3-b0=default MODE - BIT SETV - JSR KBDTEST - BCS :KBDINITOK ; Return default MODE=0 - STA KBDSTRB ; Ack. keypress - TAX ; Use keypress as default MODE + STX FX254VAR ; b7-b4=default KBD map, b3-b0=default MODE + BIT SETV ; Set V + JSR KBDTEST ; Test if key being pressed + BCS :KBDINITOK ; Return default MODE=0 + STA KBDACK ; Ack. keypress + TAX ; Use keypress as default MODE :KBDINITOK TXA RTS @@ -115,88 +122,89 @@ KBDINIT LDX #DEFBYTEEND-DEFBYTE-1 * Read a character from current input * All registers preserved except A, Carry * Flashes a soft cursor while waiting for input +* *NB* OSRDCH returns with IRQs enabled, INKEY returns with IRQs preserved * -RDCHHND LDA #$80 ; flag=wait forever +RDCHHND LDA #$80 ; flag=wait forever PHY TAY - BRA INKEYGO ; Wait forever for input + BRA INKEYGO ; Wait forever for input * XY<$8000 - wait for a keypress -INKEY PHY ; Dummy PHY to balance RDCH -INKEYGO PHX ; Save registers +INKEY PHY ; Dummy PHY to balance RDCH +INKEYGO CLI ; Enable IRQs + PHX ; Save registers PHY - BIT VDUSTATUS ; Enable editing cursor - BVC INKEYGO2 ; No editing cursor - JSR GETCHRC ; Get character under cursor - STA COPYCHAR ; Save char under edit cursor + BIT VDUSTATUS ; Enable editing cursor + BVC INKEYGO2 ; No editing cursor + JSR GETCHRC ; Get character under cursor + STA COPYCHAR ; Save char under edit cursor LDA CURSORED - JSR PUTCHRC ; Display edit cursor - JSR COPYSWAP1 ; Swap to copy cursor -INKEYGO2 JSR GETCHRC ; Get character under cursor + JSR PUTCHRC ; Display edit cursor + JSR COPYSWAP1 ; Swap to copy cursor +INKEYGO2 JSR GETCHRC ; Get character under cursor STA OLDCHAR - BRA INKEY1 ; Turn cursor on + BRA INKEY1 ; Turn cursor on INKEYLP CLC - LDA #$01 ; Slow flash, every 32 frames + LDA #$01 ; Slow flash, every 32 frames BIT VDUSTATUS BVC INKEY0 - ASL A ; Fast flash, every 16 frames + ASL A ; Fast flash, every 16 frames INKEY0 ADC FLASHER STA FLASHER AND #15 - BNE INKEY3 ; Not time to toggle yet - LDA OLDCHAR ; Prepare to remove cursor + BNE INKEY3 ; Not time to toggle yet + LDA OLDCHAR ; Prepare to remove cursor BIT FLASHER - BMI INKEY2 ; Remove cursor -INKEY1 LDA CURSOR ; Add cursor + BMI INKEY2 ; Remove cursor +INKEY1 LDA CURSOR ; Add cursor BIT VDUSTATUS BVC INKEY2 LDA CURSORCP -INKEY2 JSR PUTCHRC ; Toggle cursor +INKEY2 JSR PUTCHRC ; Toggle cursor INKEY3 LDA ESCFLAG - BMI INKEYOK ; Escape pending, return it -INKEY4 JSR KEYREAD ; Test for input, all can be trashed + BMI INKEYOK ; Escape pending, return it +INKEY4 JSR KEYREAD ; Test for input, all can be trashed PLY - BCC INKEYOK ; Char returned, return it - BMI INKEY6 ; Loop forever, skip countdown + BCC INKEYOK ; Char returned, return it + BMI INKEY6 ; Loop forever, skip countdown PLX BNE INKEY5 TYA - BEQ INKEYOUT ; XY=0, timed out - DEY ; 16-bit decrement + BEQ INKEYOUT ; XY=0, timed out + DEY ; 16-bit decrement INKEY5 DEX PHX INKEY6 PHY * * VBLK pulses at 50Hz/60Hz, toggles at 100Hz/120Hz - LDX RDVBL ; Get initial VBLK state -INKEY8 BIT KEYBOARD - BMI INKEY4 ; Key pressed + LDX IOVBLNK ; Get initial VBLK state +INKEY8 BIT KBDDATA + BMI INKEY4 ; Key pressed TXA - EOR RDVBL - BPL INKEY8 ; Wait for VBLK change - BMI INKEYLP ; Loop back to key test + EOR IOVBLNK + BPL INKEY8 ; Wait for VBLK change + BMI INKEYLP ; Loop back to key test -INKEYOUT PLA ; Drop stacked Y - LDA #$FF ; Prepare to stack $FF -* -INKEYOK PHA ; Save key or timeout - PHP ; Save CC=key, CS=timeout - LDA OLDCHAR ; Prepare for main cursor +INKEYOUT PLA ; Drop stacked Y + LDA #$FF ; Prepare to stack $FF +INKEYOK PHA ; Save key or timeout + PHP ; Save CC=key, CS=timeout + LDA OLDCHAR ; Prepare for main cursor BIT VDUSTATUS - BVC INKEYOFF2 ; No editing cursor - JSR PUTCHRC ; Remove cursor - JSR COPYSWAP1 ; Swap cursor back - LDA COPYCHAR ; Remove main cursor -INKEYOFF2 JSR PUTCHRC ; Remove cursor + BVC INKEYOFF2 ; No editing cursor + JSR PUTCHRC ; Remove cursor + JSR COPYSWAP1 ; Swap cursor back + LDA COPYCHAR ; Remove main cursor +INKEYOFF2 JSR PUTCHRC ; Remove cursor * PLP - BCS INKEYOK3 ; Timeout - LDA ESCFLAG ; Keypress, test for Escape - ASL A ; Cy=Escape flag - PLA ; Get char back - PLX ; Restore X,Y for key pressed -INKEYOK3 PLY ; Or pop TimeOut + BCS INKEYOK3 ; Timeout + LDA ESCFLAG ; Keypress, test for Escape + ASL A ; Cy=Escape flag + PLA ; Get char back + PLX ; Restore X,Y for key pressed +INKEYOK3 PLY ; Or pop TimeOut RTS * RDCH Character read: CC, A=char, X=restored, Y=restored * RDCH Escape: CS, A=char, X=restored, Y=restored @@ -206,17 +214,17 @@ INKEYOK3 PLY ; Or pop TimeOut BYTE81 TYA - BMI NEGINKEY ; XY<0, scan for keypress - JSR INKEY ; XY>=0, wait for keypress + BMI NEGINKEY ; XY<0, scan for keypress + JSR INKEY ; XY>=0, wait for keypress * Character read: CC, A=char, X=???, Y<$80 * Escape: CS, A=char, X=???, Y<$80 * Timeout: CS, A=???, X=???, Y=$FF - TAX ; X=character returned + TAX ; X=character returned TYA - BMI BYTE81DONE ; Y=$FF, timeout + BMI BYTE81DONE ; Y=$FF, timeout LDY #$00 - BCC BYTE81DONE ; CC, not Escape - LDY #$1B ; Y=27 + BCC BYTE81DONE ; CC, not Escape + LDY #$1B ; Y=27 BYTE81DONE RTS * Returns: Y=$FF, X=???, CS - timeout * Y=$1B, X=???, CS - escape @@ -224,25 +232,21 @@ BYTE81DONE RTS NEGINKEY CPX #$01 - LDX #$00 ; Unimplemented + LDX #$00 ; Unimplemented BCS NEGINKEY0 - - JSR NEGCALL ; Read machine ID from aux - TAX ; *TEST* - BIT $E0 ; *TEST* - BVS NEGINKEY1 ; *TEST* + JSR NEGCALL ; Read machine ID from mainmem LDX #$2C TAY - BEQ NEGINKEY0 ; $00 = Apple IIc -> INKEY-256 = $2C + BEQ NEGINKEY0 ; $00 = Apple IIc -> INKEY-256 = $2C LDX #$2E AND #$0F - BEQ NEGINKEY0 ; $x0 = Apple IIe -> INKEY-256 = $2E - LDX #$2A ; else = Apple IIgs -> INKEY-256 = $2A + BEQ NEGINKEY0 ; $x0 = Apple IIe -> INKEY-256 = $2E + LDX #$2A ; else = Apple IIgs -> INKEY-256 = $2A NEGINKEY0 LDY #$00 NEGINKEY1 CLC RTS -NEGCALL >>> XF2MAIN,MACHRD ; Try to read Machine ID +NEGCALL >>> XF2MAIN,MACHRD ; Try to read Machine ID * KERNEL/KEYBOARD.S @@ -256,15 +260,14 @@ NEGCALL >>> XF2MAIN,MACHRD ; Try to read Machine ID * On exit, CS=no keypress * CC=keypress * A =keycode, X,Y=corrupted -KEYREAD LDY FXEXEC ; See if *EXEC file is open - BEQ KEYREAD1 - JSR OSBGET ; Read keypress from file - BCC KEYREADOK - LDA #0 ; EOF, close *EXEC file - STA FXEXEC - JSR OSFIND +KEYREAD LDY FXEXEC ; See if EXEC file is open + BEQ KEYREAD1 ; No, skip past + JSR OSBGET ; Read character from file + BCC KEYREADOK ; Not EOF, return it + LDA #$00 ; EOF, close EXEC file + STA FXEXEC ; Clear EXEC handle + JSR OSFIND ; And close it KEYREAD1 - * * TO DO: expand current soft key * LDA SOFTKEYLEN @@ -277,46 +280,45 @@ KEYREAD1 * RTS * KEYREAD2 * - JSR KBDREAD ; Fetch character from KBD "buffer" - BCS KEYREADOK ; Nothing pending - TAY - BPL KEYREADOK ; Not top-bit key - AND #$CF + JSR KBDREAD ; Fetch character from KBD "buffer" + BCS KEYREADOK ; Nothing pending + TAY ; Y=unmodified character + BPL KEYREADOK ; Not top-bit key + AND #$CF ; Drop Shift/Ctrl bits CMP #$C9 - BCC KEYSOFT ; Not cursor key + BCC KEYSOFTY ; Not cursor key LDX FX4VAR - BEQ KEYCURSOR ; *FX4,0 - editing keys - LDY FXTABCHAR - CMP #$C9 - BEQ KEYREADOKY ; TAB key + BEQ KEYCURSOR ; *FX4,0 - editing keys + CPY #$C9 + CLV + BEQ KEYCOPYTAB ; TAB key DEX - BNE KEYSOFT1 ; Not *FX4,1 - soft key - SBC #$44 ; Return $88-$8B - TAY -KEYREADOKY TYA + BNE KEYSOFTHI ; Not *FX4,1 - soft key + SBC #$44 ; Return $88-$8B KEYREADOK1 CLC KEYREADOK RTS -* + * Process soft key -KEYSOFT1 LDX FX254VAR +KEYSOFTHI LDX FX254VAR CPX #$C0 - BCC KEYSOFT + BCC KEYSOFTY + TYA AND #$BF TAY -KEYSOFT TYA +KEYSOFTY TYA ; Get key including Shift/Ctrl LSR A LSR A LSR A - LSR A ; A=key DIV 16 - EOR #$04 ; Offset into KEYBASE + LSR A ; A=key DIV 16 + EOR #$04 ; Offset into KEYBASE TAX LDA FXKEYBASE-8,X * TO DO: *BEQ KEYNONE ; $00=ignored *DEC A *BEQ expandfunction - CMP #2 ; *TEMP* - BCC KEYNONE ; *TEMP* + CMP #2 ; *TEMP* + BCC KEYNONE ; *TEMP* TYA AND #$0F CLC @@ -329,26 +331,26 @@ KEYCURSOR CMP #$C9 BEQ KEYCOPY PHA LDA OLDCHAR - JSR PUTCHRC ; Remove cursor + JSR PUTCHRC ; Remove cursor PLA - JSR COPYMOVE ; Move copy cursor - JSR GETCHRC ; Save char under cursor + JSR COPYMOVE ; Move copy cursor + JSR GETCHRC ; Save char under cursor STA OLDCHAR KEYNONE SEC RTS -KEYCOPY LDA FXTABCHAR ; Prepare TAB if no copy cursor - BIT VDUSTATUS - BVC KEYREADOK1 ; No copy cursor, return TAB - LDA OLDCHAR ; Get the char under cursor +KEYCOPY BIT VDUSTATUS +KEYCOPYTAB LDA FXTABCHAR ; Prepare TAB if no copy cursor + BVC KEYREADOK1 ; No copy cursor, return TAB + LDA OLDCHAR ; Get the char under cursor PHA - JSR OUTCHARCP ; Output it to restore and move cursor - JSR GETCHRC ; Save char under cursor + JSR OUTCHARCP ; Output it to restore and move cursor + JSR GETCHRC ; Save char under cursor STA OLDCHAR PLA - BNE KEYREADOK1 ; Ok character + BNE KEYREADOK1 ; Ok character SEC - JMP BEEP ; Beep and return CS=No char + JMP BEEP ; Beep and return CS=No char * KBDREAD @@ -363,63 +365,63 @@ KEYCOPY LDA FXTABCHAR ; Prepare TAB if no copy cursor * TAB -> $C9 * Cursors -> $CC-$CF * -KBDREAD CLV ; VC=return keypress -KBDTEST LDA KEYBOARD ; VS here to test for keypress - EOR #$80 ; Toggle bit 7 +KBDREAD CLV ; VC=return keypress +KBDTEST LDA KBDDATA ; VS here to test for keypress + EOR #$80 ; Toggle bit 7 CMP #$80 - BCS KBDDONE ; No key pressed - BVS KBDDONE ; VS=test for keypress - STA KBDSTRB ; Ack. keypress - BIT BUTTON0 - BMI KBDLALT ; Left Apple pressed - BIT BUTTON1 - BMI KBDRALT ; Right Apple pressed + BCS KBDDONE ; No key pressed + BVS KBDDONE ; VS=test for keypress + STA KBDACK ; Ack. keypress +KBDREAD2 BIT KBDAPPLFT + BMI KBDLALT ; Left Apple pressed + BIT KBDAPPRGT + BMI KBDRALT ; Right Apple pressed CMP #$09 - BEQ KBDTAB ; TAB is dual action TAB/COPY + BEQ KBDTAB ; TAB is dual action TAB/COPY CMP #$08 - BCC KBDCHKESC ; <$08 not cursor key + BCC KBDCHKESC ; <$08 not cursor key CMP #$0C - BCC KBDCURSR ; $08-$0B are cursor keys + BCC KBDCURSR ; $08-$0B are cursor keys CMP #$15 - BNE KBDCHKESC ; $15 is cursor key + BNE KBDCHKESC ; $15 is cursor key * -KBDCUR15 LDA #$0D ; Convert RGT to $09 -KBDTAB SBC #$04 ; Convert TAB to &C9 +KBDCUR15 LDA #$0D ; Convert RGT to $09 +KBDTAB SBC #$04 ; Convert TAB to &C9 KBDCURSR CLC - ADC #$C4 ; Cursor keys $C0+x + ADC #$C4 ; Cursor keys $C0+x BRA KBDCHKESC -KBDRALT ; Right Apple key pressed -KBDLALT CMP #$40 ; Left Apple key pressed +KBDRALT ; Right Apple key pressed +KBDLALT CMP #$40 ; Left Apple key pressed BCS KBDCTRL CMP #$30 - BCC KBDCHKESC ; <'0' + BCC KBDCHKESC ; <'0' CMP #$3A - BCS KBDCHKESC ; >'9' -KBDFUNC AND #$0F ; Convert Apple-Num to function key + BCS KBDCHKESC ; >'9' +KBDFUNC AND #$0F ; Convert Apple-Num to function key ORA #$80 - BIT BUTTON1 - BPL KBDCHKESC ; Left+Digit -> $8x - ORA #$90 ; Right+Digit -> $9x - BIT BUTTON0 +KBDFUNC2 BIT KBDAPPRGT + BPL KBDCHKESC ; Left+Digit -> $8x + ORA #$90 ; Right+Digit -> $9x + BIT KBDAPPLFT BPL KBDCHKESC - EOR #$30 ; Left+Right+Digit -> $Ax + EOR #$30 ; Left+Right+Digit -> $Ax BRA KBDCHKESC -KBDCTRL AND #$1F ; Apple-Letter -> Ctrl-Letter +KBDCTRL AND #$1F ; Apple-Letter -> Ctrl-Letter * -* Test for Escape key -KBDCHKESC TAX ; X=keycode - EOR FXESCCHAR ; Current ESCAPE char? - ORA FXESCON ; Is ESCAPE an ASCII char? - BNE KBDNOESC ; Not ESCAPE or ESCAPE=ASCII - LDA FX200VAR ; Is ESCAPE ignored? - LSR A ; Check bit 0 - BCS KBDDONE ; ESCAPE completely ignored +* Test for Escape character +KBDCHKESC TAX ; X=keycode + EOR FXESCCHAR ; Current ESCAPE char? + ORA FXESCON ; Is ESCAPE an ASCII char? + BNE KBDNOESC ; Not ESCAPE or ESCAPE=ASCII + LDA FX200VAR ; Is ESCAPE ignored? + LSR A ; Check bit 0 + BCS KBDDONE ; ESCAPE completely ignored SEC - ROR ESCFLAG ; Set Escape flag -KBDNOESC TXA ; A=keycode - CLC ; CLC=Ok + ROR ESCFLAG ; Set Escape flag +KBDNOESC TXA ; A=keycode + CLC ; CLC=Ok KBDDONE RTS