I've oversimplified somewhat below, but this is the gist of it.
BDD is right in that top execution speed was a goal, but there is another consideration. Because of the way the 5.25" disk hardware works, when writing data (sync bytes are a slightly different beast) you must write to the (memory-mapped) I/O location exactly every 32 cycles, no more, no less; thus loops required precise timing, and addressing mode selection is paramount. And watch out for page boundary crossings! Reading doesn't require exact timing, but it has to be fast; if it takes longer than 32 cycles you'll miss bits.
When you read or write to the I/O location (assuming you read valid data), you get (when reading) or use (when writing) one of 64 possible values, called a disk nibble (in Apple II terminology). So you have 6 bits of information, and you need 4 disk nibbles to get 3 data (8-bit) bytes. (So each 256-byte sector has 342 data nibbles, with 4 bits being unused, i.e. 342 * 6 = 256 * 8 + 4). This (6-bit) disk nibble to (8-bit) data byte mapping is known as (again, in Apple II terminology) 6-and-2 encoding.
The DOS 3.3 disk driver (known as RWTS) was straightforward, and had no self-modified code (at least not that I can remember). To read a sector, read and store the disk nibbles in a (342-byte) RAM buffer in one pass, then make a second pass to convert disk nibbles to data bytes. To write a sector, it's the opposite order: convert data bytes to disk nibbles in one pass, then write the disk nibbles from the RAM buffer in the second pass, and this second pass requires exact timing but none of the other three passes do. (Formatting a disk also requires exact timing, since data is being written then as well.)
The ProDOS disk driver does a read & convert all in one pass (there is still some preparation before writing data, though). Why do this? Well, there are 16 (256-byte) sectors in each (circular) track: 0, 1, 2, 3, and so on. Since there is some processing after reading or writing, say sector 0, the disk will already be past sector 1, so DOS 3.3 and ProDOS use a 2:1 interleave, in other words, it reads and writes in the order: 0, 2, 4, ..., 12, 14, 1, 3, 5, and so on.
In DOS 3.3, RWTS itself is fast enough even with two passes to handle a 2:1 interleave (booting could read an entire track in 2 revolutions), but the File Manager (as its name implies, that's the part of DOS 3.3 that deals with things on a file level), was brutally inefficient, and after reading sector 0, with all of the subsequent processing, it had missed sector 2, and had to make a complete revolution to get back to sector 2. Thus a command like RUN APPLE-VISION took 18 (!) revolutions to read an entire track. (Yes, 18; remember, one revolution gets you from track 0 to track 0, it takes another 1/8 revolution to get to sector 2.)
DOS 3.3 could be (and was) patched to be somewhat smarter about things, and not miss sector 2, which sped things up considerably, but no doubt one of the intentions in ProDOS was to leave as much time as possible for file-level processing.
|