I've been tinkering with hardware for a couple of years now, most of this is trivial stuff if I'm honest, for example:
- Wiring a display to a WiFi-enabled ESP8266 device.
- Making it fetch data over the internet and display it.
- Hooking up a temperature/humidity sensor to a device.
- Submit readings to an MQ bus.
Off-hand I think the most complex projects I've built have been complex in terms of software. For example I recently hooked up a 933Mhz radio-receiver to an ESP8266 device, then had to reverse engineer the protocol of the device I wanted to listen for. I recorded a radio-burst using an SDR dongle on my laptop, broke the transmission into 1 and 0 manually, worked out the payload and then ported that code to the ESP8266 device.
Anyway I've decided I should do something more complex, I should build "a computer". Going old-school I'm going to stick to what I know best the Z80 microprocessor. I started programming as a child with a ZX Spectrum which is built around a Z80.
Initially I started with BASIC, later I moved on to assembly language mostly because I wanted to hack games for infinite lives. I suspect the reason I don't play video-games so often these days is because I'm just not very good without cheating ;)
Anyway the Z80 is a reasonably simple processor, available in a 40PIN DIP format. There are the obvious connectors for power, ground, and a clock-source to make the thing tick. After that there are pins for the address-bus, and pins for the data-bus. Wiring up a standalone Z80 seems to be pretty trivial.
Of course making the processor "go" doesn't really give you much. You can wire it up, turn on the power, and barring explosions what do you have? A processor executing NOP instructions with no way to prove it is alive.
So to make a computer I need to interface with it. There are two obvious things that are required:
- The ability to get your code on the thing.
- i.e. It needs to read from memory.
- The ability to read/write externally.
- i.e. Light an LED, or scan for keyboard input.
I'm going to keep things basic at the moment, no pun intended. Because I have no RAM, because I have no ROM, because I have no keyboard I'm going to .. fake it.
The Z80 has 40 pins, of which I reckon we need to cable up over half. Only the arduino mega has enough pins for that, but I think if I use a Mega I can wire it to the Z80 then use the Arduino to drive it:
- That means the Arduino will generate a clock-signal to make the Z80 tick.
- The arduino will monitor the address-bus
- When the Z80 makes a request to read the RAM at address 0x0000 it will return something from its memory.
- When the Z80 makes a request to write to the RAM at address 0xffff it will store it away in its memory.
- Similarly I can monitor for requests for I/O and fake that.
In short the Arduino will run a sketch with a 1024 byte array, which the Z80 will believe is its memory. Via the serial console I can read/write to that RAM, or have the contents hardcoded.
I thought I was being creative with this approach, but it seems like it has been done before, numerous times. For example:
Anyway I've ordered a bunch of Z80 chips, and an Arduino mega (since I own only one Arduino, I moved on to ESP8266 devices pretty quickly), so once it arrives I'll document the process further.
Once it works I'll need to slowly remove the arduino stuff - I guess I'll start by trying to build an external RAM/ROM interface, or an external I/O circuit. But basically:
- Hook the Z80 up to the Arduino such that I can run my own code.
- Then replace the arduino over time with standalone stuff.
The end result? I guess I have no illusions I can connect a full-sized keyboard to the chip, and drive a TV. But I bet I could wire up four buttons and an LCD panel. That should be enough to program a game of Tetris in Z80 assembly, and declare success. Something like that anyway :)
Expect part two to appear after my order of parts arrives from China.