6502-OS/system/keypad.s65
2023-10-26 19:51:20 +02:00

118 lines
2.9 KiB
Plaintext

;********************************************************************************
; @module 4x4 Keypad
; @type driver
; @device 4x4 Matrix Keypad
; @details
; Keypad must be connected to a VIA
; @requires KP_IO: Base Address of IO Chip
; @depends IO-W65C22N
;********************************************************************************
.ifndef INCLUDE_KEYPAD
INCLUDE_KEYPAD = 1
.ifndef KP_IO
.fatal "KP_IO is not defined: set it to the base address of the IO chip of the Keypad"
.endif
;********************************************************************************
; Keypad Buffer from $202 to $2ff
;********************************************************************************
KB_VAR = $00
KB_WRITE = $200
KB_READ = $201
KB_START = $202
KB_LENGTH = $fd
kb_init:
stz KB_WRITE
stz KB_READ
; write null to entire buffer
ldx #$00
@kb_init_loop:
stz KB_START,x
inx
cpx #KB_LENGTH
bne @kb_init_loop
rts
; read from keybuffer, if empty null will be read
kb_read:
ldx KB_READ
lda KB_START,x
beq @kb_read_rts ; if a buffer is null, dont increment KB_READ
stz KB_START,x ; set buffer location to null
inx ; increment KB_READ pointer
cpx #KB_LENGTH
beq @kb_read_jump
stx KB_READ
@kb_read_rts:
rts
@kb_read_jump:
stz KB_READ
rts
; write to keybuffer
_kb_write:
lda kp_VALUES, x ; load the char in a
ldx KB_WRITE
sta KB_START,x
inx ; increment KB_WRITE pointer
cpx #KB_LENGTH
beq @kb_jump_write
stx KB_WRITE
rts
@kb_jump_write: ; when the end of the buffer is reached, the next keys go to the start again
stz KB_WRITE
rts
kp_init:
; INIT KEYPAD
lda #%00001111; KP_IO+IO_RB 0-3 output
sta KP_IO+IO_DDRB
stz KP_IO+IO_RB ; KP_IO+IO_RB 4-7 1 so keypad press can be detected
stz KP_IO+IO_ACR
lda #%10010000 ; enable interrupt for CB1 on KP_IO+IO_IO
sta KP_IO+IO_IER
lda #%00010000 ; set CB1 to interrupt on pos. edge
sta KP_IO+IO_PCR
jsr kb_init ; init keybuffer
rts
;********************************************************************************
; Reading the Keypad
;********************************************************************************
kp_read: ; test each "row" and check which column is 1
lda #%00001110
ldx #$00
jsr @kp_read_branch
lda #%00001101
ldx #$04
jsr @kp_read_branch
lda #%00001011
ldx #$08
jsr @kp_read_branch
lda #%00000111
ldx #$0c
jsr @kp_read_branch
@kp_read_rts:
stz KP_IO+IO_RB
lda KP_IO+IO_RB ; read to definetly clear the interrupt flag
rts
@kp_read_branch:
sta KP_IO+IO_RB
lda KP_IO+IO_RB
sta KB_VAR ; store result in zeropage so that bbr can be used
bbr4 KB_VAR,_kb_write
inx
bbr5 KB_VAR,_kb_write
inx
bbr6 KB_VAR,_kb_write
inx
bbr7 KB_VAR,_kb_write
rts
kp_VALUES:
; TODO change to literal
.byte "123A", "456B", "789C", "*0#D"
.endif