13

Many ZX Spectrum games* (and demos) would improve loading time and save space in the tape using rudimentary compression. During decompression, the game would display "decrunching" for several seconds. What compression algorithm was typically used? Was it simple RLE?

How did this typically compare with the technique of XORing the tape with a repeating value to reduce the number of 1 bits (which took 3420 T-states to read; 0 bits took only 1710 T-states)?

* I'm mostly talking about those made in the Russian hacker and demoscene, not mass-marketed commercial games.

9
  • 2
    I don't know whether it filtered up from the Spectrum or down from the ST/Amiga but the most popular cruncher and decruncher for the SAM Coupé was definitely Huffman-based. Alas I don't recall whether it also had a predecessor stage in which it applied RLE, or applied a sliding window, or anything like that. But clearly somebody was reading the literature.
    – Tommy
    Jun 21, 2021 at 21:34
  • 2
    Can you point to a specific example of a game that did this? I don't remember seeing any at the time.
    – Chromatix
    Jun 21, 2021 at 21:37
  • 2
    @introspec : Random example: SEAlink, one of several XMODEM extensions with compression, using ARC in mid-80s. Howard Chu's ports (1986) were Huffman encoded LZW. Admittedly, compression in the file transport was not typical -- compress then upload and/or download then decompress were very frequent operation sequences. Jun 22, 2021 at 20:03
  • 3
    @EricTowers, come on, we have "ZX Spectrum tapes" in the heading, do I really need to pre-empt my every comment with "Talking about ZX Spectrum tapes"? Anyway, talking about ZX Spectrum tapes, many thanks for the information that SEAlink existed on ZX. I did not know about it. However, anything ARC-based would require substantial memory for decompression (for tree etc). It may work in a file downloading utility, but not very likely as part of a game loader. So, I am still very sceptical about prospects of finding games packed using ARC or a similar scheme prior to ~second half of the 1990s.
    – introspec
    Jun 22, 2021 at 22:58
  • 2
    @EricTowers, I found a SEAlink source, it does not use any compression: github.com/cpeterso/sealink/blob/master/sealink.c Please clarify.
    – introspec
    Jun 22, 2021 at 23:06

5 Answers 5

19

I don't recall any mass-market commercial software for the Spectrum using the term "decrunching" - I'd associate that more with the demo and cracking scenes of central and eastern Europe, and my guess is that the software you saw originated from there. Around the early 1990s there were a few compression tools in use in that community, and while there's not much detailed documentation of the algorithms they used, there are a few clues to hint at something more advanced than RLE:

  • Turbo Imploder - the instructions (via Google translate) describe the "implode" mode as "extremely efficient compression based on the search method the same blocks of bytes", which sounds like Huffman encoding;
  • Mr.Pack II - as per the screenshot, this offered a "huffman - yes/no" option.

In more recent times, cross-development has opened up possibilities for more advanced compression algorithms, with the host machine doing the "heavy lifting" on the compression side while the decompressor is still simple and fast enough to implement in Z80. Among the current state of the art is Shrinkler and LZSA.

6
  • You're right. I think it was from the eastern European demoscene. Edited my question just now to be more precise.
    – forest
    Jun 21, 2021 at 22:59
  • 9
    "Implosion" is the name often given to an LZ78-based compression algorithm, usually LZW, which is not based on Huffman encoding at all. Instead it builds a dictionary of data blocks as they arise in the data, and the encoding is simply indices into that dictionary (which begins with a fixed set of literals and a "clear code"). LZW was used in GIF. It was found that combining LZ77 substring searches with Huffman compression was more effective than LZW, but a Z80 might not be able to decode it while keeping up with the tape.
    – Chromatix
    Jun 22, 2021 at 5:09
  • 4
    @introspec based on finding the "same blocks of bytes" definitely sounds like an LZ approach though.
    – hobbs
    Jun 22, 2021 at 13:39
  • 1
    @hobbs, yes, almost all of them would be derived from LZ77 or LZSS. Much more practical on 8-bit computers. LZW is derived from LZ78 - a very different algorithm that requires a lot more memory during decompression. RLE was also pretty common, but got completely wiped away by the middle of 1990s. The only reason RLE survived for a fairly long time is because many hacker releases were based on Multiface snapshots. This included the full system memory, so unusued memory tended to be filled by zeros and tended to compress well.
    – introspec
    Jun 22, 2021 at 13:45
  • 1
    I've just read the Turbo Imploder decompressor - it is a byte-aligned variation of LZ77 (LZF would be the nearest modern equivalent of it). I'll read MR Pack II as well - I'd surprised to see actual Huffman codes used, but never say never.
    – introspec
    Jun 24, 2021 at 10:22
13

As far as I know, there were two main approaches to compress the data. The first one, more common, was to load the whole code and "de-crunch" it. It uses RLE or simple vocabulary algorithm (LZ-like). RLE was pretty common to compress screen (there is a lot of zero sequences in many cases).

The second one, less common, performs decompression during the loading. The best example I remember (Digi Synth demo) uses the Huffman-coded data and its loader decompresses its data on the fly. But RLE is suitable for this case too.

I should mention that some tape-copy programs use on-the-fly compression and decompression to fit the most data into the limited memory of ZX Spectrum (TF-Copy, BS-Copy, etc.) The most common compression method for that was the RLE, mentioned above.

I never met a software that uses the second method you mention to reduce 1s. The typical Z80 machine code has a pretty big "entropy", so XORing cannot reduce the number of 1s in any significant way. A more efficient way was to use a custom loader routine with some kind of "turbo" approach (typically shortens the length of pulses), but it has some disadvantages too (higher sensitivity to tape errors, etc.)

3
  • 1
    Many thanks for mentioning Digi Synth demo - this is probably the earliest example of Huffman coding on ZX Spectrum that I am aware of. Do you know any other examples of programs from late 1980s/early 1990s that would use anything different from RLE or LZ77/LZSS style compression?
    – introspec
    Jun 22, 2021 at 10:38
  • 2
    @introspec I have to confess: my greatest hobby was the loader routines, not the compression itself. But as far as I remember, there were no advanced methods of data compression available in the late '80s. RLE was the simplest, LZ was more efficient. There were some optimization approaches, e.g. line reorder for the screen data or RLE with pre-counted value for the best compression ratio. Jun 22, 2021 at 11:49
  • @MartinMaly: Did you experiment with using more than two lengths of pulse? I don't know how much wow and flutter cheap tape drive had, but if one could classify pulses as being 1.0, 1.5, 2.0, or 2.5 times the minimum width, and had a uniform distribution of the four pulse widths, that would take an average of 1.75 times the minimum pulse length for every two bits of data stored.
    – supercat
    Oct 5, 2021 at 21:55
12

I wrote the compression routine use by the Multiface on the Spectrum and Amstrad machines. It was a plug in unit that would save all memory to tape and allow you to continue your game where you left off. Not at all to be used for piracy of course. I asked the makers, Romantic Robot, if it did any compression or just saved masses of zeros for a 16k game. It didn't do any compression, which added a lot of loading time for 16k games. I said I had some code that could do it in about 250 bytes, they told me they had about 120 spare. That's when I discovered the LDIR and CPIR commands. Basically my code would only look for a sequence of >8 identical bytes, and replace them with a 5 byte marker, the byte being repeated and the repeat count. The marker was a series of bytes I thought highly unlikely to appear as attributes, bitmap code, text, or assembly. So a very simple technique but it still saved a lot of loading time

1
  • 2
    Many thanks for your comment, it is great to see non-trivial examples of RLE being commonly used in the 1980s.
    – introspec
    Oct 4, 2021 at 10:10
4

For what it's worth, "decrunching" (and the opposite, crunching) appears to be a relatively common slang term for decompression on load on from the time when these systems were popular and is even still used in the current retrocomputing scene (see, for example, this demo from 2015.

The Wikipedia page for Amiga Software mentions it as having originated on the Commodore, at least a specific algorithm that involves using video memory as temporary storage - and this seems to have started the tradition of displaying "decrunching" along with possibly an animation.

1
  • 1
    fileformats.archiveteam.org/wiki/Crunch#Disambiguation lists a lot of compression utilities called "Crunch but doesn't give dates, making it difficult to tell which came first. Under CP/M, at least, "Crunch" was associated with LZW compression (as opposed to "Squeeze", which used Huffman compression).
    – john_e
    Nov 15, 2023 at 22:21
3

In the old days I looked into lots of game loders, so there was no 'decrunching' and no depacking in any original game software. Only turbo-loaders (like Speedlock, Alcatraz protections 'loading schemas') and special loading routines for 'loading screens' that didn't load all 6912 bytes directly. Just take a look at Alcatraz protected screens, which load screens nicely. But, yes, this may increase data size because it may not fill the whole screen. If this is the kind of compression you mentioned, ok, but actually it's a different screen format.

While the earliest pirate copies (e.g. from Bill Gilbert) at the end of the '80s and earliest '90s had some primitive RLE's. They also started to pack loading screens (laser compact or something like this - do not remember that old stuff). Some cool screen loaders also appeared on cracked versions of the games. Just take a look at cracked 'Foxx Fights Back' (don't remember what crack: it was in Bill Gilbert's or S.S. Captain's crack).

Since those times on, crack- and demoscene people started to pack everything, except some individual people. E.g. one Moscow guy made lots of game cracks, Softstar. Until the second half of the '90s he didn't use any packers to reduce the size of his TR-DOS versions. Just take a look at large images like Stormlord (Softstar '93) 269 TR-DOS sectors length: only cracktro, XOR-protection on loaders, but no depacking here. Not a big deal to sell fewer programs on 5.25" diskette because of their size, right? :)

The oldschool demosceners and system programmers brought lots of compressors since the '90s: KSA code cruncher (LZSS), megalz, hrust, hrum, rip... and that's not a complete list. But none of these listed packers were used originally by game developers in the '80s and early '90s. Some game developers pack their messages in text adventures using not ASCII, but 7 or 6 bit encodings. Some of these words were tokenized. Sometimes developers packed their graphic slides in adventures by programming lines and textures. In the '80s there were some examples of graphic slide programming (that you could call 'procedural output graphics'), but they were all quite primitive, although they saved memory. That's all in those days.

About packers since the '90s till nowadays, here is a visual comparison of all known compression algorithms on the ZX-Spectrum alongside 7zip on PC:

introspec's latest compression chart

In my Speccy days there was no 7zip depacker on the ZX-Spectrum. But, yeah, depacking PKZIP and RAR is possible on the ZX-Spectrum.

You can also read some articles about packing on the ZX-Spectrum:

As for me, in the old days after hrust packer I started to pack with rip: slower, but smaller size. Sometimes with handmade RLE because of unpacked block size limits, but sometimes also with handmade delta pack because of two code block with small differences. You should use some pre-processing tricks when your unpacked code block size is about #A000 bytes, or you have two equal code blocks with some differences (e.g. 48k and 128k versions of game).

Now let's move to the term 'decrunching'. If you mean self-modifying code, or prebuilt code for non-cycled outputs there were earlier examples from the '80s. I don't really know who was the first, but isometric 3d engines from Ultimate Play The Game was cool for the middle of the '80s (especially Bubbler). Some of them had non-cycle output program routines.

If you mean self-modifying code, or pre-built code for non-cycled outputs there was earlier examples from 80s. I don't really know who was the first, but isometric 3d engines from Ultimate Play The Game was cool for the middle of 80s (especially Bubbler). Some of them had non-cycle output program routines. But most of them was made without initialization, so if you wish LDI command 16 times instead of LD BC, 16: LDIR these games had 16 LDIs after the loading already. This is a quite simple example to show you why 16 LDIs is better than one LDIR:

# Copy block using one LDIR command:
LD BC,16                                          # 10 tacts
LD HL,<start address of code block to copy from>  # 10 tacts
LD DE,<start address of code block to copy>       # 10 tacts
LDIR                                              # 21 tact per one byte copy * 16 = 336

# Copy block using 16 LDI commands:
DUP 16                                            # start of duplicating command
LDI                                               # 16 tacts
EDUP                                              # 16 tacts per one byte copy * 16 = 256

So 336 vs 256 CPU tacts. That's the reason to use non-cycled output program routines.

Of course real examples of 'decrunched' (or initialized self-modifying code) routines can be more complex:

# Put 4 bytes 8 times
LD SP,<address on the screen>
LD HL,<two bytes of data 1>
LD DE,<two bytes of data 2>
DUP 8
PUSH HL
PUSH DE
EDUP

Lots of 'plasma' demo effects output data like in this example. But I find it difficult to remember at least a few games from the '80s that output graphics through the machine stack. At the same time demoscene products started to use initializing and self-modifying code from the early '90s. For example, Shock megademo from ESI (see on YouTube). But the longest decrunch in the '90s was in the 3d tunnel part of Insult megademo (you can see them on YouTube, but I'm not sure that it wasn't cut). You can also check crack intros from 'Mafia Private corporation', a demoscene team, they had long decrunches.

In the second part of the '90s and '00s demosceners got rid of long "decrunches" for the sake of action and drive. Now loading a part of data again from floppy is faster than pre-calculating everything. Although this is not the case for intros and some demos, most demos Went that way. These days some guys decided to decrunch or "unpack" some data on the go. Why not if you have a special format for it? Take a look at 'chunked' colour animation with bubble Weed demo by Triebkraft (YouTube). Each frame is divided into some chunks, which are stored in their own format. Is it a unique technique to save memory? Or "decrunching on the go"? There are other examples of how for the last 30 years the retro demoscene has only been trying to efficiently use the already small amount of RAM, doesn't matter if it's RLE, modern Exomizer and Shrinkler or animation store technique.

10
  • "Decrunching" is just one of many terms used for "decompressing". I remember some commandline tools for Unix or maybe the Amiga that detected the compression method and used different verbs depending on which method, such as "deflate", "implode", "reduce", "shrink", etc. I'd guess the cracking and demoscene guys learned compression from free Unix source code and made up a new cool verb of their own. Nov 15, 2023 at 8:23
  • 1
    Not sure not a new verb. Depacking and decrunching is not the same: decrunching is mostly about pre-built code, look-up tables and data on initialization. Nov 15, 2023 at 9:33
  • Hmm maybe. I didn't know about the demoscene until near the end of the Amiga era. I always interpreted it as decompressing but I wasn't actually in the scene. I'll ask some friends who were. Nov 15, 2023 at 9:50
  • It's 'unpacking', not 'depacking'.(There seems to be a small contingent trying to prefix 'de' onto words that already have an existing opposite that's existed for decades or centuries.)
    – TonyM
    Nov 15, 2023 at 12:42
  • 1
    Yes, "Euroenglish". Lots Amiga guys for example guys still depack a block of code: github.com/AxisOxy/Planet-Rocklobster Because of Poland, Finland, etc... There's nothing bad when they unpack Amiga taken from the farthest shelf of the cupboard to depack their own code :) Nov 15, 2023 at 13:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .