6502 from 74HC logic

I designed and built an 8-bit CPU from scratch with 74HC logic gates using the 6502 instruction set. It is capable of running the 6502 version of Microsoft BASIC (source tarball). I have also written a program to calculate 500 digits of pi — and it works! It uses no microprocessor — apart from EPROMs it uses only 74HC series parts (gates, registers, counters etc.). It uses a total of 96 ICs (that is CPU + front panel logic) and runs at up to about 4 MHz, doing about one million instructions per second (instructions taking 2-7 clock cycles). It was constructed on six 160x100 mm perfboards using pen wiring and took about 3 months to design and build (my studies taking up a lot of my time during term).

Here you can see it just hooked up to RAM:

Running a simple program at slow speed (1.3 MB GIF)

The architecture was intentionally kept simple and the CPU has a fairly long datapath, but the focus was on producing a working design, with performance a secondary consideration. It does use a fairly horizontal microcode (40 bits wide), allowing me to do a few things in parallel and speeding up many instructions. Addressing the microcode ROM took advantage of the enormous EPROMs available today, allowing me to use 16 address bits of which 8 bits are simply the opcode, 4 bits act as a microprogram counter and 4 processor status bits are also available (IRQ, alu carry, P register carry bit and another bit from the P register). The microcode syntax is fairly nice and makes the instruction set almost self-documenting, e.g.:

0x69 A = A + [PC++] + C <NVZC>;
0x65 A = A + zero + C <NVZC>;

This defines the ADC instruction for immediate and zero page operands. zero is a "function" defined by

func zero {
    AL = [PC++];
    return [0:AL];
}

This is compiled to binary form by a microcode compiler written in C. There are a few caveats which were mostly hacks in order to save precious microcode bits.

Number of ICs used
ICfunctiontotalALAHALUROMFP1FP2
74HC00 4×NAND 2 2
74HC02 4×NOR 1 1
74HC04 6×NOT 2 1 1
74HC08 4×AND 3 1 1 1
74HC14 6×Schmitt trigger2 1 1
74HC32 4×OR 5 4 1
74HC86 4×XOR 2 2
74HC138 3-to-8 Decoder 4 1 1 2
74HC151 8-to-1 Mux 6 6
74HC154 4-to-16 Decoder 2 2
74HC163 4-bit Counter 10 4 2 4
74HC181 4-bit ALU 2 2
74HC244 8× 3-state Buffer32 10 9 3 6 4
74HC374 8-bit register 3 1 1 1
74HC377 8-bit register 9 2 2 1 2 2
27C1001 1 Mbit EPROM 5 5
ULN2003 Transistor array 6 3 3
total 96 17 16 18 14 15 16