mirror of
https://github.com/irmen/prog8.git
synced 2024-12-04 19:50:19 +00:00
add compression.decode_rle_vram() to decompress RLE data directly to X16's VRAM.
Document the compression library.
This commit is contained in:
parent
2eed75f602
commit
bc9683cc54
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
smallringbuffer {
|
smallringbuffer {
|
||||||
; -- A ringbuffer (FIFO queue) that occupies a single page in memory, containing 255 bytes maximum.
|
; -- A ringbuffer (FIFO queue) that occupies a single page in memory, containing 255 bytes maximum.
|
||||||
; You can store and retrieve words too.
|
; You can store and retrieve bytes and words too.
|
||||||
; It's optimized for speed and depends on the byte-wrap-around feature when doing incs and decs.
|
; It's optimized for speed and depends on the byte-wrap-around feature when doing incs and decs.
|
||||||
|
|
||||||
ubyte fill
|
ubyte fill
|
||||||
@ -70,8 +70,8 @@ smallringbuffer {
|
|||||||
|
|
||||||
|
|
||||||
ringbuffer {
|
ringbuffer {
|
||||||
; -- A ringbuffer (FIFO queue) that occupies a single page in memory, containing 8 KB maximum.
|
; -- A ringbuffer (FIFO queue) that uses a block of 8 KB of memory.
|
||||||
; You can store and retrieve words too.
|
; You can store and retrieve bytes and words too.
|
||||||
|
|
||||||
uword fill
|
uword fill
|
||||||
uword head
|
uword head
|
||||||
@ -148,5 +148,5 @@ ringbuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; TODO ringbuffer (FIFO queue) should use banked ram on the X16, but still work on virtual
|
; TODO ringbuffer (FIFO queue) should use banked ram on the X16, but still work on virtual target
|
||||||
; TODO stack (LIFO queue) using more than 1 page of ram (maybe even banked ram on the x16)
|
; TODO stack (LIFO queue) using more than 1 page of ram (maybe even banked ram on the x16)
|
||||||
|
@ -7,7 +7,7 @@ compression {
|
|||||||
sub encode_rle_outfunc(uword data, uword size, uword output_function, bool is_last_block) {
|
sub encode_rle_outfunc(uword data, uword size, uword output_function, bool is_last_block) {
|
||||||
; -- Compress the given data block using ByteRun1 aka PackBits RLE encoding.
|
; -- Compress the given data block using ByteRun1 aka PackBits RLE encoding.
|
||||||
; output_function = address of a routine that gets a byte arg in A,
|
; output_function = address of a routine that gets a byte arg in A,
|
||||||
; this is the next RLE byte to write to the compressed output buffer or file.
|
; which is the next RLE byte to write to the compressed output buffer or file.
|
||||||
; is_last_block = usually true, but you can set it to false if you want to concatenate multiple
|
; is_last_block = usually true, but you can set it to false if you want to concatenate multiple
|
||||||
; compressed blocks (for instance if the source data is >64Kb)
|
; compressed blocks (for instance if the source data is >64Kb)
|
||||||
; Worst case result storage size needed = (size + (size+126) / 127) + 1
|
; Worst case result storage size needed = (size + (size+126) / 127) + 1
|
||||||
@ -136,9 +136,9 @@ compression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
asmsub decode_rle_srcfunc(uword source_function @AY, uword target @R0, uword maxsize @R1) clobbers(X) -> uword @AY {
|
asmsub decode_rle_srcfunc(uword source_function @AY, uword target @R0, uword maxsize @R1) clobbers(X) -> uword @AY {
|
||||||
; -- decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
; -- Decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
||||||
; instead of a source buffer, you provide a callback function that must return the next byte to compress in A.
|
; Also stops decompressing when the maxsize has been reached. Returns the size of the decompressed data.
|
||||||
; Stops decompressing when the maxsize has been reached.
|
; Instead of a source buffer, you provide a callback function that must return the next byte to compress in A.
|
||||||
%asm {{
|
%asm {{
|
||||||
sta _cb_mod1+1
|
sta _cb_mod1+1
|
||||||
sty _cb_mod1+2
|
sty _cb_mod1+2
|
||||||
@ -234,8 +234,9 @@ _end
|
|||||||
}
|
}
|
||||||
|
|
||||||
asmsub decode_rle(uword compressed @AY, uword target @R0, uword maxsize @R1) clobbers(X) -> uword @AY {
|
asmsub decode_rle(uword compressed @AY, uword target @R0, uword maxsize @R1) clobbers(X) -> uword @AY {
|
||||||
; -- decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
; -- Decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
||||||
; Stops decompressing when the maxsize has been reached.
|
; Also stops decompressing if the maxsize has been reached.
|
||||||
|
; Returns the size of the decompressed data.
|
||||||
%asm {{
|
%asm {{
|
||||||
sta P8ZP_SCRATCH_W1 ; compressed data ptr
|
sta P8ZP_SCRATCH_W1 ; compressed data ptr
|
||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
@ -345,6 +346,65 @@ _end
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmsub decode_rle_vram(uword compressed @R0, ubyte vbank @X, uword vaddr @AY) {
|
||||||
|
; -- Decodes "ByteRun1" (aka PackBits) RLE compressed data directly into Vera VRAM.
|
||||||
|
; Control byte value 128 ends the decoding. This routine is for the Commander X16 only.
|
||||||
|
%asm {{
|
||||||
|
stz cx16.VERA_CTRL
|
||||||
|
sta cx16.VERA_ADDR_L
|
||||||
|
sty cx16.VERA_ADDR_M
|
||||||
|
txa
|
||||||
|
ora #%00010000 ; autoincr by 1
|
||||||
|
sta cx16.VERA_ADDR_H
|
||||||
|
_loop
|
||||||
|
lda (cx16.r0)
|
||||||
|
bpl _copy_literals
|
||||||
|
cmp #128
|
||||||
|
bne +
|
||||||
|
rts ; DONE!
|
||||||
|
|
||||||
|
; replicate the next byte -n+1 times
|
||||||
|
+
|
||||||
|
inc cx16.r0L
|
||||||
|
bne +
|
||||||
|
inc cx16.r0H
|
||||||
|
+ eor #255
|
||||||
|
clc
|
||||||
|
adc #2
|
||||||
|
tay
|
||||||
|
lda (cx16.r0)
|
||||||
|
- sta cx16.VERA_DATA0
|
||||||
|
dey
|
||||||
|
bne -
|
||||||
|
inc cx16.r0L
|
||||||
|
bne _loop
|
||||||
|
inc cx16.r0H
|
||||||
|
bra _loop
|
||||||
|
|
||||||
|
_copy_literals
|
||||||
|
; copy the next n+1 bytes
|
||||||
|
inc cx16.r0L
|
||||||
|
bne +
|
||||||
|
inc cx16.r0H
|
||||||
|
+ pha
|
||||||
|
tax
|
||||||
|
inx
|
||||||
|
ldy #0
|
||||||
|
- lda (cx16.r0),y
|
||||||
|
sta cx16.VERA_DATA0
|
||||||
|
iny
|
||||||
|
dex
|
||||||
|
bne -
|
||||||
|
; increase pointer by n+1 bytes
|
||||||
|
pla
|
||||||
|
sec
|
||||||
|
adc cx16.r0L
|
||||||
|
sta cx16.r0L
|
||||||
|
bcc _loop
|
||||||
|
inc cx16.r0H
|
||||||
|
bra _loop
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
; prog8 source code for the asm routine above:
|
; prog8 source code for the asm routine above:
|
||||||
|
@ -928,6 +928,37 @@ the `bmx source code <https://github.com/irmen/prog8/tree/master/compiler/res/pr
|
|||||||
There's also the "showbmx" example to look at.
|
There's also the "showbmx" example to look at.
|
||||||
|
|
||||||
|
|
||||||
|
compression
|
||||||
|
-----------
|
||||||
|
Routines for data compression and decompression. Currently only the 'ByteRun1' aka 'PackBits' RLE encoding
|
||||||
|
is available. This is the compression that was also used in Amiga IFF images and in old MacPaint images.
|
||||||
|
|
||||||
|
``encode_rle (uword data, uword size, uword target, bool is_last_block) -> uword``
|
||||||
|
Compress the given data block using ByteRun1 aka PackBits RLE encoding.
|
||||||
|
Returns the size of the compressed RLE data. Worst case result storage size needed = (size + (size+126) / 127) + 1.
|
||||||
|
'is_last_block' = usually true, but you can set it to false if you want to concatenate multiple
|
||||||
|
compressed blocks (for instance if the source data is >64Kb)
|
||||||
|
|
||||||
|
``encode_rle_outfunc (uword data, uword size, uword output_function, bool is_last_block)``
|
||||||
|
Like ``encode_rle`` but not with an output buffer, but with an 'output_function' argument.
|
||||||
|
This is the address of a routine that gets a byte arg in A,
|
||||||
|
which is the next RLE byte to write to the compressed output buffer or file.
|
||||||
|
|
||||||
|
``decode_rle (uword compressed, uword target, uword maxsize) -> uword``
|
||||||
|
Decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
||||||
|
Also stops decompressing if the maxsize has been reached. Returns the size of the decompressed data.
|
||||||
|
|
||||||
|
``decode_rle_srcfunc (uword source_function, uword target, uword maxsize) -> uword``
|
||||||
|
Decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
||||||
|
Also stops decompressing when the maxsize has been reached. Returns the size of the decompressed data.
|
||||||
|
Instead of a source buffer, you provide a callback function that must return the next byte to compress in A.
|
||||||
|
|
||||||
|
``decode_rle_vram (uword compressed, ubyte vbank, uword vaddr)`` (cx16 only)
|
||||||
|
Decodes "ByteRun1" (aka PackBits) RLE compressed data directly into Vera VRAM.
|
||||||
|
Control byte value 128 ends the decoding.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
emudbg (cx16 only)
|
emudbg (cx16 only)
|
||||||
-------------------
|
-------------------
|
||||||
X16Emu Emulator debug routines, for Cx16 only.
|
X16Emu Emulator debug routines, for Cx16 only.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
work a bit more on the buffers library
|
||||||
|
|
||||||
document the @R0 - @R15 register support for normal subroutine parameters (footgun!)
|
document the @R0 - @R15 register support for normal subroutine parameters (footgun!)
|
||||||
|
|
||||||
make a compiler switch to disable footgun warnings
|
make a compiler switch to disable footgun warnings
|
||||||
|
@ -82,7 +82,8 @@ class BitmapImage:
|
|||||||
def show(self) -> None:
|
def show(self) -> None:
|
||||||
"""Shows the image on the screen"""
|
"""Shows the image on the screen"""
|
||||||
if self.img.mode == "P":
|
if self.img.mode == "P":
|
||||||
self.img.convert("RGB").convert("P").show()
|
self.img.show()
|
||||||
|
# self.img.convert("RGB").convert("P").show()
|
||||||
else:
|
else:
|
||||||
self.img.show()
|
self.img.show()
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ class BitmapImage:
|
|||||||
elif bits_per_pixel == 4:
|
elif bits_per_pixel == 4:
|
||||||
num_colors = 15 if fixed_color_zero else 16
|
num_colors = 15 if fixed_color_zero else 16
|
||||||
if num_colors==16 and preserve_first_16_colors:
|
if num_colors==16 and preserve_first_16_colors:
|
||||||
return self.quantize_to(default_colors[:16])
|
return self.quantize_to(default_colors[:16], 0)
|
||||||
elif bits_per_pixel == 2:
|
elif bits_per_pixel == 2:
|
||||||
assert preserve_first_16_colors==False, "bpp is too small for 16 default colors"
|
assert preserve_first_16_colors==False, "bpp is too small for 16 default colors"
|
||||||
num_colors = 3 if fixed_color_zero else 4
|
num_colors = 3 if fixed_color_zero else 4
|
||||||
|
Loading…
Reference in New Issue
Block a user