Times sure have changed: a fingernail-sized 2 GB µSD card of a few dollars can now easily store over a thousand 1.44 MB floppy disk images, while being quicker than the fastest hard drive from the glory days of CP/M (and MS-DOS, for that matter).
A lot of software has been created for CP/M, most of it now relegated to historical archives, such as this one. These were the early days of modems, file exchanges, and BBS’es. It was also the main goal behind the EZ-Retro: being able to dabble in that old 8-bit world of computing.
Which brings us to the last major feature of this project: access to a virtually unlimited amount of storage from CP/M, to explore collections such as the 1994 Walnut Creek CP/M CDROM.
The idea is to organise everything you might want to explore into a set of 1440K floppy images - from the comfort of a modern laptop with internet access and lots of storage - and then copy these disk images as files to a FAT16-formatted µSD card. The utilities for this can be found in the cpmtools package, which works on all mainstream platforms. With a bit of scripting, it’s fairly simple to automate the process of creating suitable floppy disk images.
Here is a small example of such a personal collection:
$ ls -l
total 4704
-rw-r--r-- 1 jcw staff 464896 Mar 29 20:48 BASIC.105
-rw-r--r-- 1 jcw staff 698368 Mar 29 20:46 FORTH.104
-rw-r--r-- 1 jcw staff 770048 Mar 29 20:43 NZCOM.103
-rw-r--r-- 1 jcw staff 782336 Mar 29 18:08 SIMHCPM2.100
-rw-r--r-- 1 jcw staff 610304 Mar 29 18:08 STARTKIT.101
-rw-r--r-- 1 jcw staff 75776 Mar 29 18:08 TRYOUT.099
-rw-r--r-- 1 jcw staff 210944 Mar 29 20:50 TURBO.106
-rw-r--r-- 1 jcw staff 1196032 Mar 29 18:08 ZCPR33.102
On a few of these disks, files have been placed in more than one “user area” (CP/M’s way of grouping files on a disk). As you can see, most of these 1440K images are far from fully loaded.
All files have been copied to a 2 GB µSD card, along with three images of empty
disks, called d.img
, e.img
, and f.img
. These are the default floppies,
attached by the Blue Pill on startup.
What we need now, is a way to switch floppies. The most convenient option would be the ability to switch them from inside CP/M, because then we can stay in the CP/M mindset, and run a command to map another file onto a specific drive. A bit like swapping physical disks!
This is what mapdrive.z80 does: it takes an argument, specifying the drive on the CP/M side to change (one of D:, E:, or F:) and the file on the Blue Pill side to “map” to it:
A>b:mapdrive e:turbo.106
A>dir e:
E: CMDLIN PAS : LISTER PAS : MC-MOD00 INC : MC-MOD01 INC
E: MC-MOD02 INC : MC-MOD03 INC : MC-MOD04 INC : MC-MOD05 INC
E: MC COM : MC HLP : MC PAS : MCDEMO MCS
E: PIP COM : READ ME : TINST COM : TINST DTA
E: TINST MSG : TURBO COM : TURBO MSG : TURBO OVR
A>
Keep in mind that D: is implemented as read-write drive, but E: and F: are
always read-only. This is intentional: that way, we do not need to worry about
messing up disks with carefully selected file collections, and can simply copy
stuff off them if we want to change things. Only drive D: is writable, and is
probably best left mapped to its default d.img
file on the SD card.
Internally, this is implemented as yet another request sent over SPI to the Blue
Pill. As it so happens, the request format matches the way CP/M parses file
names given on the command line, so mapdrive.z80
is a very small and simple
assembly language utility.
The 12-byte disk map request packet looks like this:
Bytes | Content | Notes |
---|---|---|
0 | $10 + disk# | only disks 3..5 are accepted, i.e. D: E: F: |
1..11 | 8.3 filename | space-padded and without the dot separator |
And the corresponding single-byte disk map reply is:
Bytes | Content | Notes |
---|---|---|
0 | error code | always zero for now |
There’s no error checking, so for the time being, you have to be careful and call mapdrive with a valid (existing) filename. There is also no way at the moment to list what’s on the SD card.
In fact, it’s much simpler to do that on MacOS or Linux, using the flexibility of the Unix tools and pipes. The following command will create a multi-column listing, sorted by extension:
$ ls | sort -t. -k 2,2 -k 1,1 | pr -5tFl50 | tr '\f''\n'
TRYOUT.099 STARTKIT.101 NZCOM.103 BASIC.105
SIMHCPM2.100 ZCPR33.102 FORTH.104 TURBO.106
$
(not a very good example, but it’ll become more useful with a large number of floppy images)
The virtual disk code is in
vdisk.fs
on GitHub. It extends PokeMon with vx
and vy
commands, which start up the
Blue Pill with either a hard or soft reset of the eZ80, respectively. To burn
this code into a Blue Pill pre-loaded with the USB console version of Mecrisp
Forth, in Folie:
<<<core>>>
compiletoflash
!s vdisk.fs
Using EZ-Retro is now a matter of inserting a µSD card, powering it up, and
typing “vy
“:
[connected to /dev/cu.usbmodem372C6601]
vy blocks: 3919
label: FATCPM format: FAT16 capacity: 4013853
FATCPM 28 0 0
SPOTLI~1 12 2 0
TRYOUT 099 20 92 75776
NZCOM 103 20 383 770048
SIMHCPM2100 20 398 782336
STARTKIT101 20 420 610304
TURBO 106 20 303 210944
BASIC 105 20 236 464896
FORTH 104 20 335 698368
ZCPR33 102 20 346 1196032
E IMG 20 108 1474560
D IMG 20 28 1474560
F IMG 20 248 1474560
A>
With this setup, we can now try out a lot of CP/M software. Such as ZCPR, a CP/M enhancer from the 1980’s, which offers considerably more features on the command line:
A>d:
D>nzcom
NZCOM Version 1.2 System Loader for Z-Com v2.0
Copyright (C) 1987-88 Alpha Systems 001-11255
Open D0:NZCOM.LBR
Input buffer start 2B00
Read buffer start 2C00
Write buffer start 4C00
Loading D0:NZCOM.ZCM
Loading D0:NZCOM.LBR|NZCPR.ZRL for CD00 at 4C00
Loading D0:NZCOM.LBR|NZDOS.ZRL for D500 at 5400
Loading D0:NZCOM.LBR|NZBIO.ZRL for E300 at 6200
Loading D0:NZCOM.LBR|NZIOP.ZRL for E400 at 6300
Loading D0:NZCOM.LBR|NZRCP.ZRL for EA00 at 6900
Loading D0:NZCOM.LBR|NZFCP.ZRL for F300 at 7200
Loading D0:NZCOM.LBR|NZCOM.NDR for F580 at 7480
Loading D0:NZCOM.Z3T for F800 at 7700
Writing A0:NZCOM.CCP
Booting NZ-COM...
READY...
D0>sdz /a
Drive D0 Files: 45/236k Free: 250k
-TESTVOL.123 0k : HEXSAVE .COM 2k : NZCOM .ENV 2k : STAT .COM 6k
ALIAS .CMD 4k : IF .COM 6k : NZCOM .LBR 14k : SUBMIT .COM 2k
ARUNZ .COM 8k : LDIR .COM 2k : NZCOM .Z3T 2k : XMODEM .CFG 2k
ASM .COM 8k : LOAD .COM 2k : NZCOM .ZCM 2k : XMODEM .COM 4k
DDT .COM 6k : LS .COM 4k : NZCPM .COM 4k : XSUB .COM 2k
DDTZ .COM 8k : LX .COM 4k : PIP .COM 8k : ZEX .COM 12k
DISPLAY .COM 2k : MAPDISK .COM 2k : SALIAS .COM 8k : ZEXALL .COM 10k
DOWNLOAD.COM 2k : MINIMAL .ENV 2k : SARGON .COM 16k : ZFILER .CMD 2k
DUMP .COM 2k : MINIMAL .ZCM 2k : SD .COM 6k : ZFILER .COM 16k
ED .COM 8k : MKZCM .COM 6k : SDZ .COM 6k :
EZFLASH .COM 2k : NZCOM .CCP 2k : SHOW .COM 12k :
FMT360 .COM 2k : NZCOM .COM 12k : STARTZCM.COM 2k :
Drive D1 Files: 49/928k Free: 250k
00-INDEX.TXT 4k : Z33DEBUG.LBR 16k : Z33PNOTE.0Z1 4k : Z3INS15 .LBR 10k
DESCRIPT.ION 2k : Z33ERR07.LBR 12k : Z33PNOTE.0Z2 4k : Z3INSTP .LBR 24k
FILES .BBS 2k : Z33FCP10.LBR 42k : Z33PNOTE.0Z3 6k : Z3KEY14 .LBR 66k
WILDCAT .TXT 2k : Z33FIX .001 6k : Z33RCP02.LBR 48k : Z3LIBHLP.LBR 42k
Z33-M80 .HOW 6k : Z33FIX .0Z1 4k : Z33TRC11.LBR 16k : Z3LOC .OBJ 2k
Z33-M80 .HZW 4k : Z33GCONF.TXT 52k : Z33TSS-C.LBR 108k : Z3LOC13 .LBR 8k
Z33-M80 .LBR 26k : Z33GCONF.TZT 26k : Z33UPD .DOC 18k : Z3LOC15 .OZJ 2k
Z33-TM2 .LBR 6k : Z33IF14 .LBR 34k : Z33UPD .DZC 8k : Z3TCAP26.LBR 18k
Z33-ZASM.LBR 8k : Z33LIB05.LBR 8k : Z33UTIL .LBR 28k : Z3TURKP2.LBR 34k
Z33ANOTE.001 2k : Z33MAKE .LBR 22k : Z33VER10.LBR 32k : Z3USER .LBR 26k
Z33ANOTE.002 12k : Z33PNOTE.001 6k : Z33ZASM .LBR 8k :
Z33ANOTE.0Z1 2k : Z33PNOTE.002 6k : Z34RCP10.LBR 78k :
Z33ANOTE.0Z2 6k : Z33PNOTE.003 12k : Z3CUBE11.LBR 10k :
D0>
Wanna play chess?
D0>sargon
DO YOU WANT THE ERROR BELL?(Y OR N):n
SARGON 2.1
BY
DAN AND KATHY SPRACKLEN
MODIFIED TO OPERATE UNDER
DIGITAL RESEARCH CP/M
BY
KEVIN LEAVELLE AND JIM HENDERSON
COPYRIGHT (C)1981 BY
HAYDEN BOOK COMPANY, INC.
ALL RIGHTS RESERVED
****** SARGON 2.1 ******
SELECT OPTIONS
NEW GAME, CHANGE BOARD OR EXIT? (G,C,X):g
PRINTER?(Y,N)N
YOUR COLOR? (B,W):B
LEVEL OF PLAY? (1-6):1
DISPLAY BOARD EVERY MOVE?(Y OR N)y
H G F E D C B A
1 WR WN WB WK WQ WB WN WR 1
2 WP WP WP WP WP WP WP WP 2
3 :: :: :: :: 3
4 :: :: :: :: 4
5 :: :: :: :: 5
6 :: :: :: :: 6
7 BP BP BP BP BP BP BP BP 7
8 BR BN BB BK BQ BB BN BR 8
H G F E D C B A
1 SARGON PLAYER
------ ------
1 E2-E4
H G F E D C B A
1 WR WN WB WK WQ WB WN WR 1
2 WP WP WP WP WP WP WP 2
3 :: :: :: :: 3
4 :: :: WP :: :: 4
5 :: :: :: :: 5
6 :: :: :: :: 6
7 BP BP BP BP BP BP BP BP 7
8 BR BN BB BK BQ BB BN BR 8
H G F E D C B A
1 SARGON PLAYER
------ ------
1 E2-E4 E7-E5
H G F E D C B A
1 WR WN WB WK WQ WB WN WR 1
2 WP WP WP WP WP WP WP 2
3 :: :: :: :: 3
4 :: :: WP :: :: 4
5 :: BP :: :: 5
6 :: :: :: :: 6
7 BP BP BP :: BP BP BP BP 7
8 BR BN BB BK BQ BB BN BR 8
H G F E D C B A
1 SARGON PLAYER
------ ------
1 E2-E4 E7-E5
2 G1-F3
H G F E D C B A
1 WR :: WB WK WQ WB WN WR 1
2 WP WP WP WP WP WP WP 2
3 :: WN :: :: :: 3
4 :: :: WP :: :: 4
5 :: BP :: :: 5
6 :: :: :: :: 6
7 BP BP BP :: BP BP BP BP 7
8 BR BN BB BK BQ BB BN BR 8
H G F E D C B A
[...etc...]
And that concludes this article series on the EZ-Retro project for now. A fantastic window into the past, from which so many things evolved that we now take for granted on the PC…