The  Boot Sector   of
IBM® Personal Computer™ DOS
Version 1.10 (1982)


Copyright © 2005, 2017, 2021, 2024 by Daniel B. Sedory

NOT to be reproduced in any form without Permission of the Author !

 

See our Tech Notes on the difficulty of working with versions 1.10 and 1.00 of IBM®'s Personal Computer™ DOS.

NOTE: The FORMAT.COM file (05-07-1982; 3,816 bytes; MD5: 31B9C8001D7E9D9E98808B93BADF4B98) contains an exact copy of the Boot Sector; it's located at offsets BE8h through DE7h within that file. In an image file of the whole diskette, it can be found at offsets 4FE8h through 51E7h.

Unlike later versions of DOS, 1.10 (and 1.00) never contained a BPB (BIOS Parameter Block; though it appears to have a pre-cursor for one) nor what has become the standard Boot Signature (AA55h) at the end of almost every other DOS Boot Sector. These differences mean that most utility programs and even MS-DOS versions running in PC Compatibles as well as the Microsoft™ Windows® Operating Systems will consider these diskettes to be incorrectly formatted; even though their FAT12 file system is basically the same as the ones found on later MS-DOS diskettes! As we pointed out on our Tech Notes page, the main reason for this problem has to do with the so-called "compatibles" not containing actual clones of the IBM PC ROM chips, and deciding not to support the old IBM diskette capacities.[1]

IBM PC DOS 1.10 was only distributed on 160 KiB single-sided diskettes. However, it was possible to create a 320 KiB system boot diskette in a double-sided B: drive, if your IBM PC had one. Such a diskette has only a two-byte difference in its Boot Sector beginning at offset 003h, where the bytes "08 00" are changed to: "03 01" for a 320 KiB diskette. Instructions for creating a 320 KiB boot diskette using PCE (and its IBM PC DOS 1.10 image file) can be found here.[2]

A Disk Editor View of the Boot Sector

Absolute Sector 0 (Track 0, Side 0, Sector 1)

       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

0000  EB 27 90 08 00 14 00 00 00 00 00 00 00 00 00 00  .'..............
0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0020  00 00 00 00 00 00 00 CD 19 FA 8C C8 8E D8 33 D2  ..............3.
0030  8E D2 BC 00 7C FB B8 60 00 8E D8 8E C0 33 D2 8B  ....|..`.....3..
0040  C2 CD 13 72 69 E8 85 00 72 DD 2E 83 3E 03 7C 08  ...ri...r...>.|.
0050  74 06 2E C6 06 64 7D 02 BB 00 00 2E 8B 0E 03 7C  t....d}........|
0060  51 B0 09 2A C1 B4 00 8B F0 56 33 D2 33 C0 8A C5  Q..*.....V3.3...
0070  2E F6 36 64 7D 8A E8 8A F4 8B C6 B4 02 CD 13 72  ..6d}..........r
0080  2D 5E 59 2E 29 36 05 7C 74 1F 8B C6 2E F7 26 65  -^Y.)6.|t.....&e
0090  7D 03 D8 FE C5 B1 01 51 BE 08 00 2E 3B 36 05 7C  }......Q....;6.|
00A0  7C 05 2E 8B 36 05 7C EB C0 EA 00 00 60 00 BE 67  |...6.|.....`..g
00B0  7D E8 02 00 EB FE 32 FF 2E AC 24 7F 74 0B 56 B4  }.....2...$.t.V.
00C0  0E BB 07 00 CD 10 5E EB EF C3 E9 33 FF BB 00 00  ......^....3....
00D0  B9 04 00 B8 01 02 CD 13 1E 72 33 8C C8 8E D8 BF  .........r3.....
00E0  00 00 B9 0B 00 26 80 0D 20 26 80 4D 20 20 47 E2  .....&.. &.M  G.
00F0  F4 BF 00 00 BE 8B 7D B9 0B 00 FC F3 A6 75 0F BF  ......}......u..
0100  20 00 BE 97 7D B9 0B 00 F3 A6 75 02 1F C3 BE 1B   ...}.....u.....
0110  7D E8 A2 FF B4 00 CD 16 1F F9 C3 0D 0A 4E 6F 6E  }............Non
0120  2D 53 79 73 74 65 6D 20 64 69 73 6B 20 6F 72 20  -System disk or 
0130  64 69 73 6B 20 65 72 72 6F 72 0D 0A 52 65 70 6C  disk error..Repl
0140  61 63 65 20 61 6E 64 20 73 74 72 69 6B 65 20 61  ace and strike a
0150  6E 79 20 6B 65 79 20 77 68 65 6E 20 72 65 61 64  ny key when read
0160  79 0D 0A 00 01 00 02 0D 0A 44 69 73 6B 20 42 6F  y........Disk Bo
0170  6F 74 20 66 61 69 6C 75 72 65 0D 0A 00 4D 69 63  ot failure...Mic
0180  72 6F 73 6F 66 74 2C 49 6E 63 20 69 62 6D 62 69  rosoft,Inc ibmbi
0190  6F 20 20 63 6F 6D 30 69 62 6D 64 6F 73 20 20 63  o  com0ibmdos  c
01A0  6F 6D 30 05 C6 06 77 2F FF 83 7E FC 00 75 0B 80  om0...w/..~..u..
01B0  7E F7 3B 75 05 C6 06 76 2F FF 89 EC 5D CA 04 00  ~.;u...v/...]...
01C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

The string you see from offset 017Dh through 018Ah ("Microsoft, Inc ") replaced
the name of the Boot Sector's author in the previous version (cf. version 1.00).

The two underlined ASCII "0" bytes (30h) following each of the System file names
(at offsets 196h and 1A2h) are not used in any of the code below. For a discussion
on how they got there, see our comments on the PC DOS 1.00 Boot Sector here.

Junk Bytes No Longer

The hex bytes shown above in DARK RED italics, are never accessed in any way by the code. After examining and discussing the code with others, it was our opinion that these bytes (at offsets 01A3h through 01BEh) were simply junk bytes that should have been zeroed-out  before mass producing the distribution diskette! Then next question was: "But, they only appear on original distribution diskettes (or exact copies), right?" Wrong! It turned out, and you should have already guessed this from my comments further above — where I wrote, "...contains an exact copy of the Boot Sector," that these bytes were also included in FORMAT.COM, so were written to every newly formatted diskette! So, which came first? Was it a dirty Boot Sector that someone copied into FORMAT.COM (without ever checking it), or a corrupted FORMAT.COM used to make the “Master” distribution diskette? For the most plausible answer, see the Conclusion: section below.

Finally, on December 9, 2021, I wondered if these were truly random bytes, or  if they were actually part of an x86 program. And if so, could I ever find it? As any assembly programmer knows, some code is always the same no matter where it's located in a program, yet, other code is very much dependent upon its location and the offset  it has from the code around it. Well, I quickly discovered some repeating bytes that make sense no matter where they occur, and they are also part of the last 6 bytes here; when including a zero byte at the end, "89 EC 5D CA 04 00" which disassemble into:

 89EC    MOV  SP,BP
 5D      POP  BP
 CA0400  RETF 0004

Apart from the Boot Sector and FORMAT.COM, these appear no less than 14 times elsewhere on the diskette. Without trying to find any meaning in those locations, I began searching for similarities to the whole string we'd labeled as junk (or garbage) bytes. After searching again, I identified the program they must have originated from! Here are the former junk bytes from the Boot Sector, followed by the same number of bytes (which happen to be the very last bytes; including 17 zero bytes), from the end of a program in Absolute Sector 166, beginning at offset 14D53:

         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

 001A3           05 C6 06 77 2F FF 83 7E FC 00 75 0B 80 
 001B0  7E F7 3B 75 05 C6 06 76 2F FF 89 EC 5D CA 04 00 
 001C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

 14D53           05 C6 06 57 30 FF 83 7E FC 00 75 0B 80 
 14D60  7E F7 3B 75 05 C6 06 56 30 FF 89 EC 5D CA 04 00 
 14D70  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

These are the last 45 bytes of the program: LINK.EXE.[3] This program also includes 35 occurrences of the string "89 EC 5D CA 0H 00"; with H representing 02 (10 times), 06 (9 times), 08 (6 times), 0A (6 times), 0C (3 times) and 0E (once).

Conclusion: I don't see how the 25 matching bytes in the same positions (41 if we include the 16 zero bytes at the end) could possibly be a coincidence!

So, “How did what appears to be only a slightly different version of the end of the largest program on the diskette (41,856 bytes) show up in its Boot Sector?” I believe this segment of code, during the development of LINK.EXE, became part of the Slack Space of FORMAT.COM during its own development, and rather than determining exactly what was supposed to be in the Boot Sector, that Slack Space then became part of FORMAT.COM's copy of the Boot Sector; which was later used to format another working diskette that eventually became the distribution diskette!

As evidence to support that claim, on January 5, 2022, I discovered that the unused code at the end of FORMAT.COM was also highly likely a part of LINK.EXE during its development: That code had no apparent connection to any of the code before the copy of the Boot Sector bytes in FORMAT.COM, so I began searching for a similar pattern of code elsewhere on the diskette. I found such a pattern within LINK.EXE — which although not 100% conclusive, I think you will agree it's highly probable (just as the former "junk bytes" at the end of the Boot Sector were), that these bytes came from an earlier version of LINK.EXE as shown on this page. In fact, if you shorten the length of FORMAT.COM from 3,816 bytes (and 4,096 allocated) to 3,560 bytes, 256 bytes less (and only 3,584 allocated), by manually editing the size in its Directory entry and trimming the FATs (pun intended); necessary, since it needs to have a cluster removed from its file length, FORMAT.COM will still function the same as before.

 

An Examination of the Assembly Code
for the IBM® DOS 1.10 Boot Sector
as found in Memory during Execution

What it does:

1. Initializes critical registers and checks if the floppy drive is responding (7C29—7C43).
2. Checks for a System Boot disk in floppy drive (7C45, 7CCD—7D0D),
    notifies user if none found (7D0E & 7D11 and 7CB6—7CC9) and
    waits for user to try another disk (7D14—7D1A and 7C48); using a longer process than PC DOS
    1.00, including INT 19h (at 7C27), re-initializing registers and resetting the disk drive, until a
    System Boot disk is found, or user powers off the PC.
3. Loads System files (IBMBIO.COM and IBMDOS.COM) and 2 sectors (for 320 KiB diskettes) or 3 sectors
    (for 160 KiB diskettes) of whatever follows[4] into Memory (at 0000:0600 through 0000:2DFF) using:
      (7C58—7C67) to initialize registers for copying sectors into Memory,
      (7C69—7CA7) to copy all the System code into Memory (in four passes for single-sided
       160 KiB diskettes, and only 3 passes for 320 KiB dual-sided diskettes).
4. If an error occurs while copying System files, the code at 7C7F, 7CAE—7CB4, and
    the Display subroutine (7CB6—7CC9) handle the disk error.
5. If no fatal error occurs, starts executing the IBMBIO.COM file in Memory (see: 7CA9).

Here's a disassembly of the code (; with comments on every assembly instruction) after
being loaded into Memory at locations 0000:7C00 through 0000:7DFF by the PC's BIOS:

    (Comments on the code which occur with this background
      color, apply only to 320 KiB boot diskettes / image files.)



 7C00 EB27          JMP     7C29         ; Jump over reserved data area
 7C02 90            NOP                  ; Do nothing; never executed.
 

           Data Locations which Code Execution Jumps Over:

        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

 7C03           08 00 14 00 00 00 00 00 00 00 00 00 00     .............
 7C10  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 7C20  00 00 00 00 00 00 00                             .......

                   Or, for a 320 KiB Diskette:

        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

 7C03           03 01 14 00 00 00 00 00 00 00 00 00 00     .............
 7C10  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 7C20  00 00 00 00 00 00 00                             .......

 
; This code segment can only be executed from Memory offset 7C48 :

 7C27 CD19          INT     19         ; System Boot disk not found,
                                       ;  so, Start over again with
                                       ;   System BOOTSTRAP LOADER.

; Normal code execution begins here:

 7C29 FA            CLI                ; Disable maskable Interrupts
 7C2A 8CC8          MOV     AX,CS      ; Zero-out the Accumulator &
 7C2C 8ED8          MOV     DS,AX      ;  set Data Segment to ZERO.
 7C2E 33D2          XOR     DX,DX      ; Zero-out DX and use it to
 7C30 8ED2          MOV     SS,DX      ;  set Stack Segment -> 0000
 7C32 BC007C        MOV     SP,7C00    ; Set Stack Pointer to: 7C00
 7C35 FB            STI                ; Enable Interrupts

 7C36 B86000        MOV     AX,0060    ; 0060h -> AX
 7C39 8ED8          MOV     DS,AX      ; 0060h -> DS
 7C3B 8EC0          MOV     ES,AX      ; 0060h -> ES
 7C3D 33D2          XOR     DX,DX      ; Zero-out DX & use it to
 7C3F 8BC2          MOV     AX,DX      ; set: AX = 00 (Function 00
                                       ; RESET DRIVES, of INT 13).

 7C41 CD13          INT     13         ; Reset Floppy Disk drives; if
                                       ;  CF=1(set) there's an error.
 7C43 7269          JC      7CAE       ; If CF is set, jump to Drive
                                       ; failure routine; otherwise:

 7C45 E88500        CALL    7CCD       ; Is this a System Boot disk?
 7C48 72DD          JC      7C27       ; If not, execute INT 19, after
                                       ; waiting for keypress at 7D16;
                                       ; and start all over again!

 7C4A 2E833E037C08  CMP     WORD PTR CS:[7C03],+08  ; [7c03] = 0008,
 7C50 7406          JZ      7C58                    ; so go to 7C58.

;---------------------------------------------------------------------
; This instruction will only be executed if WORD [7C03] is not 0008;

 7C52 2EC606647D02  MOV     BYTE PTR CS:[7D64],02

; A properly formatted 320 KiB (PC DOS 1.10) diskette will have 0103 
; as that WORD. So, [7D64] will become "02".
;---------------------------------------------------------------------

;=====================================================================
; INT 13, Function 02 (AH=02) parameters:
; Copies sectors from disk into Memory; using Track, Side & Sector:
;
; (IN):
;       AL = Number of Sectors to read
;       CH = Track number
;       CL = Starting Sector number (bits 0-5)
;       DH = Side number
;    ES:BX = Start of Memory to copy sectors to
;
; If CF = 1 (set), then there was a read error!
;=====================================================================
 7C58 BB0000        MOV     BX,0000    ; Copy into ES:BX (0060:0000;
                                       ; same as Memory Address 0600)

 7C5B 2E8B0E037C    MOV     CX,CS:[7C03]  ; Copy 0008 into CX and...
                                          ; Copy 0103 into CX and...
 7C60 51            PUSH    CX            ; Save it on the Stack;
                                          ; note: CH = 00 here.
                                          ; note: CH = 01 here.

 7C61 B009          MOV     AL,09      ; Put "09" into AL
 7C63 2AC1          SUB     AL,CL      ;      09 - 08 = 01 (in AL)
                                       ;      09 - 03 = 06 (in AL)
 7C65 B400          MOV     AH,00      ; Ensure AH byte is zero.
 7C67 8BF0          MOV     SI,AX      ;    0001 -> SI
                                       ;    0006 -> SI

;===========================================================================
;              System Files Loading Loop
;===========================================================================
 7C69 56            PUSH    SI         ; Saved on Stack for use below ...
                                       ; 1st pass:  SI = 0001 (from 7C67).
 ; On 2nd, 3rd & 4th passes: SI = 0008, 0008 and 0003 respectively, which
 ; correspond to the number of sectors copied  during  3 subsequent loops
 ; for a total of 1 + 8 + 8 + 3 = 20.    1st pass:  SI = 0006 (from 7C67).
 ; On 2nd & 3rd passes: SI = 0008 and 0006, respectively, which correspond
 ; to the number of sectors copied, so all  20 sectors  are copied in only
 ; three passes for a 320 KiB diskette.

 7C6A 33D2          XOR     DX,DX      ; (DH = 0 for Side 0 of diskette;
                                       ;  can change for 320 KiB at 7C77.)
 7C6C 33C0          XOR     AX,AX      ; Zero-out AX register.

;-----------------------------------------------------------------------------
; The following code only affects the results if the code at 7C52 is executed;
; that is: Only if booting a DOS 1.10 /S (System) formatted 320 KiB diskette.

 7C6E 8AC5          MOV     AL,CH    ; 1st pass: CH=00 -> AL (for all other
                                     ;  passes, AL is set to: 01, 02 and 03
 ; corresponding to the Track Numbers that the sectors are copied from.)
                                     ; The results are different for 320 KiB
 ; diskettes, since AL is divided by [7D64] = 02 (with CH = 01, 02 and 03):

 7C70 2EF636647D    DIV     AL,BYTE PTR CS:[7D64]  ; 1st pass: 0/1 = 0 -> AL
                                                   ; on the 2nd, 3rd and 4th
; passes, 1/1 = 1, 2/1 = 2 and 3/1 = 3, so AL is the same as it was in 7C6E.
                                                   ; 1st pass: 1/2 = 0 -> AL
; (but AX = 0100 [256]. Why? Because unsigned 8-bit division puts remainders
; into AH register). 2nd pass: 2/2 = 1 -> AL and the 3rd pass: 3/2 = 1 -> AL
; (with another remainder of 1 in AH, so AX = 0101 [or 257]).

 7C75 8AE8          MOV     CH,AL    ; CH also remains the same for all 4
                                     ; passes: 1st pass: 00 -> CH, and on
                       ; the 2nd, 3rd and 4th passes: 01, 02 and 03 -> CH
; However, for 320 KiB diskettes, the Track Numbers are: CH = 0 (1st pass),
; but then CH = 01 for both the 2nd and 3rd (last) passes.

; For 160 KiB diskettes, the following instruction is irrelevant, since AH
; is always zero here. But AH changes at 7C70 for 320 KiB diskettes, so...

 7C77 8AF4          MOV     DH,AH    ; 1st pass: AH (01; see above) -> DH;
                                     ; IBMBIO.COM is on Side 1 of diskette.
; 2nd pass: AH and DH are back to zero (for Side 0), but on the 3rd pass: 
; AH and DH are both 01 (for Side 1) once again!

;-----------------------------------------------------------------------------

; For all of the sector-copying after the first pass, the CH and CL registers
; are set by the code further below at 7C93 through 7C97 !!!

 7C79 8BC6          MOV     AX,SI    ; 1st pass: 0001 -> AX (1 sector will be
                                     ; copied into 0600 through 07FF), 2nd pass:
; 0008 -> AX (8 sectors copied into 0800 through 17FF), 3rd pass: 0008 -> AX (8
; more sectors copied into 1800 through 27FF; note: 511 zero bytes at end here!)
; 4th pass: 0003 -> AX (only 3 more sectors copied into 2800 through 2DFF). One
; can't help but ask: "Why the first 3 sectors of COMMAND.COM?" Answer: The only
; plausible explanation is, that at that time, it was the easiest way they could
; find for the Boot Sector to load IBMBIO and IBMDOS into Memory! As was pointed
; out for PC DOS 1.00, these 3 sectors are never used at these Memory locations.
                                     ; lst pass: 0006 -> AX (6 sectors will be  
                                     ; copied into 0600 through 11FF), 2nd pass:
 ; 0008 -> AX (8 sectors will be copied into 1200 through 21FF). On the 3rd (and
 ; final) pass: SI = 0006 -> AX, so 6 sectors are copied into 2200 through 2DFF.

 7C7B B402          MOV     AH,02    ; Function 02 of INT 13
 7C7D CD13          INT     13

; Unless a disk read error occurred (handled below at 7C7F), the code and INT13
; above copied the first sector of  IBMBIO.COM (Absolute Sector 7)  into Memory
; locations 0000:0600 through 07FF;  overwriting the Directory entries that had
; been temporarily saved there.  Subsequent passes copy the remaining 3 sectors
; of IBMBIO.COM, 13 sectors of IBMDOS.COM and 3 sectors of whatever follows it.

; The code above will copy all four sectors of IBMBIO.COM (Sectors 322-325) and
; the first 2 of IBMDOS.COM (Sectors 326-327); Clusters 2-4, from Side 1 of the
; diskette into Memory locations 0000:0600 through 11FF; overwriting  Directory
; entries that had been temporarily saved in 0600-07FF. The subsequent 2 passes
; copy Clusters 5- 8 (Sectors 8-15) of IBMDOS.COM (8 more sectors) from Side 0,
; then Clusters 9-11 (Sectors 328-333) from Side 0;  the remaining 4 sectors of
; IBMDOS.COM (which is an extra sector longer due to clusters being 1024 bytes,
; wasting that sector) and lastly, two sectors (Sectors 332-333) of whatever is
; there. It obviously doesn't matter if only 2 instead of 3 sectors are copied,
; because none of what's in them is ever used in these Memory locations.[5]

 7C7F 722D          JC      7CAE       ; If disk read error (CF=1),
                                       ; jump to error handling routine.

 7C81 5E            POP     SI    ; Restore SI -> 0001 (1st pass), 0008
                                  ; (2nd), 0008 (3rd), 0003 (4th pass).
                                  ; Restore SI -> 0006 (1st pass), 0008
                                  ; (2nd pass) and 0006 for 3rd pass!

 7C82 59            POP     CX    ; Restore CX -> 0008 (1st pass), 0101
                                  ; (2nd), 0201 (3rd), 0301 (4th pass).
                                  ; Restore CX -> 0103 (1st pass), 0201
                                  ; (2nd), 0301 (for final 3rd pass).

 7C83 2E2936057C    SUB     CS:[7C05],SI
 
; 1st pass: 20 - 1 = 19 ([7C05]=0013), 2nd: 19 - 8 = 11 ([7C05]=000B),
;      3rd: 11 - 8 =  3 ([7C05]=0003). 4th:  3 - 3 =  0 ([7C05]=0000).
; 1st pass: 20 - 6 = 14 ([7C05]=000E), 2nd: 14 - 8 =  6 ([7C05]=0006),
;      3rd:  6 - 6 =  0 ([7C05]=0000).

 7C88 741F          JZ      7CA9       ; Finished loading System code.

 7C8A 8BC6          MOV     AX,SI      ; For all 3 passes, there is no
                                       ; change in contents of AX reg!

 7C8C 2EF726657D    MUL     AX,WORD PTR CS:[7D65]

; 1st pass: 0200h (512) -> AX, 2nd pass: 8 x 0200h = 1000h (4096 in AX),
; 3rd pass: 0008 x 0200h = 1000h (4096 into AX again).
; 1st pass: 0006 x 0200h = 0C00h (3072 in AX),
; 2nd pass: 0008 x 0200h = 1000h (4096 in AX); no 3rd pass!

 7C91 03D8          ADD     BX,AX    ; 1st pass: (0000)+ AX(0200) -> BX
                                     ; 2nd: BX (0200) + AX(1000) -> BX,
; making it 1200h (or 4608 or 9 sectors), 3rd pass: BX (1200) + AX (1000)
; -> BX (now 2200h, or 8704 or 11 sectors).
                                     ; 1st pass: (0000)+ AX(0C00) -> BX
; 2nd pass: BX (0C00) + AX(1000) = 1C00 -> BX (7168); no 3rd pass!

 7C93 FEC5          INC     CH         ; For the 1st, 2nd & 3rd loops:
                                       ;  CH -> 01, 02 and 03.  Only  2 
                                       ;  passes: CH -> 02 and 03.

 7C95 B101          MOV     CL,01      ; Always Sector 1 for any Track.

 7C97 51            PUSH    CX         ; 1st pass: CX = 0101 (CX = 0201),
                                       ; 2nd pass: CX = 0201 (CX = 0301),
                                       ; 3rd pass: CX = 0301 .

 7C98 BE0800        MOV     SI,0008    ; Read up to 8 sectors maximum.

 7C9B 2E3B36057C    CMP     SI,CS:[7C05]      ; To bypass 7CA2 or not?

 ; 1st pass: CMP: 0008 < 0013 -> CF set   [CMP: 0008 < 000E -> CF set]
 ; 2nd pass: CMP: 0008 < 000B -> CF set   [CMP: 0008 > 0006 --|] 
 ; 3rd pass: CMP: 0008 > 0003 so no bypass, execute 7CA2. <---|

 7CA0 7C05          JL      7CA7          ; Bypass next instruction on 1st
                                          ;  & 2nd passes, but not the 3rd:
                                          ; Bypass on 1st pass; not on 2nd:
 7CA2 2E8B36057C    MOV     SI,CS:[7C05]  ; [7C05] = 0003 -> SI, and then...
                                          ; [7C05] = 0006 -> SI

 7CA7 EBC0          JMP     7C69          ; Loop back to copy more...
                                          ;   System code into Memory

; ------------------------------------------------------------------------
; Transfer Code Execution to IBMBIO.COM (at 0000:0600):

 7CA9 EA00006000    JMP     FAR 0060:0000   ; -> 0000:0600 (the first byte
                                            ;               of IBMBIO.COM )
; ------------------------------------------------------------------------


;===========================================================================
;              Boot Disk Error Handling Routine:
;===========================================================================
 7CAE BE677D        MOV     SI,7D67     ; -> 0D,0A,"Disk Boot failure"

 7CB1 E80200        CALL    7CB6        ; Display Error Message & Return
 7CB4 EBFE          JMP     7CB4        ; Locks-up execution in
                                        ;   never ending loop!!


;===========================================================================
;    Display Zero-terminated String Subroutine:
;===========================================================================
;==========================================================================
; Function 0Eh = TELETYPE OUTPUT -> Display one character at a time
; (IN):
;       AL = character to display
;       BH = page number (IBM PC ROMs dated 4/24/81 and 10/19/81
;              require BH be the same as the current active page)
;       BL = foreground color (graphics modes only)
;==========================================================================
 7CB6 32FF          XOR     BH,BH     ; Page 0

 7CB8 2EAC          LODSB   AL,BYTE PTR CS:[SI]   ; Moves one string byte
                                                  ; character into AL
                                                  ; and increments SI.
;---------------------------------------------------------------------------
; Although the error  messages on this boot diskette have no characters with
; a high bit; like they did under IBM PC DOS 1.00, the same instruction used
; there still has two necessary functions: 1) It sets the zero-flag if a 00
; byte is read; which is the only way to exit this subroutine at 7CBC below.
; (It could still convert high bit characters if necessary.)  And 2) The XOR
; instruction at 7CB6 also sets the zero-flag, so this logic instruction is
; required to unset it, or no message bytes would ever be displayed.[6]

 7CBA 247F          AND     AL,7F     ; If AL contains a zero-byte, ZF -> 1
;---------------------------------------------------------------------------

 7CBC 740B          JZ      7CC9      ; Return if zero-flag set (ZF = 1).
 7CBE 56            PUSH    SI        ; Save new SI value on Stack
 7CBF B40E          MOV     AH,0E     ; Function 0Eh of INT 10
 7CC1 BB0700        MOV     BX,0007   ; Light Gray or White character
 7CC4 CD10          INT     10        ; Display character on screen

 7CC6 5E            POP     SI        ; Restore SI from Stack
 7CC7 EBEF          JMP     7CB8      ; Get next character
 7CC9 C3            RET

;------------------------------------------------------------------------
; When is this code ever executed? 
; (Is there a Jump to here from IBMBIO.COM or some other code?)

 7CCA E933FF        JMP     7C00      ; Start the Boot Sector code
                                      ; in Memory all over again!
;------------------------------------------------------------------------


;===========================================================================
;             Check for System Boot Disk 
;===========================================================================

;==================================================================
; INT 13, Function 02 (AH=02) parameters:
; Copies sectors from disk into Memory; using Track, Side & Sector:
;
; (IN):
;       AL = Number of Sectors to read
;       CH = Track number
;       CL = Starting Sector number (bits 0-5)
;       DH = Side number
;    ES:BX = Start of Memory to copy sectors to
;
; If CF = 1 (set), then there was a read error!
;==================================================================
 7CCD BB0000        MOV     BX,0000  ; Copy into: ES:BX (0060:0000;
                                     ; same as Memory Address 0600)
                                     ; DX still zero, so: Side 0,
 7CD0 B90400        MOV     CX,0004  ;      Track 0 and Sector 4.
                                     ;   (Beginning of Directory)
 7CD3 B80102        MOV     AX,0201  ; AL=01, (Read 1 Sector only)
 7CD6 CD13          INT     13

; Unless a disk read error occurred (handled below at 7CD9), then all
; 512 bytes of the 4th sector (Absolute Sector 3) have been read into
; Memory locations 0000:0600 and following, and the
; first two Directory entries (of 32 bytes each) should appear as:
; -----------------------------------------------------------------------
; 0600  49 42 4D 42 49 4F 20 20 43 4F 4D 06 00 00 00 00  IBMBIO  COM.....
; 0610  00 00 00 00 00 00 00 60 A7 04 02 00 80 07 00 00  .......`........
; 0620  49 42 4D 44 4F 53 20 20 43 4F 4D 06 00 00 00 00  IBMDOS  COM.....
; 0630  00 00 00 00 00 00 00 60 A7 04 06 00 00 19 00 00  .......`........
;
; Apart from the highlighted bytes; which DOS interprets as the date May
; 7, 1982 (or "5-07-82"), the lengths of these two files (0780h = 1,920;
; 1900h = 6,400) are exactly the same as they were for IBM PC DOS 1.00.
; -----------------------------------------------------------------------

 7CD8 1E            PUSH    DS        ; Save DS (0060h) on Stack
 7CD9 7233          JC      7D0E      ; If CF=1 (set), Disk Read Error
                                      ; Jump to Error handling routine
 7CDB 8CC8          MOV     AX,CS     ; CS -> AX (should be 0)
 7CDD 8ED8          MOV     DS,AX     ; AX -> DS (should be 0)
 7CDF BF0000        MOV     DI,0000   ; Zero-out DI (start @ 0 offset)
 7CE2 B90B00        MOV     CX,000B   ; 0Bh = 11 (Number of filename
                                      ;  characters to process below.)

 7CE5 26800D20      OR      BYTE PTR ES:[DI],20   ; Convert any ASCII
                                                  ;  "A-Z" bytes into
                                                  ; lower case [a-z].
 7CE9 26804D2020    OR      BYTE PTR ES:[DI+20],20    ; Does the same
          (Note: [DI+20] is in hex, +20h = +32)       ; for 2nd entry
                                                      ; in Directory.
 7CEE 47            INC     DI        ; Add 1 to DI -> next character
 7CEF E2F4          LOOP    7CE5      ;  Loop until all 11 characters
                                      ; in both entries are processed

 7CF1 BF0000        MOV     DI,0000   ; Set offset to zero again.
 7CF4 BE8B7D        MOV     SI,7D8B   ; -> "ibmbio  com"
 7CF7 B90B00        MOV     CX,000B   ; Compare 11 characters below.
 7CFA FC            CLD               ; Clear Direction Flag; ensure
                                      ;   SI and DI increment below.
 7CFB F3            REPZ              ; Repeat CMPSB CX times:
 7CFC A6            CMPSB             ; Compare byte ES:[DI] to DS:[SI]
 7CFD 750F          JNZ     7D0E      ; If not identical, this is not
                                      ; a System Boot Disk, so jump to
                                      ; error handling routine (7D0E)
 7CFF BF2000        MOV     DI,0020   ; Set offset (DI) to 020h (32)
                                      ; for second Directory entry.
 7D02 BE977D        MOV     SI,7D97   ; -> "ibmdos  com"
 7D05 B90B00        MOV     CX,000B   ; 11 times again...
 7D08 F3            REPZ
 7D09 A6            CMPSB
 7D0A 7502          JNZ     7D0E      ; Not a System Boot Disk!
                                      ; Jump to error handling routine
 7D0C 1F            POP     DS        ; Restore Data Segment
 7D0D C3            RET


;===========================================================================
;      Non-System Disk or Disk Error — Handling Routine:
;===========================================================================

 7D0E BE1B7D        MOV     SI,7D1B   ; -> 0D,0A,"Non-System disk" etc.
 7D11 E8A2FF        CALL    7CB6      ; Display error message & return

 7D14 B400          MOV     AH,00
 7D16 CD16          INT     16        ; Wait for keypress

 7D18 1F            POP     DS        ; Restore Data Segment
 7D19 F9            STC               ;  Set the Carry Flag (CF=1) to
                                      ; notify code at 7C48 of error!
 7D1A C3            RET

Location of Error Messages and Data Bytes in Memory

 
                                         B  C  D  E  F
 7D1B                                   0D 0A 4E 6F 6E             ..Non
 7D20  2D 53 79 73 74 65 6D 20 64 69 73 6B 20 6F 72 20  -System disk or 
 7D30  64 69 73 6B 20 65 72 72 6F 72 0D 0A 52 65 70 6C  disk error..Repl
 7D40  61 63 65 20 61 6E 64 20 73 74 72 69 6B 65 20 61  ace and strike a
 7D50  6E 79 20 6B 65 79 20 77 68 65 6E 20 72 65 61 64  ny key when read
 7D60  79 0D 0A 00 01 00 02 0D 0A 44 69 73 6B 20 42 6F  y........Disk Bo
 7D70  6F 74 20 66 61 69 6C 75 72 65 0D 0A 00           ot failure...
        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

Location of  File Names in Memory

 
 7D7D                                         4D 69 63               Mic
 7D80  72 6F 73 6F 66 74 2C 49 6E 63 20 69 62 6D 62 69  rosoft,Inc ibmbi
 7D90  6F 20 20 63 6F 6D 30 69 62 6D 64 6F 73 20 20 63  o  com0ibmdos  c
 7DA0  6F 6D 30                                          om0
        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F


 

 


Footnotes

1[Return to Text]  Some 3rd party ROM upgrades, as noted on our Tech Notes page, may allow various MS-DOS versions to access and work with 160 KiB diskettes. Do you have a PC Compatible that can actually copy 160 KiB diskettes? And if so, under which version(s) of DOS?

2[Return to Text]  From the perspective of computer forensics or hackers, specifically anyone using DEBUG.COM (or similar utilities), these dual-sided diskettes were very confusing at first, and then required extra effort and time to work with, due to the following decisions made by its developer(s): The Absolute (or Relative) Sector count increases sequentially from 0 to 13Fh (319) for all of the sectors on Side 0 before starting to count any sectors on Side 1; which are Sectors 140h (320) through 27Fh (639). However, the contents of any file which needs to continue from one 8-sector Track to another will alternate from one Side to the other, understandably, to keep the time for moving the drive's heads to a minimum. Yet it was also decided that the Cluster Numbers would directly reference the data no matter where it was written on the diskette. Thus, we have what appears to be some strange facts for these diskettes: The contents, for example, of IBMBIO.COM (1,920 bytes; allocated in four 512-byte sectors) can be found in Clusters 2 and 3 (each cluster is now 1024 bytes each), but those two clusters are on Sectors 142h (322) through 145h (325). Now imagine the extra work needed to view a file using DEBUG, when its contents are spread across many sectors on both sides of a diskette!   Note: Pages C-13 through C-19 of the Disk Operating System, Second Edition (May, 1982), Version 1.10, © Copyright International Business Machines Corporation 1981, contain a "Map" (a table) showing the Track, Sector, Side, Relative Sector and Cluster Number for each sector on a dual-sided diskette. This very useful guide to PC DOS can be downloaded as a PDF from: Bit Savers, DOS Version 1.1 Reference. To illustrate the problem, look at where the three DOS System files are located on a 320 KiB diskette:

    Name   .Ext   Size  Allocated  Clusters      Absolute Sectors    (Image File Sectors)

     FAT1/FAT2    1024      -          0        1h (001) -   2h (002)       1 - 2     (Side 0)
     Directory    3584      -          0        3h (003) -   7h (007)       3 - 7     (Side 0)
                                       0      140h (320) - 141h (321)       8 - 9     (Side 1)
   IBMBIO   COM   1920    2,048      2 - 3    142h (322) - 145h (325)      10 - 13    (Side 1)
   IBMDOS   COM   6400    7,168*       4      146h (326) - 147h (327)      14 - 15    (Side 1)
                                     5 - 8      8h (008) - 00Fh (015)      16 - 23    (Side 0)
                                     9 - 10   148h (328) - 14Bh (331)      24 - 27    (Side 1)
   COMMAND  COM   4959    5,120     11 - 12   14Ch (332) - 14Fh (335)      28 - 29    (Side 1)
                                    13 - 16    10h (016) -  17h (023)      30 - 37    (Side 0)

   *Allocated space must have an even number of sectors since each cluster is 1024 bytes.

3[Return to Text]  For those who'd like more details about these code segments, here's a comparison of the assembly instructions between the end of the final version of LINK.EXE and the code fragment found in the Boot Sector (note: these are not the locations in Memory where the code would be executed!):

 Offsets in LINK.EXE (version 1.10) & Code         Code from Boot Sector if placed in same locations:
 ---------------------------------------------     --------------------------------------------------
 A352 7505         JNZ    A359                     A352 7505          JNZ     A359
 A354 C6065730FF   MOV    BYTE PTR [3057],FF       A354 C606772FFF    MOV     BYTE PTR [2F77],FF
 A359 837EFC00     CMP    WORD PTR [BP-04],+00     A359 837EFC00      CMP     WORD PTR [BP-04],+00
 A35D 750B         JNZ    A36A                     A35D 750B          JNZ     A36A
 A35F 807EF73B     CMP    BYTE PTR [BP-09],3B      A35F 807EF73B      CMP     BYTE PTR [BP-09],3B
 A363 7505         JNZ    A36A                     A363 7505          JNZ     A36A
 A365 C6065630FF   MOV    BYTE PTR [3056],FF       A365 C606762FFF    MOV     BYTE PTR [2F76],FF
 A36A 89EC         MOV    SP,BP                    A36A 89EC          MOV     SP,BP
 A36C 5D           POP    BP                       A36C 5D            POP     BP
 A36D CA0400       RETF   0004                     A36D CA0400        RETF    0004

As you can see above, after adding the likely missing 75h byte to the beginning of our fragment, the only difference in the code is where two data bytes were located; likely because the earlier code found in the Boot Sector had a shorter total byte count.

4[Return to Text]  Although the next file on the IBM PC DOS 1.00 distribution diskette is COMMAND.COM, it does not matter what the next file on the diskette is, since those 2 or 3 sectors copied into Memory are either never used during the boot process; or for COMMAND.COM, not at these Memory locations! (See next Footnote.)

5[Return to Text]  The fact that copies of these 2 or 3 sectors from COMMAND.COM are never used by the Boot Process in these Memory locations can easily be proven by formatting a diskette using /S to transfer the system files to it, deleting the COMMAND.COM file (using DEL), copying a number of other files to that diskette, and only then copying COMMAND.COM to that diskette, then, finally, putting that diskette in the A: drive and finding that you can boot-up from it! (So, it does not matter where COMMAND.COM is located on the diskette; only where IBMBIO.COM and IBMDOS.COM are located. THEREFORE, whatever happens to be copied from these 2 or 3 sectors at this point in the boot sequence does not matter; only later on is the code from COMMAND.COM made use of (wherever it happens to be located on the diskette).

6[Return to Text]  Thank you Daniel Karlsson for emailing me ("Without the instruction, nothing will be printed by the subroutine.") which called my attention to a broader misconception on my part and a review of the program flow.

 

 


 

First Published: July 29, 2005 (2005.07.29).
Updated: June 10, 2017 (2017.06.10); December 14, 2021 (2021.12.14); big offline update! Added all missing comments, big text revision. December 20, 2021 (2021.12.20); revisions published, more changes, added footnote. December 24, 2021 (2021.12.24); minor revisions, added another footnote. December 25, 2021 (2021.12.25); added notes / link to creating a 320 KiB boot diskette. January 1, 2022 (2022.01.01); finished comments for 320 KiB code, more in footnotes. January 5, 2022 (2022.01.05); added remarks about identifying code at end of FORMAT.COM. January 14, 2022 (2022.01.14); added footnotes 4 and 5.

Last Update: July 27, 2024 (2024.07.27); added footnote 6 after correcting comments.

 

You can reply to us here.

IBM PC DOS 1.10 Index

MBR and Boot Records Index

The Starman's Realm Index