Harden drive.asm against unexpected DS and ES values

This commit is contained in:
Nero 2021-01-13 18:32:17 +00:00
parent df243e668e
commit 440187c2a8
3 changed files with 87 additions and 69 deletions

View File

@ -38,7 +38,9 @@ relinit: ; print banner
db "RDOS ",2,2, 0x0A, 0x0D, 0 db "RDOS ",2,2, 0x0A, 0x0D, 0
push dx push dx
push ds
call dinit call dinit
pop ds
pop dx pop dx
mov word [0x21*4], int21 mov word [0x21*4], int21

View File

@ -34,63 +34,66 @@ section .text
; initial setup for disk i/o ; initial setup for disk i/o
dinit: ; copy previously set DPT to our data area dinit: ; copy previously set DPT to our data area
lds si, [4*0x1E] push cs
pop es
lds si, [es:4*0x1E]
mov di, dpt mov di, dpt
mov cx, 11 mov cx, 11
rep movsb rep movsb
; restore DS
xor ax, ax
mov ds, ax
; set vector ; set vector
mov word [4*0x1E], dpt mov word [cs:4*0x1E], dpt
mov word [4*0x1E+2], ds mov word [cs:4*0x1E+2], ds
; set to invalid drive ; set to invalid drive
mov byte [dsknum], 0xFF mov byte [cs:dsknum], 0xFF
ret ret
; int 13 stub ; int 13 stub
int13: ; debug output int13: ; debug output
;push bx push bx
;push dx push dx
;push cx push cx
;push ax push ax
;call printf call printf
;db "int13 CALL AX=",2," CX=",2," DX=",2," BX=",2,0x0A,0x0D,0 db "int13 CALL AX=",2," CX=",2," DX=",2," BX=",2,0x0A,0x0D,0
; do the call ; do the call
int 0x13 int 0x13
;jc .err jc .err
ret
.err: push ax
call printf
db "DISK ERR AX=",2,0x0A,0x0D,0
stc
ret ret
.err: ;push ax
;call printf
;db "DISK ERR AX=",2,0x0A,0x0D,0
;stc
;ret
; get drive parameters ; get drive parameters
; read BIOS int13h/AH=8 values ; read BIOS int13h/AH=8 values
; DPT data gets copied over our dpt ; DPT data gets copied over our dpt
; CHS data gets inserted into our bpb ; CHS data gets inserted into our bpb
getprm: test byte [dskflag], 4 getprm: ; skip if EBIOS extension enabled
jnz .nodpt test byte [cs:dskflag], 4
jnz .ret
; do the query ; do the query
mov ah, 8 mov ah, 8
mov dl, [biosnum] mov dl, [cs:biosnum]
call int13 call int13
; bail out if error ; bail out if error
jc .nodpt jc .ret
; ignore CHS values if odd
test cl, cl
jz .nochs
; get and store sector number ; get and store sector number
and cx, 0x3F and cx, 0x3F
mov word [bpb+BPBSPT], cx mov word [cs:bpb+BPBSPT], cx
; get and store number of heads ; get and store number of heads
xchg dl, dh xchg dl, dh
and dx, 0xFF and dx, 0xFF
inc dx inc dx
mov [bpb+BPBNOS], dx mov [cs:bpb+BPBNOS], dx
; test if DPT ptr is non-zero ; test if DPT ptr is non-zero
.nochs: mov ax, es .nochs: mov ax, es
or ax, di or ax, di
test ax, ax test ax, ax
jz .nodpt jz .ret
; DS:SI = ES:DI ; DS:SI = ES:DI
mov ax, es mov ax, es
mov ds, ax mov ds, ax
@ -102,20 +105,21 @@ getprm: test byte [dskflag], 4
; do the copy ; do the copy
mov cx, 11 mov cx, 11
rep movsb rep movsb
.nodpt: ; restore segment registers .ret: ret
xor ax, ax
mov ds, ax
mov es, ax
ret
; log in drive ; log in drive
; IN dl drive number ; IN dl drive number
logdrv: ; dont do anything if drive already selected logdrv: ; DS := CS
push cs
pop ds
; dont do anything if drive already selected
cmp dl, [dsknum] cmp dl, [dsknum]
je logfdd.ret je logfdd.ret
; clear out current contents ; clear out current contents
push dx push dx
push ds
call flush call flush
pop ds
mov ax, 0xFFFF mov ax, 0xFFFF
mov [dskseek], ax mov [dskseek], ax
mov [dskseek+2], ax mov [dskseek+2], ax
@ -130,16 +134,22 @@ logdrv: ; dont do anything if drive already selected
logfdd: ; save info for bios logfdd: ; save info for bios
mov [biosnum], dl mov [biosnum], dl
; reset dpt to defaults ; reset dpt to defaults
push ds
call getprm call getprm
pop ds
; set default geometry (1.44 MB floppy) ; set default geometry (1.44 MB floppy)
mov word [bpb+BPBNOS], 2 mov word [bpb+BPBNOS], 2
mov word [bpb+BPBSPT], 18 mov word [bpb+BPBSPT], 18
; load boot sector ; load boot sector
push ds
xor ax, ax xor ax, ax
xor dx, dx xor dx, dx
call mapabs call mapabs
pop ds
; copy bios parameter block ; copy bios parameter block
; TODO: guess from first byte of FAT if BPB invalid ; TODO: guess from first byte of FAT if BPB invalid
push ds
pop es
mov si, dskbuf+BPBOFF mov si, dskbuf+BPBOFF
mov di, bpb mov di, bpb
mov cx, BPBSIZ4 mov cx, BPBSIZ4
@ -153,6 +163,7 @@ logfdd: ; save info for bios
mov [bpb+BPBHS+2], ax mov [bpb+BPBHS+2], ax
.ret: ret .ret: ret
; assumes that DS == CS
loghdd: sub dl, 2 loghdd: sub dl, 2
cmp dl, 4 cmp dl, 4
jnc logerr jnc logerr
@ -187,17 +198,20 @@ loghdd: sub dl, 2
mov cl, 4 mov cl, 4
sal bx, cl sal bx, cl
; bail out if no partition ; bail out if no partition
cmp byte [dskbuf+0x1be+bx+4], 0 cmp byte [cs:dskbuf+0x1be+bx+4], 0
je logerr je logerr
; load partition offset ; load partition offset
mov ax, [dskbuf+0x1be+bx+8] mov ax, [cs:dskbuf+0x1be+bx+8]
mov dx, [dskbuf+0x1be+bx+8+2] mov dx, [cs:dskbuf+0x1be+bx+8+2]
; save to to stack ; save to to stack
push dx push dx
push ax push ax
; load vbr ; load vbr
call mapabs call mapabs
; copy bpb ; copy bpb
mov ax, cs
mov ds, ax
mov es, ax
mov si, dskbuf+BPBOFF mov si, dskbuf+BPBOFF
mov di, bpb mov di, bpb
mov cx, BPBSIZ4 mov cx, BPBSIZ4
@ -207,15 +221,15 @@ loghdd: sub dl, 2
; fix partition offset ; fix partition offset
pop ax pop ax
pop dx pop dx
mov [bpb+BPBHS], ax mov [cs:bpb+BPBHS], ax
mov [bpb+BPBHS+2], dx mov [cs:bpb+BPBHS+2], dx
ret ret
logerr: stc logerr: stc
ret ret
mapclu: ; counting from begin of cluster area mapclu: ; counting from begin of cluster area
mov bx, [bpb+BPBRDE] mov bx, [cs:bpb+BPBRDE]
mov cl, 4 mov cl, 4
shr bx, cl ; 32 bytes per entry shr bx, cl ; 32 bytes per entry
add ax, bx add ax, bx
@ -223,22 +237,22 @@ mapclu: ; counting from begin of cluster area
maprd: ; counting from beginning of dir maprd: ; counting from beginning of dir
; add fat table sizes ; add fat table sizes
xor ch, ch xor ch, ch
mov cl, byte [bpb+BPBFN] mov cl, byte [cs:bpb+BPBFN]
.loop: add ax, [bpb+BPBFS] .loop: add ax, [cs:bpb+BPBFS]
adc dx, 0 adc dx, 0
loop .loop loop .loop
mapfat: ; counting from beginning of FAT mapfat: ; counting from beginning of FAT
; add reserved sector count ; add reserved sector count
add ax, [bpb+BPBRSC] add ax, [cs:bpb+BPBRSC]
adc dx, 0 adc dx, 0
map: ; count from partition start map: ; count from partition start
add ax, [bpb+BPBHS] add ax, [cs:bpb+BPBHS]
add dx, [bpb+BPBHS+2] add dx, [cs:bpb+BPBHS+2]
mapabs: ; absolute sector count mapabs: ; absolute sector count
; skip doing a read if sector number matches ; skip doing a read if sector number matches
cmp ax, [dskseek] cmp ax, [cs:dskseek]
jne read jne read
cmp dx, [dskseek+2] cmp dx, [cs:dskseek+2]
jne read jne read
ret ret
@ -248,8 +262,8 @@ read: push ax
pop dx pop dx
pop ax pop ax
; store the sector number ; store the sector number
mov [dskseek], ax mov [cs:dskseek], ax
mov [dskseek+2], dx mov [cs:dskseek+2], dx
; do the actual read ; do the actual read
; low level read and write ; low level read and write
@ -259,6 +273,10 @@ _read: mov ch, 2
db 0x3D ; cmp ax, imm16: causes next instr to be skipped db 0x3D ; cmp ax, imm16: causes next instr to be skipped
_write: mov ch, 3 _write: mov ch, 3
mov cl, 1 ; read len mov cl, 1 ; read len
; DS := ES := CS
mov ax, cs
mov ds, ax
mov es, ax
; check if ebios supported ; check if ebios supported
test byte [dskflag], 4 test byte [dskflag], 4
jz .l00 jz .l00
@ -322,11 +340,11 @@ _write: mov ch, 3
ret ret
; mark dskbuf as containing unwritten changes ; mark dskbuf as containing unwritten changes
dirty: or byte [dskflag], 1 ; dirty dirty: or byte [cs:dskflag], 1 ; dirty
ret ret
; flush buffer if dirty ; flush buffer if dirty
flush: test byte [dskflag], 1 flush: test byte [cs:dskflag], 1
jz .ret jz .ret
; TODO: error handling & retries ; TODO: error handling & retries
jmp _write jmp _write

View File

@ -3,7 +3,7 @@ section .text
; set default drive for current process ; set default drive for current process
; IN dl drive number ; IN dl drive number
setdd: push ds setdd: push ds
mov ds, [ss:curpsp] mov ds, [cs:curpsp]
mov [PSPDD], dl mov [PSPDD], dl
pop ds pop ds
ret ret
@ -11,11 +11,23 @@ setdd: push ds
; get default drive for current process ; get default drive for current process
; OUT al drive number ; OUT al drive number
getdd: push ds getdd: push ds
mov ds, [ss:curpsp] mov ds, [cs:curpsp]
mov al, [PSPDD] mov al, [PSPDD]
pop ds pop ds
ret ret
; auto-complete drive field in fcb
; IN ds:dx far ptr FCB
; OUT si copy of dx
fixfcb: mov si, dx
cmp byte [si], 0
jne .ret
call getdd
inc dl
mov byte [si], dl
.ret: mov dx, si
ret
; Load root directory entry ; Load root directory entry
; IN ax number of directory entry ; IN ax number of directory entry
lddir: push ax lddir: push ax
@ -56,22 +68,8 @@ fnfile: mov ax, [es:bx+FCBDEN]
.err: stc .err: stc
ret ret
; initialize a FCB for directory scanning ; Open file using FCB
open: mov word [es:bx+FCBDEN], 0 ; IN DS:DX far ptr to FCB
.search: call fnfile open: call fixfcb
mov al, 0xFF int 3
jc .ret
push si
lea di, [bx+1]
mov cx, 11
rep cmpsb
pop si
jne .search
mov al, 0
.ret: ret
putfn: mov cx, 11
.loop: lodsb
call pputc
loop .loop
ret ret