The precursor to DOS
Before DOS, CP/M, the Control Program for Microcomputers, laid the groundwork for modern operating systems.
When we think of operating systems (OSs) today, we assume that we’re running lots of concurrent processes on a machine, and the OS is responsible for fairly distributing resources (e.g., processor time and memory) to those processes. We may also think about the collection of hardware drivers that comes with the OS and lets us run software that prints on ink jet and laser printers, connects to the Internet via network adapters, and embeds videos from an internal or external webcam – all without containing any specific code for all those peripherals. Applications just assume that some generic device is available, and they ask the OS to send page layout data to a printer, data packets to a server, or fetch an image from the camera. The OS then must know how to talk to the specific devices that are connected to the machine.
It has not always been like this: Back in the days of MS-DOS and PC-DOS, the operating system provided a filesystem (a way to find files on a floppy or hard disk drive) as well as access to the keyboard and the video card’s text mode memory area, and then all the rest was up to the application. For example, Figure 1 shows a step in the installation of Microsoft Word 5.5 for MS-DOS, which lets you pick one of roughly 350 printer drivers. Either your printer was supported by one of those drivers, or the printer came with a driver floppy disk that contained a Word driver. As a last option, many otherwise unsupported printers offered an Epson FX or HP LaserJet compatibility mode so that you could at least print simple text documents.
As there was no multitasking, DOS did not have to assign CPU time or memory to a program. Instead, after loading a program from disk, DOS gave that program complete control over the machine.
But MS-DOS was not the first operating system that supported a huge ecosystem of compatible computers from various hardware makers. Also, MS-DOS was not designed from scratch. Instead, it reused and improved many concepts from a predecessor: The CP/M operating system. CP/M was used on many Intel 8080 or Zilog Z80 based 8-bit computers in the 1970s and 1980s, typically for office applications such as the WordStar text processor (Figure 2) or the Microsoft Multiplan spreadsheet program, an early Excel predecessor.
BIOS, BDOS, CCP
Digital Research designed CP/M to be highly portable. There are three layers that are loaded in order, and each one depends on only the previous layer: the Basic Input/Output System (BIOS), the Basic Disk Operating System (BDOS), and the Console Command Processor (CCP).
First the BIOS provides raw access to the machine. For example, it implements READ
and WRITE
functions that read a sector from a disk drive. Older CP/M versions (up to 2.x) worked with a fixed sector size of 128 bytes, whereas CP/M 3 (also known as CP/M Plus) introduced a Disk Parameter Block (DPB) that declared the sector size. The BIOS can also read keyboard presses and write to the screen via its CONIN
and CONOUT
functions. This is the part of CP/M that needs to be rewritten from scratch (or at least modified) whenever the system is ported to a new platform: Different machines will use different memory areas for video memory. Depending on the graphics chip, writing a character to the screen could be as easy as putting an ASCII code in the right memory address, or it could require rendering that letter from a font definition and updating pixels on a graphical screen. Similarly, reading or writing a disk will mean simple tasks for an older machine that only supports floppy disks, and it might be more complex when there is a hard disk controller.
The BDOS provides higher level file operations and other I/O. For example, an application can call BDOS functions that will open a file and then read or write chunks of arbitrary size from or to that file. BDOS translates each function call into a series of BIOS function calls that will lead to the desired effect. Many of the BDOS functions were later also implemented as MS-DOS INT 21h functions. Table 1 shows a comparison of some of those functions. This level of structural compatibility simplified the process of porting a CP/M application to MS-DOS.
No. |
BDOS functions |
MS-DOS INT 21h functions |
0 |
System reset |
Program terminate |
1 |
Console input |
Character input |
2 |
Console output |
Character output |
3 |
Auxiliary (Reader) input |
Auxiliary input |
4 |
Auxiliary (Punch) output |
Auxiliary output |
5 |
Printer output |
Printer output |
6 |
Detect memory size |
Direct console I/O |
7 |
Get I/O byte |
Direct console input without echo |
8 |
Set I/O byte |
Console input without echo |
9 |
Output string |
Display string |
10 |
Buffered console input |
Buffered keyboard input |
11 |
Console status |
Get input status |
12 |
Return version number |
Flush input buffer and input |
13 |
Reset disks |
Disk reset |
14 |
Select disk |
Set default drive |
15 |
Open file |
Open file |
16 |
Close file |
Close file |
17 |
Search for first |
Find first file |
18 |
Search for next |
Find next file |
19 |
Delete file |
Delete file |
20 |
Read next record |
Sequential read |
21 |
Write next record |
Sequential write |
22 |
Create file |
Create or truncate file |
23 |
Rename file |
Rename file |
The CCP is what we call a shell today. It automatically starts at the end of the quick boot process, and it will typically stay in memory all the time.
When comparing the CP/M boot process with the DOS boot process, they do both use a BIOS on the lowest level of code, but where all of CP/M’s BIOS needs to be loaded from a system floppy disk, IBM-compatible PCs store parts of the BIOS in a ROM chip, and other parts in the IO.SYS
file. Thus, the the BIOS/BDOS/CCP layers roughly correspond to BIOS (ROM and IO.SYS
), MSDOS.SYS
, and COMMAND.COM
on MS-DOS.
Just like COMMAND.COM
, the CCP has a few built-in commands, for example DIR
for listing the drive contents and DIRSYS
(a variant that lists hidden system files), but in most cases executing a command will mean loading a program file from the disk: CP/M will keep it in the system’s largest memory area, the Transient Program Area (TPA). It’s called transient because once a program exits, that area will be freed and reused by the next program that is started.
Flat Hierarchies
One of the concepts that Microsoft initially copied from CP/M was the filesystem, which is very visible in the two systems’ filename conventions. Both use 8.3 filenames, where a filename can be up to eight characters long, followed by a dot and a file extension (such as .COM
) of up to three characters. For example, the CCP file is CCP.COM
(in CP/M Plus, it is hidden, so it will only show up when using DIRSYS
). Figure 3 shows a hexdump of the directory region of a CP/M floppy disk containing the WordStar program. The structure is pretty simple: The filename is followed by a list of block numbers. If the file is too long to fit all block numbers in one directory entry, another one with the same filename is generated. In the image, the files WSMSGS.OVR
, WSOVLY1.OVR
, and C10CPM3.EMS
use more than one entry, marked red in the screenshot. Most of the example entries have file extensions with unreadable first letters. Bit 7 of those bytes is set, which is CP/M’s way of saying that this file is read-only.
You won't find further directories on a CP/M disk, since the filesystem is flat. You can only structure a disk by storing files in “user areas” (numbered from 0
to 15
). At the CCP prompt, you can change the active user number with the USER
command. DIR
and other commands or programs will then only see files in that user area (Listing 1). Some CCP versions let you use a shortcut to change the user by typing 3:
instead of USER 3
.
Listing 1: DIR Command
01 A>dir
02 A: TERMINFO COM : ECHO COM : EXIT COM
03 A: EXPORT COM : IMPORT COM : SUBMIT COM
04 [...]
05 A:>user 1
06 1A>dir
07 No File
08 1A>
Another concept that DOS copied from CP/M is the use of drive letters. Disk drives are numbered A, B, C, and so on. It is possible to prefix a filename with a drive letter and a colon so that you can open B:DOCUMENT.TXT
from the second disk even while you’re working on drive A:
. Type A:
or B:
to change the working drive.
Disk Formats
One of the problems with CP/M was that every machine vendor would come up with their own, incompatible variation of the filesystem. So, while many machines used the same 5.25-inch floppy drives (or 8-inch drives before that), reading or writing a disk from a different CP/M machine was likely to fail. The computer simply would not recognize the floppy disk as properly formatted. Here’s a quote from the manual of the CP/M-to-DOS disk converter 22DISK: “All of the 22DISK utilities make use of a common interface to specify the format of CP/M diskette to be used. Over 200 different formats are provided with 22DISK and ‘custom’ definitions may also be written.”
Popular Applications
Most commercial CP/M programs either helped in the office – with word processors, spreadsheet, and database applications such as WordStar, Multiplan, or dBase – or they were programming language compilers and interpreters such as Turbo Pascal, Microsoft COBOL, or HI-TECH C. Figure 4 shows some of these applications running in the YAZE-AG emulator (which stands for “Yet Another Z80 Emulator by AG”) in a cool-retro-term window with colors set to mimic a classic amber monitor. Some of the commercial 1980s CP/M programs are available via the Retrocomputing Archive website.
But CP/M offered more than commercial software. A lot of public domain programs were available via CP/M user groups or – if you had the necessary hardware – dial-up mailboxes. The Classic Computing CP/M Archives contain various collections, including 90 CP/M User Group software distribution disks (Figure 5).
Because CP/M is typically used in text mode only, games are rare. Graphics System eXtension (GSX), a graphics library for CP/M computers, was introduced with CP/M Plus, and it evolved into the GEM desktop environment for different platforms, such as the Atari ST and PC-compatible computers running DOS Plus, but GSX was not intended for gaming. Many computers that can run CP/M will boot into a non-CP/M mode from which games can be started. For example, the Commodore 128 and the Amstrad CPC664 and CPC6128 can run a lot of graphical arcade games. Applications that do use a graphics mode are not portable to other systems. For example, Dr. Logo is a graphical Logo interpreter that can display the turtle graphics that pupils used to create while learning the educational Logo programming language.
Shell Scripts
With the CP/M Shell CCP, you can also do very basic shell scripting (with an emphasis on “very”). Simply write a sequence of commands into a text file with the file extension .SUB
and run it via the SUBMIT
command. The tool does not know loops, if-then-else statements, or other means of control flow. The CCP does, however, support input and output redirection to files, though that is much more complicated than what DOS and Unix-like systems use: You need to issue PUT
and GET
commands such as
PUT CONSOLE OUTPUT TO FILE LOGFILE.TXT
and then undo the redirection later. Script files are still useful because they can access command-line parameters, such as $1
, $2
, and so on, just like in a Bash shell script.
YAZE-AG Emulation
There are many ways to experience CP/M today. You can buy an old home computer (I recommend searching for an Amstrad CPC664/6128 or a Commodore 128 with a working floppy drive), try a modern retro computer (such as the ZX Spectrum Next, Figure 6) or simply run an emulator of an old computer.
If you don’t care about a specific kind of old machine, the easiest way to get a fully working CP/M system is to install YAZE-AG. Go to their website and grab the latest release 2.51.3.
On Windows, go to http://-yaze‑ag.-de/. In the Download section, click on the Standalone Binaries for Windows link. On the new page, download the installer program yaze-ag-2.51.2-x86_64bit-generic.exe
and run it. It will dump a lot of files in C:\yaze-ag-2.51.2-64Bit
and add a new submenu entry, YAZE-AG-2.51.2, to the Start menu. You can then start the emulator via YAZE-AG-2.51.2. As a first step in the emulator, you may want to change the font size; at least on our test system, the text was tiny and unreadable. Ctrl++ will increase the font size, but it does not update the window size. Once you have settled on a font size, change the window size manually. In the upper left corner, you will see the text dimensions, which should be set to 80x25.
On Linux, you will need a development environment (make
and a C compiler). Grab the source archive yaze-ag-2.51.3.tar.gz
, unpack it, delete Makefile
, and rename one of the Makefile-*
files to Makefile
(e.g., on 64-bit Linux, use Makefile_linux_64_intel_corei7
). After generating the binary with make
, you can start it via ./yaze
.
On macOS, in principle, you should be able to follow the same steps as on Linux, though with one of the Solaris Makefiles. However, while this worked well some time ago with YAZE-AG 2.50.0, compilation on macOS failed for the current 2.51.3 version. If you’re a Homebrew user, use
brew install yaze‑ag
and run yaze from the command line; this will also launch version 2.51.3. To end the CP/M session, type E
(for exit) at the CCP prompt and press Enter.
When YAZE-AG boots the CP/M system, it displays various informative messages. There are several floppy disk images that you can integrate into the system by modifying the .yazerc
file or by manually running a mount
command at the CCP prompt. Simply type
sys mount X Path
where X
is a free drive letter and Path
is the full path to a .ydsk
file (including the extension). For example, on a Linux or macOS system, you would type:
sys mount h /home/esser/Download/Retro/yaze‑ag‑2.50.0‑rc1/test‑utils‑1.10.ydsk
On a Windows PC, type:
sys mount h \yaze‑ag‑2.51.2‑64Bit\bin\disks\test‑utils‑1.10.ydsk
Accessing the built-in disks is also possible via shorter relative pathnames such as disks/test‑utils‑1.10.ydsk
. YAZE-AG shows the necessary commands in one of the boot screens: On Linux and macOS you only need the filenames (without mentioning the disks/
directory).
If successful, you can then change into the freshly mounted drive (by typing H:
) and try to start programs. You’re not restricted to the disk images that are part of the YAZE-AG package, though building your own images requires a few steps (see the box “Building YAZE-AG Disk Images”). If you only want to transfer a single file from your host system to CP/M (or vice versa), you can use the W
(write) and R
(read) commands. Run them without arguments to see how they work.
The YAZE-AG package contains a tool called
cdm
(the CP/M Disk Manager) that lets you create empty .ydsk
image files and populate them with files. However, it only adds one file at a time, and you need to provide the full path to the source file and the desired CP/M filename.I’ve written a tiny shell script that you can run from a Bash shell (on macOS or Linux) that expects two arguments: an output image file name (ending in
.ydsk
) and a directory path. It will then add all files from that directory to the new disk. Save it as mkyazefs
in a folder that’s in your $PATH
, make it executable, and try it out. I got WordStar 4 to run by unpacking the WS4.ARK
archive from the Retrocomputing Archive with these steps:wget http://www.retroarchive.org/cpm/text/WS4.ARK
unar WS4.ARK # requires unar tool
mkyazefs WS4.ydsk WS4
ARK is an old, ZIP-like archive format, and you can install the Unarchiver (
unar
), which is available in many package repositories (as well as in Homebrew for macOS), to handle many “old and obscure formats,” including ARK.Here’s the shell script for
mkyazefs
:#!/bin/bash
# mkyazefs imagefile.ydsk folder
# (c) 2023 esser.hans‑georg@fh‑swf.de
FOLDER="$2"
IMAGE="$1"
{
echo create "${IMAGE}"
echo mount a "${IMAGE}"
cd "${FOLDER}"
for file in *; do
echo "cp u:${PWD}/${file} a:${file}"
done
echo "dir"
echo "quit"
} | cdm
Alternatives
As an alternative, you could try z80pack (no longer available) which is also available as a Docker image if you like working with containers. In order to launch CP/M in a container, type:
docker run ‑it ‑‑rm dlandon/z80pack
cd /root/z80pack/cpmsim
./cpm3
The first of those three commands will take some time because the image itself is rather small, but once you start a container, its start-up sequence downloads about 100 files. To leave the CP/M emulator, type bye
, which brings you back to the container’s Bash shell from where you can start another CP/M session or leave and delete the container with exit
.
A very comfortable option is the Retro Virtual Machine emulator, which can emulate the Amstrad CPC series and a few other machines. After installing it on Windows, Linux, or macOS, simply start a fresh CPC (model 6128) and boot from a CP/M disk that you can find inside the TOSEC - Amstrad CPC collection on the Internet Archive. When you unpack that archive, extract the four ZIP files named Amstrad CPC[TOSEC]/Amstrad CPC-Applications-[DSK](TOSEC-v2011-08-31_CM)/CPM Plus v1.0(1985)(Amstrad)(Disk 1 of 4)[cpm version].zip
(as well as Disk 2, Disk 3, and Disk 4). They contain .dsk
images that work with Retro Virtual Machine.
Drag and drop the first CP/M disk onto the running Amstrad CPC and type |cpm
at the BASIC prompt to boot it (Figure 7). If you try out both YAZE-AG and Retro Virtual Machine, note that the floppy image formats (.ydsk
and .dsk
) are not compatible.
Later Developments
Digital Research had also ported CP/M to 16-bit architectures. Those ports were called CP/M-86 (for the Intel 8086) and CP/M-68K (Motorola 68000). The 8086 version was also available as a multitasking system named MP/M-86, an ancestor to Concurrent CP/M-86, DOS Plus, and DR-DOS (a direct competitor to MS-DOS).
Outside Digital Research, interest in an open source version of CP/M led to the development of CP/Mish, an open source clone of CP/M 2.2, and other CP/M compatible systems.
However, just last year DR-DOS, Inc.’s president Bryan Sparks clarified that they are the legal successor of CP/M developer Digital Research and grant a right to “use, distribute, modify, enhance, and otherwise make available in a nonexclusive manner CP/M and its derivatives”. So it’s ok to try the original CP/M, even if you don’t own a licensed copy. Application disk images may still be protected under copyright or other laws, but with the Internet Archive hosting quite a lot of these applications it seems that interest in generating revenue from software products of the 1980s has dwindled.
Have fun with the CP/M ecosystem – even if the CP/M shell is not the most comfortable user environment.