diff --git a/kernel/kbd.asm b/kernel/kbd.asm index fee5638..8e28742 100644 --- a/kernel/kbd.asm +++ b/kernel/kbd.asm @@ -17,9 +17,10 @@ ; *** Variables *** ; Set to previously received scan code .equ KBD_PREV_KC KBD_RAMSTART -; Whether Shift key is pressed -.equ KBD_SHIFT_ON KBD_PREV_KC+1 -.equ KBD_RAMEND KBD_SHIFT_ON+1 +; Whether Shift key is pressed. When not pressed, holds 0. When pressed, holds +; 0x80. This allows for quick shifting in the glyph table. +.equ KBD_SHIFT_ON @+1 +.equ KBD_RAMEND @+1 kbdInit: xor a @@ -45,58 +46,49 @@ kbdGetC: cp KBD_KC_BREAK jr z, .break cp KBD_KC_EXT - jr z, .ignore + jr z, .nothing ex af, af' ; restore saved KC + ; A scan code over 0x80 is out of bounds or prev KC tell us we should + ; skip. Ignore. cp 0x80 - jr nc, .ignore + jr nc, .nothing ; No need to skip, code within bounds, we have something! call .isShift jr z, .shiftPressed ; Let's see if there's a ASCII code associated to it. push hl ; --> lvl 1 ld hl, KBD_SHIFT_ON - bit 0, (hl) + or (hl) ; if shift is on, A now ranges in 0x80-0xff. ld hl, kbdScanCodes ; no flag changed - jr z, .shiftNotPressed - ; Shift is being pressed. Use Shifted table. - ld hl, kbdScanCodesS -.shiftNotPressed: call addHL ld a, (hl) pop hl ; <-- lvl 1 or a - jr z, kbdGetC ; no code. Keep A at 0, but unset Z + jr z, kbdGetC ; no code. ; We have something! cp a ; ensure Z ret .shiftPressed: - ld a, 1 + ld a, 0x80 ld (KBD_SHIFT_ON), a - jr .ignore ; to actual char to return + jr .nothing ; no actual char to return .break: ex af, af' ; restore saved KC call .isShift - jr nz, .ignore + jr nz, .nothing ; We had a shift break, update status xor a ld (KBD_SHIFT_ON), a - ; continue to .ignore -.ignore: - ; A scan code over 0x80 is out of bounds or prev KC tell us we should - ; skip. Ignore. - xor a - jr kbdGetC + ; continue to .nothing .nothing: ; We have nothing. Before we go further, we'll wait a bit to give our ; device the time to "breathe". When we're in a "nothing" loop, the z80 ; hammers the device really fast and continuously generates interrupts ; on it and it interferes with its other task of reading the keyboard. - push bc - ld b, 0 + xor a .wait: - nop - djnz .wait - pop bc + inc a + jr nz, .wait jr kbdGetC ; Whether KC in A is L or R shift .isShift: @@ -106,7 +98,7 @@ kbdGetC: ret ; A list of the values associated with the 0x80 possible scan codes of the set -; 2 of the PS/2 keyboard specs. 0 means no value. That value is a character than +; 2 of the PS/2 keyboard specs. 0 means no value. That value is a character that ; can be read in a GetC routine. No make code in the PS/2 set 2 reaches 0x80. kbdScanCodes: ; 0x00 1 2 3 4 5 6 7 8 9 a b c d e f @@ -126,8 +118,7 @@ kbdScanCodes: ; 0x70 27 = ESC .db '0','.','2','5','6','8', 27, 0, 0, 0,'3', 0, 0,'9', 0, 0 -; Same values, but shifted -kbdScanCodesS: +; Same values, but shifted, exactly 0x80 bytes after kbdScanCodes ; 0x00 1 2 3 4 5 6 7 8 9 a b c d e f .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,'~', 0 ; 0x10 9 = TAB