Skip to content

Software Design Notes

J.B. Langston edited this page May 20, 2018 · 18 revisions

Configuration

defines.h contains various compile-time configuration options:

  • GPIO ports and pin numbers for various bus signals.
  • A few others such as baud rate and number of emulated drives are also configured here.

Z80 Bus Control

  • bus.h provides macros to set the address and data bus and read or toggle the various control lines. This abstracts control of these signals away from the specific hardware implementation. It should be possible, for example, to port this code to another microcontroller simply by modifying bus.h and defines.h (for example ATmega2560 without an IO expander).
  • bus.c builds on top of these macros to provide functions to intialize the bus, control the clock, and enter and exit bus-master mode.
  • memory.c contains functions to read and write to the external SRAM that is shared with the Z80. For now, it also contains several higher-level memory related functions such as memory hex dump that should probably live elsewhere.
  • z80.c contains the Z80 real-time debugger and the run loop for the Z80 that handles IO requests.

SPI Peripherals

  • spi.c contains a few simple functions for initializing the SPI bus and transferring data. These functions are used by higher-level functions specific to the IO expander and SD card.
  • iox.h contains register definitions for the MCP23S17 I/O expander that were taken from its datasheet. iox.c provides some simple utility functions to make reading and writing these registers a little easier.
  • mmc_avr_spi.c contains the low-level SPI interface with the SD card that is used by FatFS. This code comes from the FatFS example project.

z80ctrl Monitor

  • cli.c contains the command-line monitor interface. The cli_loop function reads a line from the UART and tokenizes the command. It looks the command names up in a table and calls the corresponding function via a function pointer. The main loop passes parameters to all the functions via a standard argc/argv mechanism. It is up to each function to parse and interpret the individual parameters.
  • disasm.c contains the disasm function that disassembles a single instruction. It uses a large if-then-else tree to decode general classes of instructions, and then uses lookup tables for specific registers, condition codes, ALU operations, and so forth. disasm pulls in bytes as needed via a function pointer that is passed to it, allowing it to read instructions from different sources. This file also contains disasm_mem function which reads data from the external SRAM into a buffer and calls disasm to disassemble each instruction. Once a instruction has been disassembled, it formats the instruction and outputs it, then repeats for the next instruction within the specified range

Third-Party Software

  • The AVR is programmed with the MightyCore bootloader to allow it to be reprogrammed through the serial interface.
  • Although I am using the MightyCore bootloader, I do not use the Arduino libraries; only avr-libc.
  • I use the FatFS library to provide access to a FAT32-formatted SD-card containing ROM and disk images for the Z80.
  • The line editor in uart.c is borrowed from the avr-libc stdio demo. I have modified this to use interrupt-driven circular RX/TX buffers from the FatFS AVR demo project.
  • The disk emulation in diskemu.c is based on heavily modified code from the SIMH AltairZ80 emulator.
  • The dboot command uses the Altair Disk Boot Loader that I found on the Altair Clone Project's site.
  • The sboot command uses the bootloader from the Altair Z80 emulator, the source for which was found in the DISKBOOT.MAC file on the CP/M 2.2 disk image distributed on Peter Schorn's website.
  • The altmon command uses the Altair 1K Monitor that I found on the Altair Clone Project's download site. The comments say that it is based on the 2.0c Monitor by Vector Graphic.

The layout of the source code is as follows:

  • defines.h contains the specific ports and pins used for the Z80 bus interface and SPI chip selects.
  • disasm.c contains a function that disassembles a single Z80 instruction. This is called by the real-time debugger and the from-memory diassembler.
  • memory.c contains functions to do DMA transfers, and various convenience functions to dump, fill, and disassemble blocks of memory.
  • ff.c, ffsystem.c, ffunicode.c, and mmc_avr_spi.c are from the FatFS project and provide access via SPI to the FAT32 filesystem contained on the microSD card.
  • z80.c has functions run and debug the Z80 and handle I/O requests from it.
  • diskemu.c emulates an Altair 88-DISK controller to allow running CP/M and other disk-based programs.
  • ihex.c contains functions to read and write Intel HEX files.
  • z80ctrl.c contains the main function that starts initializes the bus and starts the command-line monitor interface.
Clone this wiki locally