Well, I haven't implemented the FDS so I can't pretend to be an expert, but I did read BT's doc, studied the BIOS disassembly, and also took a peek at Nestopia's source code (although it didn't sync perfectly with BT's doc). Here are a couple of notes:
$4032.1 is set by default. It remains set until the motor is on ($4025.0 set and $4025.1 clear) and the disk head reaches the beginning of the disk (supposedly takes about 0.15 seconds, though Nestopia didn't put in any delay). The flag is then clear until either $4025.1 is set or the disk head reaches the end of the disk. Basically, the flag is clear while the drive is ready for transfer and set when transfer is over.
I believe the byte transfer flag is only set if $4025.6 is 1. During reads, it will be set for the first time once the first byte of a block has been read from disk (Nestopia assumes a delay of 200 cycles before this happens, although in reality the delay would be quite longer). At this time, $4031 should have the first byte of the block (which is the block ID). Subsequent byte transfers occur about 150 cycles apart.
During writes, the byte transfer flag should be set immediately when $4025.6 is set. The value in $4024 (which the BIOS will have set to zero) is transfered to disk. The BIOS then enables interrupts, which should trip immediately since the transfer flag is raised, and then writes $80 (the block start mark) to $4024. The next time the transfer flag raises (150 cycles later), this value will get written, thereby officially starting the new block of data. Note that .fds files do NOT contain block start marks, so emulators should ignore these writes (Nestopia does this by explicitly ignoring the first 2 writes, although perhaps a better solution would be to wait for $80 to be transfered and then to start accepting data following it).
At the end of a block read, the BIOS will read and discard two bytes before turning off $4025.6 (this is for the CRC analysis). These two bytes, however, do not appear in .fds images, so when $4025.6 is cleared, you will need to subtract two from the file pointer (or else you'll get an error when the BIOS starts reading the next block because the block ID won't match).
At the end of a block write, the BIOS will wait for the last value in $4024 to get written to disk, then it sets $4025.4 to force the CRC to get written. Again, this is not in the .fds image, so you should stop writing as soon as this flag is set (stop raising the transfer flag as well, for an interrupt during this time will screw up the BIOS I believe). The BIOS will wait a certain number of cycles, then turn off $4025.6 (do not subtract 2 from the file pointer - you didn't write anything for CRC, so there's nothing to subtract).
There are no gaps between blocks in .fds images, so do not advance the file pointer unless the transfer flag raises. It should raise only when $4025.6 is set (and also if $4025.4 is clear, if in write mode).
I hope this helps. I can't guarantee I have enerything right, as I never implemented this myself. I'm merely saying what I can given the information I've seen.
|