LZ4.i

Summary
LZ4.i
LZ4Optional package adding LZ4 decompression
Macros
LZ4_decompressDecompress LZ4 frame
LZ4_decompress_blockDecompress LZ4 block

LZ4

Optional package adding LZ4 decompression

LZ4 is an extremely simple compression algorithm that still outperforms algorithms traditionally most popular on consoles – like LZSS and its derivatives – both in compression ratio and decoding speed.

Olivier Zardini has published a popular 65816 implementation which relies heavily on self-modifying code.  That makes it very fast and small, and it suits 65816-equipped home computers perfectly.  It does have some drawbacks, though∶

  • It can’t run from read only memory regions
  • It uses fixed source and destination offsets
  • The compressed stream size is needed as parameter

The implementation included in libSFX overcome all these limitations with a slight (or even moderate!) performancy penalty.  I haven’t benchmarked the two under controlled circumstances, but the libSFX implementation shouldn’t be much of a bottleneck at between 200-300KB/s (decoding 32-48KB blocks of raw image and text data from ROM to WRAM).

Decompression from any memory region to RAM is performed with the LZ4_decompress macro.  To link LZ4 support in a project, add LZ4 to libsfx_packages in the project makefile.

Makefile

# Use packages
libsfx_packages := LZ4

The lz4 encoder is included in the toolchain.  To automatically derive lz4 compressed files add them to the project makefile.

Makefile

# Derived data files
derived_files := Data/SNES.png.tiles.lz4

This will compress “Data/SNES.png.tiles” to “Data/SNES.png.tiles.lz4” during build, before any source files are assembled.

Macros

LZ4_decompress

Decompress LZ4 frame

Parameters

:in:    source  LZ4 frame address (uint24)    constant
:in:    dest    Destination address (uint24)  ay/hi:y/ex:y
                                              constant
:out?:  outlen  Decompressed length (uint16)  a/x/y

Example

;Decompress graphics and upload to VRAM

LZ4_decompress    Tilemap, EXRAM, y           ;Returns decompressed length in y
VRAM_memcpy       $2000, EXRAM, y             ;Copy y bytes to VRAM

LZ4_decompress_block

Decompress LZ4 block

Parameters

:in:    source  LZ4 block address (uint24)    constant
:in:    dest    Destination address (uint24)  ay/hi:y/ex:y
                                              constant
:out?:  outlen  Decompressed length (uint16)  a/x/y
Decompress LZ4 frame