• Please review our updated Terms and Rules here

8 bit IDE (XTA) Replacement Project

I'm not sure how interested folks are in the implementation details but figure I might as well post them in case someone is.

While I wait for boards to come in I have been experimenting with the Raspberry Pi Pico programmable IO. I wrote a couple of logic analyzer type programs to capture what is happening on the bus when the PC is communicating with a real drive. This will run on a slightly modified version of the drive hardware which already has needed signals on the cable connector. One program samples all signals on the bus at high speed and keeps a timestamp. It also filters out any duplicate frames so the Pico memory is not exhausted too quickly. This is for gathering things like precise timing of DMA and IRQ signals. The Pico easily overclocks 2x to 250MHz which gives a 35MHz sampling rate. The other program just makes one capture per read/write so I can capture all of the communications between the PC and drives. This should let me see the communication sequences on my one working drive and I am also interested to see what my two non-working drives do as well.

I have also been doodling with the PIO programs for the actual drive firmware. Mostly just to feel out how they will be implemented and what the final pin connections to the Pico will be. I am pretty sure at this point that I was quite wrong with my earlier statement that a Sound Blaster Pro might be possible with no glue logic. I think an original Sound Blaster would probably be possible with some glue logic. While the PIO is quite flexible and probably Turing complete, the limited instruction set does mean programs tend to be long. I am confident about implementing the 8 bit drives without any additional glue logic however it did take a while to find an approach that will work. Large programs that implement multiple things at the same time use less total instructions however run too slow. Programs that implement single pieces of functionality (like writing to one register) run faster but use more instructions in total. The entire budget on the Pico for PIO is only 64 instructions which is fairly tight. I got kind of lucky that the data register can not be written and read to at the same time, nor even accessed unless the drive indicates it is not busy. This will let me swap between IO read, IO write, IO read DMA and IO write DMA programs for that register. If all of those had to work at the same time I would be in a tough spot.

Here is a particularly tricky (untested) example which handles reads from the drive's status register. It is a bit special in that it merges in current IRQ and DRQ pin state with other state bits. The only other palatable way I can think of to implement this would be to use programmable logic.

Code:
;-----------------------------------------------------------------------------------------
; Register 1 is the flags register.
;
; Note: We must constantly pull from the FIFO to keep the
; register value up to date.
;
; 13 instructions.
; Up to 13 cycle delay to set up data (+ ~4 cycles in external delays)
; Allowed total delay ~27 cycles with 125MHz Pico & 10MHz ISA bus
;-----------------------------------------------------------------------------------------
.program read_register_1
.side_set 1 opt                     ; Side set maps to data_dir
wait_for_read_start:
    pull noblock                    ; Keep read values up to date. If FIFO is empty,
    mov x, osr                      ; X is moved to OSR. So save read values in X.
    ; For 1 cycle lower worst case latency we can do a "jmp pin wait_for_read_start" here on ~IOR.
    mov osr, pins                   ; in pins are configured to start at ~IOR
    out y, 4                        ; Shift ~IOR, ~CS, AEN and A1 into Y (want all 0)
    jmp y-- wait_for_read_start
    out y, 1                        ; Shift A0 into Y (want 1)
    jmp !y wait_for_read_start      ; Jump if A0 not 1
   
do_read:
    in osr, 2                       ; Shift in DRQ and IRQ still sitting in OSR
    in x, 4 side 1                  ; Shift in the 4 status bits from X and side set tranceiver direction
    mov osr, isr                    ; (Setting tranceiver direction will result in set_pindirs setting pindirs)
    out pins, 8                     ; Set data.
    wait 1 pin 9                    ; Wait for ~IOR high
    irq 3 nowait                    ; Signal to restore pindirs and tranceiver direction.

;-----------------------------------------------------------------------------------------
; Waits for data_dir to go high and then sets pindirs accordingly.
; Waits for interrupt signal before restoring.
;
; in and out pin mappings should be 1 bit starting at data_dir
; set pindir mapping should be 5 bits starting at D0
; side set mapping should be 3 bits starting at D5
;-----------------------------------------------------------------------------------------
.program set_pindirs
.side_set 3 opt pindirs             ; The 3 bits are pindirs for D6-D8
    wait 1 pin 0                    ; Wait on data_dir to go high (pin 22)
    set pindirs, 31 side 7          ; Pindirs set to out for all 8 data bits. 74LVC245 transceiver should have reversed by now.
    wait 1 irq 3                    ; Wait for signal to reverse pindirs / tranceiver direction
    set pindirs, 0 side 0           ; Restore all pindirs.
    mov pins, null                  ; Restore data_dir (tranceiver direction). Must not be before pindirs.
                                    ; Could be at same time however but would require using pindir / pull down to effect this.
                                    ; An option if we end up being an instruction over budget.

Optimization of these is challenging and I am always seeing improvements. I have juggled pin assignments numerous times to combine or remove operations. When I pasted this code in initially, read_register_1 was 18 instructions with 18 cycles of read setup time. This was getting close to my calculated maximum of 23 cycles of setup time. Before hitting send I saw improvements and some time later I had it down to 14 instructions and 14 cycles of latency. Then I decided to do this goofy thing to have another program change the Pico pin directions when it sees the bus tranceiver direction change. It increases the overall size of PIO programs by two instructions but reduces latency on all reads by 1 cycle. So now it is down to 13 cycles of read setup time which leaves a large margin of error.

I was not able to implement the functionality where writing to the select register immediately sets busy flags in the status register. Implementing register reads and writes in one program was leading to high instruction counts and high latencies. I also did not have a spare register to efficiently hold the latched busy state. So instead I will dedicate the second CPU core to run a tight polling loop to manage the status flags. I have at least 50 CPU cycles from when the PIO signals the select register to when the status register value needs to be set (time between x86 OUT and following IN instruction). This should be plenty. I would be sweating things a bit on a single CPU micro. The main CPU will have a bunch of other interrupts firing. While none of these interrupts will be particularly time sensitive they could make it tricky to implement a tight polling loop or very fast interrupt handler.
 
So this is fun! My first prototype boards for the XTA replacement came in. Because the RPi Pico IO is so programmable, I was able write something that captures reads and writes going through the IDE cable. I did some capture of the boot sequence communications that happen with different drives against different BIOSes.

Click image for larger version  Name:	IMG_20211112_092510578.jpg Views:	0 Size:	148.6 KB ID:	1232089 Click image for larger version  Name:	IMG_20211112_092510578.jpg Views:	0 Size:	148.6 KB ID:	1232089

I've learnt a lot already. The reset register does a very light reset - just cancels any previous command I think. The BIOSes expect the hardware to respond immediately after resetting this way. The Seagate BIOS resets between every command. The WD BIOS constantly spams the select register - I had assumed this register was a write-once-and-wait setup, but WD does not expect it to work this way. The Seagate BIOS use DMA for transferring sector data but not IRQ. An interesting data point is that the drive only DMA's the 512 bytes of sector data, then returns the final operation status byte via a normal IO read from the data register. The WD BIOS enables IRQ for all operations, even commands that retrieve only 1 byte. It is almost like implementing two different interfaces.

My one working drive, a ST351A/X, has very tight bearings after running for a couple of hours. It stopped spinning so fast on power off that I am worried it may not spin up again. Definitely needs to be used sparingly going forward.

My non-working ST325X does actually read the first sector during boot without error. However the low level format fails after a valiant effort and fdisk claims there is no fixed disk at all. One working sector will be good enough to measure DMA timing if the 351 doesn't make the distance. [EDIT]: Seems that the low level format I did a while back did help the drive some. fdisk does detect the drive now and will partition it after a large number of reseeks. Unfortunately format gives up fairly quickly. The poor thing has been treated badly - all banged up - even one of the rubber shock mounts has been torn off. Actually quite good enough for my needs though.

My WD drive never reports ready for a command, so definitely no good I think. I can't help but wonder if it is repairable. The last time it did work, it happened on a ctrl-alt-delete after many previously failed boot attempts. Nothing much happens on a warm boot other than the register reset command and waiting for the drive to be ready to take a command.
 
Last edited:
Some more baby steps forward. I was hoping to be a bit further forward at this point but progress is progress. I have implemented the handling of control register writes via the Pico's programmable IO.

This hardware connected to an XTA interface card:

IMG_20211119_130313735.jpg

plus these commands on the DOS PC:

IMG_20211119_130352020.jpg

gives this debug output over the Pico's USB cable:

IMG_20211119_130450474.jpg

Optimizing Pico programmable IO programs is very dependent on pin ordering, hence the big old mess of wires.
 
The programmable IO program for control register reads is now implemented. Port 321 and 322 are returning expected values. 320 and 324 are not responding as expected. This is with my 486 ISA bus overclocked to 16MHz and the timings seem to be (just) good enough.

IMG_20211121_200609909.jpg

I have to say, while using the programmable IO on the Pico is super interesting, I am not sure I would recommend others follow. Hard, low-level programming is my day job and I am finding this slow going and quite challenging. I think it would have been much easier for me to use programmable logic, and say, a STM32. And I am just a tinkerer with programmable logic. With PIO, you just need 10 or 20 crazy tricks and after that it is smooth sailing.

The control register read program has all sorts of tricks going on. Complicated branching and fall-throughs. Pins in just the right order so I can use decrements for decoding, or so bits are in just the right spot when needed to shift into another register. Look at this program flow I annotated for it:

Annotated Program.png

And there is a second program that watches for when this one flips the transceiver direction.
 
Nice work! Here is one for your XTA collection; a PrairieTek XTA ROM, dumped from an old 'AGC' (Taiwanese branded) laptop I own.
 

Attachments

  • PrairieTek_XT_ROM_BIOS_1.05.zip
    4.7 KB · Views: 6
This project looks interesting. Got a Commodore Colt PC that has an XTA interface with a 10MB or so HDD that needs work to get it to boot up.

Good thing that you provided info about the XTA being 8-bit only.

I'll backup the BIOS contents and either DM you the deets or post it on here.
 
Fascinating work! I'll be watching this closely as I have several of those IBMs mentioned needing replacement drives (pair of PS/1's and a pair of PS/2's of differing flavors). This might even be worth having in my emergency repair kit for troubleshooting.
 
The early PS/2s (model 25/30) with an 8 bit interface are not true XTA from everything I have read. This may or may not work. I'm eager to see myself.

Fascinating work! I'll be watching this closely as I have several of those IBMs mentioned needing replacement drives (pair of PS/1's and a pair of PS/2's of differing flavors). This might even be worth having in my emergency repair kit for troubleshooting.
 
Does anyone have a Tandy 1100 HD they could dump the BIOS from? I would like to learn a bit about the little Connor 2.5" XTA drives. I tried the Tandy 1100 FD and Panasonic BP150 BIOSes but no luck. I did fund some hard drive parameter tables but they are quite small. I think they must be for ROM drives.
Hey, just stumbled on this. I have a Tandy 1100HD (with working drive even!). Did you get your ROM image? I've been looking for an excuse to get a Mini Pro.
 
Does anyone have a Tandy 1100 HD they could dump the BIOS from? I would like to learn a bit about the little Connor 2.5" XTA drives. I tried the Tandy 1100 FD and Panasonic BP150 BIOSes but no luck. I did fund some hard drive parameter tables but they are quite small. I think they must be for ROM drives.
Got my MiniPro today. I've dumped in Intel hex and bin for my Tandy 1110HD. It looks like there is quite a bit of free space in this image. I'm looking forward to what you come up with.
 

Attachments

  • Tandy1110HD-BIOS-27C256.zip
    41 KB · Views: 5
I've been super busy for a few months and haven't had any spare time for this project. I hope to get back to it soon because it is a fun one.

Sorry for not replying to the messages from folks. I did not get any notifications, I assume due to the forum change. I should be getting them now.

Nice work! Here is one for your XTA collection; a PrairieTek XTA ROM, dumped from an old 'AGC' (Taiwanese branded) laptop I own.

Thank you. I have saved it off and will look at it when I get a chance. Does the laptop have one of the Connor 2.5" drives in it?

This project looks interesting. Got a Commodore Colt PC that has an XTA interface with a 10MB or so HDD that needs work to get it to boot up.

I'll backup the BIOS contents and either DM you the deets or post it on here.

It would be great to have this BIOS. I could not locate it when looking.

Got my MiniPro today. I've dumped in Intel hex and bin for my Tandy 1110HD. It looks like there is quite a bit of free space in this image. I'm looking forward to what you come up with.

Thank you. I was very keen to get this one.

- Jayeson
 
The early PS/2s (model 25/30) with an 8 bit interface are not true XTA from everything I have read. This may or may not work. I'm eager to see myself.

It is lost in the long thread somewhere, but the IBM 8 bit IDE drives you mention are definitely not XTA drives. The needed electronics are almost identical but the communication protocols and registers are significantly different. Other than mechanical, the same hardware should work for XTA and IBM 8 bit, and the firmware should be around 60% the same.
 
So this is fun! My first prototype boards for the XTA replacement came in. Because the RPi Pico IO is so programmable, I was able write something that captures reads and writes going through the IDE cable. I did some capture of the boot sequence communications that happen with different drives against different BIOSes.
I did nearly the same with the ide AT bus. To find a failure I capture all bus signals with a 32 bit logic analyzer based on a teensy 4.1.
Enclosed is an example of an ide capture with the int13 function 02 ( Does read the MBR from an AT system plus xtideuniversalbios ).

1646849072914.png
 
Another capture of a HDD Seagate 351A/X drive with WDXT-150 controller card on an XT system.

The same int13 function 2 capture as above, but on the xta bus . DMA transfer is used, signals for this are not triggered in this capture.


1647028201998.png
 
Got my MiniPro today. I've dumped in Intel hex and bin for my Tandy 1110HD. It looks like there is quite a bit of free space in this image. I'm looking forward to what you come up with.
Woot!

I dumped the BP150 ROMs here: https://forum.vcfed.org/index.php?t...ss-partner-150-tandy-1100-fd-rom-image.72011/
and the 1100FD ROMS here: https://forum.vcfed.org/index.php?threads/tandy-1100fd-bios.72104/

So now we have all three systems of the same chassis.

@CallinElvis - Do you need me to dump the 1000RLX/B BIOS for you? It only supports the 20MB/40MB XTA drives. I think the 1000TL/3 was the same, but I don't have one of those.
 
@acadiel

imho xta does only support up to 40 MB.

After spending some time on the interface I only see one solution for connecting cf-cards on xta bus:

- interface has to handle xta bus commands and datas
- interface has to handle ide bus commands and datas
- interface has to interpret commands and datas from xta bus to ide bus and vice versa
- and all very time critical

Might be the reason that up to now no solution exist.
 
@acadiel

imho xta does only support up to 40 MB.

After spending some time on the interface I only see one solution for connecting cf-cards on xta bus:

- interface has to handle xta bus commands and datas
- interface has to handle ide bus commands and datas
- interface has to interpret commands and datas from xta bus to ide bus and vice versa
- and all very time critical

Might be the reason that up to now no solution exist.

Yep... thank you for investigating it. There are a lot of systems that could use a 64MB card (and 40MB of it) and have a "built in" drive without having to attach an XTIDE card. So, I'm thankful for your work. Let me know if you need any of the BIOS'es I mentioned and I will try and dump them for you or find the dumps and give them to you.
 
You have to wonder why a custom ddo couldn’t loop a big drive into xta so it supports beyond 40mb
 
Last edited:
Back
Top