Skip to content

Pucrunch

Spend effort packing so the small machine can unpack

Pucrunch is Pasi Ojala’s compressor for small Commodore computers. It combines repeated-sequence copies with run-length encoding, doing the expensive search on a host computer and keeping decompression practical on the target.

Pucrunch puts the hard work on the computer preparing a program. Pasi Ojala, also known as Albert, wrote its compressor in portable C and its small-machine decompressor in assembly. A host can spend memory and time searching for savings; a C64 need only restore the result.

Ojala’s design page dates the first version to March 1997, with a rewrite that December and a major update in October 1998. He also explained the work in C=Hacking.

ABABABAB can be described as AB followed by a six-byte copy from two bytes back. AAAAAAAA can be described as eight repetitions of A. These are concepts, not encoded Pucrunch bytes.
Two kinds of repetition that Pucrunch can exploit. This original diagram explains the ideas; it does not show Pucrunch’s actual bit-level encoding.

Two kinds of repetition

Pucrunch combines LZ77-style copies with run-length encoding. A copy refers to an earlier sequence in the output. A run describes several repetitions of one byte. Both save space when their descriptions are shorter than the data they replace.

The distinction matters. A repeated phrase and a long area filled with one value are different opportunities. Ojala explains that a dedicated run representation can describe longer runs than the copy lengths allowed by his LZ encoding. Lengths use variable-length codes, so small and large values need not occupy equal amounts of space.

The decoder shapes the format

Ojala’s Compression Basics explains why a small computer’s needs change the design. The decompressor must be short, use little working storage and avoid arithmetic that is expensive on an 8-bit processor. A format that compresses well on a large machine is not automatically cheap to decode on a small one.

His implementation also allows packed and expanded data to share part of memory, provided unread input remains safe. That is a loading arrangement with constraints, rather than a promise that any two addresses will work.

The same decisions recur in Exomizer and ByteBoozer. File size is one part of the comparison; decoder bytes, workspace and unpacking time also belong in the budget.

Sources

Checked. Verified against primary sources and signed off by a person.