I know that the Bochs emulator determines that all sectors have been read/written by checking DMA status. But how does the controller know that it's read/written all sectors requested without DMA (Non-DMA mode)? How does the controller know how much to read/write?
The controller will transfer data until there's an error, TC is raised or it reaches EOT (actually, if EOT is reached before TC is raised in DMA mode, the controller shows an error condition. That's how the PCJR works). Note, if non-dma mode is set in the specify command (the DOR doesn't matter for this) the controller will fire an interrupt for every byte.
So if a read command (x6h) is issued with sector=0 and EOT=8(boot sector by BIOS), it will continue reading sectors until the TC is raised during DMA, or:
- error when EOT is matched during a read/write in DMA mode.
- increase/reset side and after that track (track 0 side 0, track 0 side 1, track 1 side 0, track 1 side 1, track 2 side 0 etc.) and reset sector number when Non-DMA mode is specified, next sector is given during DMA mode while TC isn't raised?
Like this:
1byte floppy_increasesector(byte floppy) //Increase the sector number automatically! 2{ 3 byte result = 1; //Default: read/write more 4 if (FLOPPY.geometries[floppy]) //Do we have a valid geometry? 5 { 6 //cylinder/track=2;head=3;sector=4;max sector number=6 7 if (++FLOPPY.commandbuffer[4] > FLOPPY.commandbuffer[6]) //Overflow next sector by parameter? 8 { 9 result = 0; //SPT finished! 10 FLOPPY.commandbuffer[4] = 0; //Reset sector number! 11 if (++FLOPPY.commandbuffer[3] >= FLOPPY.geometries[floppy]->sides) //Side overflow? 12 { 13 FLOPPY.commandbuffer[3] = 0; //Reset side number! 14 if (++FLOPPY.commandbuffer[2] >= FLOPPY.geometries[floppy]->tracks) //Track overflow? 15 { 16 FLOPPY.commandbuffer[2] = 0; //Reset track number! 17 } 18 } 19 } 20 } 21 22 FLOPPY.currentcylinder = FLOPPY.commandbuffer[2]; //Our idea of the current cylinder! 23 FLOPPY.ST0.CurrentHead = FLOPPY.currenthead[floppy] = (FLOPPY.commandbuffer[3] & 1); //Our idea of the current head! 24 25 if (FLOPPY.DOR.Mode) //DMA mode determines our triggering? 26 { 27 result = !FLOPPY.TC; //No terminal count triggered? Then we read the next sector! 28 } 29 30 return result; //Give the result: we've overflown the max sector number! 31}
Will return 1 when need to read another sector, 0 to start the read/write result phase. This is called after a sector has been transferred to/from CPU or memory(DMA). Is this correct? (TC is cleared when the command byte is received and set when TC has been reached (DMA completed transfer according to it's counters, after the final byte has been read/written to memory.))
Sector advance is the same in dma and non-dma mode. It advances by sector to EOT, side then cylinder. If an error occurs the sector isn't advanced. In multi-track mode the controller will read/write until EOT on side 1.