z80ctrl is an AVR-based bootloader, debugger, and I/O device for a Z80 retrocomputer with the following features:
- Runs CP/M-based software including WordStar, Zork, Ladder, Turbo Pascal and more!
- Plug-in module for RC2014 retrocomputer replaces the clock, serial, rom, and CF boards
- Reads HEX files and CP/M disk images from a FAT32-formatted SD Card
- Provides Altair and RC2014-compatible serial ports
- Full compatibility with unmodified Altair disk images from the SIMH emulator project
- Monitor with memory inspector and built-in Z80 disassembler
- Single-step debugging, breakpoints, and watchpoints to trace Z80 bus activity in real-time
- Flexible MIT-licensed firmware can be the basis of your own SBC or breadboard computer
- Expandable SPI bus allows bridging other SPI peripherals to the Z80
Visit the GitHub Repo for all project artifacts and the GitHub Wiki for documentation. Check out the videos below for an overview of the project.
I had a marathon hacking session this weekend and added a lot of improvements and new features to z80ctrl:
Massive reduction in memory usage. FatFS had a default configuration that used a separate buffer for each file object. I had 16 static file objects for the drive emulation. After I found the configuration option to switch to shared buffers, along with some other changes such as moving all the strings in my code to flash, static RAM usage on the AVR went from 77% down to 17%. Memory usage will still go up and down as variable are allocated on the stack in certain functions, but 17% is now the baseline. A 77% baseline was dangerously close to running out of memory if a function was run that allocated a big array on the stack.
Switch to using BUSRQ to negotiate handing the data bus back to the Z80 after an IORQ instead controlling the clock in software. Manually clocking was interfering with other peripherals like Ed Brindley's sound card that rely on a steady clock rate. This resulted in audible pops when the AVR was answering IORQs. Now it plays without any glitches.
Switch to an interrupt-driven buffered UART driver. This makes it much less likely that the AVR will lose characters when the PC is sending it data quickly. It's still possible to overrun the buffers using PuTTY but it's a lot better than it was. Copy and Pasting via TeraTerm now seems to work pretty well, and XMODEM transfers work as long as the baud rate is 115200 or less. Slower baud rates are less likely to overrun the buffer. As the AVR doesn't have any hardware flow control, this is probably the best I can do to solve this problem.
Change to a columnar directory listing a la CP/M or Unix ls, instead of one file per line used before.
Dual UART support as demonstrated in the screenshot. Either physical UART can be assigned to either of two virtual UARTs available to the Z80. So, for example, you can have debugging output from z80ctrl monitor on UART 0, and interact with the Z80 on UART 1. The default virtual to physical mapping is 0 to 0 and 1 to 1. This can be changed using the "attach" monitor command.
Run-time configurable baud rate. The default rate is still 115200 but it can be changed on the fly using the "baud" command. After you enter the command, it calculates the closest actual baud rate the AVR can achieve and prints it out. It flushes the buffer before switching baud rate so that the output doesn't get corrupted by the baud rate. You will have to change your terminal's baud rate before you can interact any further. I've tested baud rates from 600 bps all the way up to 1.25Mbps successfully. You can also configure a custom baud rate at startup using the autoexec functionality (see below).
Figured out how to get libc-avr's stdio library working with fatfs, which gives me the ability to transparently use a file in place of stdin, stdout, or stderr. This lays the groundwork for a lot of nice features, the first of which is batch files. Other potential features are the ability to redirect errors to a separate terminal, log debugging info to a file, redirect command output to a file, and so on.
Batch files! You can now place text files on your SD card with one z80ctrl monitor command per line and then execute them via the "submit" monitor command. This is very simple, just a list of commands to execute verbatim--no flow control, variables, etc. If you place a file named autoexec.z8c in the root directory of your SD card, z80ctrl will execute it automatically upon startup. This is a nice way to configure your baud rate, attach virtual UARTs, mount drives, even boot CP/M automatically.
Run-time configurable Z80 clock rate via the "clkdiv" monitor command. Any number 1-255 can be specifie for clkdiv. One of the PWM's output compare registers is set to the clkdiv value and the other is set to half the clkdiv value, so that the clock remains as close to 50% duty cycle as possible. This implementation...
I think that z80ctrl is almost ready for prime time. I now have had two additional people build working boards. I have identified several issues with the original revision of the board and figured out workarounds for them. I have also made a second revision of the board that should fix these problems. I have at least one user who has ordered a REV2 board and I am awaiting a report from him.
For those interested in a deeper dive on how the z80ctrl works, check out the Hardware and Software Design Notes. If you're feeling adventurous and don't want to invest in an RC2014, you can also check out the Breadboard Instructions for the first prototype that I built.
Finally, for a preview of what I have in mind for the future of z80ctrl, check out the Planned Features page.
Here's hoping you find the new documentation useful! Let me know if you have any feedback.