moved buffer to separate module

This commit is contained in:
matthias@rpi 2023-10-30 22:11:24 +01:00
parent 4dbdbaf55d
commit f3a51dc764
2 changed files with 148 additions and 68 deletions

97
system/buffer.s65 Normal file
View File

@ -0,0 +1,97 @@
;********************************************************************************
; @module ringbuffer
; @type utility
; @details
; Size of the ringbuffer is RBUF_MEM_END - RBUF_MEM_START - 2, since two bytes
; are used by the read and write pointer
; The RBUF_NAME variable must be defined, the functions will then be exported
; as rb_<RBUF_NAME>_<function> where <function> = init, read or write
; @requires
; RBUF_MEM_START: Start address of ringbuffer memory space
; RBUF_MEM_END: End address of ringbuffer memory space
; RBUF_NAME: Name of the ringbuffer
;********************************************************************************
.ifndef RBUF_MEM_START
.fatal "RBUF_MEM_START not defined"
.endif
.ifndef RBUF_MEM_END
.fatal "RBUF_MEM_END not defined"
.endif
; can not detect if RBUF_NAME is defined, if it is not you will get
; "String constant expected" Error on the line below
.define _RBUF_NAME .concat("rb_", RBUF_NAME)
RB_WRITE = RBUF_MEM_START ; write pointer, relative to RB_WRITE
RB_READ = RBUF_MEM_START + 1 ; read ponter, relative to RB_START
RB_START = RBUF_MEM_START + 2
RB_LENGTH = RBUF_MEM_END - RBUF_MEM_START - 2
.if RB_LENGTH < 1
.fatal "buffer size too small, must be at least 1"
.endif
.if RB_LENGTH > $ff
.fatal "buffer size too large, must be <= $ff"
.endif
;********************************************************************************
; @function Initialize the buffer
;********************************************************************************
.ident(.concat(_RBUF_NAME, "_init")):
.scope
stz RB_WRITE
stz RB_READ
rts
.endscope
;********************************************************************************
; @function Read a value from the buffer
; @details
; If there is no value to be read, the Pz will be set
; @returns A: value
; @modifies: A, X
;********************************************************************************
.ident(.concat(_RBUF_NAME, "_read")):
.scope
ldx RB_READ
cpx RB_WRITE
beq @rb_read_rts ; if buffer empty
lda RB_START,x
inx ; increment RB_READ pointer
cpx #RB_LENGTH
beq @rb_read_jump
stx RB_READ
@rb_read_rts:
rts
@rb_read_jump:
stz RB_READ
; make sure Pz is not set
ldx #$01
rts
.endscope
;********************************************************************************
; @function Write a value to the buffer
; @param A: value to store
; @modifies: X
;********************************************************************************
.ident(.concat(_RBUF_NAME, "_write")):
.scope
; lda kp_VALUES, x ; load the char in a
ldx RB_WRITE
sta RB_START,x
inx ; increment write pointer
cpx #RB_LENGTH
beq @rb_jump_write
stx RB_WRITE
rts
@rb_jump_write: ; when the end of the buffer is reached, the next keys go to the start again
stz RB_WRITE
rts
.endscope
.undefine _RBUF_NAME
.undefine RBUF_NAME

View File

@ -6,112 +6,95 @@
; The LCD must be connected to a W65C22N Interface Chip:
; - IO.RB0-7 ->
; @requires KP_IO: Base Address of IO Chip
; @depends IO-W65C22N
; @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
RBUF_MEM_START = $200
RBUF_MEM_END = $2ff
.define RBUF_NAME "keypad"
.include "buffer.s65"
; 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
KB_VAR = $05
KB_LAST = $06
; 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
.proc kp_init
; todo remove
stz KB_LAST
; todo remove later
lda #$ff
sta KP_IO+IO_DDRB
stz KP_IO+IO_RB
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
; lda #%00010000 ; set CB1 to interrupt on pos. edge
lda #IO_PCR_CB1_IP_AE
sta KP_IO+IO_PCR
jsr kb_init ; init keybuffer
jsr rb_keypad_init ; init keybuffer
lda #%10010000 ; enable interrupt for CB1 on KP_IO
sta KP_IO+IO_IER
rts
.endproc
;********************************************************************************
; Reading the Keypad
; @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
;********************************************************************************
kp_read: ; test each "row" and check which column is 1
.proc kp_read_on_irq
; test each "row" and check which column is 1
lda #%00001110
ldx #$00
jsr @kp_read_branch
jsr @kp_read_column
lda #%00001101
ldx #$04
jsr @kp_read_branch
jsr @kp_read_column
lda #%00001011
ldx #$08
jsr @kp_read_branch
jsr @kp_read_column
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:
jsr @kp_read_column
bra @kp_read_rts
@kp_read_column:
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
bbr4 KB_VAR,@kp_write
inx
bbr5 KB_VAR,_kb_write
bbr5 KB_VAR,@kp_write
inx
bbr6 KB_VAR,_kb_write
bbr6 KB_VAR,@kp_write
inx
bbr7 KB_VAR,_kb_write
bbr7 KB_VAR,@kp_write
rts
@kp_write:
; temporary: store last keypress in KB_LAST, TODO: remove
lda kp_VALUES,x
sta KB_LAST
txa
jsr rb_keypad_write
@kp_read_rts:
stz KP_IO+IO_RB
; lda KP_IO+IO_RB ; read to definetly clear the interrupt flag
rts
.endproc
.segment "RODATA"
kp_VALUES:
; TODO change to literal
.byte "123A", "456B", "789C", "*0#D"