More boot sector README updates
This commit is contained in:
parent
6d16f582c7
commit
6d8090649f
3 changed files with 203 additions and 109 deletions
|
|
@ -117,8 +117,8 @@ The boot sector of the COMPAQ MS-DOS 1.11 disk image contains the following byte
|
|||
000001e0 00 00 00 00 00 00 00 e7 01 00 00 00 00 00 00 00 |................|
|
||||
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||
|
||||
Unlike most DOS boot sectors, this boot sector doesn't start with an Intel x86 JMP instruction. Let's take a
|
||||
look at the code, using the PCjs Debugger to stop at the first instruction:
|
||||
Unlike most DOS boot sectors, this boot sector doesn't start with an Intel x86 JMP instruction.
|
||||
Let's take a look at the code, using the PCjs Debugger to stop at the first instruction:
|
||||
|
||||
>> bp 0:7c00
|
||||
bp &0000:7C00 set
|
||||
|
|
@ -134,44 +134,38 @@ look at the code, using the PCjs Debugger to stop at the first instruction:
|
|||
&0000:7C04 B8C007 MOV AX,07C0
|
||||
&0000:7C07 8ED0 MOV SS,AX
|
||||
&0000:7C09 FB STI
|
||||
;
|
||||
; At this point, the stack has been set to an unused region INSIDE the boot sector, because
|
||||
; 07C0:01E7 is the same as 0000:7C00+01E7 or 0000:7DE7. This puts a fairly low limit on stack
|
||||
; usage: as more stack is used, the COMPAQ copyright string will be trashed first, then boot
|
||||
; sector data, then boot sector code.
|
||||
;
|
||||
; Curiously, the value 01E7 is also stored at 07C0:01E7. Also curious is the choice of an ODD
|
||||
; address for the stack (although, for the 8088, this presumably didn't affect performance).
|
||||
;
|
||||
|
||||
At this point, the stack has been set to an unused region INSIDE the boot sector, because
|
||||
07C0:01E7 is the same as 0000:7C00+01E7 or 0000:7DE7. This puts a fairly low limit on stack
|
||||
usage: as more stack is used, the COMPAQ copyright string will be trashed first, then boot
|
||||
sector data, then boot sector code.
|
||||
|
||||
Curiously, the value 01E7 is also stored at 07C0:01E7. Also curious is the choice of an ODD
|
||||
address for the stack (although, for the 8088, this presumably didn't affect performance).
|
||||
|
||||
After the next two instructions, all of DS:0, ES:0, and SS:0 point to the beginning of the
|
||||
boot sector (just like CS:7C00):
|
||||
|
||||
&0000:7C0A 8ED8 MOV DS,AX
|
||||
&0000:7C0C 8EC0 MOV ES,AX
|
||||
;
|
||||
; All of DS:0, ES:0, and SS:0 now point to the beginning of the boot sector, as does CS:7C00.
|
||||
;
|
||||
&0000:7C0E 33C0 XOR AX,AX ; perform a disk reset
|
||||
|
||||
This resets the drive:
|
||||
|
||||
&0000:7C0E 33C0 XOR AX,AX ; perform a drive reset
|
||||
&0000:7C10 CD13 INT 13
|
||||
;
|
||||
; Read 1 sector (the 4th sector, which is the first sector of the directory) into memory immediately
|
||||
; above the boot sector (07C0:0200).
|
||||
;
|
||||
|
||||
Next, read 1 sector (the 4th sector, which is the first sector of the directory) into memory
|
||||
immediately above the boot sector (07C0:0200):
|
||||
|
||||
&0000:7C12 B80102 MOV AX,0201
|
||||
&0000:7C15 BB0002 MOV BX,0200
|
||||
&0000:7C18 B90400 MOV CX,0004
|
||||
&0000:7C1B 33D2 XOR DX,DX
|
||||
&0000:7C1D E88B00 CALL 7CAB ; call DISK_IO
|
||||
&0000:7C1D E88B00 CALL 7CAB ; read the disk
|
||||
&0000:7C20 EB1C JMP 7C3E
|
||||
;
|
||||
; ERROR: print error message and start over.
|
||||
;
|
||||
; Setting DS:BX to 07C0:00DA references the same memory as CS:7CDA:
|
||||
;
|
||||
; >> db cs:7cda cs:7d22
|
||||
; &0000:7CDA 0A 0D 4E 6F 6E 2D 53 79-73 74 65 6D 20 64 69 73 ..Non-System dis
|
||||
; &0000:7CEA 6B 20 6F 72 20 64 69 73-6B 20 65 72 72 6F 72 0A k or disk error.
|
||||
; &0000:7CFA 0D 52 65 70 6C 61 63 65-20 61 6E 64 20 73 74 72 .Replace and str
|
||||
; &0000:7D0A 69 6B 65 20 61 6E 79 20-6B 65 79 20 77 68 65 6E ike any key when
|
||||
; &0000:7D1A 20 72 65 61 64 79 0A 0D-24 ready..$
|
||||
;
|
||||
|
||||
Next, the error handler and restart sequence:
|
||||
|
||||
&0000:7C22 BBDA00 MOV BX,00DA
|
||||
&0000:7C25 8A07 MOV AL,[BX]
|
||||
&0000:7C27 3C24 CMP AL,24
|
||||
|
|
@ -188,51 +182,62 @@ look at the code, using the PCjs Debugger to stop at the first instruction:
|
|||
&0000:7C3B EBC3 JMP 7C00 ; start over
|
||||
&0000:7C3D C3 RET ; unreachable RET?
|
||||
|
||||
Here's the error message (setting DS:BX to 07C0:00DA references the same memory as CS:7CDA):
|
||||
|
||||
>> db cs:7cda cs:7d22
|
||||
&0000:7CDA 0A 0D 4E 6F 6E 2D 53 79-73 74 65 6D 20 64 69 73 ..Non-System dis
|
||||
&0000:7CEA 6B 20 6F 72 20 64 69 73-6B 20 65 72 72 6F 72 0A k or disk error.
|
||||
&0000:7CFA 0D 52 65 70 6C 61 63 65-20 61 6E 64 20 73 74 72 .Replace and str
|
||||
&0000:7D0A 69 6B 65 20 61 6E 79 20-6B 65 79 20 77 68 65 6E ike any key when
|
||||
&0000:7D1A 20 72 65 61 64 79 0A 0D-24 ready..$
|
||||
|
||||
Next, we have the code to validate the directory contents:
|
||||
|
||||
&0000:7C3E FC CLD
|
||||
&0000:7C3F 8BF3 MOV SI,BX
|
||||
&0000:7C41 BFC400 MOV DI,00C4 ; ES:DI -> 7C0:C4 (aka 0:7CC4)
|
||||
&0000:7C44 B90B00 MOV CX,000B
|
||||
&0000:7C47 F3 REPZ
|
||||
&0000:7C48 A6 CMPSB
|
||||
&0000:7C49 75D7 JNZ 7C22 ; if first DIRENTRY was not "IOSYS.COM", jump to ERROR
|
||||
&0000:7C49 75D7 JNZ 7C22 ; if first DIRENTRY was not "IOSYS.COM", jump to error handler
|
||||
&0000:7C4B 83C615 ADD SI,0015
|
||||
&0000:7C4E B90B00 MOV CX,000B
|
||||
&0000:7C51 F3 REPZ
|
||||
&0000:7C52 A6 CMPSB
|
||||
&0000:7C53 75CD JNZ 7C22 ; if second DIRENTRY was not "IOSYS.COM", jump to ERROR
|
||||
&0000:7C53 75CD JNZ 7C22 ; if second DIRENTRY was not "IOSYS.COM", jump to error handler
|
||||
&0000:7C55 B80102 MOV AX,0201
|
||||
&0000:7C58 BB0002 MOV BX,0200
|
||||
&0000:7C5B B90200 MOV CX,0002
|
||||
&0000:7C5E 33D2 XOR DX,DX
|
||||
&0000:7C60 E84800 CALL 7CAB ; call DISK_IO to read 1st FAT sector
|
||||
;
|
||||
; At this point, the directory sector is gone, and all this code did with it was verify the names of
|
||||
; the first two entries. It did not examine or record their starting cluster numbers. And in the FAT
|
||||
; sector just read, only one byte (the first byte) will be examined next: the media ID byte.
|
||||
;
|
||||
; Further reading will rely on on two hard-coded tables inside the boot sector: one table at DS:126 (CS:7D26)
|
||||
; if the FAT media ID byte is 0xFE (160Kb diskette), or another table at DS:13C (CS:7D3C) if the FAT media ID
|
||||
; byte is 0xFF (320Kb diskette). If the FAT media ID byte is neither, off to ERROR we go.
|
||||
;
|
||||
; Here's the table for the 160Kb diskette:
|
||||
;
|
||||
; >> dw cs:7d26 l11.
|
||||
; &0000:7D26 0201 0008 0000 0208 0200 0101 0000 0208 ................
|
||||
; &0000:7D36 1000 0201 0000 ......
|
||||
;
|
||||
; and here's the table for the 320Kb diskette:
|
||||
;
|
||||
; >> dw cs:7d3c l11.
|
||||
; &0000:7D3C 0206 0003 0100 0208 0C00 0101 0000 0203 ................
|
||||
; &0000:7D4C 1000 0101 0100 ......
|
||||
;
|
||||
; These tables are then followed by a DWORD jump address:
|
||||
;
|
||||
; >> dw cs:7d52 l2
|
||||
; &0000:7D52 0000 0060 ..`.
|
||||
;
|
||||
; which means that the "JMP FAR [0152]" instruction will jump to 60:0 after the reads are complete.
|
||||
;
|
||||
&0000:7C60 E84800 CALL 7CAB ; read 1st FAT sector
|
||||
|
||||
At this point, the directory sector is gone, and all this code did with it was verify the names of
|
||||
the first two entries. It did not examine or record their starting cluster numbers. And in the FAT
|
||||
sector just read, only one byte (the first byte) will be examined next: the media ID byte.
|
||||
|
||||
Further reading will rely on on two hard-coded tables inside the boot sector: one table at DS:126 (CS:7D26)
|
||||
if the FAT media ID byte is 0xFE (160Kb diskette), or another table at DS:13C (CS:7D3C) if the FAT media ID
|
||||
byte is 0xFF (320Kb diskette). If the FAT media ID byte is neither, off to the error handler we go.
|
||||
|
||||
Here's the table for the 160Kb diskette:
|
||||
|
||||
>> dw cs:7d26 l11.
|
||||
&0000:7D26 0201 0008 0000 0208 0200 0101 0000 0208 ................
|
||||
&0000:7D36 1000 0201 0000 ......
|
||||
|
||||
and here's the table for the 320Kb diskette:
|
||||
|
||||
>> dw cs:7d3c l11.
|
||||
&0000:7D3C 0206 0003 0100 0208 0C00 0101 0000 0203 ................
|
||||
&0000:7D4C 1000 0101 0100 ......
|
||||
|
||||
These tables are then followed by a DWORD jump address:
|
||||
|
||||
>> dw cs:7d52 l2
|
||||
&0000:7D52 0000 0060 ..`.
|
||||
|
||||
which means that the "JMP FAR [0152]" instruction will jump to 60:0 after the reads are complete.
|
||||
|
||||
&0000:7C63 8A27 MOV AH,[BX]
|
||||
&0000:7C65 80FCFE CMP AH,FE
|
||||
&0000:7C68 BE2601 MOV SI,0126
|
||||
|
|
@ -260,9 +265,10 @@ look at the code, using the PCjs Debugger to stop at the first instruction:
|
|||
&0000:7CA1 8B5414 MOV DX,[SI+14]
|
||||
&0000:7CA4 E80400 CALL 7CAB
|
||||
&0000:7CA7 FF2E5201 JMP FAR [0152]
|
||||
;
|
||||
; DISK_IO: read AL sector(s) identified by the CHS values in CX:DX into ES:BX, using DI as a retry counter.
|
||||
;
|
||||
|
||||
The final chunk of code is the disk read interface, which reads AL sector(s) identified by the CHS values in CX:DX
|
||||
into ES:BX, using DI as a retry counter:
|
||||
|
||||
&0000:7CAB BF0500 MOV DI,0005
|
||||
&0000:7CAE 57 PUSH DI
|
||||
&0000:7CAF 50 PUSH AX
|
||||
|
|
@ -279,7 +285,9 @@ look at the code, using the PCjs Debugger to stop at the first instruction:
|
|||
&0000:7CBE 75EE JNZ 7CAE
|
||||
&0000:7CC0 58 POP AX ; retry count exhausted
|
||||
&0000:7CC1 E95EFF JMP 7C22 ; jump to PRINT function
|
||||
|
||||
|
||||
And then we have the assorted strings and tables:
|
||||
|
||||
>> db 7cc4 l13c
|
||||
&7CC4 49 4F 53 59 53 20 20 20-43 4F 4D 4D 53 44 4F 53 IOSYS COMMSDOS
|
||||
&7CD4 20 20 20 43 4F 4D 0A 0D-4E 6F 6E 2D 53 79 73 74 COM..Non-Syst
|
||||
|
|
@ -310,7 +318,11 @@ relieving the code from dealing with head and track size calculations.
|
|||
|
||||
It's arguably an improvement over the [PC-DOS 1.10 Boot Sector](/disks/pcx86/dos/ibm/1.10/#pc-dos-110-boot-sector),
|
||||
because it didn't need to be altered to support both 160Kb and 320Kb diskettes. On the other hand, that flexibility
|
||||
also makes it slightly slower to boot, because it must read the first FAT sector to determine the diskette format.
|
||||
also makes it slightly slower to boot, because it must read the first FAT sector to determine the diskette format.
|
||||
|
||||
Finally, notice the letters `GAS` in the boot sector at offset 0x7D23. Presumably, they're the initials of
|
||||
author, and somewhat less conspicuous and more modest than the `Robert O'Rear` signature in the
|
||||
[PC-DOS 1.00 Boot Sector](/disks/pcx86/dos/ibm/1.00/#pc-dos-100-boot-sector).
|
||||
|
||||
### Mounting the COMPAQ MS-DOS 1.11 Diskette
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue