Introduction
The good thing about hobby projects is that you can never have enough of them. Living by that mantra, met me introduce to you to my latest fascination: a computer built out of discrete transistors. This is a step back (in time) from my other computer project, the Anachronistic computer, which I still have to finish documenting, but that’s another great thing about hobby projects: no one can tell me what to do and in what order! I’m fascinated by transistors at the moment and damn it, I’m going to chase that!
Of course, I’m not the first or only one building a transistorized computer, modern or old.
I have to admit, I don’t know all that much about transistors, so this is not only a fun project, but a great learning opportunity as well. I also decided to break my usual way of working and start documenting the project as I go as opposed to write up the story later.
So, if you’re so inclined, join me on this journey! I don’t promise a straight shot to success, in fact the opposite: there certainly won’t be any straight shots and success is far from guaranteed.
Being a computer implemented in discrete transistors, it naturally needs to be simple. But not simple to the point of uselessness. Not something with 8 bytes of memory and a 10kHz operating frequency. Something, that is actually – you know – useful.
I decided – maybe somewhat more religiously then others – that I truly use only transistors. Or, to be more precise, to no using integrated circuits.
So let’s start with sticking some goal-posts into the turf!
Goals
The basic project parameters:
- 32 kilobytes of memory
- Target 2 megahertz clock frequency (the higher the better)
- Reasonably useful instruction set
- Interface to keyboard and screen (probably a terminal interface, a.k.a. a serial port)
- Access to storage
There are a few exceptions I will make to my zealous commitment to transistors: the serial terminal could be a laptop or something modern as long as it interfaces using RS-232. I also am not that interested in ancient power supply designs, so something off the self, such as a modern ATX power supply will be acceptable.
Block diagram to the rescue!
Let’s dig a little deeper and look at the block diagram of the machine. Of course it’s going to look very similar to any other block diagram of a machine in this class, so don’t expect revolutionary stuff here:
The CPU is going to be a 16-bit processor, where both the address- and the data-bus is 16-bit wide. This means that the total addressable memory is 128kByte (64kWord). Its instruction set will use fixed length, 16-bit instructions, that is to say that each instruction is exactly one word long. It will (if I succeed in it) have a 2MHz clock, but will take several clock cycles to execute an instruction.
The main memory will be built around a ferrite core mat and will have a capacity of 32kByte. There are a few reasons for this choice, but the most important is simply that this is the one I could get my hands on. The organization of course is 16kWord x 16bits.
There is going to be a small boot ROM, but I will keep its size to the bare minimum. ROM is very expensive, when built from transistors. I haven’t coded up the boot routine yet so I don’t know how much space I’ll need. If it gets large, I might consider core rope memory, but that looks like a major headache to build and especially bug-fix.
Memory map
The 64kWord of memory will be organized in the following manner:
0x0000 … 0x3fff: Core memory
0x4000 … 0x7fff: unused
0x8000 … 0xbfff: ROM
0xc000 … 0xffff: peripherals
Decoding these spaces can be done by looking at the top-most two address bits, which is cheap.
Neither the ROM nor the peripherals will occupy the whole assigned memory space, however they will not use full-address decoding; in other words there will be a lot of aliasing.
Due to the particularities of instruction set (which I will describe next time) the peripherals are actually used in the top-most few address locations, specifically in the region of 0xffe0 … 0xffff.
Another particularity of the processor is that it’s reset vector is stored in location 0x0000. That is in core, so if we want to boot into ROM, we need to do something special. The address decoder will support a mode, where, after reset it maps both the core memory region (0x0000 … 0x3ffff) and the ROM region (0x8000 … 0xbfff) into ROM. This mode allows the reset vector (fetched from address 0x0000 but actually stored in ROM, normally at address 0x8000) to point to the ROM bootcode. Afterwards the ROM code can turn off this remapping functionality and start accessing core memory.
You might ask, why not just fetch the reset vector from address 0x8000 in the processor? The reason for that can be found in the non-volatile nature of core memory: when a stable operating system is loaded and stored in core, one probably want to directly boot into that, bypassing the ROM bootloader altogether. This is different from modern machines, where the boot always starts in some ROM location.
Peripherals
As far as peripherals go, there will be only two of them: a serial port and a tape interface. Both, I hope can be bit-banged, so the actual implementation from the CPUs perspective is just a handful of GPIOs. The serial port will work around 9600 or maybe 19200 baud and will connect to a serial terminal, a.k.a. a laptop. This is going to be the main boot interface as well: the boot ROM will simply slurp some bytes from the serial port, put them in RAM and eventually jump there to execute.
For the tape interface, I’m considering something fancier: before cassette tapes went truly out of fashion, they were used in some pretty nifty home studio equipment. There were 4-channel parallel record or playback devices, such as the Yamaha CMX100:

Later, even some 8-track ones hit the market, such as the Tascam Portastudio 488:

These are expensive kit for sure, but maybe I can snatch one for cheap on eBay. There are a few interesting things about them. One, of course is that they can record and play back four or eight parallel tracks, increasing data-rates to quite usable levels. They also have completely electrically controlled transports. This means that the computer can direct forward/rewind/record/playback operations. Some even have electronic position counters, which could be used to track roughly where in the tape we are. Of course, these machines used all manners of integrated components, which would need to go, but a tape interface out of transistors (even if replicated 8 times) doesn’t sound too bad.
Still, on each track, the data-rate would be – maybe, with high-speed playback – 4800baud, so bit-banging them should be possible.
Other ideas
I briefly considered an actual screen interface (composite video) for the machine, but the truth is that core memory is just simply not fast enough for that. At least not in a system, where all memory is shared with the CPU and the two are contending for bandwidth. Getting a second core memory bank just for video is a really expensive proposition, plus the arbitration logic between the screen interface and the CPU looks nasty. Not to mention: the screen timing controller is essentially a big bag of programmable counters with some shift-registers sprinkled about, both of which are rather expensive to build out of transistors. So, I probably will never do it, certainly not in the first iteration.
It would also be nice to have access to something slightly more modern than a tape transport for storage. A floppy disk would awesome. Here the problem is that the data-rates involved are high enough that bit-banging is out of question: a dedicated controller is called for. Even if I lower my standards and allow the drive itself to contain whatever it wishes (i.e. integrated circuits) and I limit myself to either the Shugart or the IBM PC interface, the logic involved is formidable.
Side-bar: floppy disks rotated at 300rpm, which would mean 200ms per rotation. If I look at a 3.5″ HD drive, it would have 18 512byte sectors on each track. This corresponds to 369kbit/sec data-rate, but the actual peak data-rate is higher due to inter-sector gaps and what not. Say, it’s 500kbit/sec. This is certainly not bit-bang territory for a 2MHz machine; one would need an actual controller.
Where to go from here
As of now, the following chapters are available for your reading pleasure:
- The instruction set
- The micro-architecture
- Gates from transistors
- Registers
- ALU
- Ferrite Core Memory
- Sense Amplifier
- Line Drivers
- Current sources
- Inhibit drivers
- Line Drivers Redux
- Memory Control Logic
- ROM
- Tape interface
- ROM, second pass
- Sense amplifier revisited
- Reality check
- ROM, third pass
- Tape read amplifier
- Power supplies
- More Power!
- Linear regulators
- Reset and Clock
- Modules
- Protected Mode
- Video Display
- Real Time Clock