rdos/boot/fat.asm

211 lines
3.3 KiB
NASM
Raw Normal View History

2020-09-15 21:38:26 +02:00
; Bootsector for FAT12/FAT16 filesystems
; Memory layout
ourself: equ 0x0800 ; 1 sector, this code
cluslist: equ 0x0A00 ; up-growing list of words
stack: equ 0x7C00 ; growing down
bootsect: equ 0x7C00 ; our origin before reloc
; default buffer for reads
2020-09-15 21:38:26 +02:00
cpu 8086
org 0x0800
jmp short init
nop
%include "inc/bpb.asm"
2020-10-11 23:33:01 +02:00
%define V 0x %+ VERSION
dd V, V
2020-09-15 21:38:26 +02:00
times ( 0x0B - ($-$$) ) db 0
bpb: times BPBSIZ4 db 0
2020-09-15 21:38:26 +02:00
; Area for BPB
times ( 0x3E - ($-$$) ) db 0
init: xor ax, ax
mov ss, ax
mov sp, stack
push sp
2020-09-27 17:10:28 +02:00
push dx
2020-09-15 21:38:26 +02:00
; save potential partition table entry
push ds
push si
mov ds, ax
mov es, ax
mov si, bootsect
mov di, ourself
2020-09-15 21:38:26 +02:00
mov cx, 0x0100
rep movsw
jmp 0x0:main
%include "inc/booterr.asm"
; Read sectors from disk
; IN ES:DI target buffer
; DX:AX absulute 32-bit sector number
; CX numeber of sectors
read: push ax
2020-09-15 21:38:26 +02:00
push cx
push dx
xchg ax, bx
mov al, byte [bp+BPBNOS]
mul byte [bp+BPBSPT]
xchg ax, bx
; dx:ax = lba
div word bx
xchg ax, dx
; dx = cylinder, ax = head * tracksectors + sector
div byte [bp+BPBSPT]
; dx = cylinder, al = head, ah = sector
xchg dl, dh
ror dl, 1
ror dl, 1
or dl, ah
inc dx
; al: head number
; dh bit 0-7: cylinder bits 0-7
; dl bit 0-5: sector bits 0-5
; dl bit 6-7: cylinder bits 8-9
mov cx, dx
mov dh, al
mov dl, [bp-1]
2020-09-15 21:38:26 +02:00
mov ax, 0x0201
mov bx, di
2020-09-15 21:38:26 +02:00
int 0x13
jc errjmp
2020-09-15 21:38:26 +02:00
pop dx
pop cx
pop ax
add ax, 1
adc dx, 0
add di, 0x200
loop read
2020-09-15 21:38:26 +02:00
ret
rootdirsects: mov bx, [bp+BPBRDE]
mov cl, 4
shr bx, cl ; 32 bytes per entry
2020-09-15 21:38:26 +02:00
ret
offset_cluster: ; add offset of cluster data area to DX:AX
call rootdirsects
add ax, bx
adc dx, 0
offset_rootdir: ; add length of fat table times number of fats
2020-09-15 21:38:26 +02:00
xor ch, ch
mov cl, byte [bp+BPBFN]
.loop: add ax, [bp+BPBFS]
adc dx, 0
loop .loop
offset_fat: ; add reserved sectors
add ax, [bp+BPBRSC]
adc dx, 0
offset_part: ; add partition offset
add ax, [bp+BPBHS]
add dx, [bp+BPBHS+2]
2020-09-15 21:38:26 +02:00
ret
resetbuf: ; DS = ES
push es
pop ds
; ES:DI = 07C0:0000
mov ax, ( bootsect >> 4 )
mov es, ax
xor di, di
; AX,CX = 0
xor ax, ax
xor dx, dx
2020-09-15 21:38:26 +02:00
ret
main: mov bp, bpb
mov [bp-1], dl
2020-09-15 21:38:26 +02:00
; load root directory
call resetbuf
push di
call offset_rootdir
call rootdirsects
mov cx, bx
call read
; search for file
pop bx
mov cx, [bp+BPBRDE]
.loop: push cx
mov si, filename
mov di, bx
add bx, 0x20
mov cx, 0x0B
repe cmpsb
pop cx
loopne .loop
jne err_not_found
push word [es:bx-0x20+0x1A]
; load fat table
call resetbuf
push di
call offset_fat
mov cx, [bp+BPBFS]
call read
; fetch cluster numbers (FAT12-specific)
call resetbuf
mov es, ax
mov di, cluslist
pop si ; buffer offset
pop ax ; clus num
push di ; save list for later
readfat: stosw
mov bx, ax
shr bx, 1
pushf
add bx, ax
mov ax, [bx]
popf ; CF: 0=even, 1=odd entry
jc .odd
and ax, 0x0FFF
jmp .both
.odd: mov cl, 4
shr ax, cl
.both: cmp ax, 0xFF8
jc readfat
xor ax, ax
stosw
2020-09-15 21:38:26 +02:00
; load clusters
pop si
call resetbuf
loadclus: lodsw
sub ax, 2
jc .jump
mul byte [bp+BPBSC]
call offset_cluster
xor cx, cx
mov cl, [bp+BPBSC]
call read
jmp loadclus
2020-09-15 21:38:26 +02:00
2020-09-27 17:10:28 +02:00
.jump: pop si
2020-09-15 21:38:26 +02:00
pop ds
2020-09-27 17:10:28 +02:00
pop dx
ret
2020-09-15 21:38:26 +02:00
err_not_found:
hlt: hlt
jmp hlt
times (0x1F3 - ($-$$)) db 0
filename: db "KERNEL ", "BS "
2020-09-15 21:38:26 +02:00
dw 0xAA55