diff --git a/Source/ppk.asm b/Source/ppk.asm index 10ebc95b..fc491b77 100644 --- a/Source/ppk.asm +++ b/Source/ppk.asm @@ -70,6 +70,9 @@ PPK_STAT3: ; ;__________________________________________________________________________________________________ ; KEYBOARD READ +; +; RETURNS ASCII VALUE IN E. SEE END OF FILE FOR VALUES RETURNED FOR SPECIAL KEYS +; LIKE PGUP, ARROWS, FUNCTION KEYS, ETC. ;__________________________________________________________________________________________________ ; PPK_READ: @@ -137,11 +140,12 @@ PPK_GETBYTE2: CALL PPK_WTCLKHI CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT LD A,E ; RETURN WITH RAW SCANCODE BYTE IN A - -; ; *DEBUG* -; CALL PC_SPACE -; CALL PC_LT -; CALL PRTHEXBYTE + +#IFDEF PPK_DEBUG + CALL PC_SPACE + CALL PC_LT + CALL PRTHEXBYTE +#ENDIF OR A RET @@ -155,10 +159,11 @@ PPK_PUTBYTE: ; LD E,A ; STASH INCOMING BYTE VALUE IN E -; ; *DEBUG* -; CALL PC_SPACE -; CALL PC_GT -; CALL PRTHEXBYTE +#IFDEF PPK_DEBUG + CALL PC_SPACE + CALL PC_GT + CALL PRTHEXBYTE +#ENDIF ; START WITH DATA HI AND CLOCK LOW CALL PPK_DATHI @@ -355,67 +360,147 @@ PPK_DECODE: ; PPK_KEYCODE AND PPK_STATUS ARE CLEARED AT START. IF IS THE CALLER'S RESPONSIBILITY ; TO RETRIEVE ANY PRIOR VALUE BEFORE CALLING THIS FUNCTION AGAIN. ; +; Step 0: Initialize for next keypress +; clear status ($00) +; clear keycode ($FF) +; +; Step 1: Get scancode w/timeout +; read scancode +; if timeout +; return "timeout" +; +; Step 2: Detect and flag break prefix +; if scancode == $F0 +; set status[break] +; goto Phase 1 +; +; Step 3: Detect and flag extended prefix +; if scancode == $E0 +; set status[extended] +; goto Phase 1 +; +; Step 4: Detect and handle $E1 +; if scancode == $E1 +; ***handle pause key somehow*** +; +; Step 5: Map scancode to keycode +; if status[extended] +; apply extended-map[scancode] -> keycode +; else if state[shifted] +; apply shifted-map[scancode] -> keycode +; else +; apply normal-map[scancode] -> keycode +; +; Step 6: Handle modifier keys +; if keycode is modifier (shift, ctrl, alt, win) +; set (l/r)state[] = not status[break] +; clear modifier bits in state +; set state = (lstate OR rstate OR state) +; goto Entry +; +; Step 7: Complete procesing of key break events +; if status[break] +; goto Entry +; +; Step 8: Handle toggle keys +; if keycode is toggle (capslock, numlock, scrolllock) +; invert (XOR) state[] +; update keyboard LED's +; goto Entry +; +; Step 9: Handle control keys +; if state[ctrl] +; if keycode is 'a'-'z' +; subtract 20 (clear bit 5) from keycode +; if keycode is '@'-'_' +; subtract 40 (clear bit 6) from keycode +; +; Step 10: Adjust keycode for caps lock, if needed +; if state[capslock] +; if keycode is 'a'-'z' OR 'A'-'Z' +; toggle (XOR) bit 5 of keycode +; +; Step 11: Handle num pad keys +; if keycode is numpad +; set state[numpad] +; if state[numlock] +; toggle (XOR) bit 4 of keycode +; apply numpad-map[keycode] -> keycode +; else +; clear state[numpad] +; +; Step 12: Detect unknown/invalid keycodes +; if keycode == $FF +; goto Entry +; +; Step 13: Done +; return "ready" +; +PPK_DEC0: XOR A ; A = ZERO LD (PPK_STATUS),A ; CLEAR STATUS DEC A ; A = $FF LD (PPK_KEYCODE),A ; CLEAR KEYCODE -PPK_DECODENEXT: ; PROCESS NEXT SCANCODE +PPK_DEC1: ; GET SCANCODE W/ TIMEOUT CALL PPK_GETBYTE ; GET A SCANCODE RET Z ; TIMEOUT, RETURN WITH A=0, Z SET LD (PPK_SCANCODE),A ; SAVE SCANCODE -PPK_DECODE1: ; HANDLE BREAK (KEYUP) F0 PREFIX +PPK_DEC2: ; DETECT AND FLAG BREAK PREFIX $F0 CP $F0 ; BREAK (KEY UP) PREFIX? - JR NZ,PPK_DECODE2 ; NOPE MOVE ON + JR NZ,PPK_DEC3 ; NOPE MOVE ON LD A,(PPK_STATUS) ; GET STATUS OR PPK_BREAK ; SET BREAK BIT LD (PPK_STATUS),A ; SAVE STATUS - JR PPK_DECODENEXT ; LOOP TO DO NEXT SCANCODE + JR PPK_DEC1 ; LOOP TO DO NEXT SCANCODE -PPK_DECODE2: ; HANDLE EXTENDED KEY E0 PREFIX +PPK_DEC3: ; DETECT AND FLAG EXTENDED PREFIX $E0 CP $E0 ; EXTENDED KEY PREFIX? - JR NZ,PPK_DECODE3 ; NOPE MOVE ON + JR NZ,PPK_DEC4 ; NOPE MOVE ON LD A,(PPK_STATUS) ; GET STATUS OR PPK_EXT ; SET EXTENDED BIT LD (PPK_STATUS),A ; SAVE STATUS - JR PPK_DECODENEXT ; LOOP TO DO NEXT SCANCODE + JR PPK_DEC1 ; LOOP TO DO NEXT SCANCODE -PPK_DECODE3: ; HANDLE SPECIAL EXTENDED KEY E1 PREFIX +PPK_DEC4: ; DETECT AND HANDLE EXTENDED PREFIX $E1 ; TODO: HANDLE PAUSE KEY HERE... -PPK_DECODE4: ; PERFORM EXTENDED MAPPING +PPK_DEC5: ; MAP SCANCODE TO KEYCODE LD A,(PPK_STATUS) ; GET STATUS AND PPK_EXT ; EXTENDED BIT SET? - JR Z,PPK_DECODE5 ; NOPE, MOVE ON + JR Z,PPK_DEC5C ; NOPE, MOVE ON + + ; PERFORM EXTENDED KEY MAPPING LD A,(PPK_SCANCODE) ; GET SCANCODE LD E,A ; STASH IT IN E LD HL,PPK_MAPEXT ; POINT TO START OF EXT MAP TABLE -PPK_DECODE4A: +PPK_DEC5A: LD A,(HL) ; GET FIRST BYTE OF PAIR CP $00 ; END OF TABLE? JP Z,PPK_DECODE ; UNKNOWN OR BOGUS, START OVER INC HL ; INC HL FOR FUTURE CP E ; DOES MATCH BYTE EQUAL SCANCODE? - JR Z,PPK_DECODE4B ; YES! JUMP OUT + JR Z,PPK_DEC5B ; YES! JUMP OUT INC HL ; BUMP TO START OF NEXT PAIR - JR PPK_DECODE4A ; LOOP TO CHECK NEXT TABLE ENTRY -PPK_DECODE4B: + JR PPK_DEC5A ; LOOP TO CHECK NEXT TABLE ENTRY +PPK_DEC5B: LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE LD (PPK_KEYCODE),A ; SAVE IT - JR PPK_DECODE6 + JR PPK_DEC6 -PPK_DECODE5: ; PERFORM SHIFTED/UNSHIFTED MAPPING +PPK_DEC5C: ; PERFORM REGULAR KEY (NOT EXTENDED) KEY MAPPING LD A,(PPK_SCANCODE) ; GET THE SCANCODE CP $85 ; PAST END OF TABLE? - JR NC,PPK_DECODE6 ; YES, SKIP OVER LOOKUP + JR NC,PPK_DEC6 ; YES, SKIP OVER LOOKUP + ; SETUP POINTER TO MAPPING TABLE BASED ON SHIFTED OR UNSHIFTED STATE LD A,(PPK_STATE) ; GET STATE AND PPK_SHIFT ; SHIFT ACTIVE? LD HL,PPK_MAPSTD ; LOAD ADDRESS OF NON-SHIFTED MAPPING TABLE - JR Z,PPK_DECODE5A ; NON-SHIFTED, MOVE ON + JR Z,PPK_DEC5D ; NON-SHIFTED, MOVE ON LD HL,PPK_MAPSHIFT ; LOAD ADDRESS OF SHIFTED MAPPING TABLE -PPK_DECODE5A: +PPK_DEC5D: LD A,(PPK_SCANCODE) ; GET THE SCANCODE LD E,A ; SCANCODE TO E FOR TABLE OFFSET LD D,0 ; D -> 0 @@ -423,71 +508,71 @@ PPK_DECODE5A: LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE LD (PPK_KEYCODE),A ; SAVE IT -PPK_DECODE6: ; HANDLE MODIFIER KEY MAKE/BREAK EVENTS +PPK_DEC6: ; HANDLE MODIFIER KEYS LD A,(PPK_KEYCODE) ; MAKE SURE WE HAVE KEYCODE CP $B8 ; END OF MODIFIER KEYS - JR NC,PPK_DECODE13 ; BYPASS MODIFIER KEY CHECKING + JR NC,PPK_DEC7 ; BYPASS MODIFIER KEY CHECKING CP $B0 ; START OF MODIFIER KEYS - JR C,PPK_DECODE13 ; BYPASS MODIFIER KEY CHECKING + JR C,PPK_DEC7 ; BYPASS MODIFIER KEY CHECKING ; TODO: STUFF BELOW COULD BE A LOOP ; HANDLE L/R SHIFT KEYS LD E,PPK_SHIFT ; SETUP TO SET/CLEAR SHIFT BIT SUB $B0 ; L-SHIFT? - JR Z,PPK_DECODE7 ; YES, HANDLE L-SHIFT MAKE/BREAK + JR Z,PPK_DEC6A ; YES, HANDLE L-SHIFT MAKE/BREAK DEC A ; R-SHIFT? - JR Z,PPK_DECODE8 ; YES, HANDLE R-SHIFT MAKE/BREAK + JR Z,PPK_DEC6B ; YES, HANDLE R-SHIFT MAKE/BREAK ; HANDLE L/R CONTROL KEYS LD E,PPK_CTRL ; SETUP TO SET/CLEAR CONTROL BIT DEC A ; L-CONTROL? - JR Z,PPK_DECODE7 ; YES, HANDLE L-CONTROL MAKE/BREAK + JR Z,PPK_DEC6A ; YES, HANDLE L-CONTROL MAKE/BREAK DEC A ; R-CONTROL? - JR Z,PPK_DECODE8 ; YES, HANDLE R-CONTROL MAKE/BREAK + JR Z,PPK_DEC6B ; YES, HANDLE R-CONTROL MAKE/BREAK ; HANDLE L/R ALT KEYS LD E,PPK_ALT ; SETUP TO SET/CLEAR ALT BIT DEC A ; L-ALT? - JR Z,PPK_DECODE7 ; YES, HANDLE L-ALT MAKE/BREAK + JR Z,PPK_DEC6A ; YES, HANDLE L-ALT MAKE/BREAK DEC A ; R-ALT? - JR Z,PPK_DECODE8 ; YES, HANDLE R-ALT MAKE/BREAK + JR Z,PPK_DEC6B ; YES, HANDLE R-ALT MAKE/BREAK ; HANDLE L/R WIN KEYS LD E,PPK_WIN ; SETUP TO SET/CLEAR WIN BIT DEC A ; L-WIN? - JR Z,PPK_DECODE7 ; YES, HANDLE L-WIN MAKE/BREAK + JR Z,PPK_DEC6A ; YES, HANDLE L-WIN MAKE/BREAK DEC A ; R-WIN? - JR Z,PPK_DECODE8 ; YES, HANDLE R-WIN MAKE/BREAK + JR Z,PPK_DEC6B ; YES, HANDLE R-WIN MAKE/BREAK -PPK_DECODE7: ; LEFT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) - LD HL,PPK_LSTATE - JR PPK_DECODE9 +PPK_DEC6A: ; LEFT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) + LD HL,PPK_LSTATE ; POINT TO LEFT STATE BYTE + JR PPK_DEC6C ; CONTINUE -PPK_DECODE8: ; RIGHT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) - LD HL,PPK_RSTATE - JR PPK_DECODE9 +PPK_DEC6B: ; RIGHT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) + LD HL,PPK_RSTATE ; POINT TO RIGHT STATE BYTE + JR PPK_DEC6C ; CONTINUE -PPK_DECODE9: ; BRANCH BASED ON WHETHER THIS IS A MAKE OR BREAK EVENT +PPK_DEC6C: ; BRANCH BASED ON WHETHER THIS IS A MAKE OR BREAK EVENT LD A,(PPK_STATUS) ; GET STATUS FLAGS AND PPK_BREAK ; BREAK EVENT? - JR Z,PPK_DECODE10 ; NO, HANDLE A MODIFIER KEY MAKE EVENT - JR PPK_DECODE11 ; YES, HANDLE A MODIFIER BREAK EVENT - -PPK_DECODE10: ; HANDLE STATE KEY MAKE EVENT - LD A,E - OR (HL) - LD (HL),A - JR PPK_DECODE12 - -PPK_DECODE11: ; HANDLE STATE KEY BREAK EVENT - LD A,E - XOR $FF - AND (HL) - LD (HL),A - JR PPK_DECODE12 + JR Z,PPK_DEC6D ; NO, HANDLE A MODIFIER KEY MAKE EVENT + JR PPK_DEC6E ; YES, HANDLE A MODIFIER BREAK EVENT + +PPK_DEC6D: ; HANDLE STATE KEY MAKE EVENT + LD A,E ; GET THE BIT TO SET + OR (HL) ; OR IN THE CURRENT BITS + LD (HL),A ; SAVE THE RESULT + JR PPK_DEC6F ; CONTINUE + +PPK_DEC6E: ; HANDLE STATE KEY BREAK EVENT + LD A,E ; GET THE BIT TO CLEAR + XOR $FF ; FLIP ALL BITS TO SETUP FOR A CLEAR OPERATION + AND (HL) ; AND IN THE FLIPPED BITS TO CLEAR DESIRED BIT + LD (HL),A ; SAVE THE RESULT + JR PPK_DEC6F ; CONTINUE -PPK_DECODE12: ; COALESCE L/R STATE FLAGS +PPK_DEC6F: ; COALESCE L/R STATE FLAGS LD A,(PPK_STATE) ; GET EXISTING STATE BITS AND $F0 ; GET RID OF OLD MODIFIER BITS LD DE,(PPK_LSTATE) ; LOAD BOTH L/R STATE BYTES IN D/E @@ -496,119 +581,120 @@ PPK_DECODE12: ; COALESCE L/R STATE FLAGS LD (PPK_STATE),A ; SAVE IT JP PPK_DECODE ; DONE WITH CURRENT KEYSTROKE -PPK_DECODE13: ; NO MORE BREAK KEY PROCESSING! - LD A,(PPK_STATUS) - AND PPK_BREAK - JP NZ,PPK_DECODE - -PPK_DECODE14: ; TOGGLE KEY PROCESSING - LD A,(PPK_KEYCODE) - LD E,PPK_CAPSLCK - CP $BC - JR Z,PPK_DECODE15 - LD E,PPK_NUMLCK - CP $BD - JR Z,PPK_DECODE15 - LD E,PPK_SCRLCK - CP $BE - JR Z,PPK_DECODE15 - JR PPK_DECODE16 - -PPK_DECODE15: ; RECORD THE TOGGLE - LD A,(PPK_STATE) - XOR E - LD (PPK_STATE),A +PPK_DEC7: ; COMPLETE PROCESSING OF KEY BREAK EVENTS + LD A,(PPK_STATUS) ; GET CURRENT STATUS FLAGS + AND PPK_BREAK ; IS THIS A KEY BREAK EVENT? + JP NZ,PPK_DECODE ; YES, RESTART TO PROCESS NEXT KEY + +PPK_DEC8: ; HANDLE TOGGLE KEYS + LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE INTO A + LD E,PPK_CAPSLCK ; SETUP E WITH CAPS LOCK STATE BIT + CP $BC ; IS THIS THE CAPS LOCK KEY? + JR Z,PPK_DEC8A ; YES, GO TO BIT SET ROUTINE + LD E,PPK_NUMLCK ; SETUP E WITH NUM LOCK STATE BIT + CP $BD ; IS THIS THE NUM LOCK KEY? + JR Z,PPK_DEC8A ; YES, GO TO BIT SET ROUTINE + LD E,PPK_SCRLCK ; SETUP E WITH SCROLL LOCK STATE BIT + CP $BE ; IS THIS THE SCROLL LOCK KEY? + JR Z,PPK_DEC8A ; YES, GO TO BIT SET ROUTINE + JR PPK_DEC9 ; NOT A TOGGLE KEY, CONTINUE +PPK_DEC8A: ; RECORD THE TOGGLE + LD A,(PPK_STATE) ; GET THE CURRENT STATE FLAGS + XOR E ; SET THE TOGGLE KEY BIT FROM ABOVE + LD (PPK_STATE),A ; SAVE IT + + ; UPDATE KEYBOARD LED'S LD A,$ED ; SET/RESET LED'S COMMAND - CALL PPK_PUTBYTE - CALL PPK_GETBYTE + CALL PPK_PUTBYTE ; SEND THE COMMAND + CALL PPK_GETBYTE ; READ THE RESPONSE CP $FA ; MAKE SURE WE GET ACK JP NZ,PPK_DECODE ; ABORT IF NO ACK - LD A,(PPK_STATE) - RRCA + LD A,(PPK_STATE) ; LOAD THE STATE BYTE + RRCA ; ROTATE TOGGLE KEY BITS AS NEEDED RRCA RRCA RRCA - AND $07 + AND $07 ; CLEAR THE IRRELEVANT BITS CALL PPK_PUTBYTE ; SEND THE LED DATA CALL PPK_GETBYTE ; READ THE ACK - - JP PPK_DECODE ; DONE WITH CURRENT KEYSTROKE - -PPK_DECODE16: ; CONTROL KEY PROCESSING - LD A,(PPK_STATE) - AND PPK_CTRL - JR Z,PPK_DECODE18 ; CONTROL KEY NOT PRESSED, MOVE ON - LD A,(PPK_KEYCODE) - CP 'a' - JR C,PPK_DECODE17 - CP 'z' + 1 - JR NC,PPK_DECODE17 - RES 5,A ; CLEAR BIT 5 TO MAP LOWERCASE A-Z TO UPPERCASE -PPK_DECODE17: - CP '@' - JR C,PPK_DECODE18 - CP '_' + 1 - JR NC,PPK_DECODE18 - RES 6,A + JP PPK_DECODE ; RESTART DECODER FOR A NEW KEY + +PPK_DEC9: ; HANDLE CONTROL KEYS + LD A,(PPK_STATE) ; GET THE CURRENT STATE BITS + AND PPK_CTRL ; CHECK THE CONTROL BIT + JR Z,PPK_DEC10 ; CONTROL KEY NOT PRESSED, MOVE ON + LD A,(PPK_KEYCODE) ; GET CURRENT KEYCODE IN A + CP 'a' ; COMPARE TO LOWERCASE A + JR C,PPK_DEC9A ; BELOW IT, BYPASS + CP 'z' + 1 ; COMPARE TO LOWERCASE Z + JR NC,PPK_DEC9A ; ABOVE IT, BYPASS + RES 5,A ; KEYCODE IN LOWERCASE A-Z RANGE CLEAR BIT 5 TO MAKE IT UPPERCASE +PPK_DEC9A: + CP '@' ; COMPARE TO @ + JR C,PPK_DEC10 ; BELOW IT, BYPASS + CP '_' + 1 ; COMPARE TO _ + JR NC,PPK_DEC10 ; ABOVE IT, BYPASS + RES 6,A ; CONVERT TO CONTROL VALUE BY CLEARING BIT 6 LD (PPK_KEYCODE),A ; UPDATE KEYCODE TO CONTROL VALUE -PPK_DECODE18: ; CAPS LOCK KEY PROCESSING - LD A,(PPK_STATE) - AND PPK_CAPSLCK - JR Z,PPK_DECODE21 ; CAPS LOCK NOT ACTIVE, MOVE ON - LD A,(PPK_KEYCODE) - CP 'a' - JR C,PPK_DECODE19 - CP 'z' + 1 - JR NC,PPK_DECODE19 - JR PPK_DECODE20 -PPK_DECODE19: - CP 'A' - JR C,PPK_DECODE21 - CP 'Z' + 1 - JR NC,PPK_DECODE21 - JR PPK_DECODE20 -PPK_DECODE20: - LD A,(PPK_KEYCODE) - XOR $20 - LD (PPK_KEYCODE),A - -PPK_DECODE21: ; NUM PAD PROCESSING - LD A,(PPK_STATE) - AND ~PPK_NUMPAD - LD (PPK_STATE),A ; ASSUME NOT A NUMPAD KEY +PPK_DEC10: ; ADJUST KEYCODE FOR CAPS LOCK, IF NEEDED + LD A,(PPK_STATE) ; LOAD THE STATE FLAGS + AND PPK_CAPSLCK ; CHECK CAPS LOCK + JR Z,PPK_DEC11 ; CAPS LOCK NOT ACTIVE, MOVE ON + LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE VALUE + CP 'a' ; COMPARE TO LOWERCASE A + JR C,PPK_DEC10A ; BELOW IT, BYPASS + CP 'z' + 1 ; COMPARE TO LOWERCASE Z + JR NC,PPK_DEC10A ; ABOVE IT, BYPASS + JR PPK_DEC10B ; IN RANGE LOWERCASE A-Z, GO TO CASE SWAPPING LOGIC +PPK_DEC10A: + CP 'A' ; COMPARE TO UPPERCASE A + JR C,PPK_DEC11 ; BELOW IT, BYPASS + CP 'Z' + 1 ; COMPARE TO UPPERCASE Z + JR NC,PPK_DEC11 ; ABOVE IT, BYPASS + JR PPK_DEC10B ; IN RANGE UPPERCASE A-Z, GO TO CASE SWAPPING LOGIC +PPK_DEC10B: + LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE + XOR $20 ; FLIP BIT 5 TO SWAP UPPER/LOWER CASE + LD (PPK_KEYCODE),A ; SAVE IT + +PPK_DEC11: ; HANDLE NUM PAD KEYS + LD A,(PPK_STATE) ; GET THE CURRENT STATE FLAGS + AND ~PPK_NUMPAD ; ASSUME NOT A NUMPAD KEY, CLEAR THE NUMPAD BIT + LD (PPK_STATE),A ; SAVE IT - LD A,(PPK_KEYCODE) + LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE AND 11100000B ; ISOLATE TOP 3 BITS - CP 11000000B ; IS NUMPAD RANGE? - JR NZ,PPK_DECODEX ; NOPE, GET OUT + CP 11000000B ; IS IN NUMPAD RANGE? + JR NZ,PPK_DEC12 ; NOPE, GET OUT - LD A,(PPK_STATE) - OR PPK_NUMPAD - LD (PPK_STATE),A ; SET NUMPAD BIT IN STATE - - AND PPK_NUMLCK - JR Z,PPK_DECODE22 ; SKIP NUMLOCK PROCESSING - LD A,(PPK_KEYCODE) - XOR $10 ; FLIP FOR NUMLOCK + LD A,(PPK_STATE) ; LOAD THE CURRENT STATE FLAGS + OR PPK_NUMPAD ; TURN ON THE NUMPAD BIT + LD (PPK_STATE),A ; SAVE IT + + AND PPK_NUMLCK ; IS NUM LOCK BIT SET? + JR Z,PPK_DEC11A ; NO, SKIP NUMLOCK PROCESSING + LD A,(PPK_KEYCODE) ; GET THE KEYCODE + XOR $10 ; FLIP VALUES FOR NUMLOCK LD (PPK_KEYCODE),A ; SAVE IT - -PPK_DECODE22: ; DO NUMPAD MAPPING - LD A,(PPK_KEYCODE) - LD HL,PPK_MAPNUMPAD - SUB $C0 - LD E,A - LD D,0 - ADD HL,DE - LD A,(HL) - LD (PPK_KEYCODE),A - -PPK_DECODEX: + +PPK_DEC11A: ; APPLY NUMPAD MAPPING + LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE + LD HL,PPK_MAPNUMPAD ; LOAD THE START OF THE MAPPING TABLE + SUB $C0 ; KEYCODES START AT $C0 + LD E,A ; INDEX TO E + LD D,0 ; D IS ZERO + ADD HL,DE ; POINT TO RESULT OF MAPPING + LD A,(HL) ; GET IT IN A + LD (PPK_KEYCODE),A ; SAVE IT + +PPK_DEC12: ; DETECT UNKNOWN/INVALID KEYCODES LD A,(PPK_KEYCODE) ; GET THE FINAL KEYCODE CP $FF ; IS IT $FF (UNKNOWN/INVALID) JP Z,PPK_DECODE ; IF SO, JUST RESTART THE ENGINE +PPK_DEC13: ; DONE - RECORD RESULTS LD A,(PPK_STATUS) ; GET CURRENT STATUS OR PPK_KEYRDY ; SET KEY READY BIT LD (PPK_STATUS),A ; SAVE IT @@ -653,3 +739,40 @@ PPK_MAPEXT: ; PAIRS ARE [SCANCODE,KEYCODE] FOR EXTENDED SCANCODES PPK_MAPNUMPAD: ; KEYCODE TRANSLATION FROM NUMPAD RANGE TO STD ASCII/KEYCODES .DB $F3,$F7,$F5,$F8,$FF,$F9,$F2,$F6,$F4,$F0,$F1,$2F,$2A,$2D,$2B,$0D .DB $31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$2E,$2F,$2A,$2D,$2B,$0D +; +;__________________________________________________________________________________________________ +; KEYCODE VALUES RETURNED BY THE DECODER +;__________________________________________________________________________________________________ +; +; VALUES 0-127 ARE STANDARD ASCII, SPECIAL KEYS WILL HAVE THE FOLLOWING VALUES: +; +; F1 $E0 +; F2 $E1 +; F3 $E2 +; F4 $E3 +; F5 $E4 +; F6 $E5 +; F7 $E6 +; F8 $E7 +; F9 $E8 +; F10 $E9 +; F11 $EA +; F12 $EB +; SYSRQ $EC +; PRTSC $ED +; PAUSE $EE +; APP $EF +; INS $F0 +; DEL $F1 +; HOME $F2 +; END $F3 +; PGUP $F4 +; PGDN $F5 +; UP $F6 +; DOWN $F7 +; LEFT $F8 +; RIGHT $F9 +; POWER $FA +; SLEEP $FB +; WAKE $FC +; BREAK $FD