I Like It !

Friday, September 16, 2016

The Executable Code of MBR

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