sys: parse drive number and load BPB

This commit is contained in:
Nero 2021-12-11 16:46:00 +00:00
parent a3ef693059
commit 725213b581
8 changed files with 436 additions and 5 deletions

View File

@ -11,7 +11,7 @@ PRODUCT = rdos
LABEL = $(PRODUCT) $(VERSION) LABEL = $(PRODUCT) $(VERSION)
NASM = nasm NASM = nasm
NASM_ARGS = -s -Ilib -DPRODUCT=$(PRODUCT) -DVERSION=$(VERSION) NASM_ARGS = -s -Ilib --before "cpu 8086" -DPRODUCT=$(PRODUCT) -DVERSION=$(VERSION)
QEMU_ARGS += $(shell test -w /dev/kvm && echo --enable-kvm) QEMU_ARGS += $(shell test -w /dev/kvm && echo --enable-kvm)
@ -28,7 +28,7 @@ SYS = host/sys.elf
FIXROM = host/fix-rom.elf FIXROM = host/fix-rom.elf
.PHONY: default clean qemu-floppy5 qemu-floppy3 .PHONY: default clean qemu-floppy5 qemu-floppy3
.PRECIOUS: $(DISTFILES) .PRECIOUS: %.com
default: fd1440.img default: fd1440.img
@ -37,7 +37,7 @@ host/%.elf: host/%.c
$(CC) -o $@ $< $(CC) -o $@ $<
# COM programs # COM programs
%.com: com/%.asm %.com: src/%.asm src/*.inc
$(NASM) $(NASM_ARGS) -o $@ $< $(NASM) $(NASM_ARGS) -o $@ $<
# Bootloaders, first sector on partition # Bootloaders, first sector on partition
@ -86,5 +86,8 @@ qemu-hdd: hdd.img $(ROMS)
qemu-uartctrl: uartctrl.rom chartab.bs qemu-uartctrl: uartctrl.rom chartab.bs
$(QEMU) $(QEMU_ARGS) -option-rom uartctrl.rom -serial stdio -hda chartab.bs $(QEMU) $(QEMU_ARGS) -option-rom uartctrl.rom -serial stdio -hda chartab.bs
dosbox-%: %.com dosbox-%: %.com fd1440.img
dosbox -c "mount P $(CURDIR)" -c "P:" -c "$< $(ARGS)" dosbox -c "mount P $(CURDIR)" -c "P:" -c "IMGMOUNT A: FD1440.IMG -t floppy" -c "$< $(ARGS)" -c "pause" -c "exit"
emu2-%: %.com
emu2 $< $(ARGS)

4
src/@rdos.asm Normal file
View File

@ -0,0 +1,4 @@
mov ax, 0x0e38
int 0x10
halt hlt
jmp halt

63
src/parse.inc Normal file
View File

@ -0,0 +1,63 @@
; make a char uppercase
; IN al char
; OUT al char
; do nothing if >z
ucase cmp al, 0x7B
jnc .ret
; do nothing if <a
cmp al, 0x61
jc .ret
; do it!
sub al, 0x20
.ret ret
; read integer from ascii string
; default dec but allows 0x for hex
; bogus result if larger than 16 bit
; IN ds:si source string
; cx max number of chars
; OUT ax number
; ds:si first rejected char
; cx chars ignored
lodnum xor di, di
mov bx, 10
cmp cx, 2
jc .loop
; test for 0x prefix
mov ax, [si]
cmp al, 0x30
jne .loop
mov al, ah
call ucase
cmp al, 0x58
jne .loop
; apply 0x prefix
.hex add si, 2
sub cx, 2
mov bx, 0x10
; check if there are chars left
.loop test cx, cx
jnz .do
.ret mov ax, di
ret
.do mov al, [si]
call ucase
; check if in range
sub al, 0x30
jc .ret
cmp al, 0x10
jc .skip
sub al, 7
; must be smaller than base
; necessary to prevent hex digits in decimals
.skip mov ah, 0
cmp ax, bx
jnc .ret
; mark as read
inc si
dec cx
; add digit to number
xchg ax, di
mul bx
add di, ax
jmp .loop

75
src/print.inc Normal file
View File

@ -0,0 +1,75 @@
; print AX in base BX
; destroys DX
putnum xor dx, dx
div bx
test cx, cx
loopnz .pad
test ax, ax
je .nib
.pad push dx
call putnum
pop dx
; print lower DL as digit
.nib add dl, 0x30
cmp dl, 0x3a
jl putc
add dl, 7
; print DL as char
putc mov ah, 2
int 0x21
ret
; print str at SI
; NUL-terminated
puts lodsb
test al, al
jz .l01
mov dl, al
call putc
jmp puts
.l01 ret
; print str at return addr
; NUL-terminated
putsh pop si
call puts
jmp si
; print a newline
newlin mov dl, 0x0A
call putc
mov dl, 0x0D
jmp putc
; print register set
; order AX CX DX BX BP SI DI IP
; trashes flags
debug push di
push si
push bp
push bx
push dx
push cx
push ax
mov si, sp
call dump
pop ax
pop cx
pop dx
pop bx
pop bp
pop si
pop di
ret
; dump the 8 words at SI
dump lea di, [si+16]
mov bx, 0x10
.loop lodsw
mov cx, 4
call putnum
mov dl, ' '
call putc
cmp si, di
jc .loop
jmp newlin

157
src/symbols.inc Normal file
View File

@ -0,0 +1,157 @@
; implements a 6-byte symbol table
; starts at s_end and grows down from there
; all functions require DS=+CS
s_start dw 0xC000 ; decreasing with usage
s_end dw 0xC000 ; const
; incremented on freeing an entry
; so we know if its worth searching
s_gaps db 0
; allocate a symbol table entry
; OUT bx ptr to entry
s_alloc mov bx, [s_start]
; check if its worth searching for a gap
cmp byte [s_gaps], 0
je .l04
.l02 cmp bx, [s_end]
jnc .l01
; test if unallocated
cmp byte [bx], 0
jne .l03
; we found one! take note
dec byte [s_gaps]
jmp .l05
.l03 add bx, 8
jmp .l02
; no gap found :/
.l01 mov byte [s_gaps], 0
; extend symbol table at bottom
.l04 mov bx, [s_start]
sub bx, 8
mov [s_start], bx
; insert default values
.l05 mov [bx], dx
mov [bx+2], si
mov [bx+4], di
mov [bx+6], cx
clc
ret
; free a symbol table entry
; IN bx ptr to entry
s_free mov byte [bx], 0
inc byte [s_gaps]
ret
; compare a table entry by string val
; IN bx ptr to entry
; dx:si:di 6-byte ascii name, space padded
; OUT zero flag set if match
s_comp mov ax, [bx]
and ax, 0x7F7F
cmp ax, dx
jne .l01
mov ax, [bx+2]
and ax, 0x7F7F
cmp ax, si
jne .l01
mov ax, [bx+4]
and ax, 0x7F7F
cmp ax, di
.l01 ret
; fill in a backreference
; IN bx ptr to tab entry
; cx value
s_bref push bx
mov bx, [bx+6]
; todo: handle 8-bit relative backrefs
;add [output+bx], cx
pop bx
jmp s_free
; set a symbol
; IN dx:si:di 6-byte ascii name, space padded
; cx value
s_set mov bx, [s_start]
.loop cmp bx, [s_end]
jnc .new
cmp byte [bx], 0
je .next
call s_comp
jne .l01
test byte [bx], 0x80
jnz .bref
stc
ret
; call s_prnt
; call errmsg
; db "DUP", 0
.bref call s_bref
jmp .next
.l01 cmp dl, '.'
je .next
cmp byte [bx], '.'
jne .next
; delete local symbols if current set is non-local
call s_free
.next add bx, 8
jmp .loop
.new jmp s_alloc
; get value of symbol
; IN dx:si:di 6-byte label
; OUT carry clear if label exists
; cx symbol value, or 0 if not found
s_get mov bx, [s_start]
.loop cmp bx, [s_end]
jnc .fail
call s_comp
jnz .next
; skip if backref
test byte [bx], 0x80
jnz .next
mov cx, [bx+6]
clc
ret
.next add bx, 8
jmp .loop
.fail mov cx, 0
stc
ret
; print out a table entry
; IN bx ptr to entry
s_prnt mov dx, [bx]
call putc
mov dl, dh
call putc
mov dx, [bx+2]
call putc
mov dl, dh
call putc
mov dx, [bx+4]
call putc
mov dl, dh
call putc
mov dl, ' '
call putc
mov ax, [bx+6]
mov bx, 0x10
mov cx, 4
call putnum
jmp newlin
; print out the full symbol table
s_dump mov bx, [s_start]
.loop cmp byte [bx], 0
je .next
push bx
call s_prnt
pop bx
.next add bx, 8
cmp bx, [s_end]
jc .loop
ret

87
src/sys.asm Normal file
View File

@ -0,0 +1,87 @@
fcb1 equ 0x5C
org 0x100
jmp main
%include "parse.inc"
%include "print.inc"
main mov di, 0x81
mov al, 0x20
mov ch, 0
mov cl, [0x80]
repe scasb
repne scasb
mov si, di
call lodnum
mov dx, ax
test dx, ~0x83
jnz drverr
test dl, 0x80
jz floppy
call drverr
drverr call putsh
db "Failed to access drive", 0x0A, 0x0D, 0
int 0x20
floppy mov ax, 0x0201
mov cx, 0x0001
mov dh, 0
mov bx, bs
int 0x13
jc drverr
mov ax, [bs+0x18]
call debug
ret
mov dx, fcb1
mov ah, 0xF
int 0x21
test al, al
jz .fok
.ferr call putsh
db "Failed to read input file", 0x0A, 0x0D, 0
ret
.fok mov si, prog
; apply our target address
.rloop mov dx, si
mov ah, 0x1A
int 0x21
; increment address for next iteration
add si, 0x80
; do a read
mov dx, fcb1
mov ah, 0x14
int 0x21
; success: continue
cmp al, 0
jz .rloop
; eof: break
cmp al, 1
jz .cok
; segment wrap: fail
cmp al, 2
jz .ferr
; we assume al=3: eof
.cok nop
mov ax, si
sub ax, args
call debug
call putsh
db "yay", 0x0A,0x0D,0
ret
; mov ax, 0x0201
; mov cx, 0x0001
; mov dh, 0
; mov bx, bs
; int 0x13
; mov ax, [bs+0x18]
;.ret ret
align 2
bs equ $
psp equ bs + 0x200
args equ psp + 0x80
prog equ psp + 0x100

42
src/testsym.asm Normal file
View File

@ -0,0 +1,42 @@
jmp main
%include "print.inc"
%include "symbols.inc"
; OUT cx value of '$' label
asmcur mov cx, 0
ret
; IN cx runtime address
; OUT es:bx address in binary
asmptr mov bx, ds
mov es, bx
mov bx, cx
add bx, buf
ret
main call putsh
db "Normal read-back... ", 0
mov dx, "LA"
mov si, "BE"
mov di, "L1"
mov cx, 0x1234
call s_set
xor cx, cx
call s_get
cmp cx, 0x1234
call testz
ret
testz jnz .fail
call putsh
db "OK", 0x0A, 0x0D, 0
ret
.fail call putsh
db "FAIL", 0x0A, 0x0D, 0
ret
buf times 0x100 db 0