|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- ; kbd - implement GetC for PS/2 keyboard
- ;
- ; It reads raw key codes from a FetchKC routine and returns, if appropriate,
- ; a proper ASCII char to type. See recipes rc2014/ps2 and sms/kbd.
- ;
- ; *** Defines ***
- ; Pointer to a routine that fetches the last typed keyword in A. Should return
- ; 0 when nothing was typed.
- ; KBD_FETCHKC
-
- ; *** Consts ***
- .equ KBD_KC_BREAK 0xf0
- .equ KBD_KC_EXT 0xe0
- .equ KBD_KC_LSHIFT 0x12
- .equ KBD_KC_RSHIFT 0x59
-
- ; *** 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
-
- kbdInit:
- xor a
- ld (KBD_PREV_KC), a
- ld (KBD_SHIFT_ON), a
- ret
-
- kbdGetC:
- call KBD_FETCHKC
- or a
- jr z, .nothing
-
- ; scan code not zero, maybe we have something.
- ; Do we need to skip it?
- ex af, af' ; save fetched KC
- ld a, (KBD_PREV_KC)
- ; Whatever the KC, the new A becomes our prev. The easiest way to do
- ; this is to do it now.
- ex af, af' ; restore KC
- ld (KBD_PREV_KC), a
- ex af, af' ; restore prev KC
- ; If F0 (break code) or E0 (extended code), we skip this code
- cp KBD_KC_BREAK
- jr z, .break
- cp KBD_KC_EXT
- jr z, .ignore
- ex af, af' ; restore saved KC
- cp 0x80
- jr nc, .ignore
- ; 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)
- 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
- jp z, unsetZ ; no code. Keep A at 0, but unset Z
- ; We have something!
- cp a ; ensure Z
- ret
- .shiftPressed:
- ld a, 1
- ld (KBD_SHIFT_ON), a
- jr .ignore ; to actual char to return
- .break:
- ex af, af' ; restore saved KC
- call .isShift
- jr nz, .ignore
- ; 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
- jp unsetZ
- .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
- .wait:
- nop
- djnz .wait
- pop bc
- jp unsetZ
- ; Whether KC in A is L or R shift
- .isShift:
- cp KBD_KC_LSHIFT
- ret z
- cp KBD_KC_RSHIFT
- 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
- ; 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
- .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,'`', 0
- ; 0x10 9 = TAB
- .db 0, 0, 0, 0, 0,'q','1', 0, 0, 0,'z','s','a','w','2', 0
- ; 0x20 32 = SPACE
- .db 0,'c','x','d','e','4','3', 0, 0, 32,'v','f','t','r','5', 0
- ; 0x30
- .db 0,'n','b','h','g','y','6', 0, 0, 0,'m','j','u','7','8', 0
- ; 0x40 59 = ;
- .db 0,',','k','i','o','0','9', 0, 0,'.','/','l', 59,'p','-', 0
- ; 0x50 13 = RETURN 39 = '
- .db 0, 0, 39, 0,'[','=', 0, 0, 0, 0, 13,']', 0,'\', 0, 0
- ; 0x60 8 = BKSP
- .db 0, 0, 0, 0, 0, 0, 8, 0, 0,'1', 0,'4','7', 0, 0, 0
- ; 0x70 27 = ESC
- .db '0','.','2','5','6','8', 27, 0, 0, 0,'3', 0, 0,'9', 0, 0
-
- ; Same values, but shifted
- kbdScanCodesS:
- ; 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
- .db 0, 0, 0, 0, 0,'Q','!', 0, 0, 0,'Z','S','A','W','@', 0
- ; 0x20 32 = SPACE
- .db 0,'C','X','D','E','$','#', 0, 0, 32,'V','F','T','R','%', 0
- ; 0x30
- .db 0,'N','B','H','G','Y','^', 0, 0, 0,'M','J','U','&','*', 0
- ; 0x40 59 = ;
- .db 0,'<','K','I','O',')','(', 0, 0,'>','?','L',':','P','_', 0
- ; 0x50 13 = RETURN
- .db 0, 0,'"', 0,'{','+', 0, 0, 0, 0, 13,'}', 0,'|', 0, 0
- ; 0x60 8 = BKSP
- .db 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0
- ; 0x70 27 = ESC
- .db 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0
|