drive i/o: improvements regarding reset and stack usage
- read and write now run in the same function, less branching - implemented on-demand controller reset - set up a function stub for int 0x13 for later stack switching
This commit is contained in:
parent
0a2a0e4659
commit
424e174523
111
kernel/drive.asm
111
kernel/drive.asm
@ -17,7 +17,9 @@ biosnum: resb 1
|
|||||||
; absolute, ignores partition
|
; absolute, ignores partition
|
||||||
dskseek: resd 1
|
dskseek: resd 1
|
||||||
|
|
||||||
; bit 0 - dirty flag for dskbuf
|
; bit 0 (1) - dirty flag for dskbuf
|
||||||
|
; bit 1 (2) - controller configured
|
||||||
|
; bit 2 (4) - EBIOS supported
|
||||||
dskflag: resb 1
|
dskflag: resb 1
|
||||||
|
|
||||||
; disk buffer for I/O operations
|
; disk buffer for I/O operations
|
||||||
@ -42,6 +44,13 @@ dinit: ; copy previously set DPT to our data area
|
|||||||
mov word [4*0x1E+2], ds
|
mov word [4*0x1E+2], ds
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; int 13 stub
|
||||||
|
; place reserved for stack switches
|
||||||
|
int13: ;int 3
|
||||||
|
int 0x13
|
||||||
|
;int 3
|
||||||
|
ret
|
||||||
|
|
||||||
; restore DPT to default values if possible
|
; restore DPT to default values if possible
|
||||||
; IN dl bios drive number
|
; IN dl bios drive number
|
||||||
rstdpt: mov ah, 8
|
rstdpt: mov ah, 8
|
||||||
@ -109,35 +118,6 @@ logdrv: ; dont do anything if drive already selected
|
|||||||
mov [bpb+BPBHS+2], ax
|
mov [bpb+BPBHS+2], ax
|
||||||
.ret: ret
|
.ret: ret
|
||||||
|
|
||||||
calchs: ; put sectors per cylinder into bx
|
|
||||||
mov ax, [bpb+BPBSPT]
|
|
||||||
mul word [bpb+BPBNOS]
|
|
||||||
mov bx, ax
|
|
||||||
; put linear sector num into dx:ax
|
|
||||||
mov ax, [dskseek]
|
|
||||||
mov dx, [dskseek+2]
|
|
||||||
; dx:ax = linear count, bx = sectors / cylinder
|
|
||||||
div bx
|
|
||||||
xchg ax, dx
|
|
||||||
; dx = cylinder, ax = head * spt + sector
|
|
||||||
mov bl, [bpb+BPBSPT]
|
|
||||||
div byte bl
|
|
||||||
; dx = cylinder, al = head, ah = sector
|
|
||||||
xchg dl, dh
|
|
||||||
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
|
|
||||||
mov cx, dx
|
|
||||||
mov dh, al
|
|
||||||
mov dl, [biosnum]
|
|
||||||
mov bx, dskbuf
|
|
||||||
ret
|
|
||||||
|
|
||||||
mapclu: ; counting from begin of cluster area
|
mapclu: ; counting from begin of cluster area
|
||||||
mov bx, [bpb+BPBRDE]
|
mov bx, [bpb+BPBRDE]
|
||||||
mov cl, 4
|
mov cl, 4
|
||||||
@ -175,10 +155,66 @@ read: push ax
|
|||||||
mov [dskseek], ax
|
mov [dskseek], ax
|
||||||
mov [dskseek+2], dx
|
mov [dskseek+2], dx
|
||||||
; do the actual read
|
; do the actual read
|
||||||
; TODO: error handling & retries
|
|
||||||
call calchs
|
; set the operation code and back it up to the stack
|
||||||
mov ax, 0x0201
|
_read: mov ch, 2
|
||||||
int 0x13
|
db 0x3D ; cmp ax, imm16: causes next instr to be skipped
|
||||||
|
_write: mov ch, 3
|
||||||
|
mov cl, 1 ; read len
|
||||||
|
; TODO: do ebios i/o
|
||||||
|
; check if we can skip controller reset
|
||||||
|
test byte [dskflag], 2
|
||||||
|
jnz .l01
|
||||||
|
; do controller reset
|
||||||
|
mov dl, [biosnum]
|
||||||
|
mov ah, 0
|
||||||
|
call int13
|
||||||
|
or byte [dskflag], 2
|
||||||
|
.l01: ; put sectors per cylinder into bx
|
||||||
|
mov ax, [bpb+BPBSPT]
|
||||||
|
mul word [bpb+BPBNOS]
|
||||||
|
mov bx, ax
|
||||||
|
; put linear sector num into dx:ax
|
||||||
|
mov ax, [dskseek]
|
||||||
|
mov dx, [dskseek+2]
|
||||||
|
; dx:ax = linear count, bx = sectors / cylinder
|
||||||
|
div bx
|
||||||
|
xchg ax, dx
|
||||||
|
; dx = cylinder, ax = head * spt + sector
|
||||||
|
mov bl, [bpb+BPBSPT]
|
||||||
|
div byte bl
|
||||||
|
; dx = cylinder, al = head, ah = sector
|
||||||
|
xchg dl, dh
|
||||||
|
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
|
||||||
|
; shuffle values around for bios
|
||||||
|
xchg ax, cx
|
||||||
|
xchg cx, dx
|
||||||
|
xchg dh, dl
|
||||||
|
mov dl, [biosnum]
|
||||||
|
mov bx, dskbuf
|
||||||
|
; ah: subfunction selected via cx previously
|
||||||
|
; al: 1 = reading 1 sector
|
||||||
|
; cx: sector and cylinder number
|
||||||
|
; dh: head number
|
||||||
|
; dl: drive number
|
||||||
|
; bx: offset to disk buffer
|
||||||
|
call int13
|
||||||
|
jc .err
|
||||||
|
; clear dirty flag on success
|
||||||
|
and byte [dskflag], 0xFE
|
||||||
|
clc
|
||||||
|
ret
|
||||||
|
.err: ; assume controller is misconfigured
|
||||||
|
and byte [dskflag], 0xFD
|
||||||
|
; exit with carry flag set
|
||||||
|
stc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; mark dskbuf as containing unwritten changes
|
; mark dskbuf as containing unwritten changes
|
||||||
@ -188,11 +224,6 @@ dirty: or byte [dskflag], 1 ; dirty
|
|||||||
; flush buffer if dirty
|
; flush buffer if dirty
|
||||||
flush: test byte [dskflag], 1
|
flush: test byte [dskflag], 1
|
||||||
jz .ret
|
jz .ret
|
||||||
; do the write
|
|
||||||
; TODO: error handling & retries
|
; TODO: error handling & retries
|
||||||
call calchs
|
jmp _write
|
||||||
mov ax, 0x0301
|
|
||||||
int 0x13
|
|
||||||
; remove dirty flag
|
|
||||||
and byte [dskflag], 0xFE
|
|
||||||
.ret: ret
|
.ret: ret
|
||||||
|
Loading…
Reference in New Issue
Block a user