Another Myth Busted

More than once I came across a story of a heroic MicroPro programmer who in an all-night session managed to port WordStar from CP/M to DOS by patching a single byte. This is how the legend was retold by Joel Spolsky:

Now, here’s a little known fact: even DOS 1.0 was designed with a CP/M backwards compatibility mode built in. Not only did it have its own spiffy new programming interface, known to hard core programmers as INT 21, but it fully supported the old CP/M programming interface. It could almost run CP/M software. In fact,  WordStar was ported to DOS by changing one single byte in the code. (Real Programmers can tell you what that byte was, I’ve long since forgotten).

Joel Spolsky,

Now, that story is slightly misleading. The “spiffy new programming interface” accessible through INT 21h pretty much was the CP/M programming interface, and it wasn’t until DOS 2.0 that the INT 21h interface was significantly enhanced.

But the gist of the story does not even make sense. Although DOS was designed to make porting from CP/M easy, it was never a question of patching a byte here or there, since CP/M ran on 8080 CPUs and DOS ran on 8086/8088 processors. The processor families are certainly related, but not at all binary compatible. 8080 assembly source code could be machine translated to 8086 source and reassembled, but the code quality was reportedly less than ideal.

And yet… there is a kernel of truth in the story, even though it morphed into something highly implausible. Not unlike there really are Wang word processor symbols in the IBM PC character set, even though the stories told by Bill Gates are very difficult to take seriously.

The other day I tried to understand the very interesting disk format of Victor 9000 (aka Sirius S1) machines, and a Supplementary Technical Reference Manual from 1984 proved very helpful. Therein I found the following section that is short enough to quote in full:

6.4   How to turn a CP/M version of WordStar 3.21 into an  MS-DOS 
version using DDT86

DDT86
DDT86 1.1
-RWS.CMD
  START       END
03C0:0000 03C0:52FF
-S0324
03C0:0324 E9 90
03C0:0325 39 90
03C0:0326 00 C3
03C0:0327 E9 90
03C0:0328 4A 90
03C0:0329 00 C3
03C0:032A 01 00
03C0:0328 00 .
-S0356
03C0:0356 00 FF
03C0:0357 00 .
-WWS.COM,180,52FF

Use RDCPM to copy WS.COM and all overlays to an MS-DOS disc.
Depending  on  the  version  of DDT86,  and the  version  of  the 
operating system,  DDT86 may load to a different segment address.  
Start changing bytes at location 324 anyway.   You may also  find 
that  some of your original bytes differ from those shown  above, 
change them regardless.

In other words, one could take a CP/M-86 version of WordStar, patch a few bytes, and turn it into WordStar that could run on top of DOS. In some cases, patching a single byte (at 03C0:0356 in the example above) may have been sufficient.

To sum up, it really was possible to patch a single byte in a CP/M version of WordStar and turn it into a DOS version! And yet… not surprisingly, the truth is much less sensational than the legend.

The True Story

WordStar was arguably the killer app of CP/M. In 1981, the personal computing landscape started shifting towards 16-bit machines based on the Intel 8086/8088, of which the IBM PC was but one. According to the “official” WordStar history, sometime in late 1981 MicroPro ported WordStar to CP/M-86; note that CP/M-86 was itself probably finalized around December 1981.

In the Fall of 1981, the IBM PC with DOS was already out, but perhaps not yet a force to be reckoned with. In early 1982, the IBM PC started taking off and MicroPro did not want to be left behind. In April 1982, MicroPro started getting serious about releasing a DOS version of WordStar. Quoting the WordStar history:

In one single all-night session Jim Fox patched the CP/M-86 version of WordStar to make it run under MS-DOS on the IBM PC so that it could be demonstrated to Rubenstein. The actual port was done by a group of Irish programmers using Intel development systems, which ran the ISIS II operating system.

There is one element of the legend: Yes, there really was a programmer who turned a CP/M version of WordStar into a DOS version in an all-nighter. But it was a CP/M-86 version of WordStar, so it was porting from one 8086 OS to another with a compatible API. That is much less impressive than porting from the original 8080 CP/M to DOS, but also far more plausible.

It is clear that the DOS version of WordStar was built from the same source as the CP/M-86 version. That made good sense, both because CP/M and DOS ran on the same sort of machines and because the programming interface was compatible.

WordStar could access the DOS API through INT 21h and the CP/M-86 API through INT E0h. The interfaces were similar enough that WordStar had an internal switch which chose between the CP/M or DOS interface. This was a single byte in “user area 1” which was designed to be patched by users.

We don’t have to guess what the user area looked like because MicroPro published the listing, see e.g. page 232 in this PDF. On page 246, we see the following:

MSDOS DB  0H;  SET TO 00H FOR CP/M-86,0FFH FOR MSDOS(PCDOS)

Note that the ‘MSDOS’ byte is at offset 356h in WS.CMD, which corresponds to offset 2D6h in the loaded program (as shown in the listing). Also note that the conversion process skips 180h bytes when saving WS.COM, skipping over the CP/M-86 CMD executable header.

And there we have another element of the legend. Yes, it really was possible to patch a single byte in the CP/M-86 version of WordStar to make it run on MS-DOS… because MicroPro made it that way.

Fact to Legend

There may not be contemporary written evidence, but there is no reason to doubt that a single programmer named Jim Fox did port the CP/M-86 version of WordStar to DOS in one night. The programming interface of the two operating systems is similar enough that the 8086 version of WordStar has a single code location which calls either INT 21h (DOS) or INT E0h (CP/M-86). Users could patch the one byte directing the system call choice, and that was documented by MicroPro.

In retelling, somehow this morphed into a story of a programmer porting the CP/M version of WordStar to DOS by changing one single byte. It is apparent that even though the legend is not (and can not) be true, it was not exactly made up; rather actual facts were mixed up and crucial details omitted.

This entry was posted in CP/M, DOS, PC history, WordStar. Bookmark the permalink.

5 Responses to Another Myth Busted

  1. Richard Wells says:

    Wordstar for CP/M-86 has those inverted jump sequences that are common for automated conversion from Z-80 to 8086. Performance didn’t suffer much.

    Note that while Wordstar 3.3 has both CP/M-86 and MS-DOS interrupts, it isn’t identical code blocks. CP/M-86 has the function call in register CL while DOS uses AH. The primary interrupt call routine which handles most functions works identically with the stack being setup and then the function being called with a comparison to choose the correct interrupt. Strangely, the function value is set in AH and the CP/M-86 portion includes MOV CL, AH to put the function in the correct register. Not what I was expecting from software that went to CP/M-86 first. The exiting code does CL=0 first and only moves CL into AH after checking the magic value.

    The exceptions include the keyboard routines where the DOS version makes two calls to AH=6 while the CP/M-86 version uses a radically different method involving CL=32h and the OS version check that only applies to CP/M-86. The conversion between CP/M-86 and MS-DOS was a lot more complex than it seems at first glance.

  2. Michal Necasek says:

    The original 8086 port of WordStar was not 3.3 though, it was probably something closer to 3.0. There is known to have been a DOS version of WS 3.02.

    For what it’s worth, in the PC DOS version of WordStar 3.20 (no timestamps, unfortunately), WS.COM has three instances of INT 21h, all guarded with the ‘MSDOS’ check and with alternate INT E0h code paths. IIRC the later versions have just one INT 21h in there.

    I have also seen 8086 WordStar version 2.99b which is CP/M-86 only, no INT 21h. Unfortunately also no way to date it.

  3. Rich Shealer says:

    I love the Wordstar posts.

    At some point MicroPro released an MS/PC-DOS PC hardware specific version that wrote directly to screen hardware. I don’t know if there was a CP/M-86 version like that or not. It definitely added some life to the product.

  4. Michal Necasek says:

    At least in WordStar 3.3, the CP/M-86 version is nearly identical to the DOS version. To the extent that the .OVR files are 100% identical and the biggest difference between WS.COM and WS.CMD is that the latter has a CP/M-86 style executable file header at the beginning. If the DOS version could use direct screen access, the same code would have worked in the CP/M-86 version too.

    With the caveat that perhaps for Concurrent CP/M-86 that would not have been desirable.

    I’ve not been able to find CP/M-86 versions of WordStar 3.2x for comparison.

  5. Richard Wells says:

    Wordstar 3.2 manual has a lengthy section regarding memory mapped video. The IBM PC fails to meet the requirements of having the memory structure with one byte per character. Wordstar 3.31 does a lot of screen activity through INT 10h which does entail a level of memory mapping. I can’t be sure that all the video calls were done through INT 10h; the code is far too gnarly to be absolutely sure about anything.

    I mainly went looking for the INT 10h code to find Wordstar code that had never been used on a Z-80 to compare code structure done for the 8088 as opposed to code that might have gone through a translator. This new code has no conditional jumps over an unconditional jump while the seemingly older sections of code have many examples of that. Translators generate that structure since they can’t know ahead of time if the block of code to be skipped will end up at less than 128 bytes.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.