I'm stuck with memory-mapped writes for my XTIDE derived board so I'd really appreciate some help checking the transfer code.
Linked to below is code I've added to the (otherwise unmodified) XTIDEv2 Beta BIOS. I've linked to it as it's quite readable in the mediawiki format, and of course it can be kept current.
If there is an error it presumably is near .WriteTransferLoop, since the routine works with port-based IO. Reads are working OK already.
Working Reads Code - This routine works with both port-based and memory-mapped transfers.
Possibly Bad Write Code - This routine works with port-based transfers, but when memory-mapped is attempted there is a brief blink of the drive LED, then a long pause, then the OS returns device not ready. After that reads can be undertaken OK.
Notes:
Many thanks!!
------------------------------------------------------------------------------------------------
Board Logic - Port Based IO
Assume port base 300h for the sake of clarity.
Board Logic - Memory Mapped IO
A loadable register at port 30Fh is used by a second address decoder to match the high 8-bits of the ISA address bus. To prevent a clash with port-based IO address decoder, the loaded value's MSB must be set (and similarly the port-based address decoder needs ISA A19 to be low).
Say D8h is loaded (via port 30Fh), the memory-mapped decoder will watch for addresses D800:0000h to D800:03FFh, as with port-based IO in two ranges:
ISA A0 is again used to control IDE /CS0 and /CS1, its function being reversed here by A9 to get the required IDE no-op ordering.
When the memory-mapped decoder matches, IDE DA0..2 are held low. Hence, the CPU should be able to transfer by "rep movsw" starting with D800:0000h for reads, and D800:0200h for writes.
Linked to below is code I've added to the (otherwise unmodified) XTIDEv2 Beta BIOS. I've linked to it as it's quite readable in the mediawiki format, and of course it can be kept current.
If there is an error it presumably is near .WriteTransferLoop, since the routine works with port-based IO. Reads are working OK already.
Working Reads Code - This routine works with both port-based and memory-mapped transfers.
Possibly Bad Write Code - This routine works with port-based transfers, but when memory-mapped is attempted there is a brief blink of the drive LED, then a long pause, then the OS returns device not ready. After that reads can be undertaken OK.
Notes:
- The board has a 'device ID' byte at port 30Fh, which returns '4'.
- My 'technical reference' for the board has lots more details on how it is supposed to work, which I've summarised a bit below for the sake of brevity.
Many thanks!!
------------------------------------------------------------------------------------------------
Board Logic - Port Based IO
Assume port base 300h for the sake of clarity.
- Reads via 300h/301h
- Writes via 310h/311h (ISA A4 is used to distinguish reads & writes)
- For reads, IDE /CS0 and /CS1 are set so that the drive sees a data transfer for port 300h and a no-op for port 301h. Hence the first read to 300h triggers a 16-bit transfer, the high byte being stored in a latch, and the second read (from 301h) transfers that byte from the latch. Programmatically, this is exactly per original XT/IDE 'chuck-mod' design.
- Writes work in the same way, except that /CS0 and /CS1 function is reversed (by A4 being high), so the drive sees the no-op on port 310h (allowing the low byte to be stored in the latch) and the data transferred (to the drive) on port 311h. Hence, words can be written to port 300h.
- IDE address lines follow the 'chuck-mod' address line mapping:
- IDE Control ports are via base 308h
Board Logic - Memory Mapped IO
A loadable register at port 30Fh is used by a second address decoder to match the high 8-bits of the ISA address bus. To prevent a clash with port-based IO address decoder, the loaded value's MSB must be set (and similarly the port-based address decoder needs ISA A19 to be low).
Say D8h is loaded (via port 30Fh), the memory-mapped decoder will watch for addresses D800:0000h to D800:03FFh, as with port-based IO in two ranges:
- 0000h to 01FFh for reads
- 0200h to 03FFh for writes (ISA A9 is used to distinguish reads & writes)
ISA A0 is again used to control IDE /CS0 and /CS1, its function being reversed here by A9 to get the required IDE no-op ordering.
When the memory-mapped decoder matches, IDE DA0..2 are held low. Hence, the CPU should be able to transfer by "rep movsw" starting with D800:0000h for reads, and D800:0200h for writes.