The virtual floppy jukebox Apr 2017

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…

Weblog © Jean-Claude Wippler. Generated by Hugo.