diff --git a/kernel/bpb.asm b/kernel/bpb.asm deleted file mode 100644 index f0213e5..0000000 --- a/kernel/bpb.asm +++ /dev/null @@ -1,31 +0,0 @@ -; IN DL drive number -; BP ptr to bpb_size'd buffer -bpb_load: - push ax - push dx - - mov [bp+(bpb_size-1)], dl - - ; load first sector - xor dx, dx - xor ax, ax - call drive_read - - push cx - push si - push di - - ; copy BPB to BP - mov si, (diskbuf+0x0B) - mov di, bp - mov cx, (bpb_size-1) - rep movsb - - pop di - pop si - pop cx - - pop dx - pop ax - ret - diff --git a/kernel/drive.asm b/kernel/drive.asm index aa4dfc0..cdb1600 100644 --- a/kernel/drive.asm +++ b/kernel/drive.asm @@ -1,6 +1,32 @@ +; Load a sector from drive. +; IN DX:AX sector number (lba) +; BX ptr to FCB +; OUT CL Sector number +; CH Cylinder number +; DH Head number +drive_chs_calc: + push bx ; backup fcb ptr + mov bx, [bx+fcb_spt] ; nos is in BH now + push bx ; backup nos + xor bh, bh ; zero out nos so spt is left + div word bx ; ax:temp = (lba / spt) + inc dx ; dx:sector = (lba % spt) + 1 + mov cl, dl ; sector number + + pop bx ; restore nos + xchg bl, bh ; put nos into bl + xor bh, bh ; zero out spt + div word bx ; ax:cylinder = (temp / nos) + ; dx:head = (temp % nos) + mov ch, al ; cylinder number + mov dh, dl ; head number + + pop bx ; restore fcb ptr + ret + ; Load a sector from drive. ; IN DX:AX sector number -; BP ptr to BPB +; BX ptr to FCB drive_read: push ax push cx @@ -12,19 +38,14 @@ drive_read: or cx, ax jz .fast - div word [bp+13] ; ax:temp = (lba / spt) - inc dx ; dx:sector = (lba % spt) + 1 - mov cl, dl ; sector number + call drive_chs_calc - div word [bp+15] ; ax:cylinder = (tmp / heads) - ; dx:head = (tmp % heads) - mov ch, al ; cylinder number - mov dh, dl ; head number mov si, 5 ; retry count .try: - mov dl, [bp+(bpb_size-1)] ; drive number - mov bx, diskbuf + mov dl, [bx+fcb_drv] ; drive number + dec dl mov ax, 0x0201 + mov bx, diskbuf int 0x13 .giveup: pop si diff --git a/kernel/exec.asm b/kernel/exec.asm index 2e416b5..2632196 100644 --- a/kernel/exec.asm +++ b/kernel/exec.asm @@ -7,7 +7,7 @@ exec: mov bx, sp call fcb_parse - call fcb_open + call fcb_open_rootdir add sp, fcb_size pop bx diff --git a/kernel/fcb.asm b/kernel/fcb.asm index 892e893..ddc6185 100644 --- a/kernel/fcb.asm +++ b/kernel/fcb.asm @@ -1,70 +1,58 @@ -; Parse ASCIIZ string into FCB -; IN SI ptr to filename -; BX ptr to FCB -fcb_parse: - push di - push ax - mov di, bx - xor ax, ax - stosb -.cleanout: - push di - mov cx, 0x0A - mov al, 0x20 - rep stosb - pop di -.base_loop: - call .read - cmp al, 0x2E - je .ext_start - cmp al, 0x20 - je .ret - stosb - jmp .base_loop -.ext_start: - mov di, bx - add di, 9 -.ext_loop: - call .read - cmp al, 0x20 - je .ret - stosb - jmp .ext_loop -.read: - lodsb - test al, al - jz .eret - cmp al, 0x0D - je .eret - ret -.eret: - dec si - pop ax -.ret: - pop ax - pop di - ret +; User-accessible part of FCB (12 bytes) +%define fcb_drv 0 ; 1 byte +%define fcb_fn 1 ; 8 bytes +%define fcb_ext 9 ; 3 bytes -fcb_open: +; Drive & FS data (4 bytes) +%define fcb_spt 12 ; byte sectors per track +%define fcb_nos 13 ; byte number of sides/heads +%define fcb_ss 14 ; byte sector size: 2^ss +%define fcb_cs 15 ; byte cluster size: 2^(ss+cs) + +; Read/Write pointer (12 bytes): +; Will be overwritten by new filename for CL=17 +%define fcb_fsize 16 ; dword file size +%define fcb_fptr 20 ; dword handle position +%define fcb_clus 24 ; word current cluster fptr points in +%define fcb_co 26 ; word start sector for theoretical cluster 0 + +; Link to directory item (3 bytes) +%define fcb_ds 28 ; word directory sector +%define fcb_do 30 ; byte directory offset + +fcb_open_rootdir: cmp byte [bx], 0 jne .drivedone mov al, default_drive inc al mov [bx], al .drivedone: - push bp - sub sp, bpb_size - mov bp, sp - mov dl, [bx] dec dl - call bpb_load - mov ax, [bp] - mov cx, [bp+2] - mov dx, [bp+4] - mov bx, [bp+6] + xor ax, ax + xor dx, dx + ; set directory sector to 0 (=rootdir) + mov [bx+fcb_ds], ax + ; load first sector + call drive_read + + ; transfer sector size + mov ax, [diskbuf + 0x0B] + call log2 + mov byte [bx+fcb_ss], al + + ; transfer cluster size + mov al, [diskbuf + 0x0D] + call log2 + mov byte [bx+fcb_cs], al + + ; transfer sectors per track + mov al, [diskbuf + 0x18] + mov byte [bx+fcb_spt], al + + ; transfer number of heads/sides + mov al, [diskbuf + 0x1A] + mov byte [bx+fcb_nos], al - add sp, bpb_size - pop bp ret diff --git a/kernel/main.asm b/kernel/main.asm index e5154c1..648c02c 100644 --- a/kernel/main.asm +++ b/kernel/main.asm @@ -13,8 +13,7 @@ cpu 8086 %define default_drive BYTE [0x5B] -%define fcb_size 16 -%define bpb_size 18 +%define fcb_size 31 org self jmp init @@ -70,5 +69,6 @@ putc: %include "exec.asm" %include "fcb.asm" -%include "bpb.asm" +%include "fcbparse.asm" %include "drive.asm" +%include "log2.asm" diff --git a/lib/log2.asm b/lib/log2.asm new file mode 100644 index 0000000..cdc2bb8 --- /dev/null +++ b/lib/log2.asm @@ -0,0 +1,14 @@ +; Calculate dual logarithm (int) +; IN AX number +; OUT AX dual logarithm +log2: + push cx + mov cx, 16 +.loop: + sar ax, 1 + loopnz .loop + xchg ax, cx + pop cx + neg ax + add ax, 15 + ret