; microsoft.windows.95.mbr.asm.txt ; Windows 95 ; MBR ( Master Boot Record ) by Daniel B. Sedory ; http://thestarman.pcministry.com 7C00 FA CLI ; Disable maskable Interrupts 7C01 33C0 XOR AX,AX ; Zero out both the Accumulator and 7C03 8ED0 MOV SS,AX ; the Stack Segment register. 7C05 BC007C MOV SP,7C00 ; Set Stack Pointer to 0000:7C00 7C08 8BF4 MOV SI,SP ; Source Index: Copy from here... 7C0A 50 PUSH AX 7C0B 07 POP ES ; Zero-out Extra Segment 7C0C 50 PUSH AX 7C0D 1F POP DS ; Zero-out Data Segment 7C0E FB STI ; Enable Interrupts again 7C0F FC CLD ; Clear Direction Flag (df=0). 7C10 BF0006 MOV DI,0600 ; Destination Index: New copy of code will begin at 0000:0600 7C13 B90001 MOV CX,0100 ; Copy 256 Words (512 bytes) (100 hex = 256 decimal) 7C16 F2 (*) REP (*) ; REPeat the following MOVSW instruction for 'CX' times(*). 7C17 A5 MOVSW ; Copy two bytes at a time. 7C18 EA1D060000 JMP 0000:061D ; Jump to new copy of code... ; Since the preceding routine copies itself and all of the following ; code to 0000:0600 and then jumps to 0000:061D before continuing to ; run, the following addresses have been changed to reflect the ; code's actual location in memory at the time of execution. ; This next bit of code tries to find an entry in the partition table ; that indicates at least one of them is ACTIVE (i.e., bootable). The ; first byte of a partition entry is used as the indicator: If it's ; an 80h, yes; if 00 then no it's not bootable. If none of the four ; possible partitions is active, then an error message is displayed. 061D BEBE07 MOV SI,07BE ; Location of first entry in the partition table (see Sample Table below). 0620 B304 MOV BL,04 ; Maximum of 4 Table Entries. 0622 803C80 CMP BYTE PTR [SI],80 ; Is this one bootable (80h)? 0625 740E JE 0635 ; Yes, so jump to next test! 0627 803C00 CMP BYTE PTR [SI],00 ; No; is it a 00? If not, it's 062A 751C JNE 0648 ; an Invalid partition table. 062C 83C610 ADD SI,+10 ; Check next entry for 80h ... (10h = 16 bytes per entry) 062F FECB DEC BL ; Subtract 1 from Entry Counter. 0631 75EF JNZ 0622 ; Have all entries been tested? 0633 CD18 INT 18 ; Yes, and NONE of them were bootable, so start...ROM-BASIC (only available onsome IBM machines!) Many BIOS simply display "PRESS A KEY TO REBOOT" when an Interrupt 18h is executed. ; We found an Active partition, so all the other entries are checked ; for being non-bootable (first byte = 0x00), or there's an error! ; (Only one entry in the Partition Table can be marked as 'Active.') ; Before doing so, we load the Head, Drive, Cylinder and Sector data ; into DX and CX for use by the DOS Interrupt 13 commands later. 0635 8B14 MOV DX,[SI] ; Drive -> DL / Head -> DH For the standard MBR code, ; DL will always be 80h; which means ONLY the first drive can ; be bootable! [ This part of the code is often changed by MBR ; replacements to boot from another (second, etc.) drive! ] 0637 8B4C02 MOV CX,[SI+02] ; Sector -> CL / Cylinder -> CH 063A 8BEE MOV BP,SI ; Save offset of Active Entry pass to Volume Boot Sector. 063C 83C610 ADD SI,+10 ; Do next Table Entry 063F FECB DEC BL ; Is this the last entry? 0641 741A JZ 065D ; All Entries look OK, so... -> Jump to Boot-routine! 0643 803C00 CMP BYTE PTR [SI],00 ; Non-bootable entry (00h)? 0646 74F4 JE 063C ; Yes, so check next entry. ; If there was an error, then this next routine displays the message that ; SI points to. After printing the ASCII-Z string (null terminated), the ; program 'locks up' by going into an infinite loop (at 065B): 0648 BE8B06 MOV SI,068B ; -> "Invalid partition table" 064B AC LODSB ; Load byte at [SI] into AL ... and increment the SI value. 064C 3C00 CMP AL,00 ; Is it a zero-byte yet ? 064E 740B JE 065B ; If yes, were done. If not ... 0650 56 PUSH SI ; Store string pointer on stack. 0651 BB0700 MOV BX,0007 ; Use Function 0E (Write Text) of 0654 B40E MOV AH,0E ; DOS Interrupt 10 to send the 0656 CD10 INT 10 ; character in AL to the screen. 0658 5E POP SI 0659 EBF0 JMP 064B 065B EBFE JMP 065B ; Infinite Loop. You must power-down or Reboot! ; Now we can load the first sector of the Active Partition (on most drives, ; this would be Absolute Sector 63 for the first or only partition of your ; Hard Drive. Absolute Sectors 2 thru 62 are normally empty, unless you've ; installed a large MBR replacement, disk translation software for a very ; large HD or some kind of multi-OS or security/encryption boot code). ; The first two words of the partition entry are the drive/head ; and the sector/cylinder numbers of the first partition sector. ; This data is in the format required by the INT 13 call below. 065D BF0500 MOV DI,0005 ; Retry 5 times (if necessary)... 0660 BB007C MOV BX,7C00 ; Load OS Boot Sector to 0000:7C00 0663 B80102 MOV AX,0201 ; Function 02h. Read 1 sector. 0666 57 PUSH DI 0667 CD13 INT 13 ; Note: This old INT 13 Read ; is limited to 1024 cylinders. 0669 5F POP DI 066A 730C JNC 0678 ; Carry Flag set? If no, jump! 066C 33C0 XOR AX,AX ; Yes, so we had an error! Must 066E CD13 INT 13 ; ...reset drive (Function 00h) 0670 4F DEC DI ; Decrement counter (if > 0) 0671 75ED JNZ 0660 ; and try again... 0673 BEA306 MOV SI,06A3 ; Or, declare: "Error loading 0676 EBD3 JMP 064B ; operating system" and hang! ; The section of code above is often changed by MBR replacements that will ; tell you if it ever takes more than ONCE to try loading the OS Boot code! ; Surely you'd want to know this wouldn't you?! ; This old code was obviously made in the days when hard drives, memory ; chips and the boot process itself may have been quite unreliable. ; Once a boot sector for the Active Partition has been loaded into memory, ; it must be checked to see if it is valid. This is accomplished by simply ; checking the last word of the sector; it must be the hex number 0xAA55. 0678 BEC206 MOV SI,06C2 ; -> "Missing operating system" Set up SI, in case we have an error in the Boot Sector read. 067B BFFE7D MOV DI,7DFE ; Point to the last Word of Boot Sector. It should be AA55 Hex. 067E 813D55AA CMP WORD PTR [DI],AA55 ; Is it? ('Signature' Check.) 0682 75C7 JNE 064B ; If not, display Error Message and 'lock-up' system. 0684 8BF5 MOV SI,BP ; SI=BP -> Both are equal to... offset of Active Partition Entry which is used by OS Boot code. 0686 EA007C0000 JMP 0000:7C00 ; Jump to OS Boot Sector code and continue booting-up! ;Location of Error Messages in Memory ;068B 49 6E 76 61 6C Inval ;0690 69 64 20 70 61 72 74 69-74 69 6F 6E 20 74 61 62 id partition tab ;06A0 6C 65 00 45 72 72 6F 72-20 6C 6F 61 64 69 6E 67 le.Error loading ;06B0 20 6F 70 65 72 61 74 69-6E 67 20 73 79 73 74 65 operating syste ;06C0 6D 00 4D 69 73 73 69 6E-67 20 6F 70 65 72 61 74 m.Missing operat ;06D0 69 6E 67 20 73 79 73 74-65 6D 00 ing system.