kernel: integrate existing farptr and drive code
This commit is contained in:
parent
a3dfd2c36c
commit
b7d596d758
3 changed files with 306 additions and 326 deletions
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
|
||||
halt hlt
|
||||
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
|
||||
|
|
46
src/farptr.inc
Normal file
46
src/farptr.inc
Normal file
|
@ -0,0 +1,46 @@
|
|||
; reset segments
|
||||
rstseg mov ax, cs
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
ret
|
||||
|
||||
; copy to far memory
|
||||
; IN es:bx far memory ptr (preserved)
|
||||
; ds:dx local ptr (preserved)
|
||||
; cx number of bytes to transfer
|
||||
; OUT cx set to zero
|
||||
; si & di trashed
|
||||
stofar mov si, dx
|
||||
mov di, bx
|
||||
rep movsb
|
||||
ret
|
||||
|
||||
; copy from far memory
|
||||
; IN es:bx far memory ptr (preserved)
|
||||
; ds:dx local ptr (preserved)
|
||||
; cx number of bytes to copy
|
||||
; OUT cx set to zero
|
||||
; si & di trashed
|
||||
lodfar call swpds
|
||||
mov si, bx
|
||||
mov di, dx
|
||||
rep movsb
|
||||
|
||||
; exchange es and ds
|
||||
swpds push ds
|
||||
push es
|
||||
pop ds
|
||||
pop es
|
||||
ret
|
||||
|
||||
; normalize ptr in ds:dx
|
||||
norm mov ax, ds
|
||||
mov cl, 4
|
||||
push dx
|
||||
ror dx, cl
|
||||
and dh, 0xF
|
||||
add ax, dx
|
||||
mov ds, ax
|
||||
pop dx
|
||||
and dx, 0xF
|
||||
ret
|
Loading…
Add table
Add a link
Reference in a new issue