This is something I’ve been meaning to do for ages. Back in the olden days, when computers still had parallel printer ports, connecting your PC to some arbitrary device in the outside world was easy. You just made a cable connecting up some pins of the printer port to whatever device you wanted, and you could read and write data at a good data rate with very low latency. Making a remote development system was possible using the PC printer port and the printer port of the ST, or the enhanced joypad ports of the STE — everyone was happy! Until the advent of USB, that is.
The Price of Progress
USB is great and all, but for doing this sort of thing just with a bunch of wires, it’s crap. USB printer ports don’t work either. Thanks to the packet based nature of USB, if you’re doing bit-banging, the latency is really poor (typically 16ms intervals for a packet of 64 bytes using interrupt mode), so this kind of old fashioned interfacing just isn’t possible.
So, these days we need to do it “properly”. Looking at the ST, the most obvious way to do this is via the cartridge port. This underused port on the ST has the very useful ability to boot directly from ROM early in the system boot-up (within a handful of cycles), and is able to directly interface to other external hardware. So this would seem to be a perfect match! Not quite.
So, I Read to Write?
The only issue with the cartridge port is that it was only ever intended as a read only device. There is no write strobe output to the cartridge port, and if you do try and write to the cartridge memory, you get a bus error. Bugger. Thankfully there is a simple workaround if you just want to write a stream of data, albeit a bit slower than directly writing, but it will work for this purpose.
To write a byte, instead of writing via the data lines, you write via the address lines. This is how the sound output devices like the MV16 worked on the STFM, and where I first came across this idea. So you set aside a small portion of your cartridge memory map (256 bytes at least for 8 bit output) and when you read from this address range, 8 bits of the address become the byte to write. The 68000 has a handy indexed addressing mode which helps here, so a simple streamed data write might look like this:
lea YourData,a0 lea $fa0000,a1 moveq #0,d0 move.w #SizeOfData-1,d1 WriteLoop: move.b (a0)+,d0 tst.b (a1,d0.w) dbra d1,WriteLoop
So that’s all good, we have a way to read and a way to write to some arbitrary data stream through the cartridge port. Now… if only there was a simple way to access a USB connection as a simple data stream.
FTDI to the Rescue!
Thanks to FTDI, there is. FTDI have numerous chips which are designed to make interfacing things via USB much easier for the hardware designer. The FT240X is the specific chip which caught my attention. This chip turns your USB connection into an easy to interface FIFO with just the one chip! Perfect.
We now need to bring it all together. There needs to be a way to boot the ST with our remote development software (this will be stored on two 8-bit flash ROMS as the 68000 has a 16-bit bus) and some glue logic to handle selecting the correct bit of hardware and correct data or address lines depending on what address we are accessing.
This is where a bit of programmable logic comes in handy. The Altera MAX 3000A range of programmable logic devices are ideal for a bit of glue logic in older systems thanks to having 5V tolerant inputs, thus removing the requirement for any kind of voltage level translation. There are other equivalent chips from Xilinx and Lattice, but I just happen to be familiar with the MAX chips already, so I chose to use them again.
So now we know its possible, and what components are required, its time to figure out how its all going to physically fit together (we’ll need a case!) and create a prototype PCB. Oh, and write the software of course!