An interesting question recently popped up: How exactly did IBM build the ROM BIOS for the IBM PC? Knowing what tools were used should make it possible to use the ROM listing published in the IBM PC Technical Reference and reproduce the ROM image.
Only one thing was clear—the PC BIOS wasn’t developed on a PC. With later IBM PC/AT and XT/286 ROMs, the situation is simple because the published listings identify IBM Macro Assembler 2.00 as the tool used. With the PC BIOS (and early AT BIOS), there’s no such identification.
The PC BIOS source code is remarkably straightforward. It is a single source file which does not use any macros. The one telltale marker is a $TITLE directive at the very beginning. No known version of MASM accepts this syntax… but at least one other assembler does.
What Tools Did IBM Use?
The following is informed speculation; so far no authoritative answer has been found in any available publication. It’s clear that the ROM BIOS would be about the first piece of software that needed to be written for the PC. If the release marker in the PC BIOS is to be believed (and there seems to be no reason to doubt it), the PC BIOS was completed on April 24, 1981. The development presumably must have started in 1980, with tools available at the time.
The obvious choice would have been Intel’s own development system which included the ASM86 assembler, together with a linker and locator. Microsoft probably did not offer an 8086 assembler at the time. It is unclear if Digital Research did. It is known that SCP used its own assembler for developing 86-DOS in the same timeframe. Note that any further mentions of ASM86 refer to the Intel product, not any of the other assemblers of the same name.
There are newer versions of ASM86 available which run on top of DOS. And perhaps not surprisingly, ASM86 accepts the $TITLE directive without complaint. Unfortunately, these ASM86 releases generate significantly different code, and also produce somewhat different listing format, so they cannot be used for re-creating the PC BIOS.
So what’s the oldest surviving version of ASM86? After some searching, ASM86 version 2.0 turned up on bitsavers… on an image of a disk intended for use with Intel’s ISIS-II.
In the 1970s, Intel started offering various development systems which could be used to run assemblers and compilers producing code for Intel’s various microprocessors and microcontrollers. This was a good way to jump-start software development because Intel provided a complete, fully functioning and debugged development system at the same time as the chips. ISIS stood for Intel Systems Implementation Supervisor and it was the operating system utilized in the Intel development systems, Intellec MDS and Intellec Series 2.
ISIS-II ran on top of 8080, Intel’s famous 8-bit CPU. It was an operating system somewhat similar to CP/M in structure, but by no means compatible. It was, perhaps surprisingly, written not in 8080 assembly but in PL/M, a high-level programming language developed for Intel by Gary Kildall in 1972. ISIS itself was first written around 1976 and upgraded to ISIS-II for floppy-based systems; it appears that ISIS was developed at Intel after Gary Kildall left to start Digital Research and commercialize CP/M (something Intel was not interested in).
Amazingly enough, there’s an ISIS-II simulator which can be used to run 8-bit software designed for the 8080 on modern x86 systems. As it turns out, the ISIS-II was quite reasonably designed and the software running on it cleanly written. All I/O was file-based (using FCBs, not file handles!) and console access was TTY-like, which means the tools can be transplanted onto the command shell of a modern OS.
One curiosity of ISIS-II is that it used OMF (Object Module Format popularized by Microsoft’s DOS development tools) not only for object files but also for the executables loaded by ISIS-II into memory. It helps that at least some tools (e.g. the dmpobj utility shipped with the Open Watcom compilers) understand the overall file structure even without knowledge of the meaning of 8080-specific records. With such tools it’s easy to verify the integrity of the files.
Extracting the Files
Okay, so there’s a working simulator, but what about the ASM86 files? The simulator works with host OS files, not with ISIS-II disk images. So the ASM86 executables somehow need to be extracted before they can be used.
As luck would have it, the ISIS-II disk format is quite well documented for such an antique and relatively obscure system. The OS/2 Museum developed a simple utility to take a raw image of an ISIS-II disk and break it down into individual files.
It’s worth mentioning that the ISIS-II had no concept of time and the files on ISIS-II disks therefore have no timestamps (clearly Intel was not yet ready for the wonders of ‘make’!). That makes it a bit difficult to determine the age of the files. The copyright messages embedded in the files hint that the newer ASM86 V2.1 was released in 1980 and V2.0 in 1979.
Running 1979 Tools 35 Years Later
With the ISIS-II simulator, it is very easy to run ASM86 V2.0, more or less exactly 35 years after it had been released. Well, that’s after fixing the simulator to load ASM86 properly—one of the overlays includes an object record loading data at a low address, which the simulator rejected, loaded the module only halfway, and soon thereafter crashed.
Running ASM86 on the PC BIOS source code (kindly provided by Vernon Brooks), things look promising:
ISIS-II MCS-86 MACRO ASSEMBLER, V2.0 ASSEMBLY COMPLETE, NO ERRORS FOUND
Besides an object file, a listing file is produced and… it does not match. For one thing, the code at FFFF:0 is assembled as a near jump (because the source code declares the target as NEAR!). There’s also only a single relocation record marked in the listing while the Technical Reference shows dozens.
Examining the differences in detail, it is apparent that ASM86 V2.0 is considerably smarted than whatever IBM used. This version of ASM86 makes good use of the fact that the code segments are declared at absolute (SEGMENT AT xxxx) and does more or less all of the relocation math on its own. The assembler used by IBM on the other hand seems to have effectively ignored that information and presumably only passed it along as a hint to the linker.
In addition, ASM86 V2.0 considers the segments private (which is the default), therefore not combinable with other segments, and calculates offsets into those segments directly. Again the assembler used by IBM did not take that into account and behaved as if the segments were public (i.e. could be combined with others, therefore the assembler emitted relocation records rather than calculating offsets itself).
All in all, the old ASM86 V2.0 produces more or less the same results as the newer V3.x which runs on top of DOS. The only result the ISIS-II excursion had was proving that ASM86 V2.x is not what IBM used.
Confirmation and Further Search
While browsing through the October 1985 issue of PC Tech Journal, an interesting nugget of information popped up. In an article reviewing IBM’s MASM 2.0 and Microsoft’s MASM 3.01 (extremely similar assemblers, despite the versioning), Ted Mirecki compares their listing format with that used in the PC Technical Reference and off-handedly mentions that the latter had been “produced with Intel’s ASM86”. Perhaps this was common knowledge 30 years ago, now long forgotten?
At any rate, it is a confirmation that IBM did in fact use Intel’s ASM86 to produce the PC BIOS. The question remains which version it was. The current best guess is that it was ASM86 V1.0, but a search did not turn up either binaries or documentation.
Looking through the ISIS-II disks, there is evidence that (not too surprisingly) ASM86 V1.0 did exist, since it left its signature in one or two object files, for example PLM86.LIB on the disk containing ASM86 V2.0 (disk 9700030-03).
Even listing files produced by ASM86 V1.0 might shed some light on the mystery; one of the differences in the Technical Reference listings and those generated by ASM86 V2.x is the way uninitialized variables created using the DUP keyword are treated, such as the one in line 52 of the original PC BIOS listing. ASM86 V2.x produces multiple lines while the version used to assemble the PC BIOS only emitted a single line to the listing.
The question remains where to find Intel ASM86 older than V2.0, or if this piece of PC history is irretrievably lost. If ASM86 V1.x surfaces, the PC BIOS should be revisited.