Lay out skeletons for FCB handling

This commit is contained in:
Nero 2020-10-11 21:33:01 +00:00
parent 31c6ef5876
commit 4e779c5a22
5 changed files with 93 additions and 147 deletions

View File

@ -6,10 +6,11 @@ QEMU = qemu-system-i386
QEMU_ARGS = $(addprefix --option-rom ,$(ROMS))
VERSION = $(shell git log -1 --format=%cd --date=format:%Y%m%d)
LABEL = RDOS $(VERSION)
PRODUCT = rdos
LABEL = $(PRODUCT) $(VERSION)
NASM = nasm
NASM_ARGS = -s -Ilib -DVERSION=$(VERSION)
NASM_ARGS = -s -Ilib -DPRODUCT=$(PRODUCT) -DVERSION=$(VERSION)
KVM = $(shell test -w /dev/kvm && echo 1)

View File

@ -14,6 +14,9 @@ bootsect: equ 0x7C00 ; our origin before reloc
%include "inc/bpb.asm"
%define V 0x %+ VERSION
dd V, V
times ( 0x0B - ($-$$) ) db 0
params: times bpb_size db 0

View File

@ -22,12 +22,18 @@ print_banner: mov si, banner
cmp al, 0x0D
jnz .loop
call dskrst
mov dl, 0
call dsksel
hlt: hlt
jmp hlt
banner: db "rdos kernel", 0x0A, 0x0D
%defstr VERSIONSTR VERSION
banner: db "RDOS ", VERSIONSTR, 0x0A, 0x0D
end: align 512
%include "kernel/drive.asm"
section .bss

View File

@ -1,159 +1,40 @@
section .bss
drives: equ 16
; ptr into currently selected drive
drive_ptr: resw 1
drive_table: resb (drives * drive_size)
; DX and CX for int 13 CHS access
chs_dx: resw 1
chs_cx: resw 1
; drive selected for I/O
dsknum: resb 1
; current sector number
dskseek: resd 1
; disk buffer for I/O operations
diskbuf: resb 1024
dskbuf: resb 512
section .text
drives_init: ; CX = number of floppy drives in the system
int 0x11
mov cl, 6
shr ax, cl
inc ax
and ax, 3
mov cx, ax
mov bx, drive_table
xor dx, dx
.loop: push cx
push dx
mov [bx+drive.biosnum], dl
mov byte [bx+drive.flag], 1 ; 1 = drive letter used
; query bios for floppy format
mov ah, 8
push bx
int 0x13
pop bx
; set up defaults if invalid data or fail
jc .defs
test cx, cx
jnz .load
.defs: ; use defaults: 360k, 40 cyl, 9 sects
les di, [0x1e * 4]
mov cx, 0x270
mov dh, 1
.load: ; copy dpt
push es
push ds
pop es
pop ds
push cx
mov si, di
lea di, [bx+drive.dpt]
mov cx, 11
rep movsb
pop cx
; restore ds
push cs
pop ds
; get and save number of cylinders
mov ax, cx
xchg al, ah
rol ah, 1
rol ah, 1
and ax, 0x03FF
inc ax
mov [bx+drive.cylinders], ax
; save spt
mov ax, cx
and al, 0x3F
mov [bx+drive.dpt+dpt.lastsector], al
; multiply with heads and save sectors per cylinder
inc dh
mul dh ; ax = al * dh
mov [bx+drive.spc], ax
; advance loop
pop dx
pop cx
inc dl
add bx, drive_size
loop .loop
ret
ret: ret
; select drive
; IN dl drive number
drive_select: xor dh, dh
mov ax, drive_size
mul dx
add ax, drive_table
mov word [drive_ptr], ax
ret
; reset currently selected drive
drive_reset: mov bx, [drive_ptr]
mov dl, [bx+drive.biosnum]
; our ptr = CX:BX
lea bx, [bx+drive.dpt]
mov cx, ds
; toggle in our ptr
mov si, [0x1E*4]
xchg bx, [si]
xchg cx, [si+2]
; do the call
xor ax, ax
int 0x13
pushf
; restore original ptr
xchg bx, [si]
xchg cx, [si+2]
; pass int 13 flags
popf
ret
; query status of selected drive
; OUT ah
drive_status: mov bx, [drive_ptr]
mov dl, [bx+drive.biosnum]
mov ah, 1
int 0x13
ret
; set sector for read/write operation
; IN dx:ax 32-bit sector number
drive_seek: mov bx, [drive_ptr]
div word [bx+drive.spc]
xchg ax, dx
; dx = cylinder, ax = head * spt + sector
div byte [bx+drive.dpt+dpt.lastsector]
; dx = cylinder, al = head, ah = sector
xchg dl, dh
dsksel: cmp dl, 1
jnc ret
mov al, dl
and al, 0x02
ror dl, 1
ror dl, 1
or dl, ah
inc dx
; al: head number
; dh bit 0-7: cylinder bits 0-7
; dl bit 0-5: sector bits 0-5
; dl bit 6-7: cylinder bits 8-9
xchg al, ah
mov al, [bx+drive.biosnum]
; store
mov word [chs_dx], ax
mov word [chs_cx], dx
cmp dl, byte [dsknum]
je ret
call dskrst
int 3
ret
drive_read: mov ax, 0x0201
mov cx, [chs_cx]
mov dx, [chs_dx]
mov bx, diskbuf
int 0x13
dskrst: call flush
mov ax, 0xFFFF
mov [dsknum], al
mov [dskseek], ax
mov [dskseek+2], ax
ret
drive_write: mov ax, 0x0301
mov cx, [chs_cx]
mov dx, [chs_dx]
mov bx, diskbuf
int 0x13
ret
; flush buffer if dirty
flush: ret

55
kernel/fcb.asm Normal file
View File

@ -0,0 +1,55 @@
; in FCB required
; word offset in rootdir
; used for search
; word current cluster
; byte record num in cluster
; FCB open
fcbopn: ; call fcbfst
; copy match
; store cluster number in fcb
; record = 0
ret
; FCB close
fcbcls: ; flush disk buffer
ret
; FCB find first
fcbfst: ; init search state in FCB
; jmp to fcbnxt
ret
; FCB find next
fcbnxt: ; load rootdir sector from state
; search until next match
; next sec & loop if mismatch
; err exit if no further matches
ret
; FCB delete file
fcbdel: ; call fcbfst
; get search state, load root dir from there
; mark file as deleted
ret
; FCB read
; read sector from cluster into diskbuf
fcbrd: ; read record from sector
; advance record num, carry over to cluster
ret
; FCB write
fcbwr: ; read sector from cluster into diskbuf
; write record into sector
; mark buffer dirty
; advance record num, carry over to cluster
ret
; FCB create
fcbcre:
ret
; FCB rename
fcbren:
ret