Workstate on disk I/O rework
This commit is contained in:
parent
79a86bad49
commit
e26adff688
19
boot/mbr.asm
19
boot/mbr.asm
@ -1,6 +1,7 @@
|
|||||||
cpu 8086
|
cpu 8086
|
||||||
|
|
||||||
%define seg 0x060
|
%define seg 0
|
||||||
|
%define off 0x700
|
||||||
|
|
||||||
org 0x7C00 - (seg << 4)
|
org 0x7C00 - (seg << 4)
|
||||||
|
|
||||||
@ -16,24 +17,12 @@ init: cli
|
|||||||
.retry: mov ax, 0x0208
|
.retry: mov ax, 0x0208
|
||||||
mov cx, 2
|
mov cx, 2
|
||||||
mov dh, 0
|
mov dh, 0
|
||||||
mov bx, 0x100
|
mov bx, off
|
||||||
|
|
||||||
int 0x13
|
int 0x13
|
||||||
jc .retry
|
jc .retry
|
||||||
|
|
||||||
xor di, di
|
jmp seg:off
|
||||||
mov ax, 0x18CD
|
|
||||||
stosw
|
|
||||||
int 0x12
|
|
||||||
mov cl, 6
|
|
||||||
shl ax, cl
|
|
||||||
stosw
|
|
||||||
mov al, 2
|
|
||||||
stosb
|
|
||||||
mov ax, 0x18CD
|
|
||||||
stosw
|
|
||||||
|
|
||||||
jmp seg:0x100
|
|
||||||
|
|
||||||
times (0x1BE - ($-$$)) db 0
|
times (0x1BE - ($-$$)) db 0
|
||||||
|
|
||||||
|
151
src/@rdos.asm
151
src/@rdos.asm
@ -1,15 +1,15 @@
|
|||||||
|
org 0x700
|
||||||
|
cseg equ 0x0
|
||||||
jmp init
|
jmp init
|
||||||
|
|
||||||
%include "bpb.inc"
|
%include "bpb.inc"
|
||||||
%include "farptr.inc"
|
%include "farptr.inc"
|
||||||
|
|
||||||
; drive actually selected for I/O
|
; dflags bitfields
|
||||||
dsknum db 0xFF
|
DRVLOG equ 0x01 ; bit 0 (1) - drive logged in (see drvnum)
|
||||||
|
DRVRST equ 0x02 ; bit 1 (2) - controller configured
|
||||||
dap db 0x10, 0
|
DRVEXT equ 0x04 ; bit 2 (4) - EBIOS supported
|
||||||
dw 1
|
DIRTY equ 0x08 ; bit 3 (8) - dskbuf dirty
|
||||||
dapbuf dw dskbuf, 0
|
|
||||||
dskseek dw 0,0,0,0
|
|
||||||
|
|
||||||
; initial setup for disk i/o
|
; initial setup for disk i/o
|
||||||
; copy previously set DPT to our data area
|
; copy previously set DPT to our data area
|
||||||
@ -23,8 +23,6 @@ dinit xor ax, ax
|
|||||||
mov es, cx
|
mov es, cx
|
||||||
mov word [es:4*0x1E], dpt
|
mov word [es:4*0x1E], dpt
|
||||||
mov word [es:4*0x1E+2], ds
|
mov word [es:4*0x1E+2], ds
|
||||||
; set segment addr in DAP
|
|
||||||
mov [dapbuf+2], cs
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
@ -36,6 +34,8 @@ i13isp jmp short int13i
|
|||||||
iret
|
iret
|
||||||
align 16
|
align 16
|
||||||
|
|
||||||
|
; Entry point when user program calls int13h
|
||||||
|
; TODO: flush buffer and log out drive
|
||||||
int13i call int13
|
int13i call int13
|
||||||
iret
|
iret
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ getprm test byte [dskflag], 4
|
|||||||
; select a drive for io
|
; select a drive for io
|
||||||
; IN dl drive number
|
; IN dl drive number
|
||||||
; dont do anything if drive already selected
|
; dont do anything if drive already selected
|
||||||
select cmp dl, [dsknum]
|
select cmp dl, [drvnum]
|
||||||
je logfdd.ret
|
je logfdd.ret
|
||||||
; clear out current contents
|
; clear out current contents
|
||||||
push dx
|
push dx
|
||||||
@ -140,7 +140,7 @@ loghdd sub dl, 2
|
|||||||
sbb bx, 0xAA55
|
sbb bx, 0xAA55
|
||||||
jnz .chs
|
jnz .chs
|
||||||
; enable ebios and assume controller is configured
|
; enable ebios and assume controller is configured
|
||||||
or byte [dskflag], (2+4)
|
or byte [dflags], DRVCTL | DRVEXT
|
||||||
; get chs data (needed or we cant load vbr)
|
; get chs data (needed or we cant load vbr)
|
||||||
.chs call getprm
|
.chs call getprm
|
||||||
; read mbr
|
; read mbr
|
||||||
@ -181,74 +181,68 @@ logerr stc
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; map sector into dskbuf
|
; map sector into dskbuf
|
||||||
; sector number from partition start
|
|
||||||
; IN dx:ax sector number
|
|
||||||
map add ax, [bpb+BPBHS]
|
|
||||||
add dx, [bpb+BPBHS+2]
|
|
||||||
; absolute sector count
|
|
||||||
; skip doing a read if sector number matches
|
; skip doing a read if sector number matches
|
||||||
; IN dx:ax sector number
|
; IN dx:ax absolute sector number
|
||||||
mapabs cmp ax, [dskseek]
|
map cmp ax, [drvseek]
|
||||||
jne l003
|
jne .do
|
||||||
cmp dx, [dskseek+2]
|
cmp dx, [drvseek+2]
|
||||||
je l002
|
jne .do
|
||||||
; flush and read other sector
|
ret
|
||||||
l003 push ax
|
; flush previous contents
|
||||||
|
.do push ax
|
||||||
push dx
|
push dx
|
||||||
call flush
|
call flush
|
||||||
pop dx
|
pop dx
|
||||||
pop ax
|
pop ax
|
||||||
; store the sector number
|
; set sector number
|
||||||
mov [dskseek], ax
|
mov [drvseek], ax
|
||||||
mov [dskseek+2], dx
|
mov [drvseek+2], dx
|
||||||
jmp _read
|
; issue read cmd
|
||||||
|
mov ch, 2
|
||||||
|
jmp diskio
|
||||||
|
|
||||||
; mark dskbuf as containing unwritten changes
|
; mark dskbuf as containing unwritten changes
|
||||||
dirty or byte [cs:dskflag], 1 ; dirty
|
dirty or word [cs:dflags], DIRTY
|
||||||
l002 ret
|
l002 ret
|
||||||
|
|
||||||
; flush buffer if dirty
|
; flush buffer if dirty
|
||||||
flush test byte [cs:dskflag], 1
|
flush test word [cs:dflags], DIRTY
|
||||||
jz l002
|
jz l002
|
||||||
; low level read and write
|
; issue write cmd
|
||||||
; call again to retry, no input registers
|
mov ch, 3
|
||||||
; read or write is configured in cx
|
|
||||||
_write mov ch, 3
|
; Do disk I/O
|
||||||
db 0x3D ; cmp ax, imm16: causes next 2 bytes to be skipped
|
; IN ch 2 = read
|
||||||
_read mov ch, 2
|
; 3 = write
|
||||||
mov cl, 1 ; read len
|
; Sector number is read from [drvseek]
|
||||||
|
diskio mov cl, 1 ; read len
|
||||||
; DS := ES := CS
|
; DS := ES := CS
|
||||||
mov ax, cs
|
call rstseg
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
; check if ebios supported
|
; check if ebios supported
|
||||||
test byte [dskflag], 4
|
test word [dflags], DRVEXT
|
||||||
jz .l00
|
jz .noext
|
||||||
|
; set up regs for ebios call
|
||||||
mov ax, cx
|
mov ax, cx
|
||||||
or ah, 0x40
|
or ah, 0x40
|
||||||
mov si, dap
|
mov si, dap
|
||||||
jmp .do
|
jmp .do
|
||||||
; check if we can skip controller reset
|
; check if we can skip controller reset
|
||||||
.l00 test byte [dskflag], 2
|
.noext test word [dflags], DRVRST
|
||||||
jnz .l01
|
jnz .norst
|
||||||
; do controller reset
|
; do controller reset
|
||||||
mov dl, [biosnum]
|
mov dl, [biosnum]
|
||||||
mov ah, 0
|
mov ah, 0
|
||||||
call int13
|
call int13
|
||||||
or byte [dskflag], 2
|
or word [dflags], DRVRST
|
||||||
; put sectors per cylinder into bx
|
|
||||||
.l01 mov ax, [bpb+BPBSPT]
|
|
||||||
mul word [bpb+BPBNOS]
|
|
||||||
mov bx, ax
|
|
||||||
; put linear sector num into dx:ax
|
; put linear sector num into dx:ax
|
||||||
mov ax, [dskseek]
|
.norst mov ax, [drvseek]
|
||||||
mov dx, [dskseek+2]
|
mov dx, [drvseek+2]
|
||||||
; dx:ax = linear count, bx = sectors / cylinder
|
; dx:ax = linear count
|
||||||
div bx
|
div word [drvspc]
|
||||||
|
; TODO: is it possible to get an overflow here?
|
||||||
xchg ax, dx
|
xchg ax, dx
|
||||||
; dx = cylinder, ax = head * spt + sector
|
; dx = cylinder, ax = head * spt + sector
|
||||||
mov bl, [bpb+BPBSPT]
|
div byte [drvspt]
|
||||||
div byte bl
|
|
||||||
; dx = cylinder, al = head, ah = sector
|
; dx = cylinder, al = head, ah = sector
|
||||||
xchg dl, dh
|
xchg dl, dh
|
||||||
ror dl, 1
|
ror dl, 1
|
||||||
@ -274,34 +268,57 @@ _read mov ch, 2
|
|||||||
call int13
|
call int13
|
||||||
jc .err
|
jc .err
|
||||||
; clear dirty flag on success
|
; clear dirty flag on success
|
||||||
and byte [dskflag], 0xFE
|
and word [dflags], ~DIRTY
|
||||||
clc
|
clc
|
||||||
ret
|
ret
|
||||||
; assume controller is misconfigured
|
; assume controller is misconfigured
|
||||||
.err and byte [dskflag], 0xFD
|
.err and word [dflags], ~DRVRST
|
||||||
; exit with carry flag set
|
; exit with carry flag set
|
||||||
stc
|
stc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
init mov ax, 0x0e38
|
init mov ax, cs
|
||||||
int 0x10
|
; boot failure if loaded wrong
|
||||||
|
cmp ax, cseg
|
||||||
|
je $+4
|
||||||
|
int 0x18
|
||||||
halt hlt
|
halt hlt
|
||||||
jmp halt
|
jmp halt
|
||||||
|
|
||||||
section .bss
|
dap db 0x10, 0
|
||||||
|
dw 1
|
||||||
|
dw dskbuf, cseg
|
||||||
|
drvseek dw 0,0,0,0
|
||||||
|
|
||||||
; bios drive we end up using
|
; bit 0 (1) - drive logged in (see drvnum)
|
||||||
biosnum resb 1
|
|
||||||
|
|
||||||
; bit 0 (1) - dirty flag for dskbuf
|
|
||||||
; bit 1 (2) - controller configured
|
; bit 1 (2) - controller configured
|
||||||
; bit 2 (4) - EBIOS supported
|
; bit 2 (4) - EBIOS supported
|
||||||
dskflag resb 1
|
; bit 3 (8) - dskbuf dirty
|
||||||
|
dflags dw 0
|
||||||
|
|
||||||
dpt resb 11
|
section .bss
|
||||||
|
|
||||||
bpb resb BPBSIZ
|
; drive currently logged in
|
||||||
|
drvnum resb 1
|
||||||
|
; number, just for bios
|
||||||
|
biosnum resb 1
|
||||||
|
|
||||||
|
; DPT tables for 4 floppy drives
|
||||||
|
dpt resb 4*14
|
||||||
|
|
||||||
|
; Information for logged in drive
|
||||||
|
drvss resb 1 ; sector size, 2^(7+n) bytes
|
||||||
|
drvcs resb 1 ; cluster size, 2^(7+n) bytes
|
||||||
|
alignb 4
|
||||||
|
drvspt resb 2 ; sectors per track
|
||||||
|
drvspc resb 2 ; sectors per cylinder
|
||||||
|
drvoff resb 4 ; partition offset
|
||||||
|
drvend resb 4 ; first sector after the partition
|
||||||
|
drvfat resb 4 ; offset to fat table
|
||||||
|
drvrd resb 4 ; offset of root directory
|
||||||
|
drvcla resb 4 ; offset to cluster area
|
||||||
|
drvfn resb 2 ; sectors per fat table
|
||||||
|
|
||||||
; disk buffer for I/O operations
|
; disk buffer for I/O operations
|
||||||
alignb 2
|
alignb 2
|
||||||
dskbuf resb 512
|
dskbuf resb 1024
|
||||||
|
Loading…
Reference in New Issue
Block a user