diff --git a/com/@rdos.asm b/com/@rdos.asm index 7bc6e42..fe8fa6f 100644 --- a/com/@rdos.asm +++ b/com/@rdos.asm @@ -9,6 +9,7 @@ banner: db "RDOS KERNEL ", V, 0x0A, 0x0D, '$', 0x1A %include "kernel/char.asm" %include "inc/bpb.asm" %include "kernel/drive.asm" +%include "kernel/fcb.asm" section .text @@ -18,20 +19,22 @@ init: call rstseg mov dx, banner call puts - mov byte [testbuf], 5 - mov dx, testbuf - call gets - - mov ax, [testbuf] - mov cx, [testbuf+2] - mov dx, [testbuf+4] - mov bx, [testbuf+6] + call rstseg + mov dx, testdta + call setdta + mov dx, testfcb + call fndfst int 3 hlt: hlt jmp hlt +section .data + +testfcb db 0, "HELLO ","COM" + times FCBSIZ db 0 + section .bss -testbuf resb 130 +testdta resb 128 diff --git a/kernel/drive.asm b/kernel/drive.asm index e26caee..8037ff5 100644 --- a/kernel/drive.asm +++ b/kernel/drive.asm @@ -90,6 +90,7 @@ getprm test byte [dskflag], 4 ; copy BIOS dpt table over ours mov dx, dpt mov bx, di + mov cx, 11 call lodfar .ret ret @@ -112,13 +113,15 @@ logdrv cmp dl, [dsknum] cmp dl, 2 jnc loghdd - ; save info for bios 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 call getprm - ; set default geometry (1.44 MB floppy) - mov word [bpb+BPBNOS], 2 - mov word [bpb+BPBSPT], 18 ; load boot sector xor ax, ax xor dx, dx @@ -133,10 +136,6 @@ logfdd mov [biosnum], dl ; copy SPT to DPT mov al, [bpb+BPBSPT] 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 loghdd sub dl, 2 @@ -192,28 +191,13 @@ loghdd sub dl, 2 logerr stc 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 -map add ax, [bpb+BPBHS] + ; IN dx:ax sector number +maprel add ax, [bpb+BPBHS] add dx, [bpb+BPBHS+2] ; absolute sector count ; skip doing a read if sector number matches + ; IN dx:ax sector number mapabs cmp ax, [dskseek] jne read cmp dx, [dskseek+2] diff --git a/kernel/fcb.asm b/kernel/fcb.asm index 689d355..f2ce2f6 100644 --- a/kernel/fcb.asm +++ b/kernel/fcb.asm @@ -1,94 +1,152 @@ - ; FCB layout ; 1 byte drive (0=default, 1=A:, 2=B:, ...) ; 8.3 filename ; 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 ; auto-complete drive field in fcb - ; also returns the drive number - ; IN es:bx far ptr FCB - ; OUT dl dl (0=A:, 1=B:, 2=C:, ...) -fcbdrv: mov dl, [es:bx] + ; also logs in the drive + ; IN ds:dx far ptr FCB +fcbdrv push ds + push dx + mov si, dx + ; if currently zero, ... + mov dl, [si] ; 1-based test dl, dl - jnz .ret - call getdd - mov dl, al + jnz .log + ; replace with current drive + mov dl, [cs:defdrv] ; 0-based inc dl - mov [es:bx], dl -.ret: dec dl + mov [si], dl ; 1-based +.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 ; Load root directory entry ; IN ax number of directory entry - ; OUT cs:si ptr to directory entry -lddir: push ax + ; OUT cs:di ptr to directory entry +lddir push ax + push ax + call rstseg + pop ax mov cl, 4 shr ax, cl xor dx, dx - call maprd - ; get si to point to entry - pop si + ; dx:ax = sector number in rootdir + ; add sizes of FAT tables + 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 - shl si, cl - and si, 0x1FF - add si, dskbuf + shl di, cl + and di, 0x1FF + add di, dskbuf ret ; find first matching file - ; IN ES:BX input fcb -fndfst: ; get and log in drive + ; IN DS:DX input fcb +fndfst mov bp, sp call fcbdrv - call logdrv ; set search state to zero - push es - push bx - call getdta + les di, [cs:dta] xor ax, ax - mov [es:bx+0x20+1], ax - pop bx - pop es + mov [es:di+FCBSIZ], ax ; find next matching file ; 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 - push es - push bx - call getdta - mov ax, [es:bx+0x20+1] - inc word [es:bx+0x20+1] - pop bx - pop es +.loop les di, [cs:dta] + mov ax, [es:di+FCBSIZ] + inc word [es:di+FCBSIZ] ; bail out if we are at end of dir cmp ax, [bpb+BPBRDE] jnc .err ; load entry and first byte - push bx + push ds + push dx call lddir - pop bx + pop dx + pop ds ; next if hidden, dir or vol label - test byte [si+0x0B], 0xDA - jnz fndnxt + test byte [cs:di+0x0B], 0xDA + jnz .loop ; bail out if end of dir - mov al, [si] + mov al, [di] cmp al, 0 je .err ; next if deleted entry cmp al, 0xE5 - je fndnxt - ; compate DS:SI with ES:BX+1 - lea di, [bx+1] + je .loop + ; DS:SI := FCB+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 + push di rep cmpsb - ; try next if mismatch - jne fndnxt - clc + pop di + pop si + 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 + .err: stc +.ret: sbb al, al ret open: