"In the land of the blind, the one-eyed man is king"
MSDOS 6.2 Boot Sector
7C00 JMP START
7C02 NOP
7C03 bsOEM_NAME DB 'MSDOS5.0' ; 8 bytes
7C0B bsBYTES_PER_SECTOR DW ?
7C0D bsSECTORS_PER_CLUSTER DB ?
7C0E bsRESERVED_SECTORS DW ?
7C10 bsFAT_COPIES DB ?
7C11 bsROOT_DIR_ENTRIES DW ?
7C13 bsTOTAL_DISK_SECTORS DW ?
7C15 bsMEDIA_DESCRIPTOR DB ?
7C16 bsSECTORS_PER_FAT DW ?
7C18 bsSECTORS_PER_TRACK DW ?
7C1A bsSIDES DW ?
7C1C bsHIDDEN_SECTORS_HIGH DW ?
7C1E bsHIDDEN_SECTORS_LOW DW ?
7C20 bsTOTAL_NUM_SECTORS DD ?
7C24 bsPHYS_DRIVE_NUMBER_1 DB ?
7C25 bsPHYS_DRIVE_NUMBER_2 DB ?
7C26 bsBOOT_RECORD_SIG DB 29h
7C27 bsVOL_SERIAL_NUM DD 1F61A800h
7C2B bsVOLUME_LABEL DB 'NO NAME ' ; 11 bytes
7C36 bsFILE_SYSTEM_ID DB 'FAT16 ' ; 8 bytes
[========================================================================]
Disk Parameter Block
The DPB is located in the ROM BIOS at the address pointed to by 0078h.
The 11 bytes starting from START are overwritten at COPY_DPB with the
DPB (7C3E-7C48). This is what the area looks like *after* the copy
at COPY_DPB:
[========================================================================]
7C3E dpbCONTROL_TIMERS DW ?
7C40 dpbMOTOR_OFF_DELAY DB ?
7C41 dpbBYTES_PER_SECTOR DB ?
7C42 dpbSECTORS_PER_TRACK DB ?
7C43 dpbGAP_LENGTH DB ?
7C44 dpbDATA_LENGTH DB ?
7C45 dpbFORMAT_GAP_LENGTH DB ?
7C46 dpbFORMAT_FILLER_BYTE DB ?
7C47 dpbHEAD_SETTLE_TIME DB ?
7C48 dpbMOTOR_START_TIME DB ?
[========================================================================]
Following the copy of the DPB, more information is copied over
previously existing code:
[========================================================================]
7C49 cpbsHIDDEN_SECTORS_HIGH DW ?
7C4B cpbsHIDDEN_SECTORS_LOW DW ?
7C4D DB ?
7C4E DB ?
7C4F DB ?
7C50 cpbsHIDDEN_SECTORS_HIGH DW ?
7C52 cpbsHIDDEN_SECTORS_LOW DW ?
[========================================================================]
Here is the start of the boot sector code. Note that the first 11
bytes will be destroyed later on as described above.
[========================================================================]
7C3E START CLI ; Disable interrupts
7C3F XOR AX,AX ; AX=0000
7C41 MOV SS,AX ; SS=0000
7C43 MOV SP,7C00 ; SP grows in decrements
7C46 PUSH SS
7C47 POP ES ; ES=0000
7C48 MOV BX,0078 ; The address of the ROM
; BIOS disk table is 78h.
; (INT 18h). ROM routine
; copies this address during
; cold boot initialization.
7C4B SS:
7C4C LDS SI,[BX] ; SI points to ROMBIOS table
; The source for the copy
7C4E PUSH DS
7C4F PUSH SI
7C50 PUSH SS
7C51 PUSH BX
7C52 MOV DI,START ; Address of destination
7C55 MOV CX,000B ; Size of area to copy
; (Disk parameters)
7C58 CLD ; Set direction flag to inc
7C59 COPY_DPB REPZ ; Move 11 bytes from the
; disk parameter area to
; overlap with the start
; of the code at 7D3E
; (save space?)
7C5A MOVSB
7C5B PUSH ES
7C5C POP DS ; DS=0000
7C5D MOV BYTE PTR [DI-02],0F
; At this point, DI points
; to 7C49, one byte after
; the last thing copied.
; Destination operand is
; dpbHEAD_SETTLE_TIME.
7C61 MOV CX,bsSECTORS_PER_TRACK
7C65 MOV [DI-07],CL ; Destination operand is
; dpbSECTORS_PER_TRACK.
7C68 MOV [BX+02],AX ; Destination operand is
; dpbMOTOR_OFF_DELAY.
7C6B MOV WORD PTR [BX],START
7C6F STI ; The code at 7C6B installs
; the new Int 1E into the
; interrupt table at
; 0000:0078. At 7C68, AX is
; 0. START is the offset
; for the new INT 1E.
7C70 INT 13 ; Reset drives (AX=0000)
7C72 JB ERROR_IN_BOOT_1
7C74 XOR AX,AX
7C76 CMP bsTOTAL_DISK_SECTORS,AX
7C7A JZ LOOP_1
7C7C MOV CX,bsTOTAL_DISK_SECTORS
7C80 MOV bsTOTAL_NUM_SECTORS,CX
7C84 LOOP_1 MOV AL,bsFAT_COPIES
7C87 MUL WORD PTR bsSECTORS_PER_FAT
7C8B ADD AX,bsHIDDEN_SECTORS_HIGH
7C8F ADC DX,bsHIDDEN_SECTORS_LOW
7C93 ADD AX,bsRESERVED_SECTORS
7C97 ADC DX,+00
7C9A MOV [7C50],AX
7C9D MOV [7C52],DX
7CA1 MOV [7C49],AX
7CA4 MOV [7C4B],DX
7CA8 MOV AX,0020
7CAB MUL WORD PTR bsROOT_DIR_ENTRIES
7CAF MOV BX,bsBYTES_PER_SECTOR
7CB3 ADD AX,BX
7CB5 DEC AX
7CB6 DIV BX
7CB8 ADD [7C49],AX
7CBC ADC WORD PTR [7C4B],+00
7CC1 MOV BX,0500 ; Buffer for root directory
7CC4 MOV DX,[7C4B]
7CC8 MOV AX,[7C49]
7CCB CALL CALCULATE
7CCE JB ERROR_IN_BOOT_1
7CD0 MOV AL,01
7CD2 CALL READ_SECTOR
7CD5 JB ERROR_IN_BOOT_1 ; Error? Print message
; and reboot.
7CD7 MOV DI,BX
7CDC MOV SI,OFFSET FILE_IO_SYS
7CDF REPZ
7CE0 CMPSB
7CE1 JNZ ERROR_IN_BOOT_1 ; First file in root
; dir is not IO.SYS?
; Print error.
7CE3 LEA DI,[BX+20]
7CE6 MOV CX,000B ; 11 characters in DOS
; filename.
7CE9 REPZ
7CEA CMPSB ; Is second file in root
; MSDOS.SYS?
7CEB JZ LOOP_2 ; Yes? Then continue on.
7CED ERROR_IN_BOOT_1 MOV SI,OFFSET NON_SYSTEM_DISK
7CF0 CALL WRITE_STRING
7CF3 XOR AX,AX
7CF5 INT 16
7CF7 POP SI
7CF8 POP DS
7CF9 POP [SI]
7CFB POP [SI+02]
7CFE INT 19
7D00 ERROR_IN_BOOT_2 POP AX
7D01 POP AX
7D02 POP AX
7D03 JMP ERROR_IN_BOOT_1
7D05 LOOP_2 MOV AX,[BX+1A]
7D08 DEC AX
7D09 DEC AX
7D0A MOV BL,SECTORS_PER_CLUSTER
7D0E XOR BH,BH
7D10 MUL BX
7D12 ADD AX,[7C49]
7D16 ADC DX,[7C4B]
7D1A MOV BX,0700 ; DOS loading buffer
7D1D MOV CX,0003
7D20 LOOP_3 PUSH AX
7D21 PUSH DX
7D22 PUSH CX
7D23 CALL CALCULATE
7D26 JB ERROR_IN_BOOT_2
7D28 MOV AL,01
7D2A CALL READ_SECTOR
7D2D POP CX
7D2E POP DX
7D2F POP AX
7D30 JB ERROR_IN_BOOT_1
7D32 ADD AX,0001
7D35 ADC DX,+00
7D38 ADD BX,BYTES_PER_SEC
7D3C LOOP LOOP_3
7D3E MOV CH,MEDIA_DESCRIPTOR
7D42 MOV DL,PHYS_DRIVE_NUMBER_1
7D46 MOV BX,[7C49]
7D4A MOV AX,[7C4B]
7D4D JMP 0070:0000 ; Transfer to ROM BIOS
[========================================================================]
Procedure WRITE_STRING
[========================================================================]
Parameters:
SI: Address of string to write
7D52 WRITE_STRING LODSB
7D53 OR AL,AL
7D55 JZ RETURN_FROM_2
7D57 MOV AH,0E
7D59 MOV BX,0007
7D5C INT 10
7D5E JMP WRITE_STRING
[========================================================================]
Procedure CALCULATE
This procedure probably translates the sector numbers into physical
addresses for the low level BIOS functions.
[========================================================================]
7D60 CALCULATE CMP DX,SECTORS_PER_TRACK
7D64 JNB RETURN_FROM_1
7D66 DIV WORD PTR SECTORS_PER_TRACK
7D6A INC DL
7D6C MOV [7C4F],DL
7D70 XOR DX,DX
7D72 DIV WORD PTR SIDES
7D76 MOV PHYS_DRIVE_NUMBER_2,DL
7D7A MOV [7C4D],AX
7D7D CLC
7D7E RET
7D7F RETURN_FROM_1 STC
7D80 RETURN_FROM_2 RET
[========================================================================]
Procedure READ_SECTOR
[========================================================================]
7D81 READ_SECTOR MOV AH,02 ; 02h is ReadSector .
7D83 MOV DX,[7C4D] ; DH is head/side number.
; DL is drive number.
; (Bit 7 of DL set for HD)
7D87 MOV CL,06 ; CL is sector number.
7D89 SHL DH,CL ; Multiply DH (number of
; heads) by 6.
7D8B OR DH,[7C4F]
7D8F MOV CX,DX
7D91 XCHG CH,CL
7D93 MOV DL,bsPHYS_DRIVE_NUMBER_1
7D97 MOV DH,bsPHYS_DRIVE_NUMBER_2
7D9B INT 13 ; ReadSector
7D9D RET
7D9E NON_SYSTEM_DISK DB 13,10
7DA0 DB 'Non-System disk or disk error'
7DBD DB 13,10
7DBF DB 'Replace and press any key when ready'
7DE3 DB 13,10,0
7DE6 FILE_IO_SYS DB 'IO SYS'
7DF1 FILE_MSDOS_SYS DB 'MSDOS SYS'
7DFC DB 0,0,55,AA