; 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) length If highest bit set, uncompressed! ; data (see below), followed by checksum? ; 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) ; At end you have 4 byte end-of-block marker (all zeros?) then ; 4 bytes of checksum (if marked in flags) ; our code does that, so be sure to set end -8 ;LZ4_SRC EQU $00 ;LZ4_DST EQU $02 ;LZ4_END EQU $04 ;COUNT EQU $06 ;DELTA EQU $08 ;UNPACK_BUFFER EQU $5E00 ; offset of first unpacked byte ;====================== ; LZ4 decode ;====================== ; input buffer in LZ4_SRC ; output buffer hardcoded still ; size in ENDH:ENDL lz4_decode: ; lda LZ4_SRC ; packed data offset ; clc ; adc LZ4_END ; sta LZ4_END ; lda LZ4_SRC+1 ; adc LZ4_END+1 ; sta LZ4_END+1 ; lda #>UNPACK_BUFFER ; original unpacked data offset ; sta LZ4_DST+1 ; lda #