kernel: First steps of calculating drive tab data from BPB

This commit is contained in:
Nero 2020-08-31 20:11:05 +00:00
parent cc3fe6c4ee
commit 352540bd25
3 changed files with 77 additions and 118 deletions

View File

@ -2,9 +2,28 @@
org 0x500 org 0x500
%include "inc/bpb.asm" %include "inc/bpb.asm"
%include "inc/mbr.asm"
%include "inc/dpt.asm" %include "inc/dpt.asm"
; drive table entry
struc drive
.biosnum: resb 1
.flag: resb 1
.spc: resw 1
.cylinders: resw 1
.dpt: resb dpt_size
.type: resb 1 ; 12 or 16, depending on FAT type
.fat_offset: resd 1 ; offset of fat table
.fat_num: resw 1 ; number of fat tables
.fat_size: resw 1 ; sectors per fat table
.dir_offset: resd 1 ; offset of root directory
.dir_size: resw 1 ; size of root directory in sectors
.clus_offset: resd 1 ; offset of clusters
.clus_num: resw 1 ; number of clusters
.clus_size: resw 1 ; sectors per cluster
endstruc
; kernel stack size in words ; kernel stack size in words
%define stacksize 512 %define stacksize 512
@ -240,6 +259,7 @@ fputc: push ax
iret iret
%include "kernel/drive.asm" %include "kernel/drive.asm"
%include "kernel/fat.asm"
zero: dw 0 zero: dw 0

View File

@ -2,15 +2,6 @@ section .bss
drives: equ 16 drives: equ 16
; drive table entry
struc drive
.biosnum: resb 1
.flag: resb 1
.spc: resw 1
.cylinders: resw 1
.dpt: resb dpt_size
endstruc
; ptr into currently selected drive ; ptr into currently selected drive
drive_ptr: resw 1 drive_ptr: resw 1

View File

@ -1,111 +1,59 @@
section .bss section .text
; the sector numbers have the partition offset already included load_bpb: mov bx, [drive_ptr]
fat_offset:
resd 1
fat_size:
resd 1
fat_num: ; a byte would be enough, but i want to work with cx
resw 1
rootdir_offset:
resd 1
rootdir_size:
resw 1
clusters_offset:
resd 1
clusters_num:
resd 1
section .text
load_ts: ; load total number of sectors into DX:AX
xor dx, dx
mov ax, [disk_buffer+0x013]
test ax, ax
jnz .ret
mov ax, [disk_buffer+0x020]
mov dx, [disk_buffer+0x022]
.ret: ret
; invoked after disk select
load_bpb:
; read word for "sectors per fat" ; read word for "sectors per fat"
mov ax, [disk_buffer+0x016] mov ax, [diskbuf+0x016]
xor dx, dx xor dx, dx
; if zero, we need to check dword in BPB 7.1 ; if zero, we need to check dword in BPB 7.1
test ax, ax test ax, ax
jnz .short_sf jnz .short_sf
; fail if BPB 7.1 signature is not present ; fail if BPB 7.1 signature is not present
mov cl, [disk_buffer+0x042] mov cl, [diskbuf+0x042]
or cl, 1 or cl, 1
cmp cl, 0x29 cmp cl, 0x29
jne .err jne .err
; load dword ; load dword
mov ax, [disk_buffer+0x024] mov ax, [diskbuf+0x024]
mov dx, [disk_buffer+0x026] mov dx, [diskbuf+0x026]
.short_sf: .short_sf:
; store local value ; store local value
mov [fat_size], ax mov [bx+drive.fat_size], ax
mov [fat_size+2], dx mov [bx+drive.fat_size+2], dx
; copy number of fat's ; copy number of fat's
xor ah, ah xor ah, ah
mov al, [disk_buffer+0x010] mov al, [diskbuf+0x010]
mov [fat_num], ax mov [bx+drive.fat_num], ax
; copy number of root directory entries ; copy number of root directory entries
mov ax, [disk_buffer+0x011] mov ax, [diskbuf+0x011]
mov cl, 4 mov cl, 4
shr ax, cl shr ax, cl
mov [rootdir_size], ax mov [bx+drive.dir_size], ax
; calculate offsets for everything ; calculate offsets for everything
mov ax, [part_offset] xor ax, ax
mov dx, [part_offset+2] xor dx, dx
; add reserved sectors ; add reserved sectors
add ax, [disk_buffer+0x0B+bpb_rsc] add ax, [diskbuf+0x0B+bpb_rsc]
adc ax, 0 adc ax, 0
; save begin of FAT tables ; save begin of FAT tables
mov [fat_offset], ax mov [bx+drive.fat_offset], ax
mov [fat_offset+2], dx mov [bx+drive.fat_offset+2], dx
; add FAT size * FAT number ; add FAT size * FAT number
mov cx, [fat_num] mov cx, [bx+drive.fat_num]
.floop: add ax, [fat_size] .floop: add ax, [bx+drive.fat_size]
adc dx, [fat_size+2] adc dx, [bx+drive.fat_size+2]
loop .floop loop .floop
; save begin of root directories ; save begin of root directories
mov [rootdir_offset], ax mov [bx+drive.dir_offset], ax
mov [rootdir_offset+2], dx mov [bx+drive.dir_offset+2], dx
; add root directory size (might be zero) ; add root directory size (might be zero)
add ax, [rootdir_size] add ax, [bx+drive.dir_size]
adc dx, 0 adc dx, 0
; save start of data area ; save start of data area
mov [clusters_offset], ax mov [bx+drive.clus_offset], ax
mov [clusters_offset+2], dx mov [bx+drive.clus_offset+2], dx
call load_ts
add ax, [part_offset]
adc dx, [part_offset+2]
sub ax, [clusters_offset]
sbb dx, [clusters_offset+2]
; get "sectors per cluster"
mov cl, [disk_buffer+0x00D]
; this turns dx:ax from data sectors to number of clus
.sloop: shr cl, 1
test cl, cl
jz .send
clc
rcr dx, 1
rcr ax, 1
jmp .sloop
.send: mov [clusters_num], ax
mov [clusters_num+2], dx
int 3
ret ret
.err: stc .err: stc