Improve FAT offset calculation

This commit is contained in:
Nero 2020-03-30 15:07:09 +00:00
parent d718777ef6
commit bbe006c9bc
1 changed files with 66 additions and 73 deletions

View File

@ -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