6502-OS/system/keypad.s65
2023-12-04 20:56:16 +01:00

109 lines
2.8 KiB
Plaintext

;********************************************************************************
; @module keypad4x4
; @type driver
; @device 4x4 Matrix Keypad
; @details
; The LCD must be connected to a W65C22N Interface Chip:
; - IO.RA0-7 ->
; @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
.zeropage
_KP_COLUMN: .res 1 ; for storing stuff
.bss ; reserve space or ringbuffer
KP_BUF_SIZE = 10
RBUF_MEM_START: .res KP_BUF_SIZE
RBUF_MEM_END = RBUF_MEM_START + KP_BUF_SIZE - 1
.define RBUF_NAME "keypad"
.include "buffer.s65"
.code
.proc kp_init
; todo remove later and test
lda #$ff
sta KP_IO+IO::DDRA
stz KP_IO+IO::RA
; INIT KEYPAD
; todo: use masks
lda #%11110000; KP_IO+IO::RA 0-3 output
sta KP_IO+IO::DDRA
; output 0, key press will pull input pin low
stz KP_IO+IO::RA
stz KP_IO+IO::ACR
; lda #%00010000 ; set CA1 to interrupt on pos. edge
; todo: use masks
lda #IO::PCR::CA1_IP_AE
sta KP_IO+IO::PCR
jsr rb_keypad_init ; init keybuffer
lda #(IO::IRQ::IRQ | IO::IRQ::CA1) ; enable interrupt for CA1 on KP_IO
sta KP_IO+IO::IER
rts
.endproc
;********************************************************************************
; @function Read which key is pressed on the keypad
; @details
; Checks which key is pressed and stores it in the keybuffer
; The value stored in the keybuffer is the offset which must be added to
; kp_VALUES to retrieve the key that was pressed
;********************************************************************************
.proc kp_read_on_irq
; test each "row" and check which column is 1
; TODO dont check every column if the value has been found
lda #%11100000
ldx #$00
jsr @kp_read_column
lda #%11010000
ldx #$04
jsr @kp_read_column
lda #%10110000
ldx #$08
jsr @kp_read_column
lda #%01110000
ldx #$0c
jsr @kp_read_column
stz KP_IO+IO::RA
lda KP_IO+IO::RA ; clear interrupt flag again beceause it might be set again through the above tests
rts
@kp_read_column:
sta KP_IO+IO::RA
lda KP_IO+IO::RA
sta _KP_COLUMN ; store result in zeropage so that bbr can be used
bbr0 _KP_COLUMN,@kp_write ; row 1
inx
bbr1 _KP_COLUMN,@kp_write ; row 3
inx
bbr2 _KP_COLUMN,@kp_write ; row 2
inx
bbr3 _KP_COLUMN,@kp_write ; row 4
rts
@kp_write:
lda _KP_VALUES,x
jsr rb_keypad_write
rts
.endproc
.rodata
_KP_VALUES:
.byte "174*"
.byte "396#"
.byte "2850"
.byte "ABCD"
; keypad conencted so that
; row 1 = PA0
; row 2 = PA2
; row 3 = PA1
; row 4 = PA3
.endif