mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
245 lines
5.1 KiB
Lua
245 lines
5.1 KiB
Lua
; **experimental** buffer data structures, API subject to change!!
|
|
|
|
%option no_symbol_prefixing, ignore_unused
|
|
|
|
smallringbuffer {
|
|
; -- A ringbuffer (FIFO queue) that occupies 256 bytes in memory.
|
|
; You can store and retrieve bytes and words. No guards against over/underflow.
|
|
; It's optimized for speed and depends on the byte-wrap-around when doing incs and decs.
|
|
|
|
ubyte fill = 0
|
|
ubyte head = 0
|
|
ubyte tail = 255
|
|
ubyte[256] buffer
|
|
|
|
sub init() {
|
|
; -- (re)initialize the ringbuffer
|
|
head = fill = 0
|
|
tail = 255
|
|
}
|
|
|
|
sub size() -> ubyte {
|
|
return fill
|
|
}
|
|
|
|
sub free() -> ubyte {
|
|
return 255-fill
|
|
}
|
|
|
|
sub isfull() -> bool {
|
|
return fill>=254
|
|
}
|
|
|
|
sub isempty() -> bool {
|
|
return fill<=1
|
|
}
|
|
|
|
sub put(ubyte value) {
|
|
; -- store a byte in the buffer
|
|
buffer[head] = value
|
|
head++
|
|
fill++
|
|
}
|
|
|
|
sub putw(uword value) {
|
|
; -- store a word in the buffer
|
|
fill += 2
|
|
buffer[head] = lsb(value)
|
|
head++
|
|
buffer[head] = msb(value)
|
|
head++
|
|
}
|
|
|
|
sub get() -> ubyte {
|
|
; -- retrieves a byte from the buffer
|
|
fill--
|
|
tail++
|
|
return buffer[tail]
|
|
}
|
|
|
|
sub getw() -> uword {
|
|
; -- retrieves a word from the buffer
|
|
fill -= 2
|
|
tail++
|
|
cx16.r0L = buffer[tail]
|
|
tail++
|
|
cx16.r0H = buffer[tail]
|
|
return cx16.r0
|
|
}
|
|
}
|
|
|
|
; note: for a "small stack" (256 bytes size) just use the CPU stack via sys.push[w] / sys.pop[w].
|
|
|
|
stack {
|
|
; -- A stack (LIFO) that uses a block of 8 KB of memory. Growing downward from the top of the buffer.
|
|
; You can store and retrieve bytes and words. There are no guards against stack over/underflow.
|
|
|
|
uword sp
|
|
ubyte bank
|
|
|
|
sub init(ubyte rambank) {
|
|
; -- initialize the stack, must be called before use. Supply the HiRAM bank to use as buffer space.
|
|
sp = $bfff
|
|
bank = rambank
|
|
}
|
|
|
|
sub size() -> uword {
|
|
return $bfff-sp
|
|
}
|
|
|
|
sub free() -> uword {
|
|
return sp-$a000
|
|
}
|
|
|
|
sub isfull() -> bool {
|
|
return sp<=$a001
|
|
}
|
|
|
|
sub isempty() -> bool {
|
|
return sp==$bfff
|
|
}
|
|
|
|
sub push(ubyte value) {
|
|
; -- put a byte on the stack
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
@(sp) = value
|
|
sp--
|
|
|
|
cx16.rambank(sys.pop())
|
|
}
|
|
|
|
sub pushw(uword value) {
|
|
; -- put a word on the stack (lsb first then msb)
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
@(sp) = lsb(value)
|
|
sp--
|
|
@(sp) = msb(value)
|
|
sp--
|
|
|
|
cx16.rambank(sys.pop())
|
|
}
|
|
|
|
sub pop() -> ubyte {
|
|
; -- pops a byte off the stack
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
sp++
|
|
cx16.r0L = @(sp)
|
|
cx16.rambank(sys.pop())
|
|
return cx16.r0L
|
|
}
|
|
|
|
sub popw() -> uword {
|
|
; -- pops a word off the stack.
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
sp++
|
|
cx16.r0H = @(sp)
|
|
sp++
|
|
cx16.r0L = @(sp)
|
|
cx16.rambank(sys.pop())
|
|
return cx16.r0
|
|
}
|
|
}
|
|
|
|
|
|
ringbuffer {
|
|
; -- A ringbuffer (FIFO queue) that uses a block of 8 KB of memory.
|
|
; You can store and retrieve bytes and words too. No guards against buffer under/overflow.
|
|
|
|
uword fill, head, tail
|
|
ubyte bank = 255 ; set via init()
|
|
|
|
sub init(ubyte rambank) {
|
|
; -- initialize the ringbuffer, must be called before use. Supply the HiRAM bank to use as buffer space.
|
|
head = $a000
|
|
tail = $bfff
|
|
fill = 0
|
|
bank = rambank
|
|
}
|
|
|
|
sub size() -> uword {
|
|
return fill
|
|
}
|
|
|
|
sub free() -> uword {
|
|
return $1fff-fill
|
|
}
|
|
|
|
sub isempty() -> bool {
|
|
return fill<=1
|
|
}
|
|
|
|
sub isfull() -> bool {
|
|
return fill>=8191
|
|
}
|
|
|
|
sub put(ubyte value) {
|
|
; -- store a byte in the buffer
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
@(head) = value
|
|
fill++
|
|
inc_head()
|
|
cx16.rambank(sys.pop())
|
|
}
|
|
|
|
sub putw(uword value) {
|
|
; -- store a word in the buffer
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
pokew(head, value)
|
|
fill += 2
|
|
inc_head()
|
|
inc_head()
|
|
cx16.rambank(sys.pop())
|
|
}
|
|
|
|
sub get() -> ubyte {
|
|
; -- retrieves a byte from the buffer
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
fill--
|
|
inc_tail()
|
|
cx16.r0L= @(tail)
|
|
cx16.rambank(sys.pop())
|
|
return cx16.r0L
|
|
}
|
|
|
|
sub getw() -> uword {
|
|
; -- retrieves a word from the buffer
|
|
sys.push(cx16.getrambank())
|
|
cx16.rambank(bank)
|
|
|
|
fill -= 2
|
|
inc_tail()
|
|
cx16.r0L = @(tail)
|
|
inc_tail()
|
|
cx16.r0H = @(tail)
|
|
cx16.rambank(sys.pop())
|
|
return cx16.r0
|
|
}
|
|
|
|
sub inc_head() {
|
|
head++
|
|
if msb(head)==$c0
|
|
head=$a000
|
|
}
|
|
|
|
sub inc_tail() {
|
|
tail++
|
|
if msb(tail)==$c0
|
|
tail=$a000
|
|
}
|
|
}
|
|
|