System/1 Build Log
An ongoing chronology of System/1's construction, and any other related musings.
23rd November, 2017 - Thinking about peripheral device connections
Before I can finalise the schematics for the serial board — although, in truth, I have been putting off even starting them because I lack the enthusiasm to double-check my notes correspond accurately to the mess on my breadboards — I need to decide upon a final form for its connection to the memory bus.
Since a full memory bus connection is fairly bulky (consisting of a 50-way ribbon cable carrying the address and control lines, and another 34-way cable carrying the data lines) and a fair number of things I might want to hook up to the system end up having 8-bit interfaces, I've been planning to define a smaller connection for such peripherals. This would carry an 8-bit data bus, power, as few control signals as I think I can get away with, and some addressing pins allowing devices to easily present several registers to the host system. Juggling some ideas around, I think it absolutely must carry READ, WRITE and IRQ signals; RESET would be nice too, to avoid every device needing to generate its own power-on reset. The memory bus also includes a WAIT signal to introduce wait states when accessing slow devices, which is unlikely to be a problem in practice but I should probably expose it here too just in case. With 20-pin connectors looking like a convenient size, that would leave five pins free for addressing — a bit of a peculiar number, but not unreasonable. In fact, I have a vague recollection that some of the HP dot-matrix displays I have floating around the place use a five-bit-wide register address, so perhaps that'll work out neatly.
(Spoiler alert: when I later checked the datasheet for those displays, it turns out it's more like a six-bit address in a weird disguise, with some of the high-order address bits given signal names instead. Oh well.)
The plan is to provide a number of these connections on a peripheral interface board which will handle the bulk of the address decoding for each connection; I spent a little time debating whether to implement that as a device-selection line for each device, so they only respond to READ/WRITE when selected, or whether it would make more sense to generate individual READ/WRITE strobes for each device. The 74HC138 1-of-8 address decoder has enough enable inputs to make it trivial to decode register addresses only when a device is selected, although would require two chips to implement both read and write decoding; the 74HC139 dual 1-of-4 decoder I was thinking of using for the serial board could decoder both read and write in one chip, but only has a single enable input. On balance I think I prefer the flexibility of being able to use the '139 for smaller register sets, so in the end I went for individual READ/WRITE strobes and no device selection line. Hopefully this won't come back to bite me!
After digging out some of those HP displays I was thinking about using and realising that the five-bit addressing won't make them easier to interface to, and that in practical terms most devices are going to have few enough registers that four bits should be plenty, I've decided to repurpose one of the address lines as an ID pin. This will allow the system to query the peripheral interface board and discover which devices are connected to which ports; making it active-high allows the device-side implementation to be as simple as a diode or two connected between it and the data bus, so even if I end up hooking up something implemented as a single ASIC from a commercial computer it wouldn't be a huge overhead to identify it to the system on request.
Having sketched out the circuitry required to implement this much on the interface board — higher-order address decoding, device READ/WRITE/ID strobe generation, and some buffers for the data and address lines (since I'm not entirely certain whether hanging a handful of foot-long ribbon cables off the bus directly would be particularly sensible!) — it looks like there isn't much left to do on the board design and so I might as well just finish it. The largest part left to think about is an IDE interface, which I'd already planned to include on the same board as there's very little circuitry required apart from address decoding. Although IDE supports an 8-bit transfer mode I've seen suggestions from people designing machines around 8-bit CPUs that not all later IDE devices support this properly, so it's definitely wiser to put the IDE port on this interface board where the full data bus is available rather than try to hang it off one of the 8-bit ports later.
Unfortunately for the address decoding logic I've drawn up to this point, IDE does actually specify a device-select line — in fact, it requires two: one for the Command Block registers, and one for the Control Block registers. Historically these correspond to the 1F8h-1FFh and 3F8h-3FFh I/O port ranges on the IBM PC, hence their historic names CS1FX and CS3FX in earlier versions of the IDE specification, but they were later renamed to the slightly-less-weird CS0 and CS1 (CS standing for chip-select throughout). Alongside these device-select lines are a three-bit address bus, used to select registers within the respective blocks — not all eight registers are defined in each block, though, and in fact most of the control block is defined in the specification as leaving the bus in a high-impedance state so as not to conflict with other devices (which turns out to mean 'this is where the floppy drive controller lived in the original PC'). Taken as a whole, these various specifications mean I can use one of the device 'slots' on my board, plus the highest-order address bit within that device space, to decode the two IDE device selection lines; that then presents the IDE register blocks as a single 16-register device, with some of the registers unused. A little extra decoding to recognise the section of that space that's reserved for the floppy controller of an IBM PC will also allow me to add a latch to read back the IDE status signals, just in case they're more important than my initial reading of the specification suggests, and that should just about wrap it up.
After the last-minute addition of a bank of DIP switches (possibly for configuration purposes, or maybe just because I had a bank of rainbow DIP switches I wanted to use somewhere) that can be queried similarly to the connected device ID values, and replacing a couple of gates with wired diode-OR equivalents to make the design fit a bit more neatly onto a Eurocard board, the interface board design is complete; now I just need to decide whether to build it before or after the serial board.