rdos/boot/fat32.asm
Nero 1981a8efba fat32 bs: use BPB include header and base off BP
We now set BP once at the start to point to the beginning of the BPB.
Encoding an direct address access can then be done relative to BP, which
saves an immediate byte per access.
2020-03-31 20:03:05 +00:00

239 lines
3.4 KiB
NASM

; 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: