dirkwhoffmann / virtualc64

VirtualC64 is a cycle-accurate C64 emulator for macOS
https://dirkwhoffmann.github.io/virtualc64
Other
355 stars 33 forks source link

Compress memory in snapshots #802

Closed dirkwhoffmann closed 1 month ago

dirkwhoffmann commented 3 months ago

Snapshots can grow large, especially when a memory extension such as a REU or a GeoRam is attached.

In 5.1, memory should be stored in a compressed format in snapshots. A simple run-length encoding seems appropriate for this use case.

dirkwhoffmann commented 2 months ago

I've implemented a simple run-length compressor and did some experimental tests:

Test 1: A snapshot of a C64 after powering up with no disk present:

Compressing 935278 bytes (hash: 0x2a8e5948)...
Compressed size: 789779 bytes
Uncompressing 789779 bytes...
Uncompressed size: 935278 bytes (hash: 0x2a8e5948)

Test 2: A snapshot of a C64 after powering up with a blank disk inserted:

Compressing 1617776 bytes (hash: 0x72f5abcc)...
Compressed size: 1030954 bytes
Uncompressing 1030954 bytes...
Uncompressed size: 1617776 bytes (hash: 0x72f5abcc)

Test 3: A snapshot of a C64 after powering up with an XL REU (2MB) attached:

Snapshot:168 Compressing 3032541 bytes (hash: 0x6ff7edea)...
Snapshot:173 Compressed size: 814491 bytes
Snapshot:181 Uncompressing 814491 bytes...
Snapshot:186 Uncompressed size: 3032541 bytes (hash: 0x6ff7edea)

Compression rates:

Test 1: 85% of the original size Test 2: 64% of the original size Test 3: 27% of the original size

Test 1 exhibits a low compression rate because the run-length encoder does not work well on uninitialized RAM. This is due to the RAM init pattern, which looks like this:

Bildschirmfoto 2024-08-30 um 19 07 41

Lempel-Ziv encoding would be a good fit for this kind of data, but I aim to keep the code overhead low for this feature. My RL encoder and decoder are just a few lines of code.

dirkwhoffmann commented 2 months ago

Seems to work...

Bildschirmfoto 2024-08-31 um 11 50 13 Bildschirmfoto 2024-08-31 um 11 50 40