Flashback: CP/M and the beginning of the microcomputer era

Back in the days of wooden ships and iron programmers, there was an operating system called CP/M. Now, after 30 years, you can finally download its source code. Plus, Gewirtz goes ancient geek and talks about language design in 1980.
Written by David Gewirtz, Senior Contributing Editor

There was a time long, long ago, in a place far, far away when I lived day and night, night and day in something called CP/M. CP/M was one of the most influential early operating systems of the microcomputer era.

A recording of "Oh, say can you see by the dawn's early..." would use up all the RAM in a CP/M machine from 1980.

Compared to the operating systems of today, the CP/M of the late 1970s was barely a file controller. There were no APIs. There was barely a command-line interpreter (although if you know what an A: prompt is, you have CP/M to thank).

But CP/M was a game changer. It introduced the concept of a BIOS, which separated out the most hardware-specific elements of a computer from the OS code, and which allowed one main code base to run on many different combinations of hardware.

CP/M was MS-DOS before MS-DOS was MS-DOS.

In fact, CP/M was the model for MS-DOS. I won't take you through the apocryphal story of how Digital Research (makers of CP/M) lost to Microsoft for the first IBM PC operating system, but the fact was, MS-DOS felt like CP/M on the outside, but had different code internally.

Many household names of the 1980s, like WordStar (yes, I still remember the command keys!), dBase, and even AutoCAD originated on CP/M and were first sold for computers that ran CP/M.

Let's put this in perspective, shall we? CP/M ran on 8080-class microprocessors. The Z80 Zilog 8080-clone (Zilog then was to Intel like AMD is to Intel processors today) supported up to 64K RAM.

Let me be clear here. We're talking 64K. Kilobytes. Not megabytes. Not gigabytes. Not terabytes. Kilobytes. 64K RAM was 64 times 1024 bytes.

Here's another way to put this in perspective. An Army MP3 consisting of a band playing and a chorus singing the Star Spangled Banner clocks in at 1.6 megabytes. The entire 64K CP/M address space is 1/25th of the Star Spangled Banner. A recording of "Oh, say can you see by the dawn's early..." would use up all the RAM in a CP/M machine from 1980.

Even so, I lived in CP/M. The motherboard on my first CP/M machine was screwed down onto a piece of green plywood left over from someone's Christmas celebration. I had S-100 cards stacked on the board, a front panel made up of hundreds of tiny wires and switches, and, eventually, a set of gargantuan 8-inch floppy disk drives.

I also had a C compiler. That's right. I was able to compile and edit C code (and run it) in 64K. That shows you how much of the C language is language and how much of the language today is really APIs and interfaces.

By contrast, Microsoft says Visual Studio Express 2013 requires a minimum of 1 GB RAM to run. That's 15,625 times more RAM than I needed to compile C back in 1980. Of course, that gig of RAM is also a whole lot cheaper today than that 64K was back then. So, you know, Moore's Law for the win.

Like all operating systems of the time, CP/M was a proprietary operating system, with the source code closely protected by its creators. Even so, through judicious pre-Internet networking on the university-centric Arpanet, I was able to get my hands on a reverse-engineered dump of the CP/M source code.

In fact, the CP/M source code is what inspired me to write this article today. In honor of the 40th anniversary of the first build of CP/M, the Computer History Museum is releasing dumps of a few different versions of CP/M source code, including the reverse-engineered listing I found so valuable to my work.

Ah, yes. My work. The reason I was living in CP/M so intensely was I was working on my engineering school thesis, which involved a project called The Hope System. For all intents and purposes, The Hope System was a replacement command-line shell for CP/M.

CP/M had a very, very rudimentary command-line shell call CCP for Console Command Processor. It only had a few commands, it didn't have much of a batch language, it didn't have history, it didn't have command completion, it didn't know about execution paths, and it didn't even have much of a command-line editor. Delete was all you got.

My project was to replace the CCP with a highly-extensible and infinitely flexible batch language (CP/M only allowed a list of commands to run in a SUBMIT file, with no flow control), and replace the command line processor with one that included command completion, history, multiple command directories, and other convenience UI features.

The challenge, of course, was that 64K of RAM. I had to load and run Hope in the same memory footprint as the CCP, yet Hope was vastly more complex. To pull it off, I had to code in dynamic paging and transient modules to make it all work.

The Hope System consisted of three main components: the Hope Language, the Hope Shell, and the Hope Loader. The loader was the reason I got to know CP/M source code so well. In order to replace the CP/M CCP, I had to patch CP/M to load my loader instead. My loader then took over, managed all program loading, and did a ton of memory management. Remember, this was back in 1980 -- and my notes show that I was actually able to run the entire system in 48K of RAM.

The Hope Shell was advanced for 1980, but would seem pretty primitive to us today. Even so, the ability to incorporate command line completion and history, along with a batch language, was unusual for the time -- especially on such a small RAM-footprint system.

But where Hope was unique was the language. To this day, I can't think of any other languages that were structurally extensible at runtime. Let me take a minute to explain what took 18 months to design back then. My idea (and this was the core of the thesis) was that computer languages did not need to have a fixed syntax.

By creating a structurally extensible language, you allow the programmer to make syntax decisions on the fly, all the way down to how you block your code, how parameters work, and so forth.

Thinking on this after 30+ more years of experience in the tech business, the idea of a structurally extensible language syntax gives me the shudders. Maintaining it -- and  especially -- supporting it would be a nightmare.

But, back in 1980, we didn't really have much of a standard. CP/M was the only cross-vendor operating system there was. We really weren't sure how these machines were going to be used, and the idea of a language that could be tailored to specific needs seemed to remove the restrictions that computer users had grown accustomed to prior to that time.

It was good work. I graduated with honors and received the Sigma Xi Research Award in Engineering for the Hope System (particularly the structurally extensible nature of the language).

Until I sat down to write this, I hadn't looked at my thesis since 1982 or so. What struck me about reading it now is how elements of the work I did then have unconsciously found their way into the work I've done over the years.

ZENPRESS, the CMS I built back in 1998 to run ZATZ, for example, shares many of the language extensibility, tokenizing, and abstracting aspects I developed for Hope -- even though I have no recollection of thinking of Hope while building ZENPRESS.

Of course, the other thing that took me aback as I looked back, is just how little RAM we had to work in -- and how much we were able to get done.

Take advantage of the release from the Computer History Museum and dig on through the CP/M source code. You'll be looking back at some of the most formative lines of code ever written.

By the way, I'm doing more updates on Twitter and Facebook than ever before. Be sure to follow me on Twitter at @DavidGewirtz and on Facebook at Facebook.com/DavidGewirtz.

Editorial standards