Improve FAT offset calculation

This commit is contained in:
Nero 2020-03-30 15:07:09 +00:00
parent d718777ef6
commit bbe006c9bc

View File

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