32

Some Apple II 5.25" floppies used a special pattern of bytes that could not be automatically detected by disk copying software. How could the pattern be invisible to disk copiers but detectable by the program itself?

1 Answer 1

32

The Apple II reads disk tracks as a continuous stream of bits. To make sense of the data, it's necessary to figure out where individual bytes start. This is done with self-sync bytes.

Standard self-sync bytes are FF, followed by two "invisible" zeroes:

 byte 0  **  byte 1  **  byte 2  **
11111111 00 11111111 00 11111111 00

The Apple II will read bits from the bit stream, sliding them in from right to left, until a 1 lands in the high bit of the 8-bit register. If you start reading from a 1, you will read 7 more bits. If you start reading from a 0, you will read 8 or 9 more bits, because the initial zeroes just slide off the left end of the register. With just a few self-sync bytes, we can ensure that we fall into sync with the byte boundaries.

For example, suppose you started reading at an offset of 4 bits into a self-sync pattern:

....11110011111111001111111100

The code would read 11110011 for the first byte, 11111100 for the second, and 11111111 for the third -- synchronization achieved. The extra zeroes are read, but just slide off the left end of the register, because we're waiting for a 1 to appear in the high bit. The only way to tell the difference between a self-sync FF, and a regular FF, is by how long it takes to read. With one bit arriving every 4 CPU cycles, detecting the difference is tricky.

The trick exploited by the bit-slip technique is to follow the self-sync bytes with a pattern that includes additional zeroes between bytes. For example, consider this stream:

11100111011100111001110011111100111

If we latch 8-bit bytes as usual, we'll read it like this:

 byte 0  *  byte 1  **  byte 2   byte 3
11100111 0 11100111 00 11100111 11100111

Because the "extra" 0 bits "between" bytes are ignored, this will be read as E7 E7 E7 E7. But what happens if we deliberately stall for 12 cycles, ignoring the first three bits?

xxx **  byte 0  *  byte 1  **  byte 2  ...
111 00 11101110 0 11100111 00 11111100 111

We get a different pattern: EE E7 FC. By deliberately desynchronizing the stream, the program can detect the shifted pattern. And because the pattern starts with zeroes, the delay doesn't have to be perfectly cycle-accurate.

Copy programs can pretty reliably detect the difference between "normal" and "long" bytes with a carefully timed loop -- either the byte is ready after 32 cycles, or it isn't. The pattern above uses both 9-bit and 10-bit bytes, so to reproduce it correctly you'd need to accurately detect the difference between a 32-cycle read, a 36-cycle read, and a 40-cycle read. Very difficult to do on a 1MHz 6502.

For additional details, see this article and this comp.sys.apple2 posting.

5
  • 1
    There's also this: pferrie.host22.com/papers/apple2_e7.pdf from Peter Ferrie, and Mark Pilgrim's talk here: youtu.be/IGo7wUo64LI?t=6h42m36s
    – zellyn
    May 9, 2016 at 20:46
  • One approach I've been pondering lately would be to have a track which reads almost entirely as a sequence 1010101010... but varying the data rate so that each octet of data on the disk would encode a single 1 or 0 of "hidden" data based upon whether it took more or less time than normal to read. Ever heard of such a thing? I'd think such a thing would be pretty well invisible to any code that wasn't looking for it, and would probably require a custom Woz-machine ROM to create.
    – supercat
    May 9, 2016 at 22:42
  • If memory serves, 101010... would normally involve one flux transition every eight cycles. To encode custom data one could have code that would generate a groups of four flux transitions at 7-cycle or 9-cycle intervals depending upon the bits to be encoded, and I would think looking for whether each octet was more or less than 32 cycles would then be pretty reliable.
    – supercat
    May 9, 2016 at 22:49
  • 1
    This brings back memories.... I wrote and sold a disk copy protection system that used this method. I called it "Finger Print" protection, the finger print being effectively invisible to most bit copiers. Nov 9, 2017 at 12:28
  • @AnthonyLambert: Cool. I've just dug my Apple //c out of the garage and would like to start using it. What's the best way of getting software to it? I was thinking that a little microcontroller hooked to the floppy connector and a PC's USB port could probably fake a read-only floppy drive pretty easily (keep count of head movement pulses and simply send one of 35 sets of bit patterns). Any idea of any cheap and simple interfaces?
    – supercat
    Mar 6, 2018 at 3:52

You must log in to answer this question.

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