;******************************************************************************** ; @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__ where = 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