VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

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?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 5, by crazyc

User metadata
Rank Member
Rank
Member

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.

Reply 3 of 5, by crazyc

User metadata
Rank Member
Rank
Member
peterferrie wrote:

IRQ6 is generated after an operation completes (i.e. all sectors read), not on every byte. Imagine the performance hit if it did it for every byte.

That's true for DMA mode, not for non-DMA mode.

Reply 4 of 5, by superfury

User metadata
Rank l33t++
Rank
l33t++

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:

byte floppy_increasesector(byte floppy) //Increase the sector number automatically!
{
byte result = 1; //Default: read/write more
if (FLOPPY.geometries[floppy]) //Do we have a valid geometry?
{
//cylinder/track=2;head=3;sector=4;max sector number=6
if (++FLOPPY.commandbuffer[4] > FLOPPY.commandbuffer[6]) //Overflow next sector by parameter?
{
result = 0; //SPT finished!
FLOPPY.commandbuffer[4] = 0; //Reset sector number!
if (++FLOPPY.commandbuffer[3] >= FLOPPY.geometries[floppy]->sides) //Side overflow?
{
FLOPPY.commandbuffer[3] = 0; //Reset side number!
if (++FLOPPY.commandbuffer[2] >= FLOPPY.geometries[floppy]->tracks) //Track overflow?
{
FLOPPY.commandbuffer[2] = 0; //Reset track number!
}
}
}
}

FLOPPY.currentcylinder = FLOPPY.commandbuffer[2]; //Our idea of the current cylinder!
FLOPPY.ST0.CurrentHead = FLOPPY.currenthead[floppy] = (FLOPPY.commandbuffer[3] & 1); //Our idea of the current head!

if (FLOPPY.DOR.Mode) //DMA mode determines our triggering?
{
result = !FLOPPY.TC; //No terminal count triggered? Then we read the next sector!
}

return result; //Give the result: we've overflown the max sector number!
}

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.))

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 5, by crazyc

User metadata
Rank Member
Rank
Member

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.