|
|
@ -70,6 +70,9 @@ PPK_STAT3: |
|
|
; |
|
|
; |
|
|
;__________________________________________________________________________________________________ |
|
|
;__________________________________________________________________________________________________ |
|
|
; KEYBOARD READ |
|
|
; 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: |
|
|
PPK_READ: |
|
|
@ -137,11 +140,12 @@ PPK_GETBYTE2: |
|
|
CALL PPK_WTCLKHI |
|
|
CALL PPK_WTCLKHI |
|
|
CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT |
|
|
CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT |
|
|
LD A,E ; RETURN WITH RAW SCANCODE BYTE IN A |
|
|
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 |
|
|
OR A |
|
|
RET |
|
|
RET |
|
|
@ -155,10 +159,11 @@ PPK_PUTBYTE: |
|
|
; |
|
|
; |
|
|
LD E,A ; STASH INCOMING BYTE VALUE IN E |
|
|
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 |
|
|
; START WITH DATA HI AND CLOCK LOW |
|
|
CALL PPK_DATHI |
|
|
CALL PPK_DATHI |
|
|
@ -355,67 +360,147 @@ PPK_DECODE: |
|
|
; PPK_KEYCODE AND PPK_STATUS ARE CLEARED AT START. IF IS THE CALLER'S RESPONSIBILITY |
|
|
; 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. |
|
|
; 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[<modifier>] = 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[<toggle>] |
|
|
|
|
|
; 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 |
|
|
XOR A ; A = ZERO |
|
|
LD (PPK_STATUS),A ; CLEAR STATUS |
|
|
LD (PPK_STATUS),A ; CLEAR STATUS |
|
|
DEC A ; A = $FF |
|
|
DEC A ; A = $FF |
|
|
LD (PPK_KEYCODE),A ; CLEAR KEYCODE |
|
|
LD (PPK_KEYCODE),A ; CLEAR KEYCODE |
|
|
|
|
|
|
|
|
PPK_DECODENEXT: ; PROCESS NEXT SCANCODE |
|
|
|
|
|
|
|
|
PPK_DEC1: ; GET SCANCODE W/ TIMEOUT |
|
|
CALL PPK_GETBYTE ; GET A SCANCODE |
|
|
CALL PPK_GETBYTE ; GET A SCANCODE |
|
|
RET Z ; TIMEOUT, RETURN WITH A=0, Z SET |
|
|
RET Z ; TIMEOUT, RETURN WITH A=0, Z SET |
|
|
LD (PPK_SCANCODE),A ; SAVE SCANCODE |
|
|
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? |
|
|
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 |
|
|
LD A,(PPK_STATUS) ; GET STATUS |
|
|
OR PPK_BREAK ; SET BREAK BIT |
|
|
OR PPK_BREAK ; SET BREAK BIT |
|
|
LD (PPK_STATUS),A ; SAVE STATUS |
|
|
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? |
|
|
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 |
|
|
LD A,(PPK_STATUS) ; GET STATUS |
|
|
OR PPK_EXT ; SET EXTENDED BIT |
|
|
OR PPK_EXT ; SET EXTENDED BIT |
|
|
LD (PPK_STATUS),A ; SAVE STATUS |
|
|
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... |
|
|
; TODO: HANDLE PAUSE KEY HERE... |
|
|
|
|
|
|
|
|
PPK_DECODE4: ; PERFORM EXTENDED MAPPING |
|
|
|
|
|
|
|
|
PPK_DEC5: ; MAP SCANCODE TO KEYCODE |
|
|
LD A,(PPK_STATUS) ; GET STATUS |
|
|
LD A,(PPK_STATUS) ; GET STATUS |
|
|
AND PPK_EXT ; EXTENDED BIT SET? |
|
|
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 A,(PPK_SCANCODE) ; GET SCANCODE |
|
|
LD E,A ; STASH IT IN E |
|
|
LD E,A ; STASH IT IN E |
|
|
LD HL,PPK_MAPEXT ; POINT TO START OF EXT MAP TABLE |
|
|
LD HL,PPK_MAPEXT ; POINT TO START OF EXT MAP TABLE |
|
|
PPK_DECODE4A: |
|
|
|
|
|
|
|
|
PPK_DEC5A: |
|
|
LD A,(HL) ; GET FIRST BYTE OF PAIR |
|
|
LD A,(HL) ; GET FIRST BYTE OF PAIR |
|
|
CP $00 ; END OF TABLE? |
|
|
CP $00 ; END OF TABLE? |
|
|
JP Z,PPK_DECODE ; UNKNOWN OR BOGUS, START OVER |
|
|
JP Z,PPK_DECODE ; UNKNOWN OR BOGUS, START OVER |
|
|
INC HL ; INC HL FOR FUTURE |
|
|
INC HL ; INC HL FOR FUTURE |
|
|
CP E ; DOES MATCH BYTE EQUAL SCANCODE? |
|
|
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 |
|
|
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 A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE |
|
|
LD (PPK_KEYCODE),A ; SAVE IT |
|
|
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 |
|
|
LD A,(PPK_SCANCODE) ; GET THE SCANCODE |
|
|
CP $85 ; PAST END OF TABLE? |
|
|
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 |
|
|
LD A,(PPK_STATE) ; GET STATE |
|
|
AND PPK_SHIFT ; SHIFT ACTIVE? |
|
|
AND PPK_SHIFT ; SHIFT ACTIVE? |
|
|
LD HL,PPK_MAPSTD ; LOAD ADDRESS OF NON-SHIFTED MAPPING TABLE |
|
|
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 |
|
|
LD HL,PPK_MAPSHIFT ; LOAD ADDRESS OF SHIFTED MAPPING TABLE |
|
|
PPK_DECODE5A: |
|
|
|
|
|
|
|
|
PPK_DEC5D: |
|
|
LD A,(PPK_SCANCODE) ; GET THE SCANCODE |
|
|
LD A,(PPK_SCANCODE) ; GET THE SCANCODE |
|
|
LD E,A ; SCANCODE TO E FOR TABLE OFFSET |
|
|
LD E,A ; SCANCODE TO E FOR TABLE OFFSET |
|
|
LD D,0 ; D -> 0 |
|
|
LD D,0 ; D -> 0 |
|
|
@ -423,71 +508,71 @@ PPK_DECODE5A: |
|
|
LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE |
|
|
LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE |
|
|
LD (PPK_KEYCODE),A ; SAVE IT |
|
|
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 |
|
|
LD A,(PPK_KEYCODE) ; MAKE SURE WE HAVE KEYCODE |
|
|
CP $B8 ; END OF MODIFIER KEYS |
|
|
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 |
|
|
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 |
|
|
; TODO: STUFF BELOW COULD BE A LOOP |
|
|
|
|
|
|
|
|
; HANDLE L/R SHIFT KEYS |
|
|
; HANDLE L/R SHIFT KEYS |
|
|
LD E,PPK_SHIFT ; SETUP TO SET/CLEAR SHIFT BIT |
|
|
LD E,PPK_SHIFT ; SETUP TO SET/CLEAR SHIFT BIT |
|
|
SUB $B0 ; L-SHIFT? |
|
|
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? |
|
|
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 |
|
|
; HANDLE L/R CONTROL KEYS |
|
|
LD E,PPK_CTRL ; SETUP TO SET/CLEAR CONTROL BIT |
|
|
LD E,PPK_CTRL ; SETUP TO SET/CLEAR CONTROL BIT |
|
|
DEC A ; L-CONTROL? |
|
|
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? |
|
|
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 |
|
|
; HANDLE L/R ALT KEYS |
|
|
LD E,PPK_ALT ; SETUP TO SET/CLEAR ALT BIT |
|
|
LD E,PPK_ALT ; SETUP TO SET/CLEAR ALT BIT |
|
|
DEC A ; L-ALT? |
|
|
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? |
|
|
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 |
|
|
; HANDLE L/R WIN KEYS |
|
|
LD E,PPK_WIN ; SETUP TO SET/CLEAR WIN BIT |
|
|
LD E,PPK_WIN ; SETUP TO SET/CLEAR WIN BIT |
|
|
DEC A ; L-WIN? |
|
|
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? |
|
|
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 |
|
|
LD A,(PPK_STATUS) ; GET STATUS FLAGS |
|
|
AND PPK_BREAK ; BREAK EVENT? |
|
|
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 |
|
|
LD A,(PPK_STATE) ; GET EXISTING STATE BITS |
|
|
AND $F0 ; GET RID OF OLD MODIFIER BITS |
|
|
AND $F0 ; GET RID OF OLD MODIFIER BITS |
|
|
LD DE,(PPK_LSTATE) ; LOAD BOTH L/R STATE BYTES IN D/E |
|
|
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 |
|
|
LD (PPK_STATE),A ; SAVE IT |
|
|
JP PPK_DECODE ; DONE WITH CURRENT KEYSTROKE |
|
|
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 |
|
|
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 |
|
|
CP $FA ; MAKE SURE WE GET ACK |
|
|
JP NZ,PPK_DECODE ; ABORT IF NO 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 |
|
|
RRCA |
|
|
RRCA |
|
|
RRCA |
|
|
AND $07 |
|
|
|
|
|
|
|
|
AND $07 ; CLEAR THE IRRELEVANT BITS |
|
|
CALL PPK_PUTBYTE ; SEND THE LED DATA |
|
|
CALL PPK_PUTBYTE ; SEND THE LED DATA |
|
|
CALL PPK_GETBYTE ; READ THE ACK |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
LD A,(PPK_KEYCODE) ; GET THE FINAL KEYCODE |
|
|
CP $FF ; IS IT $FF (UNKNOWN/INVALID) |
|
|
CP $FF ; IS IT $FF (UNKNOWN/INVALID) |
|
|
JP Z,PPK_DECODE ; IF SO, JUST RESTART THE ENGINE |
|
|
JP Z,PPK_DECODE ; IF SO, JUST RESTART THE ENGINE |
|
|
|
|
|
|
|
|
|
|
|
PPK_DEC13: ; DONE - RECORD RESULTS |
|
|
LD A,(PPK_STATUS) ; GET CURRENT STATUS |
|
|
LD A,(PPK_STATUS) ; GET CURRENT STATUS |
|
|
OR PPK_KEYRDY ; SET KEY READY BIT |
|
|
OR PPK_KEYRDY ; SET KEY READY BIT |
|
|
LD (PPK_STATUS),A ; SAVE IT |
|
|
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 |
|
|
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 $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 |
|
|
.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 |
|
|
|