The CP/M-based Research Machines 380Z/480Z series were a competitor to Acorn's BBC Micro for the UK schools market in the 1980s. The RM machines were popular enough initially that quite a bit of educational software got released on both platforms. While I've never used an RM CP/M machine myself, I'd acquired a box of (what I thought were) RM disks in the mid-90s, and a bit of searching revealed the 380Z group who were trying to build a comprehensive collection of RM software.
Imaging RM disks
From a message on the 380Z mailing list, I knew RM used several different 5.25" disk formats:
- 380Z MDS or 480Z SD: 40 track, single density, 16x128 (track 0-2 for CP/M, track 3 is the directory, 72k data)
- 480Z MD: 40 track, double density, 9x512
- 480Z MQ: 80 track, "quad density" (?), 9x512
So the first step was to image all the disks I had using dumpfloppy. Let's walk through what dumpfloppy's output looked like for the SPA ProText disk:
Probe 2.0: MFM-250k 9x512: 1 2 3 4 5 6 7 8 9
Probe 2.1: unknown data mode
Single-sided disk
It's tried to read the second side, and found the sectors claim to be on logical surface 0, so the two sides of the disk are separate filesystems. (It's also checked the logical cylinder numbers to see if we're trying to read a 40 track disk in an 80 track drive, but we aren't.)
Since the logical sector numbers are in order, there was no interleaving used when formatting the disk.
Probe 0.0: FM-250k 16x128: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Read 0.0: 1* 2* 3* 4* 5* 6* 7* 8* 9* 10* 11* 12* 13* 14* 15* 16*
It probed side 0 track 0 to find the encoding and logical sector numbers, then read the track successfully first time.
Read 1.0: 1- 2- 3- 4- 5- 6- 7- 8- 9- 10- 11- 12- 13- 14- 15- 16-
Probe 1.0: MFM-250k 9x512: 1 2 3 4 5 6 7 8 9
Read 1.0: 1* 2* 3* 4* 5* 6* 7* 8* 9*
Read 2.0: 1* 2* 3* 4* 5* 6* 7* 8* 9*
Read 3.0: 1* 2* 3* 4* 5* 6* 7* 8* 9*
Reading side 0 track 1 as the same format didn't work, so it probed the format again; it's changed. It then read tracks 1 to 33 successfully first time...
Read 34.0: 1+ 2+ 3+ 4? 5+ 6+ 7+ 8+ 9+
Probe 34.0: sector sequence did not repeat consistently
Probe 34.0: MFM-250k 9x512: 1 2 3 4 5 6 7 8 9
Read 34.0: 1+ 2+ 3+ 4? 5+ 6+ 7+ 8+ 9+
Read 34.0: 4?
Read 34.0: 4*
Read 35.0: 1* 2* 3* 4* 5* 6* 7* 8* 9*
Track 34 had an error on one sector on the first read, so it re-probed the track and tried again. It's faster to read the whole track at once if no sectors have errors, so dumpfloppy tries that first, but it'll then reread any missing sectors individually. Sector 4 read successfully on the fourth try, and then the rest of the disc (up to track 39) read successfully first time.
So this disk has track 0 as FM 16x128, and tracks 1-39 as MFM 9x512, which sounds like the MD format above, assuming track 0 is reserved (e.g. a bootblock in a common format).
To cut a long story short, I ended up with:
- 15 "SD" disks: track 0-39 FM 16x128.
- 11 "MD" disks: track 0 FM 16x128, track 1-39 MFM 9x512.
- No "MQ" disks, but I was able to find one in the 380Z group collection: track 0 FM 16x128, track 1-79 MFM 9x512 (so by "quad density" they just mean "80 track").
Both formats could be either single- or double-sided; when double-sided, the two surfaces were separate filesystems. Some disks didn't have any data on the first three tracks (and one didn't even have them formatted). In general, my 40 track drive did a better job of reading these 40-track disks than my 80 track drive.
Some of the RM-branded SD disks (e.g. "Extended BASIC version 6 for 380Z Disc Systems 1/2") were actually formatted with 17x128 FM sectors, numbered 0 to 16, but with sector 0 empty. This wouldn't have made a difference to the RM disk controller, and I have to wonder if it was intentional or an error in the duplication process. I added an option to dumpfloppy to ignore the 0 sectors.
Imaging Alphatronic disks
However, eight of the disks turned out to be in a third format, which dumpfloppy reported as follows:
Double-sided disk
Probe 0.0: MFM-250k 16x256: 1 2 3 4 9 10 11 12 5 6 7 8 13 14 15 16
Read 0.0: 1* 2* 3* 4* 9* 10* 11* 12* 5* 6* 7* 8* 13* 14* 15* 16*
Probe 0.1: MFM-250k 16x256: 1 2 3 4 9 10 11 12 5 6 7 8 13 14 15 16
Read 0.1: 1* 2* 3* 4* 9* 10* 11* 12* 5* 6* 7* 8* 13* 14* 15* 16*
Read 1.0: 1* 2* 3* 4* 9* 10* 11* 12* 5* 6* 7* 8* 13* 14* 15* 16*
Read 1.1: 1* 2* 3* 4* 9* 10* 11* 12* 5* 6* 7* 8* 13* 14* 15* 16*
...
This is one filesystem with two logical surfaces, and was formatted with
logical sector interleaving enabled.
Running strings
across the resulting disk images found:
56K CP/M 2.2 / 3.01 alphatronic PC Serial number 00000
So these eight disks, all with handwritten labels, are for a Alphatronic PC; a different kind of CP/M machine.
Extracting the data
cpmtools provides utilities
for working with CP/M filesystems (as mtools does for MS-DOS).
Its diskdefs
configuration file gives the disk geometry and filesystem
parameters for many kinds of CP/M disks, and it includes an alpha
configuration for Alphatronic disks.
The cpmtools documentation also includes a good overview of how CP/M
filesystems work, which you'll need to read if you want to add a new
one.
I can examine one of the Alphatronic disks by first making a flat image
using imdcat
:
$ imdcat -o tmp.img micro-prolog.imd
$ cpmls -f alpha tmp.img
0:
b.log
deftrap.log
editor.log
errtrap.log
exptran.log
...
$ cpmcp -f alpha tmp.img 0:simple.log .
$ cat simple.log
query-mod
( "FIND:" "?VARTRANS?"
APPEND CONS ON
Parse-of-S Parse-of-ConjC Parse-of-SS Parse-of-Cond Parse-of-CC ...
Configuring cpmtools for RM filesystems
However, there are no diskdefs
for the RM formats yet.
We know the geometry, and can work the other parameters out by looking
at the filesystem.
For an SD disk, using an RM original disk as a reference...
Skew: looking at the directory, the first entries are at C3 H0 S0, then the next at S3, then S6, S9, S12, S15 etc. The same applies for text files later on the disk (which you can reasonably assume will have been written sequentially). So the skew is 3 — the next sector of data is always three logical sectors after the previous one.
Block size: compare a directory entry to the corresponding data.
000034e0 00 52 45 4c 45 41 53 45 20 d4 58 54 00 00 00 0e |.RELEASE .XT....|
000034f0 3a 3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |:;..............|
The second row of numbers are the disk blocks in which RELEASE.TXT
is
stored: blocks 0x3a and 0x3b.
From inspection of the data, the start of the file is at C32 H0 S0, and
the end at C32 H0 S7, with S10 and S13 immediately afterwards (skew 3,
remember) being empty.
So it looks like a block is half a track — 8 * 128 = 1024 bytes.
The first three tracks of the disk are reserved, so block 0x3a will be
stored on track 3 + (0x3a / 2) = 32 — which matches.
Maximum number of directory entries: we know from the description above that the entire of track 3 is the directory, and each entry is 32 bytes long, so 16 * 128 / 32 = 64 entries. Looking at the disks, they do indeed seem to fill the whole of track 3 with 0xe5 (the unused marker) when the directory is empty.
We can go through the same process with an MD disk: skew is 5, block size is 1024, directory size is 64. For MQ disks, skew is 5, block size is 1024, directory size is 128. All three formats have 3 reserved boot tracks, and use CP/M 2.2.
Turning a MD/MQ RM disk into a flat image for cpmtools needs some care,
because the first (FM) track contains less data than the later (MFM)
ones, which messes up the alignment.
To solve this, I gave imdcat
options to select the range of tracks to
extract:
$ imdcat -c2: -C0: -h0 -o tmp.img spa-wordsquare.imd
$ cpmls -f rm-dd tmp.img
0:
animals.w
wsquare.com
Here is a diskdefs file for the three RM formats. These are now included in cpmtools as of version 2.18.
Emulating CP/M
I'm not sure that any of the software would be terribly exciting even if I had an RM with a graphics board to run it on ("COMANEX Management Challenge", anyone?). Nonetheless, the command-line CP/M tools, including the earlier version of CBASIC, run happily under z80pack's CP/M 2:
The "ZASM-ZSID" disk contains a patch to make RM's ZASM and ZSID tools run on other CP/M systems, by preserving the IX register during BDOS calls. This also works in z80pack: