diff --git a/boot/fat32.asm b/boot/fat32.asm index 6d7f8d5..cf825bd 100644 --- a/boot/fat32.asm +++ b/boot/fat32.asm @@ -50,13 +50,15 @@ mloop: lodsb 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 -offd: ; add offset of cluster data area to DX:AX +readd: ; add offset of cluster data area to DX:AX push cx mov di, [rde] mov cl, 4 @@ -64,7 +66,7 @@ offd: ; add offset of cluster data area to DX:AX add ax, di adc dx, 0 pop cx -offr: ; add offset to rootdir to DX:AX (FAT12/FAT16 only) +readr: ; add offset to rootdir to DX:AX (FAT12/FAT16 only) push cx xor ch, ch mov cl, byte [fn] @@ -72,17 +74,14 @@ fatlp: add ax, [sf] adc dx, [sf+2] loop fatlp pop cx -offf: ; add offset to FAT table to DX:AX +readf: ; 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 +read_: ; read sector DX:AX from disk ; qword sector number DX:AX push cs push cs @@ -105,16 +104,15 @@ readd: ; read sector DX:AX from disk mov dl, 0x80 stc int 0x13 - jc err + jc dskerr add sp, bp ret -next: ; Advances [clus] to next FAT entry - ; get current cluster number - mov ax, [clus] - mov dx, [clus+2] +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 @@ -124,31 +122,30 @@ shftl: clc rcr ax, 1 loop shftl - call offf - mov bx, 0xA0 mov cx, 1 - call readp + call readf - ; get lower part of cluster number - mov si, [clus] + 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 - mov di, clus - ; copy dword from FAT to [clus] - movsw - movsw + ; load dword from FAT + lodsw + mov dx, [si] ret ; reads current cluster into [dest] readc: ; load cluster number - mov ax, [clus] - mov dx, [clus+2] + push ax + push dx ; subtract the two dummy entries from FAT start sub ax, 2 @@ -156,47 +153,82 @@ readc: ; load cluster number ; convert cluster number to sector number ; this is some cheapo multiplication with 2^n - mov ch, [sc] + mov cl, [sc] l02: shr cl, 1 jz l02e clc - rcl dx, 1 rcl ax, 1 + rcl dx, 1 jmp l02 l02e: ; dx:ax is now sector num in data area - call offd - mov bx, [dest] mov cx, [sc] xor ch, ch - call readp + call readd - xchg bx, cx + xchg bp, cx mov cl, 5 - sal bx, cl - add [dest], bx + sal bp, cl + add bx, bp + + pop dx + pop ax ret -loadf: call readc + ; load cluster chain DX:AX to [dest]:0 +load: mov bx, 0x07C0 +lloop: call readc call next - cmp word [clus+2], 0x0FFF - jne loadf + cmp word dx, 0x0FFF + jne lloop ret -main: call loadf - mov ax, [0x7C00] - mov cx, [0x7C02] - int 3 + ; 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 - xor ah,ah - int 0x16 - int 0x19 - jmp hlt +main: mov ax, 2 + xor dx, dx + call load - ; current cluster number -clus: dd 2 + ; search for an system directory + mov ah, 0x14 + call search + jne end + + mov ax, [si+0x1A] + mov dx, [si+0x14] + + call load + mov ah, 0x04 + call search + jne end + + mov ax, [si+0x1A] + mov dx, [si+0x14] + + call load + jmp 0:0x7C00 + +end: call msg + db "DIR", 0 + jmp err ; segment register for data dest: dw 0x07c0