Patching An Old OS for the New Altair
I’ve really been enjoying the newly built Altair I described building from scratch in my recent posts. Many technologists can claim to have built their own computer, but for most that involved assembling components. It felt awesome to write and execute software on a computer I soldered together myself. Of course, this is nothing compared to those who design their own computer circuits, but I did get a small taste of that by modifying the memory card to work on the Altair’s front panel design.
Once I got the hardware together, its up to software to make the machine useful. I picked up programming the Intel 8080 instruction set well enough, and it wasn’t too hard to load software into the machine via the serial port with a bootstrap loader. But I found myself wanting read-write storage and an operating system to make it easier to load and save programs.
As demonstrated in my past posts, one didn’t have to use an operating system to use this computer; software could always talk directly to the hardware. For example, Microsoft’s original Altair Basic was coded to use the Altair’s original serial IO port address. If other IO cards were used, the software needed to be patched. This quickly got out of hand once other vendors came on the scene; the I/O options for the Altair might not match the I/O options for the Osborne or the Cromemco. The problems extended to other hardware devices too: all the new floppy drives on the market had different numbers of tracks, sectors sizes, and drive controllers. Software vendors couldn’t keep up with producing new versions for all the options out there. There was an entire cottage industry of people patching software for new models.
So the market was ripe for an operating system that would abstract away the hardware and allow software to run on all the machines out there using the same OS. Enter the Control Program/Monitor, or CP/M, later renamed to Control Program for Microprocessors, the original OS for the personal computer.
CP/M was written for the Intel 8080 processor, which also worked for the Z80 processor (purposely designed to be backwards-compatible with the 8080), covering the majority of the PC market in the late 70s and early 80s. Written by Gary Kildall of Digital Research, it made it easy for software developers to do IO to the console, printers, and tape punchers, but also abstracted away the floppy drive with a file system so programmers could use system calls to read and write files instead of knowing everything about the underlying hardware. Hundreds of thousands of microcomputers ran CP/M.
The business model was pretty straightforward: Digital Research would license CP/M to the hardware manufacturer, who would modify it to abstract away the specific hardware in use, and the hardware manufacturer would sell it with their system. But it was also common for third parties to license CP/M and then modify it for specific machines as well.
CP/M gave us many modern PC concepts, some of which are still used by Microsoft Windows today, such as naming drives after letters (A:, C:, etc). When Digital Research was delayed in making a version of CP/M for the 8086 processor, Seattle Computer Products made 86-DOS, built with all-new code but also cloning the CP/M programming interface. This OS was later bought by Microsoft and renamed MS-DOS.
A quick aside here: much has been made about Bill Gates offering to sell IBM an OS that Microsoft didn’t even have…but its important to remember that this was completely normal at the time. Microsoft was just offering to license Seattle Computer Product’s 86-DOS and modify it specifically for the IBM PC’s hardware, just as other companies did with CP/M all the time. The only difference here is that the IBM ended up being so big that Microsoft bought the rights to 86-DOS outright, renamed it MS-DOS, and the rest is, as we say, history.
But back to my Altair: the same reasons everyone else wanted an OS in the 70s also applied to my situation. I wanted an easier execution environment where I could program without having to worry about low-level IO and storage access. I also wanted to run many of the software programs available from that time. So I needed to get CP/M running on my Altair.
The problem: CP/M needs a floppy drive, and I didn’t have one. The original Altairs use 8" floppies, though 5.25" “mini” floppies were used later as well. Finding drives and floppy disks in good working condition is an issue, but with enough money and patience can be done. But I questioned the need for a floppy drive in the first place.
Other retro computing platforms have virtual floppy options, emulating floppy drives either in hardware or software, backed by either SD cards or by connecting to a modern PC over serial with software that serves up the chosen disk images. I’d used both with my Tandy Color Computer 3 with the CocoSDC and with DriveWire. Similar solutions are available for vintage Apple IIs, Macintosh, Commodores, Ataris, and the like. Its also been done for the Altair before as well, with the FDC+ and APE.
The FDC+ is a hardware device, and a great option for Altair owners. But I was proud of soldering all the cards in my Altair myself, and the FDC+ comes pre-built. It also uses closed-source Windows software. APE looked like it hadn’t been updated for 5 years, required two serial devices, and was also closed-source. So I decided to write my own.
To do this I’d have to modify CP/M, replace its disk read-and-write routines to instead fetch and send sectors over the serial port with an invented protocol, and write software to sit on the other side of the serial connection and serve the requests against disk image files. As a bonus, I thought I could also modify the standard IO routines of CP/M to play nicely with the modified disk routines, allowing both the terminal and the disk access to share the same serial connection.
I designed a simple protocol wherein a python script running on a Linux machine would listen to the serial connection from the Altair. Normally the serial traffic is sent straight to the console, just like a normal terminal to the Altair. But if it received a control code (0xFF), the control routines would then take over the connection and listen for the next code to know if the Altair was requesting a disk read or disk write. Then it would listen for the track number, sector number, and write data (if writing), and then process the request, returning the requested data (if reading). The protocol is easily extendable to also carry other IO streams, such as that for the printer port. I then modified CP/M’s BOOT.ASM and BIOS.ASM, stripped out all the floppy drive controller code, and replaced it with code to make these requests out the serial connection. I compiled it, and with the help of some helper scripts I wrote, embedded the new code into the disk image.
Most often, a disk controller, or sometimes another card in the Altair, would have a boot-up ROM that contained code to load the first few sectors of the drive. After loading, this code would then bootstrap the rest of the OS. But I didn’t have such hardware handy. But no matter; I would just do what they did back in the day as well: key in small bootstrap code that would load the equivalent ROM code directly from the serial port. I reverse-engineered and modified the DBLv4–5.TAP file found at https://deramp.com/downloads/altair/software/8_inch_floppy/BASIC/ for this.
Put it all together, and the Altair should boot up CPM, all console access would go over the serial connection like normal, but would also share this serial connection for all disk access using disk image files stored on the hosting Linux machine.
After debugging another bad 74LS244 chip and a few minor mistakes in my assembly code, CP/M started up, and I got the familiar A> prompt. It worked!
Using this setup, I could easily swap in and out virtual disk images, giving me quick access to all kinds of software written in the 70s and 80s, such as Wordstar, Supercalc, and of course, Zork (an immensely popular text-based RPG). Of course, for the latter, I was soon eaten by a grue.
Getting an OS on the Altair has also made it much easier to develop software for it.
I extended the serial protocol and modified some XMODEM utility programs to trigger protocol file transfers. This makes it easy to get files back and forth from the Altair. That accelerated my development cycle, giving me a chance to develop some nifty (to me) 8080 routines for converting between strings and 16-bit integers (think C’s atoi() or strtoul() functions) and doing shift-and-add software multiplication (there is no hardware multiply on the Intel 8080). None of this is ground-breaking or anything, just some hobbyist fun.
I will add this though: after coding against both early Intel and early Motorola chips, I totally get why there were flame wars between the Intel versus Motorola camps back in the day. I found the Motorola instruction set to be much more intuitive and elegant. But Intel was first, and that counts for a lot.
If you’re interested in trying out CP/M with a virtual floppy drive, I’ve made my code available for others to use here: https://github.com/barberd/altair-cpm-serialdisk.
This brings my series on building a new Altair from scratch to a close. It was a great learning experience, and really helped me to understand a critical time period in our society’s (and my chosen industry’s) history. This machine was simple enough that one person could build and understand the entire thing, and one can see how modern computers are just the same thing with layers upon layers of improvement. There is a straight line from this machine soldered by hobbyists to today’s efficiencies-through-scale cloud computing industry. It makes me wonder: what will be the next big thing that allows individual hobbyists to shape the future so directly?