diff --git a/boot/mbr.asm b/boot/mbr.asm index c7cb2e2..5db6217 100644 --- a/boot/mbr.asm +++ b/boot/mbr.asm @@ -1,136 +1,142 @@ -; Memory layout: -%define self 0x00600 ; 1 sector -%define prog 0x07C00 ; 1 sector - ; FDC fields in VBR -%define spt (prog + 0x18) -%define nos (prog + 0x1A) -%define po (prog + 0x1C) +%define bps (bs + 0x0B) +%define md (bs + 0x15) +%define spt (bs + 0x18) +%define nos (bs + 0x1A) +%define po (bs + 0x1C) -org self -cpu 8086 +; blah dont judge me, i miss 8080 +%macro retnz 0 + jz short ($+3) + ret +%endmacro +%macro callc 1 + jnc short ($+5) + call %1 +%endmacro -init: - cli + cpu 8086 + org 0x0600 +bs: equ 0x7C00 - ; Stack grows down from PSP + 64k - xor ax, ax - mov ss, ax - mov sp, ax +init: cli + xor ax, ax + mov ss, ax + xor sp, sp - push dx + ; save driver number + push dx - ; Relocate from [prog] to [self] - mov ds, ax - mov es, ax - mov si, prog - mov di, self - mov cx, 0x100 - rep movsw + ; save PnP ptr + push es + push di - jmp 0:main + ; Relocate away from bootsector loading area + mov ds, ax + mov es, ax + mov si, bs + mov di, $$ + mov cx, 0x100 + rep movsw -main: - mov bp, 0x3335 - mov si, part1 - mov cx, 4 -.loop: - test BYTE [si], 0x80 - jnz loadpart - add si, 0x10 - loop .loop - jmp error + jmp 0:main -loadpart: - ; transfer starting address into DAP - push si - add si, 0x08 - mov di, dap.blocknum - movsw - movsw - pop si + %include "inc/booterr.asm" - ; load sector - push si - mov si, dap - mov bp, 0x3336 - mov ah, 0x42 - stc - int 0x13 - jc error - pop si + ; find active partition or bail out + ; result in si +findp: mov si, part1 + mov cx, 4 +.loop: test BYTE [si], 0x80 + retnz + add si, 0x10 + loop .loop + call errcll - cmp BYTE [si+4], 0x01 - jne jump +main: ; find active partition + call findp -adjust: - push dx + ; transfer starting address into DAP + push si + add si, 0x08 + mov di, dap.num + movsw + movsw + pop si - mov bp, 0x3337 - mov ah, 0x08 - stc - int 0x13 - jc error + ; load sector + push si + mov si, dap + mov ah, 0x42 + stc + int 0x13 + callc errcll + pop si - ; update sectors per track - xor ax, ax - mov al, cl - mov [spt], ax + ; FAT bpb has "bytes per sector" at this place + ; we support only 512 byte sectors anyways + cmp word [bps], 512 + jne chain - ; update number of sides - xor ax, ax - mov al, dh - mov [nos], ax + ; Media descriptor byte is never smaller than 0xF0 + cmp byte [md], 0xF0 + jc chain - ; update partition offset - push si - add si, 0x08 - mov di, po - movsw - movsw - pop si + ; ask BIOS what our disk geometry is + mov ah, 0x08 + stc + int 0x13 + jc chain - pop dx + ; ES might be messed up from int 13h, fix it + push cs + pop es -jump: - jmp 0:prog + ; update sectors per track + xor ax, ax + mov al, cl + mov [spt], ax -error: - mov ax, bp - mov ah, 0x0e - mov bx, 7 - int 0x10 - mov al, 0x21 - int 0x10 - xor ax, ax - int 0x16 - int 0x19 + ; update number of sides + xor ax, ax + mov al, dh + mov [nos], ax + + ; update partition offset + push si + add si, 0x08 + mov di, po + movsw + movsw + pop si + +chain: ; restore PnP structure + pop di + pop es + pop dx + xor cx, cx + mov bp, si + ; chain into partition boot sector + jmp 0:bs dap: -.size: - db 0 - db 0 -.count: - dw 1 -.buffer: - dw prog - dw 0 -.blocknum: - dq 0 +.size: db 0 + db 0 +.count: dw 1 +.buf: dw bs + dw 0 +.num: dq 0 -times (0x1BE - ($-$$)) db 0 -part1: - db 0x80 -.chs_start: - db 0xFF, 0xFF, 0xFF -.type: - db 0x01 -.chs_end: - db 0xFF, 0xFF, 0xFF -.begin: - dd 1 -.end: - dd (FLOPPY * 2) + times (0x1BE - ($-$$)) db 0 -times (0x1FE - ($-$$)) db 0 -dw 0xAA55 +part1: db 0x80 + db 0xFF, 0xFF, 0xFF + db 0x01 + db 0xFF, 0xFF, 0xFF + dd 1 + dd (FLOPPY * 2) + + times (0x1FE - ($-$$)) db 0 + + ; Boot signature + dw 0xAA55