; Bootsector for FAT32 filesystems org 0x0800 cpu 8086 jmp short init nop %include "inc/bpb.asm" bpb: equ 0x080B ; Area for BPB times ( 0x5A - ($-$$) ) db 0 init: xor ax, ax mov ss, ax mov sp, 0x7C00 ; save potential partition table entry push ds push si mov ds, ax mov es, ax mov si, 0x7C00 mov di, 0x0800 mov cx, 0x0100 rep movsw jmp 0x0:main msg: pop si mloop: lodsb test al, al jz mend mov ah, 0x0e mov bx, 7 int 0x10 jmp mloop mend: push si ret dskerr: call msg db "DISK", 0 err: call msg db "ERR", 0x0A, 0x0D, 0 hlt: hlt jmp hlt ; offsets relative to FS readd: ; add offset of cluster data area to DX:AX push cx mov di, [bp+bpb_rde] mov cl, 4 shr di, cl ; 32 bytes per entry add ax, di adc dx, 0 pop cx readr: ; add offset to rootdir to DX:AX (FAT12/FAT16 only) push cx xor ch, ch mov cl, byte [bp+bpb_fn] fatlp: add ax, [bp+bpb7_lsf] adc dx, [bp+bpb7_lsf+2] loop fatlp pop cx readf: ; add offset to FAT table to DX:AX add ax, word [bp+bpb_rsc] adc dx, 0 readp: ; read sector DX:AX from partition add ax, word [bp+bpb_po] adc dx, word [bp+bpb_po+2] jc err read_: ; read sector DX:AX from disk ; qword sector number DX:AX push cs push cs push dx push ax ; dword target buffer: BX:0 push bx push cs ; word sector number push cx ; size & passing mov di, 0x10 push di mov si, sp mov ah, 0x42 mov dl, [bp+bpb7_dn] stc int 0x13 jc dskerr add sp, di ret next: ; Advances DX:AX to next FAT entry push ax push bx ; shift 2 left for dword-sized FAT entries ; shift 9 right for sector size mov cl, 7 shftl: clc rcr dx, 1 rcr ax, 1 loop shftl mov bx, 0xA0 mov cx, 1 call readf pop bx ; get lower part of cluster number pop si ; multiply with 4 sal si, 1 sal si, 1 ; make sure its within sector range and si, 0x1FF add si, buf ; load dword from FAT lodsw mov dx, [si] ret ; reads current cluster into [dest] readc: ; load cluster number push ax push dx ; subtract the two dummy entries from FAT start sub ax, 2 sbb dx, 0 ; convert cluster number to sector number ; this is some cheapo multiplication with 2^n mov cl, [bp+bpb_sc] l02: shr cl, 1 jz l02e clc rcl ax, 1 rcl dx, 1 jmp l02 l02e: ; dx:ax is now sector num in data area mov cx, [bp+bpb_sc] xor ch, ch call readd xchg di, cx mov cl, 5 sal di, cl add bx, di pop dx pop ax ret ; load cluster chain DX:AX to [dest]:0 load: mov bx, 0x07C0 lloop: call readc call next cmp word dx, 0x0FFF jne lloop ret ; Search for first entry with matching fsattr search: mov si, (0x7C00-0x20) loop: add si, 0x20 ; check if entry is valid mov al, [si] ; unallocated direntry test al, al jz end ; deleted files cmp al, 0xE2 je loop ; check attr mov al, [si+11] and al, 0x5C cmp al, ah jne loop ret loadr: mov ax, 2 xor dx, dx jmp load loadf: call search jne end mov ax, [si+0x1A] mov dx, [si+0x14] jmp load main: mov bp, bpb mov [bp+bpb7_dn], dl ; load root directory call loadr ; search for first system directory mov ah, 0x14 call loadf ; search for first system file mov ah, 0x04 call loadf ; jump xor ax, ax xor cx, cx xor dx, dx xor bx, bx xor di, di ; restore drive number mov dl, [bp+bpb7_dn] ; restore potential partition table pop si pop ds jmp 0:0x7C00 end: call msg db "DIR", 0 jmp err ; Padding and signature times (0x1FE - ($-$$)) db 0 dw 0xAA55 buf: