I've built my own 8-bit computer from 4000 and 74HC series CMOS ICs. It has 4KB of RAM and is Turing complete. It has 16 arithmetic operations in its ALU and can perform conditional jumps. Programs are loaded by a BIOS module from a cartridge.
I was among others inspired by the work of Ben Eater:
https://eater.net/
https://www.youtube.com/channel/UCS0N5baNlQWJCUrhCEo8WlA
Thanks for the inspiration.
Here's some basic info about the computer:
The individual modules are plugged into a board connecting them on 36 rails. The modules are as follows (top to bottom). Links go the schematics and PCB designs.
Notes:
Next steps:
Commands | ||
---|---|---|
Command | Parameters | Description |
NOOP | Do nothing | |
LDA | Memory address [0-4095] | Load RAM content to register A |
STA | Memory address [0-4095] | Store Register A to RAM |
LDAB | Upper 4 bits of memory address [0-15] | Load lower 8 bits of memory address from register B and load RAM content to register A |
STAB | Upper 4 bits of memory address [0-15] | Load lower 8 bits of memory address from register B and store register A to RAM |
LDIA | Value [0-255] | Load Value to register A |
CALC0 | Function [0-15] | Calculate with low carry in bit |
CALC1 | Function [0-15] | Calculate with high carry in bit |
JC | Function [0-15], Memory address [0-255] | Jump to program line if calculation with low carry in bit yields high carry out bit. Use "JC 3" for unconditional jumps |
JCC | Function [0-15], Memory address [0-255] | Jump to program line if calculation with high carry in bit yields high carry out bit |
OUT | Display content of register A | |
AtoB | Copy register A to register B | |
IOACT | IO device ID [0-15] | Activate IO device matching id, deactivate all others |
IOREAD | Reads IO data from active IO device into memory address stored in register A and overwrites register A with IO data | |
IOWRITE | Write data from memory address stored in Register A to active IO device | |
HALT | Halt computer |
ALU functions | ||
---|---|---|
ID | CALC0 / JC | CALC1 / JCC |
0 | A | A plus 1 |
1 | A + B | (A + B) plus 1 |
2 | A + B_ | (A + B_) plus 1 |
3 | minus 1 | Zero |
4 | A plus AB_ | A plus AB_ plus 1 |
5 | (A + B) plus AB_ | (A + B) plus AB_ plus 1 |
6 | A minus B minus 1 | A minus B |
7 | AB_ minus 1 | AB_ |
8 | A plus AB | A plus AB plus 1 |
9 | A plus B | A plus B plus 1 |
10 | (A + B_) plus AB | (A + B_) plus AB plus 1 |
11 | AB minus 1 | AB |
12 | A plus A | A plus A plus 1 |
13 | (A + B) plus A | (A + B) plus A plus 1 |
14 | (A+ B_) plus A | (A + B_) plus A plus 1 |
15 | A minus 1 | A |
Where A+B is a bitwise OR, AB is a bitwise AND and A_ is the complement of A. Taken from the HCF40181B datasheet.
An editor, emulator, and compiler for my assembler that runs right in your browser can be found here.
A video of the computer loading and executing a program calculating the 13th Fibbonacci number and dividing it by 3 at 500Hz can be found here.
What you see:
First, you see the computer counting up to 94 while the left blue LED on the control monitor is on. This indicates the BIOS is loading the program from the cartridge to ram. As the BIOS itself has 22 lines, the counter starts at 22 and loads 72 lines of code into RAM. after that the BIOS LED turns off and the program executes, calculating the 13th Fibonacci Number, which is 233, then dividing it by 3,yielding 77. Then the computer halts and I give it a thumbs up.
A video of the computer loading and executing a program calculating the 13th Fibbonacci number and dividing it by 2 at 2.048KHz using the new quarz clock can be found here.
A video of me interacting with the computer through the new keyboard module can be found here: here.
A video of the computer loading and executing a program calculating the Fibbonacci sequence at 40Hz can be found here.
Rails | ||
---|---|---|
Pin | Name | Function |
1 | VCC | +5V |
2 | CLOCK | Clock pulse |
3 | BUS0 | Bus bit 0 |
4 | BUS1 | Bus bit 1 |
5 | BUS2 | Bus bit 2 |
6 | BUS3 | Bus bit 3 |
7 | BUS4 | Bus bit 4 |
8 | BUS5 | Bus bit 5 |
9 | BUS6 | Bus bit 6 |
10 | BUS7 | Bus bit 7 |
11 | CTRL0 | ALU function register in |
12 | CTRL1 | ALU out |
13 | CTRL2 | ALU carry bit |
14 | CTRL3 | Register A in |
15 | CTRL4 | Register A out |
16 | CTRL5 | Register B in |
17 | CTRL6 | Register B out |
18 | CTRL7 | Instruction register in |
19 | CTRL8 | Instruction register out |
20 | CTRL9 | Memory address register 1 in |
21 | CTRL10 | Memory address register 2 in |
22 | CTRL11 | RAM in |
23 | CTRL12 | RAM out |
24 | CTRL13 | Output in |
25 | CTRL14 | Counter enable |
26 | CTRL15 | Counter out |
27 | CTRL16 | Counter in / Jump |
28 | CTRL17 | Conditional Jump |
29 | CTRL18 | Instruction counter reset |
30 | CTRL19 | I/O device out |
31 | CTRL20 | I/O device in |
32 | CTRL21 | BIOS active |
33 | CTRL22 | Reset |
34 | CTRL23 | Halt |
35 | CLOCK_I | Inverted clock pulse |
36 | GND | Ground |
I defined my assembler and BIOS within an libreoffice calc sheet. It can be downloaded here
I've built my EEPROM writer as described by Ben Eater in this video
The Arduino programs can be downloaded here: