6502-OS/system/buffer.h65

115 lines
3.3 KiB
Plaintext
Raw Normal View History

2024-08-08 20:39:25 +02:00
;;********************************************************************************
;; @module ringbuffer
;; @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`
;;
;; @note
;; Doxygen can not generate proper documentation for this module, because
;; all names are defined using macros
;; @requires
;; RBUF_MEM_START: First address of ringbuffer memory space
;; RBUF_MEM_END: Last address of ringbuffer memory space
;; RBUF_NAME: Name of the ringbuffer
;; @ingroup utility
;;********************************************************************************
2023-11-11 12:13:47 +01:00
.code
2023-10-30 22:11:24 +01:00
.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
2024-08-08 20:39:25 +02:00
;;********************************************************************************
;; @function Initialize the buffer
;;********************************************************************************
2023-10-30 22:11:24 +01:00
.ident(.concat(_RBUF_NAME, "_init")):
.scope
stz RB_WRITE
stz RB_READ
rts
.endscope
2024-08-08 20:39:25 +02:00
;;********************************************************************************
;; @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
;;********************************************************************************
2023-10-30 22:11:24 +01:00
.ident(.concat(_RBUF_NAME, "_read")):
.scope
ldx RB_READ
cpx RB_WRITE
beq @rb_read_rts ; if buffer empty
lda RB_START,x
2023-11-01 13:13:23 +01:00
inx ; increment RB_READ pointer, not using macro bec. of unknown Pz
2023-10-30 22:11:24 +01:00
cpx #RB_LENGTH
2023-11-01 13:13:23 +01:00
beq @read_wrap
2023-10-30 22:11:24 +01:00
stx RB_READ
@rb_read_rts:
rts
2023-11-01 13:13:23 +01:00
@read_wrap: ; ptr == RB_LENGTH -> ptr = 0
2023-10-30 22:11:24 +01:00
stz RB_READ
; make sure Pz is not set
ldx #$01
rts
.endscope
2024-08-08 20:39:25 +02:00
;;********************************************************************************
;; @function Write a value to the buffer
;; @param A: value to store
;; @modifies X
;;********************************************************************************
2023-10-30 22:11:24 +01:00
.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
2023-11-01 13:13:23 +01:00
beq @write_wrap
2023-10-30 22:11:24 +01:00
stx RB_WRITE
2023-11-01 13:13:23 +01:00
@check_buf_full: ; increment read if buffer is full
cpx RB_READ
2023-11-09 12:09:36 +01:00
beq @read_inc
2023-10-30 22:11:24 +01:00
rts
2023-11-01 13:13:23 +01:00
@write_wrap: ; ptr == RB_LENGTH -> ptr = 0
2023-10-30 22:11:24 +01:00
stz RB_WRITE
2023-11-09 12:09:36 +01:00
ldx #0
2023-11-01 13:13:23 +01:00
bra @check_buf_full
@read_inc:
ldx RB_READ
inx
cpx #RB_LENGTH
2023-11-09 12:09:36 +01:00
beq @read_wrap
2023-11-01 13:13:23 +01:00
stx RB_READ
rts
@read_wrap: ; ptr == RB_LENGTH -> ptr = 0
stz RB_READ
2023-10-30 22:11:24 +01:00
rts
.endscope
.undefine _RBUF_NAME
.undefine RBUF_NAME