diff --git a/boot/fat32.asm b/boot/fat32.asm index 78e9ca7..6d7f8d5 100644 --- a/boot/fat32.asm +++ b/boot/fat32.asm @@ -4,15 +4,23 @@ nop ; WORD reserved sector count -rsc: equ ( $$ + 0x00E ) +rsc: equ ( $$ + 0x00E ) + ; BYTE number of sectors per cluster sc: equ ( $$ + 0x00D ) + ; BYTE number of FATs fn: equ ( $$ + 0x010 ) + + ; WORD number of root directory entries +rde: equ ( $$ + 0x011 ) + ; DWORD hidden sector count (partition offset) po: equ ( $$ + 0x01C ) + ; DWORD sectors per FAT sf: equ ( $$ + 0x024 ) + ; BYTE drive number (we set it from dl) dn: equ ( $$ + 0x040 ) @@ -43,34 +51,67 @@ mend: push si ret err: call msg - db "DISKERR", 0x0A, 0x0D, 0 + db "ERR", 0x0A, 0x0D, 0 hlt: hlt jmp hlt - ; Requires DWORD ptr and QWORD sector on the stack -read: pop bp + ; offsets relative to FS +offd: ; add offset of cluster data area to DX:AX push cx - mov ax, 0x10 + mov di, [rde] + mov cl, 4 + shr di, cl ; 32 bytes per entry + add ax, di + adc dx, 0 + pop cx +offr: ; add offset to rootdir to DX:AX (FAT12/FAT16 only) + push cx + xor ch, ch + mov cl, byte [fn] +fatlp: add ax, [sf] + adc dx, [sf+2] + loop fatlp + pop cx +offf: ; add offset to FAT table to DX:AX + add ax, word [rsc] + adc dx, 0 + ret + +readp: ; read sector DX:AX from partition + add ax, word [po] + adc dx, word [po+2] + jc err + +readd: ; 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 bp, 0x10 + push bp + + mov si, sp mov ah, 0x42 mov dl, 0x80 - mov si, sp - - mov di, [si+4] + stc int 0x13 jc err - pop ax - pop cx - push bp + add sp, bp + ret - ; Advances [clus] to next FAT entry -next: ; push upper two words for sector num - xor ax, ax - push ax - push ax - +next: ; Advances [clus] to next FAT entry ; get current cluster number mov ax, [clus] mov dx, [clus+2] @@ -83,21 +124,11 @@ shftl: clc rcr ax, 1 loop shftl - ; add reserved sector count - add ax, word [rsc] - adc dx, 0 - - ; push lower dword of sector number - push dx - push ax - - ; push ptr to target buffer - push cs - mov ax, buf - push ax + call offf + mov bx, 0xA0 mov cx, 1 - call read + call readp ; get lower part of cluster number mov si, [clus] @@ -112,8 +143,6 @@ shftl: clc movsw movsw - ; 1x QWORD, 1x DWORD = 12 bytes - add sp, 12 ret ; reads current cluster into [dest] @@ -136,48 +165,18 @@ l02: shr cl, 1 jmp l02 l02e: ; dx:ax is now sector num in data area - - ; get number of FATs - xor ch, ch - mov cl, byte [fn] - ; add their sizes up -floop: add ax, [sf] - adc dx, [sf+2] - loop floop - - ; add reserved sector count - add ax, [rsc] - add dx, 0 - - ; push sector num QWORD - xor cx, cx - push cx - push cx - push dx - push ax - - ; push target buffer DWORD - ; dest gives the segment register - mov ax, [dest] - push ax - push cx - - ; push sector count - ; always an full cluster + call offd + mov bx, [dest] mov cx, [sc] xor ch, ch - call read - - cmp cl, [sc] - jne err + call readp xchg bx, cx mov cl, 5 sal bx, cl add [dest], bx - add sp, 12 ret loadf: call readc @@ -187,7 +186,8 @@ loadf: call readc ret main: call loadf - mov ax, [dest] + mov ax, [0x7C00] + mov cx, [0x7C02] int 3 xor ah,ah @@ -195,16 +195,9 @@ main: call loadf int 0x19 jmp hlt - ; the packing is so that it looks nice in a hexdump - times (0x1E0 - ($-$$)) db 0 - ; directory the kernel is in -tdir: db "RDOS ", 0 ; current cluster number clus: dd 2 - times (0x1F0 - ($-$$)) db 0 - ; filename for the kernel -tfile: db "KERNEL BS ", 0 ; segment register for data dest: dw 0x07c0