Skip to content

Instantly share code, notes, and snippets.

@mistificator
Last active July 28, 2022 20:40
Show Gist options
  • Save mistificator/a2482cdfc12c8ddd9eecab277847cda8 to your computer and use it in GitHub Desktop.
Save mistificator/a2482cdfc12c8ddd9eecab277847cda8 to your computer and use it in GitHub Desktop.
KEYZX - keyboard driver for CP/M on ZX Spectrum
; 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