mirror of
https://github.com/irmen/prog8.git
synced 2024-12-02 22:49:21 +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 {
|
||||
; -- 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.
|
||||
|
||||
ubyte fill
|
||||
@ -70,8 +70,8 @@ smallringbuffer {
|
||||
|
||||
|
||||
ringbuffer {
|
||||
; -- A ringbuffer (FIFO queue) that occupies a single page in memory, containing 8 KB maximum.
|
||||
; You can store and retrieve words too.
|
||||
; -- A ringbuffer (FIFO queue) that uses a block of 8 KB of memory.
|
||||
; You can store and retrieve bytes and words too.
|
||||
|
||||
uword fill
|
||||
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)
|
||||
|
@ -7,7 +7,7 @@ compression {
|
||||
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.
|
||||
; 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
|
||||
; compressed blocks (for instance if the source data is >64Kb)
|
||||
; 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 {
|
||||
; -- 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.
|
||||
; Stops decompressing when the maxsize has been reached.
|
||||
; -- 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.
|
||||
%asm {{
|
||||
sta _cb_mod1+1
|
||||
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 {
|
||||
; -- decodes "ByteRun1" (aka PackBits) RLE compressed data. Control byte value 128 ends the decoding.
|
||||
; Stops decompressing when the maxsize has been reached.
|
||||
; -- 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.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1 ; compressed data ptr
|
||||
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:
|
||||
|
@ -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.
|
||||
|
||||
|
||||
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)
|
||||
-------------------
|
||||
X16Emu Emulator debug routines, for Cx16 only.
|
||||
|
@ -1,6 +1,8 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
work a bit more on the buffers library
|
||||
|
||||
document the @R0 - @R15 register support for normal subroutine parameters (footgun!)
|
||||
|
||||
make a compiler switch to disable footgun warnings
|
||||
|
@ -82,7 +82,8 @@ class BitmapImage:
|
||||
def show(self) -> None:
|
||||
"""Shows the image on the screen"""
|
||||
if self.img.mode == "P":
|
||||
self.img.convert("RGB").convert("P").show()
|
||||
self.img.show()
|
||||
# self.img.convert("RGB").convert("P").show()
|
||||
else:
|
||||
self.img.show()
|
||||
|
||||
@ -198,7 +199,7 @@ class BitmapImage:
|
||||
elif bits_per_pixel == 4:
|
||||
num_colors = 15 if fixed_color_zero else 16
|
||||
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:
|
||||
assert preserve_first_16_colors==False, "bpp is too small for 16 default colors"
|
||||
num_colors = 3 if fixed_color_zero else 4
|
||||
|
Loading…
Reference in New Issue
Block a user