It's been a long time since my last update. I took a break from the project for the first half of the year, and for the last few months I've been quietly working on some new features that I think are ready to announce. First, check out the video overview, then read on below to find out more.
Seamless CP/M Integration
The headline feature is a BDOS emulation layer that allows unmodified CP/M programs to seamlessly integrate with z80ctrl and access files on the SD card's FAT filesystem directly without using disk images. In addition, the z80ctrl monitor can now run .COM files directly. This means you can copy CP/M .COM programs and their associated files directly to your SD card and run them from the z80ctrl> prompt without booting into CP/M first.
In order for CP/M programs to work, z80ctrl needs to load some Z80 runtime support into memory that allows the programs to access the FAT filesystem via BDOS calls. This runtime is automatically loaded from a file called BDOS.BIN in either your root directory or the current directory. The BDOS.BIN file should be assembled using sjasm from the bdos.asm file in the examples directory.
The CP/M program will be able to transparently access any files located in the current directory when the program was launched. I plan to also add support for mounting additional directories on drives so it will be possible to access files in multiple directories at the same time, but that's not done yet.
The current status of the BDOS emulation is pretty complete. I have been able to successfully run many programs including Turbo Pascal 3.0, Microsoft BASIC-80 (MBASIC.COM), Microsoft M80 assembler, BBC BASIC, Hi-Tech C, SuperZAP file manager, WordMaster, WordStar, Zork, Catchum, Ladder and more. Currently the ZDE editor is the only program I am aware of that does not work. I still need to investigate why.
For the curious, the code for the BDOS emulation is in bdosemu.c. Credit is due to the RunCPM project for showing me that it is possible to emulate BDOS calls on a FAT filesystem and for serving as a sanity check to understand BDOS behavior when I was having trouble understanding the BDOS assembly code. However, none of my code has been copied from RunCPM.
The general concept of the emulation is that the BDOS runtime code establishes a DMA mailbox where the FCB address, DMA address, return code and other pertinent information can be exchanged between the Z80 and the z80ctrl. The Z80 initiates a BDOS command by writing to port 0xC. The z80ctrl will then pick up the command, perform the necessary FAT filesystem operations, and read or write the file or directory data at the specified DMA address in the format that CP/M expects. z80ctrl then returns control to the Z80 and the CP/M program is none the wiser that the data it requested came from a FAT filesystem.
FatFS DMA Interface
For programs written especially for the z80ctrl, I have also provided a way to make FatFS API calls directly from Z80 code. The DMA interface code is in filedma.c, and an assembly library to access the DMA interface from the Z80 is available in filedma.asm. An example filecopy.asm program that copies a file on the FAT filesystem is also provided.
Using the FatFS API is more performant and full featured than using the BDOS emulation. Almost all FatFS API functions can be called directly from the Z80 and FAT-native features like subdirectories are therefore available. In addition, DMA transfers are not limited to 128 bytes at a time like they are when using BDOS emulation.
z80ctrl now automatically loads and executes files with a .PRG extension as a bare-metal program. I borrowed the idea of .PRG files from the C64, where the first two bytes of the file encode the load address. z80ctrl automatically loads the rest of the file minus these two bytes to the specified address and executes it from there. The FatFS API also provides the ability to access command line parameters.
File Management Commands
I have also added several new commands to the z80ctrl command line interface so you can now do standard file operations to files on the SD card, including:
- del/era/rm to delete files
- ren/move/mv to rename or move files
- copy/cp to copy files
- mkdir/md to make directories
- chdir/cd to change the default directory
- rmdir/rd to remove directories
z80ctrl has aliases for both DOS and Linux names for each command so your muscle memory will work regardless of what you're used to. Note that all commands use the "cmd src dest" convention from DOS/Linux instead of the "cmd dest=src" convention used by CP/M. The commands support wildcards so it's possible to copy, move or delete multiple files at once. If wildcards are used, the final parameter is assumed to be a directory. The delete command doesn't prompt for confirmation, so be careful using it with wildcards.
Halt via Keyboard Shortcut
It's now possible to halt a running program using a keyboard shortcut. This is configured using the haltkey command, which can either take the ASCII code in hex or control key ^X notation, where X is any letter A-Z. SIMH AltairZ80 uses ^E to exit to the monitor, so I have been using the same shortcut. However, there's a possibility it could interfere with existing CP/M programs so I didn't want to enable it by default. (I know for a fact it conflicts with WordStar and Turbo Pascal's editor, since they use ^E to move up a line.) If you want this enabled by default, put it in your autoexec.z8c file.
Serial Port File Attachment
z80ctrl can now attach the virtual serial ports to a file, so CP/M can read from the file via the paper tape punch device or write to a file via the paper tape reader devices. It is possible to transfer files to or from a disk image by attaching them using the attach command in the z80ctrl monitor and then using PIP to transfer to and from the PTP: and PTR: devices (e.g., pip test.txt=ptr:). The command allows a separate file to be attached for reading and writing. Syntax for the command is "attach <virtual uart> <read/write> <physical uart or file>", for example "attach 1 read test.txt" to read test.txt over the paper tape reader.