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 Answers
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.
- 9,040
- 1
- 30
- 84
-
1There's also this: http://pferrie.host22.com/papers/apple2_e7.pdf from Peter Ferrie, and Mark Pilgrim's talk here: https://youtu.be/IGo7wUo64LI?t=6h42m36s – zellyn May 09 '16 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 09 '16 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 09 '16 at 22:49
-
1This 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. – AnthonyLambert Nov 09 '17 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 06 '18 at 03:52