AVR-based bootloader and IO card for a Z80 retrocomputer

Similar projects worth following
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.  For ordering information, refer to the Build Instructions.  

Check out the videos below for an in-depth discussion of the project.

Breadboard Overview

Software Demo

Printed Circuit Board Overview

  • DMA Disk Transfers

    J.B. Langstona day ago 0 comments

    I got DMA disk transfers partially working last night. The SIMH version of CP/M already had support for DMA access implemented in its BIOS, so I implemented a compatible port interface on the z80ctrl. The same disk images that are mounted on A: through H: will be mirrored to I: through J:. When you use drive letters I through J, the disk images are read via DMA, whereas when you use A through H, they are read using Altair Floppy emulation.  

    This division is a function of the SIMH CP/M BIOS since it sends drive numbers 0 through 8 to the DMA port for drives I through J. My DMA implementation does not modify the disk number it receives from CP/M, so the drives end up being mirrored. The CP/M BIOS could be modified to use DMA for all drives, but as I am currently debugging it, this layout is convenient. It allows me to test the DMA functionality when I want to, or ignore it when I just want a working drive.

    The DMA access only uses a single port: 0xFD.  A READ or WRITE command, followed by 6 bytes specifying the drive, sector, track, and DMA address is written to the port, and then a byte is read from the port to initiate the command. The z80ctrl initiates a DMA transfer at the end of the IORQ cycle using the previously saved command and it's parameters. There is also a PARAM command that allows CP/M to interrogate the drive controller about the characteristics of the drive. The DMA disk emulation code is here and the IORQ handler calls the DMA function here.  

    So far it's working well enough that I can go to the drive and run DIR and get a directory listing, but it's still buggy. I'm getting some duplicate entries in my directory listing and I get a lot of bad sector errors.  I intentionally haven't allowed write support until I get the bugs worked out.  As expected it's considerably faster than the old method that transfers one byte at a time through programmed I/O on the Z80.

    Separately, I have also implemented a bootloader directly in the AVR, which is working very well.  There is a new "boot" command that directly loads the boot sector from the disk mounted on drive 0 into RAM and jumps to it.  I have gone ahead and removed the sboot and dboot commands which utilized the traditional Z80 boot ROMs.  Perhaps removing them so soon was a bit aggressive, but if anyone reports any problems with the new bootloader I can bring them back.

  • New and Improved!

    J.B. Langston4 days ago 0 comments

    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.  I got the idea to use BUSRQ in this way from Just4fun's AVR/Z80 project.
    • 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 change. 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...
    Read more »

  • Getting Ready for Prime Time

    J.B. Langston6 days ago 0 comments

    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.  

    To help get the project ready, I have focused a lot on documentation lately.  Have a look at the GitHub Wiki to get started.  New users want to start with the Board Assembly Instructions and Monitor User Guide. Also, check out the list of Compatible Z80 Software to find things to run on your z80ctrl-powered RC2014.  If you're building a REV1 board, be sure to check out the list of Known Issues as well.

    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.

View all 3 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates