3 ms·
LFT has come up with a clever routine for decoding Commondore floppy data in realtime. This is quite an achievement that mixes bit twiddling hacks, self-modifyi
by NateLawson 14y ago
LFT has come up with a clever routine for decoding Commondore floppy data in realtime. This is quite an achievement that mixes bit twiddling hacks, self-modifying code, cycle counting, and undocumented opcodes.
While the Commodore serial transfer routines are well-known for being terribly slow (300 bytes/sec), various fastloaders have been used since the mid 80's. The 1541 drive has its own 6502 CPU, so the computer could download code into the drive's RAM and then talk to it via an optimized protocol. These routines have been reasonably fast and Krill's loader is one of the more modern variants.
However, there's another aspect that hadn't been optimized before. Data is stored on magnetic media in an expanded form (5 bits for every 4 bits of data for Commodore's GCR coding) so that the clock signal can be regenerated from the data. Similar encodings are used for CDs and DVDs these days as well.
The data needs to be decoded from its media format into the original data. Normally, the 1541 drive does this decoding since it has plenty of time. It reads a sector, decodes it, and leisurely transmits the results back. Then it repeats the process for the next sector. Meanwhile, the disk is still spinning underneath, rotating several times per sector read.
Some fastloaders speed this up by avoiding decoding on the drive. They transfer the raw data to the C64 and decode it there, letting the drive just read sectors and transmit the data. But decoding in realtime has been the holy grail.
LFT's routine is very clever and has lessons for data packing/unpacking for other platforms as well. It's a classic time/memory tradeoff where some expansion during the unpacking process saves CPU cycles. In short, the standard approach of masking and shifting is not the only way to deal with non-byte-aligned fields. Without a more clever approach, realtime decoding is not possible.
The result is code that can decode from raw GCR to data bytes on the fly, transmitting data to the C64 at almost the rate of the floppy spinning (roughly 25 microseconds/byte).
I say "almost" since checksums still need to be validated. This means that an interleave of 2 (every other sector) can be introduced when writing the data in order to have the next sequential sector available to be read after the previous one has been decoded.
Congrats to LFT on a great accomplishment 30 years in the making.