-
-
Notifications
You must be signed in to change notification settings - Fork 66
Add LZ4 decompression #693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f6db693
c535725
dcda915
db6a6f9
3d5e706
554f679
0c9e93b
1d88fc2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,206 @@ | ||
| .assume adl=1 | ||
|
|
||
| .section .text._lz4_Decompress_Block | ||
| .global _lz4_Decompress_Block | ||
| .type _lz4_Decompress_Block, @function | ||
|
|
||
| ; size_t lz4_Decompress_Block(void *dst, const void *block, size_t block_size); | ||
| _lz4_Decompress_Block: | ||
| ld iy, 0 | ||
| add iy, sp | ||
| ; DE = dst | ||
| ld de, (iy + 3) | ||
| ; BC = block_size | ||
| ld bc, (iy + 9) | ||
| ; IY = block | ||
| ld iy, (iy + 6) | ||
| ; Save dst | ||
| push de | ||
| call lz4_decompress_block_internal | ||
| ; Calculate decompressed size based on final dst | ||
| ex de, hl | ||
| pop de | ||
| sbc hl, de | ||
| ret | ||
mateoconlechuga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| .section .text._lz4_Decompress | ||
| .global _lz4_Decompress | ||
| .type _lz4_Decompress, @function | ||
|
|
||
| ; void lz4_Decompress(void *dst, const void *src); | ||
| _lz4_Decompress: | ||
| ld hl, 3 | ||
| add hl, sp | ||
| ; DE = dst | ||
| ld de, (hl) | ||
| inc hl | ||
| inc hl | ||
| inc hl | ||
| ; IY = src | ||
| ld iy, (hl) | ||
| ; BC = size | ||
| ld bc, (iy) | ||
mateoconlechuga marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ; Skip size header | ||
| lea iy, iy + 3 | ||
| ; Fallthrough | ||
|
|
||
| .local lz4_decompress_block_internal | ||
| .type lz4_decompress_block_internal, @function | ||
|
|
||
| ; Input: IY = compressed block, DE = decompression buffer, BC = size of block | ||
| ; Output: IY = after compressed block, DE = after decompressed data, carry flag clear | ||
| ; Destroys: AF, BC, HL | ||
| lz4_decompress_block_internal: | ||
| ; HL = compressed block | ||
| lea hl, iy + 0 | ||
| ; Set IY to after compressed block | ||
| add iy, bc | ||
| inc.s bc ; BCU = 0 | ||
| ; Read the first token | ||
| ld a, (hl) | ||
| ; Check for the special case of zero-length output | ||
| or a, a | ||
| jr nz, .L.start | ||
| ret | ||
|
|
||
| .L.copy_backref_long: | ||
| ; Save the input pointer and restore the backref pointer | ||
| ex (sp), hl | ||
| ; Copy the amount prior to the last length byte, minus 1 | ||
| ldir | ||
| ; Copy the amount of the last length byte, plus 1 | ||
| ld c, a | ||
| .L.copy_backref: | ||
| ; Copy the backref data | ||
| ldir | ||
| ; Restore the input pointer | ||
| pop hl | ||
| ; Read the next token | ||
| ld a, (hl) | ||
| .L.start: | ||
| inc hl | ||
| ; Check if the literal field is zero | ||
| ; If so, this cannot be the end of block, go directly to backref handling | ||
| ld c, $10 | ||
| cp a, c | ||
| jr c, .L.backref | ||
| ; Save the token in B | ||
| ld b, a | ||
| ; Check for extended literal | ||
| add a, c | ||
| jr c, .L.literal_long | ||
| ; Multiply the token by 16, placing the literal field in B | ||
| mlt bc | ||
| ; Set BC to the literal length, which is known to be non-zero | ||
| ld c, b | ||
| ld b, 0 | ||
| ; Copy the literals | ||
| ldir | ||
| ; Mask the backref field | ||
| and a, $0F | ||
| ; If the backref field is non-zero, this cannot be end of block | ||
| jr nz, .L.backref | ||
| ; Check for end of block quickly | ||
| ld a, l | ||
| sub a, iyl | ||
| jr z, .L.maybe_end_of_block | ||
| xor a, a | ||
| .L.backref: | ||
| ; Read backref offset into BC | ||
| ld c, (hl) | ||
| inc hl | ||
| ld b, (hl) | ||
| inc hl | ||
| ; Save the input pointer | ||
| push hl | ||
| ; Add 4 to backref length field, and clear carry | ||
| add a, 4 | ||
| ; Calculate HL = DE - BC | ||
| sbc hl, hl | ||
| add hl, de | ||
| sbc hl, bc | ||
| ; Set BC to backref length | ||
| ld c, a | ||
| ld b, 0 | ||
| ; Check for extended length | ||
| add a, -($0F + 4) | ||
| jr nz, .L.copy_backref | ||
| ; Save the backref pointer and restore the input pointer | ||
| ex (sp), hl | ||
| .L.backref_loop: | ||
| ; Read the next length byte and add 1 | ||
| adc a, (hl) | ||
| inc hl | ||
| ; Decrement the length by 1 | ||
| dec bc | ||
| ; Check if the length byte was 255 | ||
| jr nz, .L.copy_backref_long | ||
| ; Increment the length by 256 | ||
| inc b | ||
| ; Loop if B did not carry to 0 | ||
| jr nz, .L.backref_loop | ||
| ; Save C | ||
| ld a, c | ||
| ; Set B = C = 255 | ||
| dec b | ||
| ld c, b | ||
| ; Increment BCU and set B = C = 0 | ||
| inc bc | ||
| ; Restore C | ||
| ld c, a | ||
| ; Set A = 0, preserving carry as 1 | ||
| ld a, b | ||
| jr .L.backref_loop | ||
|
|
||
| .L.literal_long: | ||
| ; Save the backref field and zero flag | ||
| push af | ||
| ; Start with literal length of 15 | ||
| ld b, 0 | ||
| dec bc | ||
| .L.literal_loop_outer: | ||
| ; Set A = 0, preserving carry as 1 | ||
| ld a, b | ||
| .L.literal_loop: | ||
| ; Read the next length byte and add 1 | ||
| adc a, (hl) | ||
| inc hl | ||
| ; Decrement the length by 1 | ||
| dec bc | ||
| ; Check if the length byte was 255 | ||
| jr nz, .L.copy_literal_long | ||
| ; Increment the length by 256 | ||
| inc b | ||
| ; Loop if B did not carry to 0 | ||
| jr nz, .L.literal_loop | ||
| ; Save C | ||
| ld a, c | ||
| ; Set B = C = 255 | ||
| dec b | ||
| ld c, b | ||
| ; Increment BCU and set B = C = 0 | ||
| inc bc | ||
| ; Restore C | ||
| ld c, a | ||
| jr .L.literal_loop_outer | ||
|
|
||
| .L.copy_literal_long: | ||
| ; Copy the amount prior to the last length byte, minus 1 | ||
| ldir | ||
| ; Copy the amount of the last length byte, plus 1 | ||
| ld c, a | ||
| ldir | ||
| ; Restore the backref field and zero flag | ||
| pop af | ||
| ; If the backref field is non-zero, this cannot be end of block | ||
| jr nz, .L.backref | ||
| ; Clear carry | ||
| or a, a | ||
|
Comment on lines
+194
to
+198
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would have been, yes, but it became set again from the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (my original comment was deleted)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading it over again, it looks like the carry is always set: add a, c
jr c, .L.literal_long
; NOT FALL-THROUGH
.L.literal_long:
push afThis means we might be able to do something like. This does change it so carry is set if ; or a, a
; carry always set
.L.maybe_end_of_block:
; Full check for end of block (carry is clear and A = 0)
lea bc, iy - 1
sbc hl, bc
add hl, bc
inc.s bc ; BCU = 0
jr nz, .L.backref
ret
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That won't work because it would need an added |
||
| .L.maybe_end_of_block: | ||
| ; Full check for end of block (carry is clear and A = 0) | ||
| lea bc, iy + 0 | ||
| sbc hl, bc | ||
| add hl, bc | ||
| inc.s bc ; BCU = 0 | ||
| jr nz, .L.backref | ||
| ret | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| obj/ | ||
| bin/ | ||
| src/gfx/*.c | ||
| src/gfx/*.h | ||
| src/gfx/*.8xv | ||
| .DS_Store | ||
| convimg.yaml.lst |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| { | ||
| "transfer_files": | ||
| [ | ||
| "bin/DEMO.8xp" | ||
| ], | ||
| "target": | ||
| { | ||
| "name": "DEMO", | ||
| "isASM": true | ||
| }, | ||
| "sequence": | ||
| [ | ||
| "action|launch", | ||
| "delay|500", | ||
| "hashWait|1", | ||
| "key|enter", | ||
| "hashWait|2", | ||
| "key|enter", | ||
| "hashWait|3" | ||
| ], | ||
| "hashes": | ||
| { | ||
| "1": | ||
| { | ||
| "description": "Test fullscreen image display", | ||
| "start": "vram_start", | ||
| "size": "vram_8_size", | ||
| "expected_CRCs": [ "69A1B0DB" ] | ||
| }, | ||
| "2": | ||
| { | ||
| "description": "Test fullscreen image display", | ||
| "start": "vram_start", | ||
| "size": "vram_8_size", | ||
| "expected_CRCs": [ "69A1B0DB" ] | ||
| }, | ||
| "3": | ||
| { | ||
| "description": "Test program exit", | ||
| "start": "vram_start", | ||
| "size": "vram_16_size", | ||
| "expected_CRCs": [ "FFAF89BA", "101734A5", "9DA19F44", "A32840C8", "349F4775" ] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # ---------------------------- | ||
| # Makefile Options | ||
| # ---------------------------- | ||
|
|
||
| NAME = DEMO | ||
| ICON = icon.png | ||
| DESCRIPTION = "CE C Toolchain Demo" | ||
| COMPRESSED = NO | ||
|
|
||
| CFLAGS = -Wall -Wextra -Oz | ||
| CXXFLAGS = -Wall -Wextra -Oz | ||
|
|
||
| # ---------------------------- | ||
|
|
||
| include $(shell cedev-config --makefile) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| palettes: | ||
| - name: global_palette | ||
| images: automatic | ||
|
|
||
| converts: | ||
| - name: background | ||
| palette: global_palette | ||
| compress: lz4hc | ||
| width-and-height: false | ||
| images: | ||
| - background.png | ||
|
|
||
| outputs: | ||
| - type: c | ||
| include-file: gfx.h | ||
| palettes: | ||
| - global_palette | ||
| converts: | ||
| - background |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #include <ti/getcsc.h> | ||
| #include <graphx.h> | ||
| #include <compression.h> | ||
|
|
||
| #include "gfx/gfx.h" | ||
|
|
||
| int main(void) | ||
| { | ||
| gfx_Begin(); | ||
|
|
||
| gfx_SetPalette(global_palette, sizeof_global_palette, 0); | ||
|
|
||
| lz4_Decompress(gfx_vram, background_compressed); | ||
|
|
||
| while (!os_GetCSC()); | ||
|
|
||
| gfx_ZeroScreen(); | ||
|
|
||
| if (lz4_Decompress_Block(gfx_vram, background_compressed + sizeof(uint24_t), background_compressed_size - sizeof(uint24_t)) != background_size) | ||
| { | ||
| gfx_ZeroScreen(); | ||
| } | ||
|
|
||
| while (!os_GetCSC()); | ||
|
|
||
| gfx_End(); | ||
|
|
||
| return 0; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.