The Zilog Z80 #
The Zilog Z80 integrated chip was released in 1976 as alternative for the Intel 8080. It was software-compatible, it was faster, it added more instructions and registers, and it was easier to interface with. The Z80 ended up powering a wide range of home & business computers, such as the Tandy TRS-80 shown above.
INTRODUCTION #
This article describes an emulated version of the Z80 with 120 KB banked RAM as well as 2 GB of (emulated) disk storage, which is some two orders of magnitude more than was possible in the 70’s. This configuration can comfortably run CP/M 2 and 3, with enough storage for the equivalent of hundreds of floppy disks.
This project will not emulate the graphics and sound capabilities of the TRS-80, but rely on a terminal emulator attached via a serial USB link as a more business-like setup (similar to later TRS-80 models).
Hardware choices #
I’m going to use a “BlackPill” from WeAct for this (link). It’s based on an STM32F411CE with 128 KB RAM + 512 KB flash, and running at 100 MHz. For storage, a fingernail-sized microSD card will be used. Several aspects of this setup will make it considerably more convenient and performant than the Altair 8800 from another article.
The µSD card has its own board (link) and there’s a serial port for development and future expansion.
Putting it together #
As with the Altair 8800, everything is based on a small prototyping board with some permanent wiring soldered on the bottom: 4 wires connect +5V & GND and TX/RX to the serial interface board, and 6 wires connect +3.3V & GND and 4 signals (SPI2: MOSI, MISO, SCLK, NSEL) to the µSD card socket.
Wiring connections: A9 (USART1 TX) is connected to the serial’s RX, and A10 (USART1 RX) is connected to the serial’s TX. For SPI, the µC-side connections are B12: NSEL, B13: SCLK, B14: MISO, B15: MOSI.
Unfortunately, the wiring for the SD card is WRONG: B15..B12 instead of B12..B15. This is a silly mistake to make when turning around the board to attach wires. For the bit-banged "spi::Gpio" driver, this is easy to correct in code, but not for (more efficient) hardware-driven SPI drivers. The wiring will be fixed later ...
The WeAct µC board is socketed to allow easy replacement, for reasons which will become clear later.
LOW-HANGING FRUIT #
Verifying the Z80 emulator #
Extended BASIC #
ADDING AN SD CARD #
Blocking and deblocking #
Virtual drives for CP/M 2.2 #
CP/M needs some disk image files on the µSD card, used as “virtual drives”:
cpm2: STM32F411xx @ 100 MHz (v7.0.2-68-g9d19d8c2)
sdhc 0, 3342 us, 4014080 blocks = 2007040 KB
Files:
<VOL> ABC
256256 A-DISK.IMG
256256 B-DISK.IMG
[...]
sdcard: A=250K, B=250K, C=1440K, D=1440K, E=8192K
ram: 63396 of 131072 b free
boot (0,0,1) 5888 b @ E600h
59K CP/M vers 2.2
A>dir
A: DDTZ COM : DUMP COM : ED COM : L80 COM
A: LOAD COM : LS COM : PIP COM : STAT COM
A: SUBMIT COM : XSUB COM : Z80ASM COM : CPM2GEN SUB
A: BOOT Z80 : BDOS22 Z80 : BIOS2 Z80 : WRSYS Z80
A>
Banked memory in CP/M 3.0 #
The STM32F411 has enough RAM to emulate an extra “bank” of 60 KB, for use by the more advanced CP/M 3.0. Here is a transcript which demonstrates how CP/M 2.2 can upgrade itself to 3.0:
cpm3: STM32F411xx @ 100 MHz (v7.0.2-68-g9d19d8c2)
sdhc 0, 3342 us, 4014080 blocks = 2007040 KB
[...]
ram: 1964 of 131072 b free
boot (0,0,1) 5888 b @ E600h
59K CP/M vers 2.2
A>cpm3
LDRBIOS3 v1.07 27-Jun-2010
CP/M V3.0 Loader V1.00 18-Jan-2002
Copyright (C) 1982, Digital Research
BNKBIOS3 SPR FC00 0300
BNKBIOS3 SPR EB00 0500
RESBDOS3 SPR F600 0600
BNKBDOS3 SPR BD00 2E00
61K TPA
CP/M vers 3.0 (banked)
A>dir
A: DDTZ COM : DUMP COM : ED COM : L80 COM : LOAD COM
A: LS COM : PIP COM : STAT COM : SUBMIT COM : XSUB COM
A: Z80ASM COM : CPM2GEN SUB : BOOT Z80 : BDOS22 Z80 : BIOS2 Z80
A: WRSYS Z80 : CPM3 COM : CPM3 SYS : CCP COM
A>
The space available for transient programs went from 59K to 61K, because most of the CP/M system code is now in a separate area of memory. CP/M 3.0 does a lot more behind the scenses in fact, caching disk blocks in RAM and hashing directory entries, both for improved performance.