From ea1081093480bd0721c5fd6f552cb2abc9371a8a Mon Sep 17 00:00:00 2001 From: Dean Netherton Date: Thu, 19 Nov 2020 16:02:52 +1100 Subject: [PATCH] MSX-KEYBOARD: optimised interrupt handler --- Source/HBIOS/msxkeyb.asm | 257 ++++++++++++++++++--------------------- 1 file changed, 118 insertions(+), 139 deletions(-) diff --git a/Source/HBIOS/msxkeyb.asm b/Source/HBIOS/msxkeyb.asm index fc1ec30d..847d3557 100644 --- a/Source/HBIOS/msxkeyb.asm +++ b/Source/HBIOS/msxkeyb.asm @@ -4,10 +4,9 @@ ; CREATED BY: DEAN NETHERTON ; KBD.ASM DRIVER USED AS TEMPLATE ; -; ;====================================================================== ; USAGE: -; THIS DRIVER IS CAN BE ACTIVED WITHIN THE TMS VIDEO DRIVER +; THIS DRIVER CAN BE ACTIVED WITHIN THE TMS VIDEO DRIVER ; ADD THE OPTION TO YOUR BUILD CONFIGURATION TO ACTIVATE THE KEYBOARD ; DRIVER: ; MSKENABLE .SET TRUE @@ -16,11 +15,9 @@ ; ; TODO: ; IMPLEMENT MULTIBYTE SCAN CODES (ARROW KEYS, ETC) -; OPTIMISE INTERRUPT HANDLER - HAS NEGATIVE IMPACT ON SERIAL IO AT 115200 FOR CPU @ 8MHZ ; BACKSPACE DOES NOT AUTO-REPEAT ; AUTO DETECT PPI ; -; ;====================================================================== ; DRIVER - CONSTANTS ;====================================================================== @@ -46,10 +43,10 @@ PPICMD_GA_MODE_2 .EQU 64 PPICMD_COMMAND .EQU 128 ; COUNT FOR PERIOD TO START REPEATING CHARACTERS -KEY_REPEAT_INIT: .EQU 10 +KEY_REPEAT_INIT: .EQU 30 ; COUNT FOR PERIOD BETWEEN AUTO REPEATING CHARACTERS -KEY_REPEAT_PERIOD: .EQU 2 +KEY_REPEAT_PERIOD: .EQU 3 ; COUNT FOR INTERRUPT HANDLER TO TRIGGER KEYBOARD SCANNER (EG: SCAN KEYBOARD ONLY EVERY 3RD INTERRUPT (3/60)) SCAN_INT_PERIOD: .EQU 3 @@ -69,20 +66,20 @@ MKY_WAITTO .EQU 0 ; 0 IS MAX WAIT (256) ; ; STATUS BITS (FOR MKY_STATUS) ; -MKY_EXT .EQU 01H ; BIT 0, EXTENDED SCANCODE ACTIVE -MKY_BREAK .EQU 02H ; BIT 1, THIS IS A KEY UP (BREAK) EVENT -MKY_KEYRDY .EQU 80H ; BIT 7, INDICATES A DECODED KEYCODE IS READY +MKY_EXT .EQU 01H ; BIT 0, EXTENDED SCANCODE ACTIVE +MKY_BREAK .EQU 02H ; BIT 1, THIS IS A KEY UP (BREAK) EVENT +MKY_KEYRDY .EQU 80H ; BIT 7, INDICATES A DECODED KEYCODE IS READY ; ; STATE BITS (FOR MKY_STATE, MKY_LSTATE, MKY_RSTATE) ; -MKY_SHIFT .EQU 01H ; BIT 0, SHIFT ACTIVE (PRESSED) -MKY_CTRL .EQU 02H ; BIT 1, CONTROL ACTIVE (PRESSED) -MKY_ALT .EQU 04H ; BIT 2, ALT ACTIVE (PRESSED) -MKY_WIN .EQU 08H ; BIT 3, WIN ACTIVE (PRESSED) -MKY_SCRLCK .EQU 10H ; BIT 4, CAPS LOCK ACTIVE (TOGGLED ON) -MKY_NUMLCK .EQU 20H ; BIT 5, NUM LOCK ACTIVE (TOGGLED ON) -MKY_CAPSLCK .EQU 40H ; BIT 6, SCROLL LOCK ACTIVE (TOGGLED ON) -MKY_NUMPAD .EQU 80H ; BIT 7, NUM PAD KEY (KEY PRESSED IS ON NUM PAD) +MKY_SHIFT .EQU 01H ; BIT 0, SHIFT ACTIVE (PRESSED) +MKY_CTRL .EQU 02H ; BIT 1, CONTROL ACTIVE (PRESSED) +MKY_ALT .EQU 04H ; BIT 2, ALT ACTIVE (PRESSED) +MKY_WIN .EQU 08H ; BIT 3, WIN ACTIVE (PRESSED) +MKY_SCRLCK .EQU 10H ; BIT 4, CAPS LOCK ACTIVE (TOGGLED ON) +MKY_NUMLCK .EQU 20H ; BIT 5, NUM LOCK ACTIVE (TOGGLED ON) +MKY_CAPSLCK .EQU 40H ; BIT 6, SCROLL LOCK ACTIVE (TOGGLED ON) +MKY_NUMPAD .EQU 80H ; BIT 7, NUM PAD KEY (KEY PRESSED IS ON NUM PAD) ; MKY_DEFRPT .EQU $40 ; DEFAULT REPEAT RATE (.5 SEC DELAY, 30CPS) MKY_DEFSTATE .EQU MKY_NUMLCK ; DEFAULT STATE (NUM LOCK ON) @@ -205,10 +202,8 @@ MKY_INIT: LD A, PPICMD_COMMAND | PPICMD_GA_MODE_0 | PPICMD_GB_MODE_0 | PPICMD_A_IN | PPICMD_B_IN | PPICMD_CLOW_OUT | PPICMD_CHIGH_OUT OUT (MKY_REGCMD), A - - LD A, 64 ; CAPS OFF + LD A, 64 ; CAPS OFF OUT (MKY_REGC), A - RET ; ;__________________________________________________________________________________________________ @@ -225,10 +220,9 @@ MKY_FLUSH: ;__________________________________________________________________________________________________ ; MKY_STAT: - LD A, $FF - LD (MKY_SCANON), A - CALL MKY_DECODE ; CHECK THE KEYBOARD - JP Z,CIO_IDLE ; RET VIA IDLE PROCESSING IF NO KEY + CALL MKY_SCAN ; SCAN AND SET SCANCODE FOR DETECTED KEY EVENT + CALL MKY_DECODE ; DECODE THE SCANCODE INTO A KEYCODE + JP Z, CIO_IDLE ; RET VIA IDLE PROCESSING IF NO KEY RET ; ;__________________________________________________________________________________________________ @@ -242,19 +236,19 @@ MKY_READ: CALL MKY_STAT ; KEY READY? ; JR Z, MKY_READ ; NOT READY, KEEP TRYING - LD A,(MKY_STATE) ; GET STATE + LD A, (MKY_STATE) ; GET STATE AND $01 ; ISOLATE EXTENDED SCANCODE BIT RRCA ; ROTATE IT TO HIGH ORDER BIT - LD E,A ; SAVE IT IN E FOR NOW - LD A,(MKY_SCANCODE) ; GET SCANCODE + LD E, A ; SAVE IT IN E FOR NOW + LD A, (MKY_SCANCODE) ; GET SCANCODE OR E ; COMBINE WITH EXTENDED BIT - LD C,A ; STORE IT IN C FOR RETURN - LD A,(MKY_KEYCODE) ; GET KEYCODE - LD E,A ; SAVE IT IN E - LD A,(MKY_STATE) ; GET STATE FLAGS - LD D,A ; SAVE THEM IN D + LD C, A ; STORE IT IN C FOR RETURN + LD A, (MKY_KEYCODE) ; GET KEYCODE + LD E, A ; SAVE IT IN E + LD A, (MKY_STATE) ; GET STATE FLAGS + LD D, A ; SAVE THEM IN D XOR A ; SIGNAL SUCCESS - LD (MKY_STATUS),A ; CLEAR STATUS TO INDICATE BYTE RECEIVED + LD (MKY_STATUS), A ; CLEAR STATUS TO INDICATE BYTE RECEIVED RET ; ;__________________________________________________________________________________________________ @@ -264,9 +258,11 @@ MKY_READ: ; ; SUCUESS/FAILURE IN A ; ; NUMBER OF BYTES RETURNED IN B (ZERO IF NO SCAN CODES AVAILABLE) ; ; SCAN CODE BYTES IN D, E, H, L, C -; +; WORK - IN - PROGRESS ;__________________________________________________________________________________________________ MKY_RDSCAN: + LD A, (MKY_SCANBUFFLEN) + CALL Z, MKY_GENSCODE LD A, (MKY_SCANBUFFLEN) LD B, A LD A, (MKY_SCANBUFF) @@ -283,6 +279,36 @@ MKY_RDSCAN: XOR A LD (MKY_SCANBUFFLEN), A RET + +MKY_SCAN: + LD A, (MKY_SCANNED) ; NEED TO WAIT UNTIL A NEW SCAN HAS COMPLETED (MKY_INT) + OR A + RET Z + + DI ; CAPTURE THE LATEST KEYBOARD SCANNED STATE + XOR A ; CLEAR SCANNED STATE + LD (MKY_SCANNED), A + + LD DE, MKY_SCNKEY ; COPY NEWKEY TO SCNKEY + LD HL, MKY_NEWKEY ; AND RESET NEWKEY TO $FF + LD B, MATRIX_ROW_COUNT + LD C, 255 +MKY_SCAN_LP1: + LD A, (HL) + LD (DE), A + LD (HL), C + INC HL + INC DE + DJNZ MKY_SCAN_LP1 + EI + + EX AF, AF' + PUSH AF + CALL MKY_GENSCODE + CALL MKY_RPTGEN + POP AF + EX AF, AF' + RET ; ;__________________________________________________________________________________________________ ; HARDWARE INTERFACE @@ -291,19 +317,16 @@ MKY_RDSCAN: ; KEYBOARD INPUT STATUS ; A=0, Z SET FOR NOTHING PENDING, OTHERWISE DATA PENDING ; -MKY_IST: - LD A, (MKY_SCANBUFFLEN) - OR A - RET +#define MKY_IST LD A, (MKY_SCANBUFFLEN) \ OR A ;__________________________________________________________________________________________________ ; ; GET A RAW DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH TIMEOUT ; MKY_GETDATA: - LD B,MKY_WAITTO ; SETUP TO LOOP + LD B, MKY_WAITTO ; SETUP TO LOOP MKY_GETDATA0: - CALL MKY_IST ; GET INPUT REGISTER STATUS - JR NZ,MKY_GETDATA1 ; BYTE PENDING, GO GET IT + MKY_IST ; GET INPUT REGISTER STATUS + JR NZ, MKY_GETDATA1 ; BYTE PENDING, GO GET IT CALL DELAY ; WAIT A BIT DJNZ MKY_GETDATA0 ; LOOP UNTIL COUNTER EXHAUSTED XOR A ; NO DATA, RETURN ZERO @@ -317,7 +340,7 @@ MKY_GETDATA1: ; GET A RAW DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH NOTIMEOUT ; MKY_GETDATAX: - CALL MKY_IST ; GET INPUT REGISTER STATUS + MKY_IST ; GET INPUT REGISTER STATUS RET Z ; NOTHING THERE, DONE JR MKY_GETDATA1 ; GO GET IT @@ -660,36 +683,6 @@ MKY_DEC10B: XOR $20 ; FLIP BIT 5 TO SWAP UPPER/LOWER CASE LD (MKY_KEYCODE),A ; SAVE IT -; MKY_DEC11: ; HANDLE NUM PAD KEYS -; LD A,(MKY_STATE) ; GET THE CURRENT STATE FLAGS -; AND $7F;~MKY_NUMPAD ; ASSUME NOT A NUMPAD KEY, CLEAR THE NUMPAD BIT -; LD (MKY_STATE),A ; SAVE IT - -; LD A,(MKY_KEYCODE) ; GET THE CURRENT KEYCODE -; AND 11100000B ; ISOLATE TOP 3 BITS -; CP 11000000B ; IS IN NUMPAD RANGE? -; JR NZ,MKY_DEC12 ; NOPE, GET OUT - -; LD A,(MKY_STATE) ; LOAD THE CURRENT STATE FLAGS -; OR MKY_NUMPAD ; TURN ON THE NUMPAD BIT -; LD (MKY_STATE),A ; SAVE IT - -; AND MKY_NUMLCK ; IS NUM LOCK BIT SET? -; JR Z,MKY_DEC11A ; NO, SKIP NUMLOCK PROCESSING -; LD A,(MKY_KEYCODE) ; GET THE KEYCODE -; XOR $10 ; FLIP VALUES FOR NUMLOCK -; LD (MKY_KEYCODE),A ; SAVE IT - -; MKY_DEC11A: ; APPLY NUMPAD MAPPING -; LD A,(MKY_KEYCODE) ; GET THE CURRENT KEYCODE -; LD HL,MKY_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 (MKY_KEYCODE),A ; SAVE IT - MKY_DEC12: ; DETECT UNKNOWN/INVALID KEYCODES LD A,(MKY_KEYCODE) ; GET THE FINAL KEYCODE CP $FF ; IS IT $FF (UNKNOWN/INVALID) @@ -712,21 +705,21 @@ MKY_DECNEW: ; START NEW KEYPRESS (CLEAR ALL STATUS BITS) ;__________________________________________________________________________________________________ ; INTERRUPT HANDLER ; -; IF MKY_SCANBUFFF HAS CONTENT, DO NOTHING -; OTHERWISE, SCAN KEYBOARD AND IF A KEY EVENT IS DETECTED -; WRITE SCANCODES TO MKY_SCANBUFFF +; SCAN KEYBOARD AND IN THE NEWKEY SCAN STATS ; -; ALSO GENERATE KEY REPEAT EVENTS, IF KEY HELD DOWN -; -; NB: THIS HANDLER IS QUITE EXPENSIVE IN TIME -; AND CAN IMPACT SERIAL OPERATION FOR 115200 BAUD RATE FOR CPU AT 8MHZ ;__________________________________________________________________________________________________ ; MKY_INT: - LD A, (MKY_SCANON) ; OPTIMISATION - ONLY SCAN IF REQUIRED + LD A, (MKY_RPTACTIVE) ; NO REPEAT KEY IS HELD? OR A - RET Z + JR Z, MKY_INTSCAN1 + LD A, (MKY_RPTCNT) ; DECREMENT REPEAT COUNTER + DEC A ; DOWN TO ZERO + CP $FF + JR Z, MKY_INTSCAN1 + LD (MKY_RPTCNT), A +MKY_INTSCAN1: LD A, (MKY_SCNCNT) ; SCAN THE KEYBOARD EVERY 'SCAN_INT_PERIOD' INTERRUPTS. DEC A LD (MKY_SCNCNT), A @@ -735,16 +728,8 @@ MKY_INT: LD A, SCAN_INT_PERIOD LD (MKY_SCNCNT), A - LD A, (MKY_SCANBUFFLEN) ; SKIP SCANNING UNTIL CODE BUFFER IS EMPTY - OR A - RET NZ - - EX AF, AF' - PUSH AF -; ; SCAN KEYBOARD AND STORE ALL COLUMN RESULTS PER ROW AT MKY_NEWKEY ; -; MKY_SCAN: IN A, (MKY_REGC) ; READ AND MASK THE CURRENT STATE OF PPI PORT C AND $F0 LD D, A @@ -759,12 +744,8 @@ MKY_SCAN_LP: INC D DJNZ MKY_SCAN_LP ; LOOP UNTIL ALL ROWS READ - CALL MKY_GENSCODE - -MKY_INT_END: - CALL MKY_RPTGEN - POP AF - EX AF, AF' + LD A, $FF ; NOTE THAT A SCAN HAS BEEN DONE + LD (MKY_SCANNED), A RET ; @@ -772,20 +753,20 @@ MKY_INT_END: ; COMPARE MKY_OLDKEY O MKY_NEWKEY ; GENERATE SCAN CODES ; -; FOR EACH BIT IN MKY_OLDKEY ND MKY_NEWKEY +; FOR EACH BIT IN MKY_OLDKEY CP WITH CORRESPONDING BIT IN MKY_SCNKEY ; IF BOTH = 1, THEN NO KEY PRESS - NOTHING CHANGED ; IF BOTH = 0, THEN KEY WAS AND IS STILL PRESSED - NOTHING CHANGED -; IF OLD = 1 AND NEW = 0, KEY WAS PRESSED -; IF OLD = 0 AND NEW = 1, KEY WAS RELEASED -; STOP OF FIRST CHANGE - STORE IN BUFFER - THEN NOTHING HAPPENS, -; UNTIL MKY_RDSCAN IS CALLED AND CLEARS THE SCAN BUFFER -; ALSO RESET MKY_RPTACTIVE IS A KEY IS HELD DOWN +; IF OLD = 1 AND SCN = 0, KEY WAS PRESSED +; IF OLD = 0 AND SCN = 1, KEY WAS RELEASED +; STOP OF FIRST CHANGE - STORE IN BUFFER, AND RESET/CLEAR BIT IN MKY_OLDKEY +; ALSO SET MKY_RPTACTIVE. NZ -> A KEY IS HELD DOWN, ZERO -> NO KEYS HELD DOWN +; MKY_GENSCODE: XOR A LD (MKY_RPTACTIVE), A ; CLEAR FLAG TO INDICATE A KEYHOLD STATE LD HL, MKY_OLDKEY - LD DE, MKY_NEWKEY + LD DE, MKY_SCNKEY XOR A EX AF, AF' ; ROW COUNT IN A' @@ -856,11 +837,18 @@ MKY_NORPT: JR MKY_GENSCODENXT MKY_KEYDOWN: + PUSH AF + LD A, KEY_REPEAT_INIT ; SET COUNTER FOR REPEAT TRIGGER + LD (MKY_RPTCNT), A + POP AF + +MKY_KEYDOWN_RPT: CALL MKY_RESOLDBIT CALL MKY_SCANADDR LD A, (HL) OR A ; IF NO SCANCODE - IGNORE IT RET Z + LD (MKY_SCANBUFF), A LD A, 1 LD (MKY_SCANBUFFLEN), A @@ -887,27 +875,20 @@ MKY_RPTGEN: LD A, (MKY_RPTACTIVE) ; NO KEY IS HELD OR A - JR Z, MKY_RPTCLR + RET Z LD A, (MKY_RPTCNT) - DEC A - JR Z, MKY_RPTADD - LD (MKY_RPTCNT), A - RET + OR A + RET NZ -MKY_RPTADD: + ; GENERATE THE KEY DOWN SCAN CODE FOR THE REPEATING KEY LD A, KEY_REPEAT_PERIOD LD (MKY_RPTCNT), A LD A, (MKY_NRPTCOL) LD B, A LD A, (MKY_NRPTROW) EX AF, AF' - JR MKY_KEYDOWN - -MKY_RPTCLR: - LD A, KEY_REPEAT_INIT - LD (MKY_RPTCNT), A - RET + JR MKY_KEYDOWN_RPT ; ;__________________________________________________________________________________________________ ; @@ -917,14 +898,16 @@ MKY_RPTCLR: ; B = 1 TO 8 - COLUMN COUNT ; A' IS ROW COUNT - 0 TO MATRIX_ROW_COUNT ; OUTPUT: -; HL = BYTE WITHIN MKY_OLDKEY RRAY +; HL = BYTE WITHIN MKY_OLDKEY ARRAY ; A = BIT MASK FOR COLUMN COUNT (EG: B = 3, A = 8) ; PROTECTS: ; A' IS UNCHANGED ; B IS UNCHANGED + MKY_GETKEYIDX: + LD HL, MKY_OLDKEY LD A, $80 - LD D, B ; SAVE B (COLUMN COUNT - 1 TO 8) + LD C, B ; SAVE B (COLUMN COUNT - 1 TO 8) MKY_SETOLDBIT_LP: DEC B JR Z, SKIP @@ -932,39 +915,36 @@ MKY_SETOLDBIT_LP: JR MKY_SETOLDBIT_LP SKIP: - LD HL, MKY_OLDKEY EX AF, AF' ; RETRIEVE ROW COUNT - LD C, A + LD E, A EX AF, AF' - LD B, 0 - ADD HL, BC - LD B, D ; RETORE B (COLUMN COUNT) + LD D, 0 + LD B, C ; RETORE B (COLUMN COUNT) + ADD HL, DE RET ; ;__________________________________________________________________________________________________ ; ; SET BIT WITHIN THE KEY MATRIX ARRAY -; HL -> ADDRESS WITHIN MKY_OLDKEY R MKY_NEWKEY ARRAY +; HL -> ADDRESS WITHIN MKY_OLDKEY ARRAY ; C BIT MASK TO BE OR'ED ; MKY_SETOLDBIT: CALL MKY_GETKEYIDX - LD C, (HL) - OR C + OR (HL) LD (HL), A RET ; ;__________________________________________________________________________________________________ ; ; RESET BIT WITHIN THE KEY MATRIX ARRAY -; HL -> ADDRESS WITHIN MKY_OLDKEY R MKY_NEWKEY ARRAY +; HL -> ADDRESS WITHIN MKY_OLDKEY ARRAY ; C CPL BIT MASK TO BE AND'ED ; MKY_RESOLDBIT: CALL MKY_GETKEYIDX - LD C, (HL) CPL - AND C + AND (HL) LD (HL), A RET ; @@ -1014,19 +994,26 @@ MKY_READBYT: ; DYNAMIC DATA STORAGE: ; ; STORAGE OF KEYBOARD MATRIX, USED FOR DETECTING KEY REPETITION -MKY_OLDKEY: .FILL MATRIX_ROW_COUNT, $FF +MKY_OLDKEY: .FILL MATRIX_ROW_COUNT, $FF ; ; CURRENT STATE OF THE KEYBOARD MATRIX -MKY_NEWKEY: .FILL MATRIX_ROW_COUNT, $FF +MKY_NEWKEY: .FILL MATRIX_ROW_COUNT, $FF +; +; COPY OF MKY_NEWKEY FOR USE IN GENERATING SCANCODE +MKY_SCNKEY: .FILL MATRIX_ROW_COUNT, $FF +; +; SET TO NZ WHEN A SCAN IS COMPLETED +; SET TO ZERO AFTER A SCAN CODE CONVERSION +MKY_SCANNED: .DB 0 ; ; F3F6: VDP-INTERUPT COUNTER THAT COUNTS FROM SCAN_INT_PERIOD TO 0, WHEN IT REACHES ZERO, THE ; KEYBOARD MATRIX IS SCANNED, AND THE COUNTERS IS RESET AT SCAN_INT_PERIOD -MKY_SCNCNT: .DB SCAN_INT_PERIOD +MKY_SCNCNT: .DB SCAN_INT_PERIOD ; INITIALL SET TO FALSE, AND THUS DISABLING INTERRUPT HANDLER'S SCAN FUNCTION ; AS SOON AT THE KEY REQUEST FUNCTIONS (STATUS, READ), THIS IS SET AND INTERRUPT HANDLER ; IS PERMANETLY ON. -MKY_SCANON: .DB 0 +; MKY_SCANON: .DB 0 ; MKY_NRPTCOL: .DB 0 @@ -1081,9 +1068,6 @@ MKY_MAPEXT: ; PAIRS ARE [SCANCODE,KEYCODE] FOR EXTENDED SCANCODES .DB $74,$F9, $75,$F6, $7A,$F5, $7C,$ED .DB $7D,$F4, $7E,$FD, $00,$00 ; -; MKY_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 #ENDIF #IF (MKYKBLOUT == KBD_DE) ;__________________________________________________________________________________________________ @@ -1126,11 +1110,6 @@ MKY_MAPEXT: ; PAIRS ARE [SCANCODE,KEYCODE] FOR EXTENDED SCANCODES .DB $74,$04, $75,$05, $7A,$1A, $7C,$ED ; Cursor right , Cursor up , Page down .DB $7D,$17, $7E,$FD, $00,$00 ; Page up , n.a. , END MKY_MAPEXT (Pairs end) ; -; MKY_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 -; #ENDIF ; ;__________________________________________________________________________________________________