User Tools

Site Tools



I've wanted to build my own educational computer since the late 1980's when the old departmental Strowger relay based telephone system was thrown out. I asked my PhD professor if I could take it out of the skip, he very sensibly said “no” quite firmly.

Since then I've thought about many designs: some have been relay based, some transistor; some have included memory and other have been CPU only. Notably:

2012 Minimal Computer - a 4th year project proposal

The aim of this project is to build a minimal computer with as much as possible of the processing visible so that people can see how computers work. It will be constructed either out of relays or transistors and use LEDs to show the state. The switch count is to be minimised so that it can be easily understood by school children and so that it is affordable to reproduce. The clock rate should be low enough so that it can be seen how the next state arises from the current state and so it can be seen how operations such as addition and memory access work, as well as constructs such as registers and program counters. Efficiency is not a major issue although the aim is that it will run small programs in a few minutes which may involve an adjustable clock rate.

The provisional design is to have a four bit instruction set and a twelve bit address space accessing four bit words. Perhaps one quarter will be RAM or 4096 bits and so the memory design will be critical. Current thoughts are to use a square grid of capacitors indexed by two address decoders or core memory. Core memory would be preferable as the memory contents are visible. The lower bank of memory may be defined by DIP switches to store boot code and commonly used subroutines.

The project requires a wide range of skills:

  • the hardware must be designed and built so that the operation is reliable
  • the instruction set must be designed so that the operation of programs is clear
  • good experimental skills will be needed to design the capacitor or core memory
  • good logic skills will be needed for the circuit design
  • there will be considerable experimentation so project planning skills will have to be strong to achieve a working system at the end
  • the resulting system must look good, not spaghetti wiring, to maximise the educational impact

Ideally the project would not use silicon for the switches but use relays which would demonstrate that it would have been possible to build a computer in the late 19th century. This limits the memory capacity and design, electrolytic capacitors and micro-relays.

If time permits then some I/O will be added. Ideally the machine could be loaded remotely and the operation tracked with a webcam.

Interested students should look at:

The plan is that the final machine would be demonstrated in local schools before being donated to The National Museum of Computing at Bletchley Park.

The budget for this project is £400 donated by Cantab Research.

2017 16bit with stack instructions and a Raspberry Pi

In 2017 I started the parent of this design on I planned on a 16 bit processor: instructions, memory, busses, everything was 16 bits wide. There was five conventional registers, a program counter and two constants addressing 64k words of RAM. I expected to build it in discrete components using less than 1,000 transistors running at maybe 50kHz, so everything was very tight. Instructions were one of only three forms:

Form Example
ALU A = B + C
READ A = *B, B +-= C
WRITE *A = B, A +-= C

A Forth like language was implemented and about four thousand lines of code was written, including floating point operations and random numbers. The code, compiler and emulator is on github. The idea was to use a Raspberry Pi for external memory and to sanity check the computations. In the end this ran out of steam because:

  • The complexity of sequencing the stack based READ and WRITE operations. They were wonderful for writing FORTH like languages, but just too complex for me to build in hardware
  • The cost of the Raspberry Pi. This was supposed to be something that every school could make easily.

2019 Dippy

Even with only five registers the design of each memory cell is critical because the majority of the transistors (and other components) are taken by the memory cells. This led me down a long random search of weird memory cells and dippy which used DIP switches for ROM/program memory. In the end this ran out of steam because DIP switches didn't make cost efficient storage.

2021 Very long instruction word

If the program memory was a tape loop, like printed A4 pages taped up into a loop, then there's enough width in A4 paper to have a very long instruction word (and labels) so that it doesn't require much decoding. Given 32 words of RAM it may look a bit like Colossus.

  • It's an 8 bit processor with only 32 bytes RAM but loads of program memory
  • There are no registers, only a single bank of data memory (the program memory is completely separate)
  • All instructions are of the form: cnd Mi = Mj OP Mk
    • i, j, k are 6 bit integers
    • cnd indicates that all instructions are conditionally executed
  • Most of the bottom 5 bits of the address space (M0 to M29) are DRAM
    • Probably this will based on Homebrew Dynamic RAM but with a single bipolar transistor as the gate. The LEDs are optional, the reference design has them to show the state of everything.
    • It may be based on Yann Guidon's single capacitor, two diode DRAM especially if the read diode could be a LED
    • There will be a DRAM refresh circuit, every read will force a write.
  • M0 and M1 may be used as stack pointers. M30 contains the contents of the address in M0 (and M31 pairs with M1)
    • Reading/writing M0 or M1 works as any other memory location
    • Reading/writing M30 or M31 results in the contents of M0/M1 being placed on the address bus, so the memory accessed is in the DRAM range of M0 to M31
  • The top five bits of the address space are constants if read and control if written.
    • M32 to M47 are the constants 0 to 15 and M49 to M63 multiples of 16, both implemented by wiring the address to the data lines
    • M48 is toggle switch input
    • When written the address line is used to control:
      • Bit0 JUMPs to the value written
      • Bit1 outputs the value written
      • Bit2 sets the clock rate (potentially including HCF)
  • Whilst the RAM/ROM/CTRL space is addressed by 6 bits, the top half never needs to be decoded. If it used to read from ROM then the (shifted) address lines are used. If it is used to write control signals then only one address line is high at once so the address line can be used directly.
  • There is no program counter!
    • Ordinarily the next instruction is read from the tape and executed
    • If a JUMP occurs the tape spins until the desired label is read.
      • Not all instructions have a label so there can be more instructions than the data width
      • Duplicate labels are valid, this may be useful…
  • The instruction rate is intentionally slow. 1Hz is maybe typical, everything should be visible. There will be a single step button that is active after HALT so that everything can be as slow as needed.
  • There will be a twelve phase clock:
    • Phase 0: read the instruction from the tape and decode
    • Phase 1: read Mj to latch/register IN0
    • Phase 2: read Mk to latch/register IN1
    • Phase 3 to 10: run the ALU storing the result in latch/register OUT
    • Phase 11: write Mi
    • Phase 12: wait for tape to spin and do DRAM refresh. This is the rate limiting step and it is where the state can be seen.
  • There exists several status flags:
    • the carry bit
    • whether the last ALU result was zero
    • whether the last ALU result had the top bit set (negative)
    • ASL is hardwired in parallel, the rest are via a 1-bit serial ALU
    • There is a carry flag, ADD/SUB ignore it, ADDC/SUBC use it
  • Conditional execution is one of: never, always, ==0, !=0, <0, ⇐0, >=0, >0
  • The construction cost and time are very important. Ideally the bill of materials should come in at under £100 so that schools can buy and build it.
    • It's not quite a minimal processor, it is more important that it's understandable with school level electronics and be able to run complex programs (slowly!)
    • I expect that laminated A4 will work (print A4, laminate, punch holes, spaghetti wire through holes)
  • Input is likely to be from a simple scanner. A4 pages are taped into a loop, a motor runs until the label is reached, photodiodes/photoresistors read the instruction.
  • Output is likely to be thermal print paper and nicrome wire (alt: DIY pen plotter, eight marker pens on solonoids/springs)
  • Breadboard to begin with, but ideally A4 laminated paper or acrylic so that the circuit can be seen
  • Framed, ideally running on batteries
  • Some permissive FOSS licence will be adopted (e.g. Apache2/MIT) and experimentation and evolution are encouraged

There is an emulation with some example code in Google sheets

All instructions really are if(cond) Mi = Mj OP Mk, however the assembly language can be more more flexible and compile in constants, writing to high bit addresses and the like. We can split the generic instruction into the left hand side, Mi = and the right hand side, Mj OP Mk

human readable machine readable comment
Ri = Ri = the general case for 0 <= i < 32
JUMP R32 = writing to M32 is trapped and a JUMP is made to the RHS
OUT R48 = output the RHS
*R01 R56 = output the RHS to the 16 bits in (R0,R1)
FREQ R62 = set the system clock frequency
CPU R63 = other CPU behaviour (e.g. set flags)
HCF R63 = every homebrew computer needs this instruction!
human readable machine readable comment
Rj OP Rk Rj OP Rk the general case for all OPs except LSL
Rj » 1 Rj »1 Rk k is ignored in the case of LSL
Rj Rj | M32 OR with zero (M32) results in only Rj
Rj OP c Rj OP Rk c is a constant in the set (0, 1, … 16, 32, 64 … 240), k selects
Rj OP c Rj OP Rk c is a constant in the set (0, 1, … 16, 32, 64 … 240), k selects
c OP Rk Rj OP Rk c is a constant in the set (0, 1, … 16, 32, 64 … 240), j selects
k Rj & Rk any 8 bit number, j is from (0, 16,…240), k from (0,1,..15)
IN wait for input from toggle switch
*M01 input from address (M0, M1)

'cond' is probably the standard 3bits/8 values: Always, Never, =0, !=0, >0, >=0, 0⇐, <0. However, look at the 6502 flags, Carry, Overflow, Negative and look at what values of 'cond' were used in 'third' code.