Harden drive.asm against unexpected DS and ES values
This commit is contained in:
parent
df243e668e
commit
440187c2a8
@ -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
|
||||||
|
116
kernel/drive.asm
116
kernel/drive.asm
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user