Finally! It’s been 532 days (or 1 year, 5 months and 24 days) since my very first post here, and today I have a real, working machine, able to run programs and perform useful computations. Last night my CPU successfully executed the fibonacci program from this post from May (all homebrew CPU guys run fibonacci, right?). The code snippet calculates the fibonacci(10) function, stores the result in A register and then halts. Here’s its source, along with hand assembled binary codes:
_start: ; setup stack ld a, 0x5000 ; 21 05 00 mov sp, a ; 0a ; compute fibonacci(10) ld a, 1 ; 22 01 ld x, 0 ; 2b 00 ld y, 9 ; 34 09 fibo: push a ; 10 add a, x ; 6f pop x ; 17 dec y ; e9 jnz fibo ; dc ff f9 halt ; 01
The code uses stack, CPU arithmetics and conditional jump. After last loop run, the A register should hold a decimal value 55 (hexadecimal 0x37). The photo below shows my yesterday’s setup. You can see the three boards that make up the computer (CPU core, CPU ALU and memory) connected to the logic analyzer, and powered by an old AT power supply (by the way – I have a new, larger desk):
Most important, however, is what the HP 1631D logic analyzer displayed:
It shows a trace of a DBUS (data bus) and the ABUS (this is in fact the ALUBUS). After 128 clock cycles from reset, and just before a fetch of opcode 0x17, there is a value 0x0037 on the ALUBUS, an expected result of the ADD A, X instruction, and the correct value of the 10th number in the fibonacci sequence. Around cycle 135, the machine goes to a halt (opcode 0x01). Not bad, huh?
Now that I had a working machine, I tried speeding it up a little. During construction I was running an unimpressive 460.8kHz, so I reached for faster oscillators to plug them into the core CPU board and see what happens. First, I used an 8.192MHz oscillator. The machine ran correctly at 1/4 of this, so precisely at 2.048MHz. Then, I took even faster 16.384MHz (internal CPU speed of 4.096MHz in this case). It worked fine, too! I don’t have any higher frequency oscillators to see where’s the limit but regardless of it, I was impressed that the CPU can do >4MHz. And all that with a slow ALU (I haven’t yet populated the board with a lookahead carry generator) and only LS-type TTL chips. Ok, I know there is currently no bottleneck, like a slow device or something, but I am very pleased with the experiment.
So, what am I up to now? I have outlined a list of short term tasks to work on:
- Rebuild the MDR using four 74LS374s as described in the previous post (I have made up my mind)
- Populate and test with 74LS182 carry lookahead
- Provide bus-hold circuits where necessary (I will post on this subject soon, this problem seems quite important)
- Run the entire test suite I used with the machine simulator to comprehensively check for any further bugs
- Publish the updated schematics, microcode and whatever gets modified on the way
- Think of I/O boards to make the computer more interactive (my minimum is an LCD display, UARTs, keyboard interface and possibly a rudimentary IDE controller)
- Build the I/O boards
And, just as a reminder, the long term goals:
- Build a programmer toolchain – port some existing GNU compiler (LCC?), rewrite the assembler, write a linker.
- Write an OS, or port an existing OS (Minix?)
- Build a video card
- Build everything on a set of 160x100mm euroboards and populate in a neat 19-inch rack enclosure (see here)
- Connect the entire thing to the internet and make it serve a website about itself
Looks like there’s still a long and interesting journey. This boot was a significant milestone, though.
I’ve also built a CPU. Mine’s on an FPGA and I started in 2006. When I saw your post, it reminded me of the first day my cpu ran. It was very exciting and I remember the “It Works!” feeling.
Am reading your blog from the beginning and our systems are VERY similar. Don’t know where you are now, but if you want more details on my project, write me.
After years of effort, I have a Pascal-like compiler and I have ported large portions of Minix 1 to my cpu…