Update: The source is available at github.com/mist64/msdos1

The bootsector of DOS 1.0 is celebrating its 28th birthday today (it contains the timestamp “7-May-81”), so let’s look at it more closely.

Here it is:

00000000 eb 2f 14 00 00 00 60 00 20 37 2d 4d 61 79 2d 38 |........ 7-May-8| 00000010 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |1...............| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 fa 8c c8 8e d8 ba 00 00 8e d2 bc 00 7c fb a1 |................| 00000040 06 7c 8e d8 8e c0 ba 00 00 8b c2 cd 13 72 41 e8 |................| 00000050 58 00 72 fb 2e 8b 0e 02 7c 51 bb 00 00 33 d2 b9 |................| 00000060 08 00 be 01 00 56 b0 01 b4 02 cd 13 72 22 5e 58 |................| 00000070 e8 e7 00 2b c6 74 14 fe c5 b1 01 be 08 00 3b c6 |................| 00000080 73 04 8b f0 eb 01 96 56 50 eb dd 2e ff 2e 04 7c |................| 00000090 be 44 7d b8 42 7d 50 32 ff ac 24 7f 74 0b 56 b4 |................| 000000a0 0e bb 07 00 cd 10 5e eb f0 c3 bb 00 00 b9 04 00 |................| 000000b0 b8 01 02 cd 13 1e 72 34 8c c8 8e d8 bf 00 00 b9 |................| 000000c0 0b 00 26 80 0d 20 26 80 8d 20 00 20 47 e2 f3 bf |................| 000000d0 00 00 be 76 7d b9 0b 00 fc f3 a6 75 0f bf 20 00 |................| 000000e0 be 82 7d b9 0b 00 f3 a6 75 02 1f c3 be f9 7c e8 |................| 000000f0 a5 ff b4 00 cd 16 1f f9 c3 0d 0a 4e 6f 6e 2d 53 |...........Non-S| 00000100 79 73 74 65 6d 20 64 69 73 6b 20 6f 72 20 64 69 |ystem disk or di| 00000110 73 6b 20 65 72 72 6f f2 0d 0a 52 65 70 6c 61 63 |sk erro?..Replac| 00000120 65 20 61 6e 64 20 73 74 72 69 6b 65 20 61 6e 79 |e and strike any| 00000130 20 6b 65 79 20 77 68 65 6e 20 72 65 61 64 f9 0d | key when read?.| 00000140 0a 00 cd 18 0d 0a 44 69 73 6b 20 42 6f 6f 74 20 |......Disk Boot | 00000150 66 61 69 6c 75 72 e5 0d 0a 00 50 52 8b c6 bf 00 |failur?.........| 00000160 02 f7 e7 03 d8 5a 58 c3 52 6f 62 65 72 74 20 4f |........Robert O| 00000170 27 52 65 61 72 20 69 62 6d 62 69 6f 20 20 63 6f |'Rear ibmbio co| 00000180 6d b0 69 62 6d 64 6f 73 20 20 63 6f 6d b0 c9 00 |m.ibmdos com...| 00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200

DOS 1.0 shipped on a 160 KB single sided disk. The boot code in the IBM PC’s BIOS loaded the first sector into RAM at segment 0x0000, offset 0x7C00 and ran it. Later versions of BIOS checked for 0xAA55 in the last word of the bootsector, but the first version did not. Note that DOS 1.0 is also pre-BIOS Parameter Block, i.e. the bootsector does not contain any information about the physical layout of the disk, since there was only a single disk size.

What the boot sector is supposed to do is read “IBMBIO.COM” and “IBMDOS.COM” into RAM and run them – these are the DOS system files for machine abstraction and DOS API, respectively. In MS-DOS, they would be called “IO.SYS” and “MSDOS.SYS”.

But the DOS 1.0 bootsector takes quite a lot of shortcuts. It assumes it’s always a 40 track, 8 sectors single-sided disk and the two files occupy the first sectors of the data area contiguously – something that SYS.COM could guarantee when making a disk bootable.

So the bootsector first loads the first sector of the root directory (hardcoded to track 0, sector 4) and compares the first two entries with “IBMBIO.COM” and “IBMDOS.COM”. For some reason, the comparison is case-insensitive, although DOS only allows uppercase filenames.

00000600 49 42 4d 42 49 4f 20 20 43 4f 4d 06 00 00 00 00 |IBMBIO COM.....| 00000610 00 00 00 00 00 00 00 00 f7 02 02 00 80 07 00 00 |................| 00000620 49 42 4d 44 4f 53 20 20 43 4f 4d 06 00 00 00 00 |IBMDOS COM.....| 00000630 00 00 00 00 00 00 00 00 0d 03 06 00 00 19 00 00 |................|

If they are not there, it prompts the user to replace the disk and tries again. Otherwise, it loads 20 sectors starting from track 0, sector 8 to segment 0x0060, offset 0x0000 into memory and jumps there.

0x60:0x0000 is the same as the linear address 0x0600. On the IBM PC, 0x0000 to 0x03FF are occupied by the interrupts vectors, 0x0400 to 0x4FF is used by BIOS for its variables, and DOS 1.0 uses 0x500 to 0x5FF as the “DOS Communication Area”, so code can start at 0x0600.

00000e00 e9 62 01 e9 6d 00 e9 b2 00 e9 d8 00 e9 e8 00 e9 |................| 00000e10 24 01 e9 3a 01 e9 51 03 e9 52 03 e9 44 01 b1 00 |................| 00000e20 22 00 42 49 4f 53 20 56 65 72 73 69 6f 6e 20 31 |..BIOS Version 1| 00000e30 2e 30 30 a0 32 32 2d 4a 75 6c 2d 38 31 00 0d 0a |.00.22-Jul-81...|

These are the first few bytes of IBMBIO.COM. Its birthday is about six weeks from now, but I am going to post about its internals next week.

Let us finally look at the complete commented disassembly of the boot sector. It compiles with NASM, but will emit a few bytes differently because of variations in the assembly encoding – but variations in size have been compensated wit NOPs. It is actually quite easy to read.