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:

start address end address function
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. ROM will not use full address decoding, so 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. For protection reasons, peripherals will use full address decoding, which makes it more complicated and larger, but a small adder in the grand scheme of things.

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:

As it turns out, you can buy four-track record/playback heads still relatively cheaply. You can also buy old cassette decks with fully electrically controllable transports. Marry the two and you end up with a tape drive that gives you four bit at a time.

Of course four parallel tracks increases data-rates to quite usable levels. The electric control means that the computer can direct forward/rewind/record/playback operations. Some decks 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 four times) doesn't sound too bad.

The data-rate on each track would still be modest - maybe, with high-speed playback 4800baud - so bit-banging them should be possible.

Other ideas

I'm considering a screen interface (composite video) for the machine. There are a few problems there:

Video support takes up a lot of memory, something I don't have a tremendous amount of.

Second, generating video takes a lot of memory bandwidth away from the CPU. I think I have a way to limit the impact to about 20%, but 20% is not nothing.

Lastly, the screen interface 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.

It would also be nice to have access to something slightly more modern than a tape transport for storage. A floppy disk would be 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: 500kbit/sec. This is certainly not bit-bang territory for a 2MHz machine; one would need an actual controller.

Leave a comment

Comments are reviewed before they are published, so yours will not show up right away.

You can use **strong** and *italic* text, `code`, and lists (lines starting with - or 1.). Everything else, HTML included, is shown as it was typed.