
Intro
More nostalgia… A few weeks ago I bought the, RC2014 compatible, SC203 Modular Z180 Computer Kit for RC2014 kit on Tindie which uses the Zilog Z180, 512K fast static RAM and 512k ROM (loaded with ROMWBW). To this I added a Compact Flash Module as well for mass storage. With these components it’s possible to create a CP/M compatible system (just add a terminal) running on real hardware of that era.
Everything worked first time but when the time came to try to flash the Compact Flash card with different flavours of CP/M I hit a small snag which might be worth documenting here.
The whole build set up of ROMWBW is clearly very Windows oriented. Luckily someone (Curt Mayer) already did the hard work of writing the make files so that you can build the tools to create the different images on Linux and macOS as well. Just make sure you’re at the root of the ROMWBW directory and type:
make
Build error
in my case, the build stopped with an error… Going through the console output I found the root cause of this error:
/usr/bin/ld: prtable.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: uz80as.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: targets.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: z80.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: gbcpu.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: dp2200.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: i4004.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: i8008.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: i8048.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: i8051.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: i8080.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: mos6502.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
/usr/bin/ld: mc6800.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: multiple definition of `verbose'; main.o:/home/koen/Documents/Projects/RC2014/RomWBW/Tools/unix/uz80as/uz80as.h:11: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:59: uz80as] Error 1
It could be that this error doesn’t happen with older versions of ld
(I’m using: GNU ld (GNU Binutils) 2.35). Luckily there is a quick
work around for this problem is.
The problem is in the .../RomWBW/Tools/unix/uz80as/uz80as.h
header file
on line 11:
int verbose;
Which means that every source code file that includes this header file
will create a global variable with the name verbose
. There are 13
files that include this header file. There would thus be 13 global variables
created with the same name. Some linkers will not bother with this and
might just issue a warning. Other linkers might be more picky (as in my
case) and generate an error.
To work around this, change this line to:
static int verbose;
The addition of static
will limit the visibility of the verbose
variable to the source code file which it includes. Effectively making
this a local variable instead of a global variable. This might not be the
correct fix but it helps to get everything build and I didn’t discover any
issues with the code that is compiled/linked in this way.
Copying the images to a CF card
Now that we have our images, it’s time to flash them on our Compact Flash
card. Unfortunately there is not much documentation on how to accomplish
this on Linux/macOS other than a reference to use the dd
command.
Below is an explanation how I flashed my CF cards on a Linux PC using dd
.
Find out the mount point the CF card reader with the ls command
On most *nix OS’s, USB card readers are mounted under /dev
as e.g.
sda
, sda1
, sdb
, etc.
This is what I see when I issue an ls /dev/sd*
command without a card
reader attached:
$ ls /dev/sd*
/dev/sda /dev/sda1
This is what I see when I issue an ls /dev/sd*
command with the card
reader attached:
$ ls /dev/sd*
/dev/sda /dev/sda1 /dev/sdb
From which we can conclude that we have to write our image to /dev/sdb
.
Find out the mount point the CF card reader with the lsblk command
This is another way to determine the mounting point of your card reader. Chances
are high your Linux distribution has the lsblk
command installed as well
(otherwise it’s probably easily installed with the package manager of your Linux
distribution).
This is the output of lsblk
on my computer (with the card reader attached
and with a CF card inserted):
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 161,4M 1 loop /var/lib/snapd/snap/gnome-3-28-1804/128
loop1 7:1 0 97M 1 loop /var/lib/snapd/snap/core/9665
loop2 7:2 0 96,6M 1 loop /var/lib/snapd/snap/core/9804
loop3 7:3 0 255,6M 1 loop /var/lib/snapd/snap/gnome-3-34-1804/36
loop4 7:4 0 55,3M 1 loop /var/lib/snapd/snap/core18/1885
loop5 7:5 0 55M 1 loop /var/lib/snapd/snap/core18/1880
loop6 7:6 0 54,8M 1 loop /var/lib/snapd/snap/gtk-common-themes/1502
loop7 7:7 0 62,1M 1 loop /var/lib/snapd/snap/gtk-common-themes/1506
loop8 7:8 0 160,2M 1 loop /var/lib/snapd/snap/gnome-3-28-1804/116
sda 8:0 1 931,5G 0 disk
└─sda1 8:1 1 931,5G 0 part /media/backup
sdb 8:16 1 123M 0 disk
nvme0n1 259:0 0 894,3G 0 disk
├─nvme0n1p1 259:1 0 300M 0 part /boot/efi
├─nvme0n1p2 259:2 0 859,4G 0 part /
└─nvme0n1p3 259:3 0 34,6G 0 part [SWAP]
I know that my CF card is 128 MByte in size which maps to sdb
as well.
Writing the image with dd
Now that we know the mounting point (destination) of the card reader we use,
we can flash an image. For this we use the dd
command.
The basic syntax for dd
is as follows:
dd if=sourcePath of=destinationPath bs=SIZE
Assume our terminal is in the same directory as where the images are stored.
Then we can use the ls
command to list the available images:
$ ls -l hd*
-rw-r--r-- 1 koen koen 51118080 4 sep 14:40 hd_combo.img
-rw-r--r-- 1 koen koen 8519680 4 sep 14:40 hd_cpm22.img
-rw-r--r-- 1 koen koen 8519680 4 sep 14:40 hd_cpm3.img
-rw-r--r-- 1 koen koen 8519680 4 sep 14:40 hd_nzcom.img
-rw-r--r-- 1 koen koen 8519680 4 sep 14:40 hd_ws4.img
-rw-r--r-- 1 koen koen 8519680 4 sep 14:40 hd_zpm3.img
-rw-r--r-- 1 koen koen 8519680 4 sep 14:40 hd_zsdos.img
Assume we want to flash the big hd_combo
image then we can use the following
command line. Note I didn’t specify the BS
(Block Size) which means BS
will
be using the default value of 512 bytes (you can specify a bigger value if
you want the flashing to be faster):
sudo dd if=hd_combo.img of=/dev/sdb
Which gives as output:
$ sudo dd if=hd_combo.img of=/dev/sdb
[sudo] password for koen:
99840+0 records in
99840+0 records out
51118080 bytes (51 MB, 49 MiB) copied, 12,5086 s, 4,1 MB/s
Your CF card is flashed now and ready to be used in your RC2014 system. Enjoy!