7C3E FA CLI ; Disable maskable Interrupts
7C3F 33C0 XOR AX,AX ; Zero-out the Accumulator and set
7C41 8ED0 MOV SS,AX ; Stack Segment register to ZERO.
7C43 BC007C MOV SP,7C00 ; Stack Pointer top now 0000:7C00
7C46 16 PUSH SS ;|
7C47 07 POP ES ;|Makes sure Extra Segment = ZERO.
7C48 BB7800 MOV BX,0078 ; 0078h ---> BX
7C4B 36C537 LDS SI,SS:[BX] ; SS is still zero...
; Load Far Pointer from [SS:0078]
; into DS:SI (usually 0000:0522).
7C4E 1E PUSH DS
7C4F 56 PUSH SI
7C50 16 PUSH SS
7C51 53 PUSH BX
; The following four instructions will overwrite 11 code bytes starting at 7C3Eh:
7C52 BF3E7C MOV DI,7C3E ; Will overwrite some code bytes!
7C55 B90B00 MOV CX,000B ; Copy CX (0Bh = 11) bytes from ...
7C58 FC CLD ; Clear Direction Flag (df=0).
7C59 F3A4 REP MOVSB ; ... DS:SI to ES:DI (0000:7C3E) and
; following; DI increases to 7C49.
7C5B 06 PUSH ES
7C5C 1F POP DS ; Data Segment set to ZERO.
7C5D C645FE0F MOV BYTE PTR [DI-02],0F ; 0Fh ---> [7C47].
7C61 8B0E187C MOV CX,[7C18] ; Copy SPT ([7C18]) into CX
7C65 884DF9 MOV [DI-07],CL ; Sectors/Track --> [7C42].
; The next two instructions set the Diskette Parameters Table SEG:OFF vector
; at [0:0078] from the original vector of 0000:0522 to our 0000:7C3E address,
; so any DPT look-ups will access the data created here instead:
7C68 894702 MOV [BX+02],AX ; 0000 --> [0:007A]
7C6B C7073E7C MOV WORD PTR [BX],7C3E ; 7C3E --> [0:0078]
7C6F FB STI ; Enable maskable Interrupts
; after the next instruction.
;---------------------------------------------------------------------------
; INT 13 - DISK - RESET DISK SYSTEM
; AH = 00h
; DL = drive (if bit 7 is set both hard disks and floppy disks reset)
; Return: AH = status (see #00234)
; CF clear if successful (returned AH=00h)
; CF set on error
;---------------------------------------------------------------------------
7C70 CD13 INT 13
7C72 7279 JC 7CED ; If CF set, there's a disk error,
; so jump to Error Msg. routine!
7C74 33C0 XOR AX,AX
7C76 3906137C CMP [7C13],AX
7C7A 7408 JZ 7C84
7C7C 8B0E137C MOV CX,[7C13] ; [7C13] = Total Sectors
; 960h = 2400 sectors.
7C80 890E207C MOV [7C20],CX
7C84 A0107C MOV AL,[7C10] ; FAT12 F.S. has two FATs
7C87 F726167C MUL WORD PTR [7C16] ; of 7 sectors each, plus...
7C8B 03061C7C ADD AX,[7C1C]
7C8F 13161E7C ADC DX,[7C1E]
7C93 03060E7C ADD AX,[7C0E] ; 1 Rsrvd sector (VBR itself)
7C97 83D200 ADC DX,+00
7C9A A3507C MOV [7C50],AX
7C9D 8916527C MOV [7C52],DX
7CA1 A3497C MOV [7C49],AX
7CA4 89164B7C MOV [7C4B],DX
7CA8 B82000 MOV AX,0020 ; 20h = 32 bytes per Dir entry
7CAB F726117C MUL WORD PTR [7C11] ; [7C11] is number of possible
; Root Directory entries (224).
; So, AX now contains (32 x 224 = 7,168) more used system area in bytes.
7CAF 8B1E0B7C MOV BX,[7C0B] ; [7C0B] is 512 bytes per sector.
7CB3 03C3 ADD AX,BX ; Add 1 more sector in bytes.
7CB5 48 DEC AX ; Subtract 1 byte.
7CB6 F7F3 DIV BX ; Divide by 512 to get sectors.
7CB8 0106497C ADD [7C49],AX
7CBC 83164B7C00 ADC WORD PTR [7C4B],+00
7CC1 BB0005 MOV BX,0500 ; 500h = 1,280
7CC4 8B16527C MOV DX,[7C52]
7CC8 A1507C MOV AX,[7C50]
7CCB E89200 CALL 7D60
7CCE 721D JB 7CED
7CD0 B001 MOV AL,01
7CD2 E8AC00 CALL 7D81 ; -> Read Sectors
7CD5 7216 JB 7CED
7CD7 8BFB MOV DI,BX
7CD9 B90B00 MOV CX,000B ; 11 characters per file name.
7CDC BEE67D MOV SI,7DE6 ; Points to IO.SYS
7CDF F3 REPZ
7CE0 A6 CMPSB ; Compare "IO.SYS" name to
; first file name in Root Directory of diskette.
7CE1 750A JNZ 7CED ; If not identical, there's a
; disk error or it's not a System disk!
; Now we check if "MSDOS.SYS" is the second file in the Root Directory:
7CE3 8D7F20 LEA DI,[BX+20] ; Points to MSDOS.SYS
7CE6 B90B00 MOV CX,000B
7CE9 F3 REPZ
7CEA A6 CMPSB
7CEB 7418 JZ 7D05
7CED BE9E7D MOV SI,7D9E ; Points to Error Message
7CF0 E85F00 CALL 7D52 ; Display Character String
7CF3 33C0 XOR AX,AX
7CF5 CD16 INT 16 ; Get Keystroke from Keyboard
7CF7 5E POP SI
7CF8 1F POP DS
7CF9 8F04 POP [SI]
7CFB 8F4402 POP [SI+02]
7CFE CD19 INT 19 ; If a key was pressed, then
; Start over again with
; System BOOTSTRAP LOADER.
7D00 58 POP AX
7D01 58 POP AX
7D02 58 POP AX
7D03 EBE8 JMP 7CED
7D05 8B471A MOV AX,[BX+1A]
7D08 48 DEC AX
7D09 48 DEC AX
7D0A 8A1E0D7C MOV BL,[7C0D]
7D0E 32FF XOR BH,BH
7D10 F7E3 MUL BX
7D12 0306497C ADD AX,[7C49]
7D16 13164B7C ADC DX,[7C4B]
7D1A BB0007 MOV BX,0700
7D1D B90300 MOV CX,0003
7D20 50 PUSH AX
7D21 52 PUSH DX
7D22 51 PUSH CX
7D23 E83A00 CALL 7D60
7D26 72D8 JB 7D00
7D28 B001 MOV AL,01
7D2A E85400 CALL 7D81 ; -> Read Sectors
7D2D 59 POP CX
7D2E 5A POP DX
7D2F 58 POP AX
7D30 72BB JB 7CED
7D32 050100 ADD AX,0001
7D35 83D200 ADC DX,+00
7D38 031E0B7C ADD BX,[7C0B]
7D3C E2E2 LOOP 7D20
7D3E 8A2E157C MOV CH,[7C15]
7D42 8A16247C MOV DL,[7C24]
7D46 8B1E497C MOV BX,[7C49]
7D4A A14B7C MOV AX,[7C4B]
7D4D EA00007000 JMP FAR PTR 0070:0000 ; Same as jumping to
; 0000:0700 (start DOS).
SUBROUTINES
; Display Zero-terminated Character String
7D52 AC LODSB
7D53 0AC0 OR AL,AL
7D55 7429 JZ 7D80 ; -> RETurn from Subroutine.
7D57 B40E MOV AH,0E ; Video Function 0Eh
7D59 BB0700 MOV BX,0007 ; Page 0, Mode 7...
7D5C CD10 INT 10 ; of INT 10. 'Tele-
; type Output' AL =
; character to write.
7D5E EBF2 JMP 7D52 ; Loop until done.
;====================================================================
7D60 3B16187C CMP DX,[7C18]
7D64 7319 JNB 7D7F
7D66 F736187C DIV WORD PTR [7C18]
7D6A FEC2 INC DL
7D6C 88164F7C MOV [7C4F],DL
7D70 33D2 XOR DX,DX
7D72 F7361A7C DIV WORD PTR [7C1A]
7D76 8816257C MOV [7C25],DL
7D7A A34D7C MOV [7C4D],AX
7D7D F8 CLC ; Clear Carry Flag (CF=0)
7D7E C3 RET
7D7F F9 STC ; Set Carry Flag (CF=1)
7D80 C3 RET
; READ SECTORS INTO MEMORY
7D81 B402 MOV AH,02 ; Function 02 of INT 13
7D83 8B164D7C MOV DX,[7C4D]
7D87 B106 MOV CL,06
7D89 D2E6 SHL DH,CL
7D8B 0A364F7C OR DH,[7C4F]
7D8F 8BCA MOV CX,DX
7D91 86E9 XCHG CH,CL
7D93 8A16247C MOV DL,[7C24]
7D97 8A36257C MOV DH,[7C25]
7D9B CD13 INT 13
7D9D C3 RET