;******************************************************************************** ; @module keypad4x4 ; @type driver ; @device 4x4 Matrix Keypad ; @details ; The LCD must be connected to a W65C22N Interface Chip: ; - IO.RB0-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 ;******************************************************************************** ; Keypad Buffer from $202 to $2ff ;******************************************************************************** KB_VAR = $00 KB_WRITE = $200 ; write pointer, relative to KB_WRITE KB_READ = $201 ; read ponter, relative to KB_START 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