Last active
July 28, 2022 20:40
-
-
Save mistificator/a2482cdfc12c8ddd9eecab277847cda8 to your computer and use it in GitHub Desktop.
KEYZX - keyboard driver for CP/M on ZX Spectrum
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; KEYZX.ASM is keyboard driver for CP/M on ZX Spectrum | |
; (c) 2021, 2022 ZXLDR | |
; | |
; [email protected] | |
; get char routine (wait for key) | |
Get_Char: ; out: a - char code | |
ld hl, (0x39) | |
ld bc, rst_38_routine | |
or a ; reset carry | |
sbc hl, bc ; check Rst38 routine | |
call nz, Install_Rst38_Routine ; put Rst38 routine if absent | |
continue_keyboard_scan: | |
halt | |
call Read_Keyboard | |
jr z, continue_keyboard_scan ; no keys | |
push af | |
xor a | |
ld (rst_38_tick), a ; reset tick state | |
ld c, 0 | |
continue_keyboard_release: | |
halt | |
ld a, (rst_38_tick) | |
add a, c | |
ld c, a | |
cp 4 | |
jr nz, continue_keyboard_release | |
auto_repeat: | |
pop af | |
ret | |
; rst 38 hook installer | |
Install_Rst38_Routine: | |
ld hl, rst_38_routine | |
ld (0x39), hl | |
ld a, 0xC3 ; jp opcode | |
ld (0x38), a | |
ret | |
rst_38_tick defb 0 | |
rst_38_routine: | |
push af | |
ld a, (rst_38_tick) | |
cpl | |
and 0x01 | |
ld (rst_38_tick), a | |
pop af | |
ei | |
reti | |
IF NOT DEFINED BORDCR | |
BORDCR equ 0x5C48 ; BASIC48 border color variable | |
ENDIF | |
; key scan routine (no wait) | |
Read_Keyboard: ; out: a - char code, z = false - key scanned, z = true - no key | |
ld bc, 0xFEFE | |
ld hl, Scan_Line0 | |
Scan_Loop: | |
IF DEFINED Machine_Leningrad | |
ld d, b ; store | |
scf | |
rl b | |
ccf | |
rr b ; inversed bit 7 | |
ENDIF | |
in a, (c) | |
cpl | |
and 0x1F ; mask right 5 bits | |
ld (hl), a | |
inc hl | |
IF DEFINED Machine_Leningrad | |
ld b, d ; restore | |
ENDIF | |
rlc b | |
jr c, Scan_Loop | |
ld hl, Keyboard_Map | |
ld de, 5 * 8 ; map size | |
ld a, (Scan_Line0) | |
bit 0, a ; check CS bit is zero | |
call nz, Pressed_CS | |
ld a, (Scan_Line7) | |
bit 1, a ; check SS bit is zero | |
call nz, Pressed_SS | |
ld de, Scan_Line0 | |
ld b, 8 | |
Lines_Rotate: | |
ld a, (de) | |
ld c, 5 | |
Bits_Rotate: | |
rrc a | |
jr c, Bit_Found | |
inc hl ; keyboard map offset - select char | |
dec c | |
jr nz, Bits_Rotate | |
inc de ; scan line offset | |
djnz Lines_Rotate | |
xor a | |
ret | |
Bit_Found: | |
ld a, (hl) | |
or a | |
ret | |
Pressed_CS: | |
add hl, de | |
res 0, a | |
ld (Scan_Line0), a | |
ret | |
Pressed_SS: | |
add hl, de | |
add hl, de | |
res 1, a | |
ld (Scan_Line7), a | |
ret | |
Scan_Line0 db 0 | |
Scan_Line1 db 0 | |
Scan_Line2 db 0 | |
Scan_Line3 db 0 | |
Scan_Line4 db 0 | |
Scan_Line5 db 0 | |
Scan_Line6 db 0 | |
Scan_Line7 db 0 | |
IF NOT DEFINED CONTROL_CHAR_CODES | |
; | |
; Set control character equates. | |
; | |
CNTRLC EQU 3 ;control-c | |
CNTRLE EQU 05H ;control-e | |
BS EQU 08H ;backspace | |
TAB EQU 09H ;tab | |
LF EQU 0AH ;line feed | |
FF EQU 0CH ;form feed | |
CR EQU 0DH ;carriage return | |
ESC EQU 1BH ;escape | |
CNTRLP EQU 10H ;control-p | |
CNTRLR EQU 12H ;control-r | |
CNTRLS EQU 13H ;control-s | |
CNTRLU EQU 15H ;control-u | |
CNTRLX EQU 18H ;control-x | |
CNTRLZ EQU 1AH ;control-z (end-of-file mark) | |
DEL EQU 7FH ;rubout | |
ENDIF | |
Keyboard_Map: DB 0x00,"z","x","c","v" | |
DB "a","s","d","f","g" | |
DB "q","w","e","r","t" | |
DB "1","2","3","4","5" | |
DB "0","9","8","7","6" | |
DB "p","o","i","u","y" | |
DB CR,"l","k","j","h" | |
DB " ",0x00,"m","n","b" | |
Keyboard_Map_CS: DB 0x00,"Z","X","C","V" | |
DB "A","S","D","F","G" | |
DB "Q","W","E","R","T" | |
DB DEL,0x00,0x00,0x00,0x00 | |
DB BS,0x00,TAB,0x00,0x00 | |
DB "P","O","I","U","Y" | |
DB CR,"L","K","J","H" | |
DB " ",0x00,"M","N","B" | |
Keyboard_Map_SS: DB 0x00,":","$","?","/" | |
DB 0x00,0x00,0x00,0x00,0x00 | |
DB 0x00,0x00,ESC,"<",">" | |
DB "!","@","#","$","%" | |
DB "_",")","(","'","&" | |
DB "\"",";",0x00,0x00,0x00 | |
DB CR,"=","+","-","^" | |
DB " ",0x00,".",",","*" | |
Keyboard_Map_CSSS: DB 0x00,CNTRLZ,CNTRLX,CNTRLC,0x00 | |
DB 0x00,CNTRLS,0x00,0x00,0x00 | |
DB 0x00,0x00,CNTRLE,CNTRLR,0x00 | |
DB DEL,0x00,0x00,0x00,0x00 | |
DB BS,0x00,TAB,0x00,0x00 | |
DB CNTRLP,0x00,0x00,CNTRLU,0x00 | |
DB CR,0x00,0x00,0x00,0x00 | |
DB " ",0x00,0x00,0x00,0x00 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment