bits 16 xor ax,ax mov ss,ax mov sp, 0x7C00 sti push ax pop es push ax pop ds cld mov si, 0x7C1B mov di, 0x061B push ax ; [7BFE] = 0000 push di ; [7BFC] = 061B SP=7BFC mov cx, 0x01E5 ; ax=0 cx=0x01E5 si=0x7C1B di=0x61B ; es=0 ds=0 ss=0 sp=0x7C00 rep movsb ; copy 0x01E5=485 bytes from 0x7C1B to 0x061B ; equiv to 512 bytes 7C00->0600, ignoring first 27 retf ; jmp 00:061B, which is the very next instruction. mov si, 0x07BE mov cl, 4 L0020: cmp [si], ch ; lookat bootable bytes of each partn jl short L002D ; bootable byte negative jnz short L003B ; bootable byte pos non zero add si, byte 16 loop L0020 int 0x18 ; after 4 partns, int 0x18 = start cassette basic L002D: ; negative bootable byte mov dx, [si] ; dx is bootable byte and next, bp is its addr mov bp, si L0031: add si, byte 16 dec cx jz short L004D ; if no more partns to look at cmp [si], ch ; ch is always zero jz short L0031 L003B: ; positive bootable byte mov si, 0x0710 ; invalid partition table message L003E: ; print string starting at [si-1] and freeze dec si ; L003F: lodsb ; al = [si], and inc si cmp al, 0 jz short L003E ; infinite loop when end of string zero reached mov bx, 7 ; page 0 foreground colour 7 mov ah, 0x0E ; int 0x10 ; write single character al L004B: jmp short L003F ; go on for next character ; The only escape from the previous part is to here if ; there is exactly one partition with negative first byte ; dl contains that byte, bp its address, [si] should be 55AA L004D: ; no more partns to look at mov [bp+0x25], ax ; ax is still zero xchg ax, si ; si=0, ax=addr of 55AA mov al, [bp+4] ; al = system ident mov ah, 0x06 cmp al, 0x0E jz short L006B ; if sys id is 0E (w95 fat16 LBA) mov ah, 0x0B cmp al, 0x0C jz short L0065 ; if sys id is 0C (w95 fat32 LBA) cmp al, ah jnz short L008F ; if sys id is not 0B (w95 fat32) inc ax ; here if sys is w95-fat32-LBA, with ah=0x0B al=0x0C ; or if sys is w95-fat32, with ah=0x0B al=0x0D L0065: mov byte [bp+0x25], 6 ; word [bp+37] is now 0x0006 jnz short L008F ; here if sys is w95-fat16-LBA, with ah=0x06 al=0x0E L006B: mov bx, 0x55AA ; required for int 0x13/0x41 push ax ; [7BFA]=060E SP=7BFA mov ah, 0x41 int 0x13 ; int 0x13 function 0x41 = check for LBA extensions pop ax ; ax = 0x060E, sp back to 7BFC jc short L008C ; jump if bios extensions not found cmp bx, 0xAA55 jnz short L008C ; confirmation code wrong test cl, 1 jz short L008C ; assume this is another kind of failure mov ah, al ; ax=0x0E0E mov [bp+0x24], dl ; [bp+36]=drive number mov word [0x06A1], 0x1EEB ; here if bios extensions for LBA not present ; or after modifying program if they are present L008C: mov [bp+4], ah ; set sid to 0x0E if LBA ext pres, 0x06 if not L008F: ; all non-specific systems jump straight here mov di, 10 L0092: mov ax, 0x0201 ; read one block using CHS mode mov bx, sp ; buffer starts at SP = 7BFC xor cx, cx ; cylinder and sector = 0 cmp di, byte 5 jg short L00A1 mov cx, [bp+0x25] ; CX = 0006 for w95-fat32, or 0 for all others ; the next instruction will be changed to ; JMP $+1E = L00C1 ; if bios extensions are present L00A1: add cx, [bp+2] ; add cylinder and sector for partn to CX int 0x13 ; read into ES:BX L00A6: jc short L00D1 ; on error reset and try again mov si, 0x0746 ; missing OS message cmp word [0x7DFE], 0xAA55 jz short L010D sub di, byte 5 jg short L0092 L00B8: test si, si jnz short L003F mov si, 0x0727 ; error loading OS message jmp short L004B L00C1: cbw xchg ax, cx push dx cwd add ax, [bp+8] adc dx, [bp+10] call L00E0 pop dx jmp short L00A6 L00D1: dec di jz short L00B8 xor ax,ax int 0x13 ; int 0x13 function 0x00 = reset disc system (dl=drive) jmp short L0092 ; the read-one-block place db 0, 0, 0, 0, 0, 0 L00E0: push si xor si, si push si push si push dx push ax push es push bx push cx mov si, 16 push si mov si,sp push ax push dx mov ax, 0x4200 mov dl, [bp+0x24] ; for next, dl=drive number, DS:SI=addr packet int 0x13 ; int 0x13 function 0x42 = LBA read pop dx pop ax lea sp, [si+16] jc short L010B L0101: inc ax jnz short L0105 inc dx L0105: add bh, 2 loop short L0101 clc L010B: pop si ret L010D: jmp short L0183 L010F: db "Invalid partition table", 0 L0127: db "Error loading operating system", 0 L0146: db "Missing operating system", 0 loc 0x0183 L0183: mov di, sp push ds push di mov si, bp retf loc 0x01BE dd 0, 0, 0, 0 dd 0, 0, 0, 0 dd 0, 0, 0, 0 dd 0, 0, 0, 0 loc 0x01FE db 0x55, 0xAA