kernel: integrate existing farptr and drive code
This commit is contained in:
parent
a3dfd2c36c
commit
b7d596d758
323
kernel/drive.asm
323
kernel/drive.asm
@ -1,323 +0,0 @@
|
|||||||
; code for disk i/o
|
|
||||||
; from outside, only the following methods are meant to be called:
|
|
||||||
; - logdrv: select drive DL to operate on
|
|
||||||
; - map*: map sector DX:AX into dskbuf
|
|
||||||
; - dirty: inform that dskbuf has been written to
|
|
||||||
; access is done by accessing dskbuf directly
|
|
||||||
|
|
||||||
BPBOFF equ 0xB
|
|
||||||
|
|
||||||
; DOS 2.0 BPB
|
|
||||||
BPBSS equ 0 ; word
|
|
||||||
BPBSC equ 2 ; byte
|
|
||||||
BPBRSC equ 3 ; word
|
|
||||||
BPBFN equ 5 ; byte
|
|
||||||
BPBRDE equ 6 ; word
|
|
||||||
BPBTS equ 8 ; word
|
|
||||||
BPBMD equ 10 ; byte
|
|
||||||
BPBFS equ 11 ; word
|
|
||||||
BPBSIZ2 equ 13 ; size constant
|
|
||||||
|
|
||||||
; DOS 3.31 BPB
|
|
||||||
BPBSPT equ 0x0D ; word
|
|
||||||
BPBNOS equ 0x0F ; word
|
|
||||||
BPBHS equ 0x11 ; dword
|
|
||||||
BPBLTS equ 0x15 ; dword
|
|
||||||
BPBSIZ3 equ 25 ; size constant
|
|
||||||
|
|
||||||
; DOS 3.4 EBPB
|
|
||||||
BPBDN equ 0x19 ; byte
|
|
||||||
BPBFALG equ 0x1A ; byte
|
|
||||||
BPBSIG equ 0x1B ; byte
|
|
||||||
BPBSER equ 0x1C ; dword serial number
|
|
||||||
BPBSIZ4 equ 32 ; size constant
|
|
||||||
|
|
||||||
; Disk parameter table (int 1E)
|
|
||||||
DPTSIZE equ 11
|
|
||||||
DPTSPT equ 4
|
|
||||||
|
|
||||||
section .bss
|
|
||||||
|
|
||||||
; bios drive we end up using
|
|
||||||
biosnum resb 1
|
|
||||||
|
|
||||||
; bit 0 (1) - dirty flag for dskbuf
|
|
||||||
; bit 1 (2) - controller configured
|
|
||||||
; bit 2 (4) - EBIOS supported
|
|
||||||
dskflag resb 1
|
|
||||||
|
|
||||||
; disk buffer for I/O operations
|
|
||||||
alignb 2
|
|
||||||
dskbuf resb 512
|
|
||||||
|
|
||||||
dpt resb DPTSIZE
|
|
||||||
bpb resb BPBSIZ4
|
|
||||||
|
|
||||||
section .data
|
|
||||||
|
|
||||||
; drive actually selected for I/O
|
|
||||||
dsknum db 0xFF
|
|
||||||
|
|
||||||
dap db 0x10, 0
|
|
||||||
dw 1
|
|
||||||
dapbuf dw dskbuf, 0
|
|
||||||
dskseek dw 0,0,0,0
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
; initial setup for disk i/o
|
|
||||||
; copy previously set DPT to our data area
|
|
||||||
dinit xor ax, ax
|
|
||||||
mov es, ax
|
|
||||||
les bx, [es:4*0x1E]
|
|
||||||
mov dx, dpt
|
|
||||||
mov cx, 11
|
|
||||||
call lodfar
|
|
||||||
; set interrupt vector
|
|
||||||
mov es, cx
|
|
||||||
mov word [es:4*0x1E], dpt
|
|
||||||
mov word [es:4*0x1E+2], ds
|
|
||||||
; set segment addr in DAP
|
|
||||||
mov [dapbuf+2], cs
|
|
||||||
ret
|
|
||||||
|
|
||||||
; int 13 stub
|
|
||||||
; this is meant as a central place to implement
|
|
||||||
; stack switching or some other safeguards
|
|
||||||
int13 int 0x13
|
|
||||||
ret
|
|
||||||
|
|
||||||
; get drive parameters
|
|
||||||
; read BIOS int13h/AH=8 values
|
|
||||||
; DPT data gets copied over our dpt
|
|
||||||
; CHS data gets inserted into our bpb
|
|
||||||
getprm test byte [dskflag], 4
|
|
||||||
jnz .ret
|
|
||||||
; do the query
|
|
||||||
mov ah, 8
|
|
||||||
mov dl, [biosnum]
|
|
||||||
call int13
|
|
||||||
; bail out if error
|
|
||||||
jc .ret
|
|
||||||
; ignore CHS values if odd
|
|
||||||
test cl, cl
|
|
||||||
jz .nochs
|
|
||||||
; get and store sector number
|
|
||||||
and cx, 0x3F
|
|
||||||
mov word [bpb+BPBSPT], cx
|
|
||||||
; get and store number of heads
|
|
||||||
xchg dl, dh
|
|
||||||
and dx, 0xFF
|
|
||||||
inc dx
|
|
||||||
mov [bpb+BPBNOS], dx
|
|
||||||
; test if DPT ptr is non-zero
|
|
||||||
.nochs mov ax, es
|
|
||||||
or ax, di
|
|
||||||
test ax, ax
|
|
||||||
jz .ret
|
|
||||||
; copy BIOS dpt table over ours
|
|
||||||
mov dx, dpt
|
|
||||||
mov bx, di
|
|
||||||
mov cx, 11
|
|
||||||
call lodfar
|
|
||||||
.ret ret
|
|
||||||
|
|
||||||
; select a drive for io
|
|
||||||
; IN dl drive number
|
|
||||||
; dont do anything if drive already selected
|
|
||||||
select cmp dl, [dsknum]
|
|
||||||
je logfdd.ret
|
|
||||||
; clear out current contents
|
|
||||||
push dx
|
|
||||||
call flush
|
|
||||||
mov ax, 0xFFFF
|
|
||||||
mov [dskseek], ax
|
|
||||||
mov [dskseek+2], ax
|
|
||||||
mov byte [dskflag], 0
|
|
||||||
pop dx
|
|
||||||
; set current drive number
|
|
||||||
mov [dsknum], dl
|
|
||||||
; fork off if hdd
|
|
||||||
cmp dl, 2
|
|
||||||
jnc loghdd
|
|
||||||
|
|
||||||
logfdd mov [biosnum], dl
|
|
||||||
; assume some default values
|
|
||||||
xor ax, ax
|
|
||||||
mov word [bpb+BPBHS], ax
|
|
||||||
mov word [bpb+BPBHS+2], ax
|
|
||||||
mov word [bpb+BPBNOS], 2 ; 5 1/4" 360kB
|
|
||||||
mov word [bpb+BPBSPT], 9
|
|
||||||
; reset dpt to defaults
|
|
||||||
call getprm
|
|
||||||
; load boot sector
|
|
||||||
xor ax, ax
|
|
||||||
xor dx, dx
|
|
||||||
call mapabs
|
|
||||||
; copy bios parameter block
|
|
||||||
; TODO: guess from first byte of FAT if BPB invalid
|
|
||||||
call rstseg
|
|
||||||
mov si, dskbuf+BPBOFF
|
|
||||||
mov di, bpb
|
|
||||||
mov cx, BPBSIZ4
|
|
||||||
rep movsb
|
|
||||||
; copy SPT to DPT
|
|
||||||
mov al, [bpb+BPBSPT]
|
|
||||||
mov [dpt+4], al
|
|
||||||
.ret ret
|
|
||||||
|
|
||||||
loghdd sub dl, 2
|
|
||||||
cmp dl, 4
|
|
||||||
jnc logerr
|
|
||||||
push dx
|
|
||||||
mov dl, 0x80
|
|
||||||
mov byte [biosnum], dl
|
|
||||||
; test for ebios extensions
|
|
||||||
mov ah, 0x41
|
|
||||||
mov bx, 0x55AA
|
|
||||||
call int13
|
|
||||||
sbb bx, 0xAA55
|
|
||||||
jnz .chs
|
|
||||||
; enable ebios and assume controller is configured
|
|
||||||
or byte [dskflag], (2+4)
|
|
||||||
; get chs data (needed or we cant load vbr)
|
|
||||||
.chs call getprm
|
|
||||||
; read mbr
|
|
||||||
xor ax, ax
|
|
||||||
xor dx, dx
|
|
||||||
call mapabs
|
|
||||||
; get partition number
|
|
||||||
pop bx
|
|
||||||
xor bh, bh
|
|
||||||
mov cl, 4
|
|
||||||
sal bx, cl
|
|
||||||
; bail out if no partition
|
|
||||||
cmp byte [dskbuf+0x1be+bx+4], 0
|
|
||||||
je logerr
|
|
||||||
; load partition offset
|
|
||||||
mov ax, [dskbuf+0x1be+bx+8]
|
|
||||||
mov dx, [dskbuf+0x1be+bx+8+2]
|
|
||||||
; save to to stack
|
|
||||||
push dx
|
|
||||||
push ax
|
|
||||||
; load vbr
|
|
||||||
call mapabs
|
|
||||||
; copy bpb
|
|
||||||
mov si, dskbuf+BPBOFF
|
|
||||||
mov di, bpb
|
|
||||||
mov cx, BPBSIZ4
|
|
||||||
rep movsb
|
|
||||||
; fix CHS data
|
|
||||||
call getprm
|
|
||||||
; fix partition offset
|
|
||||||
pop word [bpb+BPBHS]
|
|
||||||
pop word [bpb+BPBHS+2]
|
|
||||||
;pop [bpb+BPBNOS]
|
|
||||||
;pop [bpb+BPBSPT]
|
|
||||||
ret
|
|
||||||
|
|
||||||
logerr stc
|
|
||||||
ret
|
|
||||||
|
|
||||||
; 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
|
|
||||||
; IN dx:ax sector number
|
|
||||||
mapabs cmp ax, [dskseek]
|
|
||||||
jne l003
|
|
||||||
cmp dx, [dskseek+2]
|
|
||||||
je l002
|
|
||||||
; flush and read other sector
|
|
||||||
l003 push ax
|
|
||||||
push dx
|
|
||||||
call flush
|
|
||||||
pop dx
|
|
||||||
pop ax
|
|
||||||
; store the sector number
|
|
||||||
mov [dskseek], ax
|
|
||||||
mov [dskseek+2], dx
|
|
||||||
jmp _read
|
|
||||||
|
|
||||||
; mark dskbuf as containing unwritten changes
|
|
||||||
dirty or byte [cs:dskflag], 1 ; dirty
|
|
||||||
l002 ret
|
|
||||||
|
|
||||||
; flush buffer if dirty
|
|
||||||
flush test byte [cs:dskflag], 1
|
|
||||||
jz l002
|
|
||||||
; low level read and write
|
|
||||||
; call again to retry, no input registers
|
|
||||||
; read or write is configured in cx
|
|
||||||
_write mov ch, 3
|
|
||||||
db 0x3D ; cmp ax, imm16: causes next 2 bytes to be skipped
|
|
||||||
_read mov ch, 2
|
|
||||||
mov cl, 1 ; read len
|
|
||||||
; DS := ES := CS
|
|
||||||
mov ax, cs
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
; check if ebios supported
|
|
||||||
test byte [dskflag], 4
|
|
||||||
jz .l00
|
|
||||||
mov ax, cx
|
|
||||||
or ah, 0x40
|
|
||||||
mov si, dap
|
|
||||||
jmp .do
|
|
||||||
; check if we can skip controller reset
|
|
||||||
.l00 test byte [dskflag], 2
|
|
||||||
jnz .l01
|
|
||||||
; do controller reset
|
|
||||||
mov dl, [biosnum]
|
|
||||||
mov ah, 0
|
|
||||||
call int13
|
|
||||||
or byte [dskflag], 2
|
|
||||||
; 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
|
|
||||||
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 bx, dskbuf
|
|
||||||
.do mov dl, [biosnum]
|
|
||||||
; 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
|
|
||||||
; assume controller is misconfigured
|
|
||||||
.err and byte [dskflag], 0xFD
|
|
||||||
; exit with carry flag set
|
|
||||||
stc
|
|
||||||
ret
|
|
305
src/@rdos.asm
305
src/@rdos.asm
@ -1,4 +1,307 @@
|
|||||||
mov ax, 0x0e38
|
jmp init
|
||||||
|
|
||||||
|
%include "bpb.inc"
|
||||||
|
%include "farptr.inc"
|
||||||
|
|
||||||
|
; drive actually selected for I/O
|
||||||
|
dsknum db 0xFF
|
||||||
|
|
||||||
|
dap db 0x10, 0
|
||||||
|
dw 1
|
||||||
|
dapbuf dw dskbuf, 0
|
||||||
|
dskseek dw 0,0,0,0
|
||||||
|
|
||||||
|
; initial setup for disk i/o
|
||||||
|
; copy previously set DPT to our data area
|
||||||
|
dinit xor ax, ax
|
||||||
|
mov es, ax
|
||||||
|
les bx, [es:4*0x1E]
|
||||||
|
mov dx, dpt
|
||||||
|
mov cx, 11
|
||||||
|
call lodfar
|
||||||
|
; set interrupt vector
|
||||||
|
mov es, cx
|
||||||
|
mov word [es:4*0x1E], dpt
|
||||||
|
mov word [es:4*0x1E+2], ds
|
||||||
|
; set segment addr in DAP
|
||||||
|
mov [dapbuf+2], cs
|
||||||
|
ret
|
||||||
|
|
||||||
|
align 16
|
||||||
|
; IBM Interrupt Sharing Protocol structure
|
||||||
|
i13isp jmp short int13i
|
||||||
|
dw 0,0xFFFF
|
||||||
|
dw 0x424B
|
||||||
|
db 0
|
||||||
|
iret
|
||||||
|
align 16
|
||||||
|
|
||||||
|
int13i call int13
|
||||||
|
iret
|
||||||
|
|
||||||
|
; Wrapper around int 13h
|
||||||
|
int13 pushf
|
||||||
|
call far [i13isp+2]
|
||||||
|
; TODO: on error: reset & retry
|
||||||
|
; TODO: record errors
|
||||||
|
; TODO: multi-track reading
|
||||||
|
; TODO: handle DMA boundaries
|
||||||
|
ret
|
||||||
|
|
||||||
|
; get drive parameters
|
||||||
|
; read BIOS int13h/AH=8 values
|
||||||
|
; DPT data gets copied over our dpt
|
||||||
|
; CHS data gets inserted into our bpb
|
||||||
|
getprm test byte [dskflag], 4
|
||||||
|
jnz .ret
|
||||||
|
; do the query
|
||||||
|
mov ah, 8
|
||||||
|
mov dl, [biosnum]
|
||||||
|
call int13
|
||||||
|
; bail out if error
|
||||||
|
jc .ret
|
||||||
|
; ignore CHS values if odd
|
||||||
|
test cl, cl
|
||||||
|
jz .nochs
|
||||||
|
; get and store sector number
|
||||||
|
and cx, 0x3F
|
||||||
|
mov word [bpb+BPBSPT], cx
|
||||||
|
; get and store number of heads
|
||||||
|
xchg dl, dh
|
||||||
|
and dx, 0xFF
|
||||||
|
inc dx
|
||||||
|
mov [bpb+BPBNOS], dx
|
||||||
|
; test if DPT ptr is non-zero
|
||||||
|
.nochs mov ax, es
|
||||||
|
or ax, di
|
||||||
|
test ax, ax
|
||||||
|
jz .ret
|
||||||
|
; copy BIOS dpt table over ours
|
||||||
|
mov dx, dpt
|
||||||
|
mov bx, di
|
||||||
|
mov cx, 11
|
||||||
|
call lodfar
|
||||||
|
.ret ret
|
||||||
|
|
||||||
|
; select a drive for io
|
||||||
|
; IN dl drive number
|
||||||
|
; dont do anything if drive already selected
|
||||||
|
select cmp dl, [dsknum]
|
||||||
|
je logfdd.ret
|
||||||
|
; clear out current contents
|
||||||
|
push dx
|
||||||
|
call flush
|
||||||
|
mov ax, 0xFFFF
|
||||||
|
mov [dskseek], ax
|
||||||
|
mov [dskseek+2], ax
|
||||||
|
mov byte [dskflag], 0
|
||||||
|
pop dx
|
||||||
|
; set current drive number
|
||||||
|
mov [dsknum], dl
|
||||||
|
; fork off if hdd
|
||||||
|
cmp dl, 2
|
||||||
|
jnc loghdd
|
||||||
|
|
||||||
|
logfdd mov [biosnum], dl
|
||||||
|
; assume some default values
|
||||||
|
xor ax, ax
|
||||||
|
mov word [bpb+BPBHS], ax
|
||||||
|
mov word [bpb+BPBHS+2], ax
|
||||||
|
mov word [bpb+BPBNOS], 2 ; 5 1/4" 360kB
|
||||||
|
mov word [bpb+BPBSPT], 9
|
||||||
|
; reset dpt to defaults
|
||||||
|
call getprm
|
||||||
|
; load boot sector
|
||||||
|
xor ax, ax
|
||||||
|
xor dx, dx
|
||||||
|
call mapabs
|
||||||
|
; copy bios parameter block
|
||||||
|
; TODO: guess from first byte of FAT if BPB invalid
|
||||||
|
call rstseg
|
||||||
|
mov si, dskbuf+BPBOFF
|
||||||
|
mov di, bpb
|
||||||
|
mov cx, BPBSIZ
|
||||||
|
rep movsb
|
||||||
|
; copy SPT to DPT
|
||||||
|
mov al, [bpb+BPBSPT]
|
||||||
|
mov [dpt+4], al
|
||||||
|
.ret ret
|
||||||
|
|
||||||
|
loghdd sub dl, 2
|
||||||
|
cmp dl, 4
|
||||||
|
jnc logerr
|
||||||
|
push dx
|
||||||
|
mov dl, 0x80
|
||||||
|
mov byte [biosnum], dl
|
||||||
|
; test for ebios extensions
|
||||||
|
mov ah, 0x41
|
||||||
|
mov bx, 0x55AA
|
||||||
|
call int13
|
||||||
|
sbb bx, 0xAA55
|
||||||
|
jnz .chs
|
||||||
|
; enable ebios and assume controller is configured
|
||||||
|
or byte [dskflag], (2+4)
|
||||||
|
; get chs data (needed or we cant load vbr)
|
||||||
|
.chs call getprm
|
||||||
|
; read mbr
|
||||||
|
xor ax, ax
|
||||||
|
xor dx, dx
|
||||||
|
call mapabs
|
||||||
|
; get partition number
|
||||||
|
pop bx
|
||||||
|
xor bh, bh
|
||||||
|
mov cl, 4
|
||||||
|
sal bx, cl
|
||||||
|
; bail out if no partition
|
||||||
|
cmp byte [dskbuf+0x1be+bx+4], 0
|
||||||
|
je logerr
|
||||||
|
; load partition offset
|
||||||
|
mov ax, [dskbuf+0x1be+bx+8]
|
||||||
|
mov dx, [dskbuf+0x1be+bx+8+2]
|
||||||
|
; save to to stack
|
||||||
|
push dx
|
||||||
|
push ax
|
||||||
|
; load vbr
|
||||||
|
call mapabs
|
||||||
|
; copy bpb
|
||||||
|
mov si, dskbuf+BPBOFF
|
||||||
|
mov di, bpb
|
||||||
|
mov cx, BPBSIZ
|
||||||
|
rep movsb
|
||||||
|
; fix CHS data
|
||||||
|
call getprm
|
||||||
|
; fix partition offset
|
||||||
|
pop word [bpb+BPBHS]
|
||||||
|
pop word [bpb+BPBHS+2]
|
||||||
|
;pop [bpb+BPBNOS]
|
||||||
|
;pop [bpb+BPBSPT]
|
||||||
|
ret
|
||||||
|
|
||||||
|
logerr stc
|
||||||
|
ret
|
||||||
|
|
||||||
|
; 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
|
||||||
|
; IN dx:ax sector number
|
||||||
|
mapabs cmp ax, [dskseek]
|
||||||
|
jne l003
|
||||||
|
cmp dx, [dskseek+2]
|
||||||
|
je l002
|
||||||
|
; flush and read other sector
|
||||||
|
l003 push ax
|
||||||
|
push dx
|
||||||
|
call flush
|
||||||
|
pop dx
|
||||||
|
pop ax
|
||||||
|
; store the sector number
|
||||||
|
mov [dskseek], ax
|
||||||
|
mov [dskseek+2], dx
|
||||||
|
jmp _read
|
||||||
|
|
||||||
|
; mark dskbuf as containing unwritten changes
|
||||||
|
dirty or byte [cs:dskflag], 1 ; dirty
|
||||||
|
l002 ret
|
||||||
|
|
||||||
|
; flush buffer if dirty
|
||||||
|
flush test byte [cs:dskflag], 1
|
||||||
|
jz l002
|
||||||
|
; low level read and write
|
||||||
|
; call again to retry, no input registers
|
||||||
|
; read or write is configured in cx
|
||||||
|
_write mov ch, 3
|
||||||
|
db 0x3D ; cmp ax, imm16: causes next 2 bytes to be skipped
|
||||||
|
_read mov ch, 2
|
||||||
|
mov cl, 1 ; read len
|
||||||
|
; DS := ES := CS
|
||||||
|
mov ax, cs
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
; check if ebios supported
|
||||||
|
test byte [dskflag], 4
|
||||||
|
jz .l00
|
||||||
|
mov ax, cx
|
||||||
|
or ah, 0x40
|
||||||
|
mov si, dap
|
||||||
|
jmp .do
|
||||||
|
; check if we can skip controller reset
|
||||||
|
.l00 test byte [dskflag], 2
|
||||||
|
jnz .l01
|
||||||
|
; do controller reset
|
||||||
|
mov dl, [biosnum]
|
||||||
|
mov ah, 0
|
||||||
|
call int13
|
||||||
|
or byte [dskflag], 2
|
||||||
|
; 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
|
||||||
|
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 bx, dskbuf
|
||||||
|
.do mov dl, [biosnum]
|
||||||
|
; 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
|
||||||
|
; assume controller is misconfigured
|
||||||
|
.err and byte [dskflag], 0xFD
|
||||||
|
; exit with carry flag set
|
||||||
|
stc
|
||||||
|
ret
|
||||||
|
|
||||||
|
init mov ax, 0x0e38
|
||||||
int 0x10
|
int 0x10
|
||||||
halt hlt
|
halt hlt
|
||||||
jmp halt
|
jmp halt
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
|
||||||
|
; bios drive we end up using
|
||||||
|
biosnum resb 1
|
||||||
|
|
||||||
|
; bit 0 (1) - dirty flag for dskbuf
|
||||||
|
; bit 1 (2) - controller configured
|
||||||
|
; bit 2 (4) - EBIOS supported
|
||||||
|
dskflag resb 1
|
||||||
|
|
||||||
|
dpt resb 11
|
||||||
|
|
||||||
|
bpb resb BPBSIZ
|
||||||
|
|
||||||
|
; disk buffer for I/O operations
|
||||||
|
alignb 2
|
||||||
|
dskbuf resb 512
|
||||||
|
@ -21,13 +21,13 @@ stofar mov si, dx
|
|||||||
; cx number of bytes to copy
|
; cx number of bytes to copy
|
||||||
; OUT cx set to zero
|
; OUT cx set to zero
|
||||||
; si & di trashed
|
; si & di trashed
|
||||||
lodfar call xchgdes
|
lodfar call swpds
|
||||||
mov si, bx
|
mov si, bx
|
||||||
mov di, dx
|
mov di, dx
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
; exchange es and ds
|
; exchange es and ds
|
||||||
xchgdes push ds
|
swpds push ds
|
||||||
push es
|
push es
|
||||||
pop ds
|
pop ds
|
||||||
pop es
|
pop es
|
Loading…
Reference in New Issue
Block a user