VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

What happens if a program tries to switch the selected master/slave to the other device using the drive/head register while the device is busy(bit 7 of the status register set) or a DMA transfer is running(PCI IDE bus mastering)?

Edit: Qemu reveals the answer: the command block registers can't be written when a DMA transfer is running. So the host can't switch to the other connected device while a DMA transfer is running, other than by aborting it through the SRST bit in the control register(which aborts the entire command that's running)?

Last edited by superfury on 2022-02-23, 21:49. Edited 1 time in total.

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

Reply 1 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. What happens if a DMA transfer is busy and a SRST is executed (the only other thing the CPU can do) or a new command is written to the command register?

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

Reply 2 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. So each ATA drive has their own IRQ line connected to the cable, doesn't it? How does stuff like drive select affect said routing to the interrupt controller(both PIC and APIC)?

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

Reply 3 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just modifed the code to not take both master and slave IRQRQ lines and simply binary OR them for the effective line for the controller to use. It will now use the IRQ line from the selected device only.
Also, drive select(changing bit 4 of the drive/head register) causes the then-selected drive to mask it's IRQRQ line off while the drive select is busy(for 400ns). So when changing between two devices that both have IRQRQ raised, it will lower the IRQRQ output for 400ns, then after the select is finished it will go high again (triggering an IRQ on the PIC or APIC that's connected to the IDE controller).
Would that be correct behaviour?

Edit: I've also just changed the nIEN (requiring it to be cleared for the IRQ line to become high, unless ATAPI) to control the IRQ line directly (becomes a set or tristate(cleared) depending on it). The SRST bit also does the same, but always forced the IRQ line to 0. Those two results are basically ANDed with each other to get a mask on the IRQ line(cleared=IRQ cleared, set=IRQ set/cleared depending on the drive select and drive's own IRQ line), which is combined with the drive select(drive select forces it low as well) and the drive's own IRQ line(which is a flag in the controller that can have two inputs. It can be any combination of being raised by the controller(bit 0 set) and being raised by the DMA controller(bit 2 set). Bit 1 is used as a simple IRQ acnowledge from the interrupt controller (used for debugging purposes(set when the 8259A PIC loads the IRQ into it's IRR register) and might be used for IRQ sharing purposes if implemented later).

The lowering of the IRQ line during drive select will cause pending IRQs from the drive to be raised with edge-triggered interrupt handling. PCI should have no problems with it's changed behaviour(since it's level-triggered, going high afterwards makes no difference).

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