Table of Contents

The Blinking Computer

The Blinking Computer will be an easy-to-build educational computer. As the name suggests, the idea is that you can write code and see it execute at every level, that means discrete components and lots of LEDs. The design has evolved very many times since my Prof forbid me from canablising the old departmental Strowger switch telephone exchange in the late 1980's. Right now there are 32 words of RAM and the program memory is a tape loop, just like Colossus.

The objectives are:

This is the plan:

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.

SIMPL

SIMPL is a SIMPL IMperative Procedural Language. It's deliberately minimal and very very simple - the aim is to show how languages and complilation work in an easily ingestible way.

statements are of the form: `a = function(b c)` where a, b and c are variables. b and/or c can of course be other function calls, so 2x+1 is `add(mul(x 2) 1)`

Variables follow :

Type size/bytes Syntax Example
boolean 1 True|False True
byte 1 \d+[U] 42
short 2 \d+[U]S 65535US
long 4 \d+[U]L -2147483647L
character 1 '\w' 'a'
string 1+ “\w*” “Hello World!”
float 3 \d+.\d*[e[-]\d+] 3.1415926535

Only fixed sized arrays are supported, the size must be known at compile time and memory is allocated as contiguous variables of the same type.

Indentation defines a code block so allow us to define functions and implement control flow:

def mul2(x)
  return mul(x 2)

and also to implement control flow:

if eq(answer 42) 
  print("The Answer is 42")
else
  print("The Answer is not 42")

a = 0
while lt(a 42)
  a = inc(a)
  print(a)
  

The aim is to do type resolution at compile time, so types do not have to be specified. The type of a constant can be determined. The return type of a function is the return type of the last call that function makes (with a check that all returns have the same type). The types of the function arguments are determined by the usage of those arguments (again, with a consistacny check). The aim is for a minimal language. There is no automatic type promotion.

History

I've wanted to build my own computer since the late 1980's when the old departmental relay based telephone system was thrown out. I asked my 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. Noteably: