implement fcb search with more efficient segmenting and dta use

This commit is contained in:
Nero 2021-02-25 00:45:56 +00:00
parent 7c4b84ecb3
commit f702006582
3 changed files with 128 additions and 83 deletions

View File

@ -9,6 +9,7 @@ banner: db "RDOS KERNEL ", V, 0x0A, 0x0D, '$', 0x1A
%include "kernel/char.asm" %include "kernel/char.asm"
%include "inc/bpb.asm" %include "inc/bpb.asm"
%include "kernel/drive.asm" %include "kernel/drive.asm"
%include "kernel/fcb.asm"
section .text section .text
@ -18,20 +19,22 @@ init: call rstseg
mov dx, banner mov dx, banner
call puts call puts
mov byte [testbuf], 5 call rstseg
mov dx, testbuf mov dx, testdta
call gets call setdta
mov dx, testfcb
mov ax, [testbuf] call fndfst
mov cx, [testbuf+2]
mov dx, [testbuf+4]
mov bx, [testbuf+6]
int 3 int 3
hlt: hlt hlt: hlt
jmp hlt jmp hlt
section .data
testfcb db 0, "HELLO ","COM"
times FCBSIZ db 0
section .bss section .bss
testbuf resb 130 testdta resb 128

View File

@ -90,6 +90,7 @@ getprm test byte [dskflag], 4
; copy BIOS dpt table over ours ; copy BIOS dpt table over ours
mov dx, dpt mov dx, dpt
mov bx, di mov bx, di
mov cx, 11
call lodfar call lodfar
.ret ret .ret ret
@ -112,13 +113,15 @@ logdrv cmp dl, [dsknum]
cmp dl, 2 cmp dl, 2
jnc loghdd jnc loghdd
; save info for bios
logfdd mov [biosnum], dl logfdd mov [biosnum], dl
; assume some default values
xor ax, ax
mov word [bpb+BPBHS], ax
mov word [bpb+BPBHS+2], ax
mov word [bpb+BPBNOS], 2 ; 5 1/4" 360kB
mov word [bpb+BPBSPT], 9
; reset dpt to defaults ; reset dpt to defaults
call getprm call getprm
; set default geometry (1.44 MB floppy)
mov word [bpb+BPBNOS], 2
mov word [bpb+BPBSPT], 18
; load boot sector ; load boot sector
xor ax, ax xor ax, ax
xor dx, dx xor dx, dx
@ -133,10 +136,6 @@ logfdd mov [biosnum], dl
; copy SPT to DPT ; copy SPT to DPT
mov al, [bpb+BPBSPT] mov al, [bpb+BPBSPT]
mov [dpt+4], al mov [dpt+4], al
; make sure partition offset is forced zero
xor ax, ax
mov [bpb+BPBHS], ax
mov [bpb+BPBHS+2], ax
.ret ret .ret ret
loghdd sub dl, 2 loghdd sub dl, 2
@ -192,28 +191,13 @@ loghdd sub dl, 2
logerr stc logerr stc
ret ret
; counting from begin of cluster area
mapclu mov bx, [bpb+BPBRDE]
mov cl, 4
shr bx, cl ; 32 bytes per entry
add ax, bx
adc dx, 0
; counting from beginning of dir
; add fat table sizes
maprd xor ch, ch
mov cl, byte [bpb+BPBFN]
.loop add ax, [bpb+BPBFS]
adc dx, 0
loop .loop
; counting from beginning of FAT
; add reserved sector count
mapfat add ax, [bpb+BPBRSC]
adc dx, 0
; count from partition start ; count from partition start
map add ax, [bpb+BPBHS] ; IN dx:ax sector number
maprel add ax, [bpb+BPBHS]
add dx, [bpb+BPBHS+2] add dx, [bpb+BPBHS+2]
; absolute sector count ; absolute sector count
; skip doing a read if sector number matches ; skip doing a read if sector number matches
; IN dx:ax sector number
mapabs cmp ax, [dskseek] mapabs cmp ax, [dskseek]
jne read jne read
cmp dx, [dskseek+2] cmp dx, [dskseek+2]

View File

@ -1,94 +1,152 @@
; FCB layout ; FCB layout
; 1 byte drive (0=default, 1=A:, 2=B:, ...) ; 1 byte drive (0=default, 1=A:, 2=B:, ...)
; 8.3 filename ; 8.3 filename
; 8.3 filename for rename ; 8.3 filename for rename
FCBDEN: equ 23 ; WORD directory entry number FCBSIZ equ 30
FCBSIZ: equ 30
section .data
defdrv db 0
dta dd 0
section .text section .text
; auto-complete drive field in fcb ; auto-complete drive field in fcb
; also returns the drive number ; also logs in the drive
; IN es:bx far ptr FCB ; IN ds:dx far ptr FCB
; OUT dl dl (0=A:, 1=B:, 2=C:, ...) fcbdrv push ds
fcbdrv: mov dl, [es:bx] push dx
mov si, dx
; if currently zero, ...
mov dl, [si] ; 1-based
test dl, dl test dl, dl
jnz .ret jnz .log
call getdd ; replace with current drive
mov dl, al mov dl, [cs:defdrv] ; 0-based
inc dl inc dl
mov [es:bx], dl mov [si], dl ; 1-based
.ret: dec dl .log dec dl
call logdrv ; 0-based
pop dx
pop ds
; if carry flag set, resume stack at bp
; this instant-returns some higher level procs
jnc .ret
mov sp, bp
; duplicate carry bit into all 8 AL bits
; similar to SALC instruction
.ret sbb al, al
ret
; set disk transfer address
; IN DS:DX dta ptr
setdta mov [cs:dta], dx
mov [cs:dta+2], ds
ret
; get disk transfer address
; OUT ES:BX dta ptr
getdta les bx, [cs:dta]
ret ret
; Load root directory entry ; Load root directory entry
; IN ax number of directory entry ; IN ax number of directory entry
; OUT cs:si ptr to directory entry ; OUT cs:di ptr to directory entry
lddir: push ax lddir push ax
push ax
call rstseg
pop ax
mov cl, 4 mov cl, 4
shr ax, cl shr ax, cl
xor dx, dx xor dx, dx
call maprd ; dx:ax = sector number in rootdir
; get si to point to entry ; add sizes of FAT tables
pop si xor ch, ch
mov cl, byte [bpb+BPBFN]
.loop: add ax, [bpb+BPBFS]
adc dx, 0
loop .loop
; add reserved sector count
add ax, [bpb+BPBRSC]
adc dx, 0
; fetch sector (relative to partition)
call maprel
; get di to point to entry
pop di
mov cl, 5 mov cl, 5
shl si, cl shl di, cl
and si, 0x1FF and di, 0x1FF
add si, dskbuf add di, dskbuf
ret ret
; find first matching file ; find first matching file
; IN ES:BX input fcb ; IN DS:DX input fcb
fndfst: ; get and log in drive fndfst mov bp, sp
call fcbdrv call fcbdrv
call logdrv
; set search state to zero ; set search state to zero
push es les di, [cs:dta]
push bx
call getdta
xor ax, ax xor ax, ax
mov [es:bx+0x20+1], ax mov [es:di+FCBSIZ], ax
pop bx
pop es
; find next matching file ; find next matching file
; state is kept in DTA ; state is kept in DTA
fndnxt: ; get net direntry to fetch fndnxt mov bp, sp
call fcbdrv
; get next direntry to fetch
; get number of current entry from DTA ; get number of current entry from DTA
push es .loop les di, [cs:dta]
push bx mov ax, [es:di+FCBSIZ]
call getdta inc word [es:di+FCBSIZ]
mov ax, [es:bx+0x20+1]
inc word [es:bx+0x20+1]
pop bx
pop es
; bail out if we are at end of dir ; bail out if we are at end of dir
cmp ax, [bpb+BPBRDE] cmp ax, [bpb+BPBRDE]
jnc .err jnc .err
; load entry and first byte ; load entry and first byte
push bx push ds
push dx
call lddir call lddir
pop bx pop dx
pop ds
; next if hidden, dir or vol label ; next if hidden, dir or vol label
test byte [si+0x0B], 0xDA test byte [cs:di+0x0B], 0xDA
jnz fndnxt jnz .loop
; bail out if end of dir ; bail out if end of dir
mov al, [si] mov al, [di]
cmp al, 0 cmp al, 0
je .err je .err
; next if deleted entry ; next if deleted entry
cmp al, 0xE5 cmp al, 0xE5
je fndnxt je .loop
; compate DS:SI with ES:BX+1 ; DS:SI := FCB+1
lea di, [bx+1] ; ES:DI := CS:dirent
mov si, dx
push si
inc si
mov ax, cs
mov es, ax
; compare and ; try next if mismatch
mov cx, 11 mov cx, 11
push di
rep cmpsb rep cmpsb
; try next if mismatch pop di
jne fndnxt pop si
clc jne .loop
; create FCB in DTA
call getdta
xchg bx, di
; copy over drive byte
movsb
; copy filename
mov ax, cs
mov ds, ax
mov si, bx
mov cx, 11
rep movsb
; done!
xor ax, ax
ret ret
.err: stc .err: stc
.ret: sbb al, al
ret ret
open: open: