diff --git a/mode7_demo/mode7_decompress.s b/mode7_demo/mode7_decompress.s index 18d39c3f..64313ec9 100644 --- a/mode7_demo/mode7_decompress.s +++ b/mode7_demo/mode7_decompress.s @@ -6,8 +6,6 @@ UNPACK_BUFFER EQU $4000 -; Adjusted using incbin directive -LZ4_DATA_BEGIN EQU 0 start: ; set flags for HGR2 @@ -15,29 +13,232 @@ start: bit PAGE1 bit FULLGR - lda #<(data+LZ4_DATA_BEGIN) + ; inline lz4_decode + +; LZ4 data decompressor for Apple II + +; Code by Peter Ferrie (qkumba) (peter.ferrie@gmail.com) +; "LZ4 unpacker in 143 bytes (6502 version) (2013)" +; http://pferrie.host22.com/misc/appleii.htm +; This is that code, but with comments and labels added for clarity. +; I also found a bug when decoding with runs of multiples of 256 +; which has since been fixed upstream. + +; For LZ4 reference see +; https://github.com/lz4/lz4/wiki/lz4_Frame_format.md + +; LZ4 summary: +; +; HEADER: +; Should: check for magic number 04 22 4d 18 +; FLG: 64 in our case (01=version, block.index=1, block.checksum=0 +; size=0, checksum=1, reserved +; MAX Blocksize: 40 (64kB) +; HEADER CHECKSUM: a7 +; BLOCK HEADER: 4 bytes (le) If highest bit set, uncompressed! +; BLOCKS: +; Token byte. High 4-bits literal length, low 4-bits copy length +; + If literal length==15, then following byte gets added to length +; If that byte was 255, then keep adding bytes until not 255 +; + The literal bytes follow. There may be zero of them +; + Next is block copy info. little-endian 2-byte offset to +; be subtracted from current read position indicating source +; + The low 4-bits of the token are the copy length, which needs +; 4 added to it. As with the literal length, if it is 15 then +; you read a byte and add (and if that byte is 255, keep adding) + + + ;====================== + ; LZ4 decode + ;====================== + ; input buffer in LZ4_SRC + ; output buffer hardcoded still + ; size in ENDH:ENDL + + lda #<(data) sta LZ4_SRC - lda #>(data+LZ4_DATA_BEGIN) + lda #>(data) sta LZ4_SRC+1 - lda #<(data_end-data+LZ4_DATA_BEGIN) +; lda #<(data_end-data+LZ4_DATA_BEGIN) +; sta LZ4_END +; lda #>(data_end-data+LZ4_DATA_BEGIN) +; sta LZ4_END+1 + + lda #<(data_end) sta LZ4_END - lda #>(data_end-data+LZ4_DATA_BEGIN) + lda #>(data_end) sta LZ4_END+1 - jsr lz4_decode +lz4_decode: + + lda #>UNPACK_BUFFER ; original unpacked data offset + sta LZ4_DST+1 + lda #