A number of years ago, an 8″ disk containing Seattle Computer Products (SCP) 86-DOS 1.0 was successfully imaged. The newest files on the disk are dated April 30, 1981, making the disk the oldest complete release of what was soon to be known as PC DOS and MS-DOS, about a month older than a pre-release of PC DOS from early June 1981.
While it is possible to run the 8″ disk image with 86-DOS version 1.00 under an emulator, it of course doesn’t run on a PC or any PC emulator/virtualizer. That’s a shame because most of the utilities included with SCP’s 86-DOS run under DOS just fine. In theory, it should be possible to provide a PC compatible “BIOS” component (IBMBIO.COM or IO.SYS equivalent) and run the rest of the system more or less unmodified on a PC.
In practice, it can in fact be done. Behold PC-86-DOS 1.00, running from this disk image:
Actually achieving this wasn’t complicated but there was one non-trivial snag.
Note that the SCP floppy uses a typical 8″ format with 77 tracks, each with twenty six 128-byte sectors, for a total capacity of 256,256 bytes (single sided). The disk uses a FAT file system same as “modern” DOS, but there is a notable difference regarding system boot.
DOS 1.x (and many later versions) has the core system files, either IBMBIO.COM/IBMDOS.COM or IO.SYS/MSDOS.SYS, listed in the directory, albeit usually hidden. The files must be the first two listed and must occupy the first consecutive allocation units on the disk. This gives the user some ability to update the system files by simply overwriting them, although care has to be exercised as the files must be contiguous on disk.
In terms of a FAT file system, a PC DOS floppy only has one reserved sector that’s not part of the FAT file system, namely the boot sector. SCP’s 86-DOS used an earlier method and reserved all of the first two tracks (52 sectors or 6,656 bytes). It’s fairly obvious why this was changed: Reserving the first two tracks is very inflexible and either wastes space or does not allow the system files to grow in size. Keep in mind that this was done before the advent of a BPB in the boot sector and the number of reserved sectors was fixed for any particular disk type.
This boot scheme poses a minor difficulty in that the IBMDOS.COM equivalent needs to be extracted from the boot tracks without knowing exactly where it starts or how big it is. But correctly guessing that was not difficult.
Mix and Match
Okay, let’s say we have the SCP 86-DOS equivalent of IBMDOS.COM. Since 86-DOS was designed to be hardware independent, it should be possible to combine it with IBMBIOS.COM to get it working.
The first attempt was a failure. 86-DOS 1.0 can not be combined with IBMBIO.COM from PC DOS 1.1. The reason is that even though the call interface is the same, the initialization table passed to the DOS kernel at startup is not. 86-DOS just hangs during initialization. Note that the newer IBMDOS.COM from PC DOS 1.1 actually detects incompatible initialization tables and reports the error, but the earlier DOS kernels clearly did not.
The next attempt was combining 86-DOS with IBMBIO.COM from the June 1981 PC DOS pre-release. The components are only a few weeks apart, so perhaps that might work? Yes, it does!
Fix and Patch
But before getting there, something else needed fixing. As it turns out, 86-DOS and later non-PC-compatible releases of MS-DOS place the BIOS component by default at address 400h (or 40:0 segmented), right after the Intel-defined interrupt vector table. The IBM PC of course has the BIOS data area at 40:0, and another BIOS/DOS/BASIC data area at 50:0. IBMBIO.COM is therefore loaded at 60:0 or address 600h in DOS 1.x.
That is a problem because the 86-DOS kernel makes direct far calls to 40:xxx and generally assumes that the BIOS is at segment 40h.
Fortunately it is not difficult to find all the instances (there are 20 total) where 40h needs to be changed to 60h in the 86-DOS kernel file.
After replacing IBMDOS.COM on the PC DOS pre-release floppy with the patched DOS kernel extracted from the SCP floppy and replacing COMMAND.COM with SCP’s, we end up with a working 160K floppy that can be booted on a PC.
How different is it?
There are numerous minor differences between 86-DOS and PC DOS. It is apparent that Microsoft liked the original 86-DOS behavior better and it was the default for OEM releases, but IBM got what IBM wanted. For good measure, I also replaced CHKDSK, DEBUG, and EDLIN with those from the 86-DOS disk, and copied over SCP’s development tools, ASM and HEX2BIN.
The prompt is ‘A:’ rather than the ‘A>’ that IBM used. The editing keys are somewhat different. SCP’s COMMAND.COM supports batch files, but does not automatically run AUTOEXEC.BAT. SCP’s COMMAND.COM is also unable to run EXE files (in DOS 1.x, EXE file loading was handled by COMMAND.COM, not by DOS itself).
The built-in DEL command is not available, but ERASE is.
The PC DOS disk format is obviously completely different from SCP’s but the BIOS abstraction takes care of it.
IBM provided Microsoft’s linker (LINK.EXE) and EXE2BIN utilities with DOS, as well as DEBUG, but no assembler. SCP shipped a miniature but complete development environment with 86-DOS. The weakest part was arguably EDLIN:
SCP’s assembler was very different from the one IBM/Microsoft shipped. SCP had no linker and their assembler produced HEX files that could be used with an EPROM programmer or similar equipment. There was also a HEX2BIN utility which simply converted the HEX files into a pure binary form.
The SCP assembler syntax was similar to Intel/Microsoft assemblers but not the same. The differences were not necessarily apparent in small programs.
This was adequate for developing COM style executables and SCP’s development tools were self-hosting, along with 86-DOS itself.
For debugging, some machines had a built-in monitor, but there was also DEBUG:
The 86-DOS development environment was fairly bare-bones but it worked, and it gave SCP a working 8086 software ensemble many months before Digital Research was able to provide one in the form CP/M-86. As it turned out, being there first ended up having pretty big consequences.
Thank you Michal for providing us with the oldest IBM PC compatible version of DOS. No doubt it’ll be of great interest to historians!
According to the article, this archaic version of DOS was found, transferred to a PC, and run in an emulator (emulating non-PC compatibles) years ago. What this article describes is a clever way to graft this DOS onto another very old DOS, but for PCs, so the result is able to run in a real PC or a PC emulator like Virtualbox.
I forgot to say in my previous post that this version of DOS (SCP 86-DOS 1.0) is NOT for IBM PC compatibles, and will NOT run on a PC without a major hack.like that described in the article.
I wouldn’t say “relocating” the BIOS component to a different segment address is a major hack (if that’s what you’re referring to). It just corrects for a deficiency in the old DOS kernel. DOS 2.0 does not have this problem because the DOS kernel is told where the BIOS (really the device drivers) is in memory.
The way the old DOS is structured is kind of odd, there’s no hardware specific code in the DOS kernel but the far calls to the BIOS segment create an indirect hardware dependency. The DOS 1.x kernel had to be rebuilt if the BIOS segment changed, but that was the only change needed for adapting to different hardware. All the code which was actually hardware specific was separated in the BIOS component. I expect this made life complicated for Microsoft because they didn’t want to distribute the DOS kernel source to OEMs, so they made sure the DOS 2.0 kernel didn’t have this particular dependency.
“the far calls to the BIOS segment create an indirect hardware dependency. The DOS 1.x kernel had to be rebuilt if the BIOS segment changed”
I find it amazing that Tim Paterson and the Microsoft guys made such a glaring mistake. They probably forgot about the “BIOS segment” at 40:0 because they were porting the CP/M behaviour and CP/M doesn’t have segments and hence it doesn’t have a 40:0 address which can make its BDOS hardware-dependent. Yet, CP/M has the same separation of roles between BIOS and BDOS, just like DOS, so probably the BDOS should know where the linear address(not segment) of BIOS is. Perhaps some who knows CP/M intimately can tell if a similar problem exists there as well.
Ugh… I’m again commenting before thinking enough, for which I’m really sorry. CP/M has no problems, because its BIOS component is always loaded at a fixed place. It’s the BDOS component which can be loaded at different addresses due to the potentially different sizes of BIOS, but this is not really a problem, because BDOS is called via syscalls, not direct call/jump instructions. Yet I wonder if any CP/M system has anything similar to the 40:0 segment of an IBM PC?
I don’t know if it was a mistake so much as a failure of imagination. Tim Paterson clearly assumed a “clean” 8086 system where only the first 1024 bytes are reserved (by Intel) and anything past that is available for BIOS/DOS. That assumption was not valid on the IBM PC and also on some other 8086/8088 based systems. Tim P of course knew which hardware he was writing for and the assumption was valid for SCP’s hardware.
And just to be clear, in 86-DOS/DOS 1.x, the DOS kernel itself (IBMDOS.COM or whatever it’s called) is relocatable and can be loaded more or less anywhere, i.e. the BIOS size is not fixed. But the DOS kernel needs to know the segment which the BIOS module is loaded at, and that’s hardcoded into the DOS kernel.
At a quick glance, CP/M-86 was different in that the BIOS + BDOS components (and CCP) were linked into a single CPM.SYS file, and CPM.SYS was relocatable as a single unit. This appears to be one of the several instances where 86-DOS is closer to CP/M-80 (separate BIOS/BDOS/CCP) than CP/M-86 is.
To explicitly answer the last question: Sort of. The default CPM.SYS load address in CP/M-86 was 40:0, but that was only stored in the file header and could be easily changed (or perhaps ignored by the boot loader). So the default was the same, but it was not hardcoded into the OS code the way it was in 86-DOS.
SYSDAT is the normal CP/M-86 counterpart to the BIOS DATA AREA on the IBM PC. It is loaded with information like the total number of drives and whether an 8087 was installed. Note: CP/M-86 1.1 added a function (49) to determine the address of the SYSDAT which the documentation for CP/M-86 for the IBM PC fails to list.
The load address could be set with GENCPM. The CP/M-86 Plus manual shows a low TPA that sits between 0040h and the start of the BDOS code segment. I presume that was for some type of application compatibility. It wasn’t required and the default for GENCPM set BDOS at 0040h.
A slight follow up on the use of absolute addressing. I think that having absolute addressing made perfect sense for the early development of an OS. There are enough potential bugs in a new OS and new assembler without also having to deal with bugs in the relocation code.
DRI in the documentation for the GENCMD program which creates executables out of HEX files provides as an example code that must be loaded at segment 40h. IBM in the CP/M-86 manual used the same example but that won’t work on an IBM PC.
It also makes sense for the hardware specific component. The BIOS module isn’t going to work on any hardware other than what it’s written for, so hardcoding it for a certain address isn’t a problem. For the hardware-independent components it’s less ideal.