The Z80 Adventure Part III

In my last post on this topic, I discussed improvements to my Z80 computer, which allowed the use of peripherals from within the Z80 OS. I recently rebuilt this computer, to allow for a bit more extensibility (and eventually, LED debugging).

Conceptually, this is similar to the last iteration, with an ATMega32A acting as a custom I/O port to the Z80, it’s gateway to the outside world. The address bus accessible to the ATMega has been reduced to 8 bits – the upper 4 bits weren’t being used, except for debugging (and we can debug with LED’s and a manual clock input).

To add wifi and disk support, I used the ESP-01 module: this acts as a WiFi bridge, so you can connect to it via netcat. It also supports a series of specially formatted (but human readable, for debugging) UART commands, which allow disk access:

The actual protocol is fairly simple:

  • !xx!yy!zz\r\n:
    • xx is set to 0xFF for read operations
    • yy is set to the low byte of the address bus.
    • zz is the data bus
    • This will wait for one byte – if it’s a “write-only” operation, like selecting the disk number, the byte will be treated as an “ack” and ignored. If it’s a read operation, like reading a byte from disk, the byte will be placed on the data bus (or routed as the ATMega sees fit).
  • !!! means an actual “!” is being printed over UART.

To correctly support replies, a change had to be made to the way the ATMega handled UART input. Previously, when the ATMega was simply bridging for the Z80, an asynchronous interrupt-based UART was fine – this was the way the Z80’s BASIC rom BIOS expected input. Here, we need to temporarily disable interrupts every time we want to wait for a response from the ESP-01 as part of a I/O operation, otherwise, your interrupt routine will consume your input:

char async_getchar()
	char tempByte;
	while(!(UCSRA & (1 << RXC)));
	tempByte = UDR;

Given the static nature of the Z80, all this occurs in one clock cycle – the clock is simply held, while the ATMega waits for a reply from the ESP module.

Finally, to connect to this system, we need to disable line buffering (stty -icanon; nc 23) before we use netcat, for characters to be sent correctly to the CP/M OS:

With this in place, the next step is to implement a working CP/M disk structure – but this can be fully implemented on the ESP side (which is, incidentally, a lot easier to program). I’m setting aside this project temporarily, to spend my time elsewhere. The code can be found on Github as usual.

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Bards, Computers, Jesting. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.