implement bpb parsing
This commit is contained in:
parent
e26adff688
commit
f1c414bb26
238
src/@rdos.asm
238
src/@rdos.asm
@ -6,24 +6,11 @@ cseg equ 0x0
|
||||
%include "farptr.inc"
|
||||
|
||||
; dflags bitfields
|
||||
DRVLOG equ 0x01 ; bit 0 (1) - drive logged in (see drvnum)
|
||||
DRVRST equ 0x02 ; bit 1 (2) - controller configured
|
||||
DRVEXT equ 0x04 ; bit 2 (4) - EBIOS supported
|
||||
DIRTY equ 0x08 ; bit 3 (8) - dskbuf dirty
|
||||
|
||||
; 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
|
||||
ret
|
||||
DRVLOG equ 0x01 ; bit 0 - drive logged in (see drvnum)
|
||||
DRVCTL equ 0x02 ; bit 1 - controller configured
|
||||
DRVEXT equ 0x04 ; bit 2 - EBIOS supported
|
||||
DIRTY equ 0x08 ; bit 3 - dskbuf dirty
|
||||
DRVCHS equ 0x10 ; bit 4 - CHS geometry known
|
||||
|
||||
align 16
|
||||
; IBM Interrupt Sharing Protocol structure
|
||||
@ -52,8 +39,11 @@ int13 pushf
|
||||
; 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
|
||||
getprm test byte [dflags], DRVEXT
|
||||
jnz .ret
|
||||
; fallback non-zero values (5 1/4", 160kB)
|
||||
mov word [drvspt], 8
|
||||
mov word [drvspc], 8
|
||||
; do the query
|
||||
mov ah, 8
|
||||
mov dl, [biosnum]
|
||||
@ -65,12 +55,16 @@ getprm test byte [dskflag], 4
|
||||
jz .nochs
|
||||
; get and store sector number
|
||||
and cx, 0x3F
|
||||
mov word [bpb+BPBSPT], cx
|
||||
; get and store number of heads
|
||||
mov word [drvspt], cx
|
||||
; get and store number heads
|
||||
xchg dl, dh
|
||||
and dx, 0xFF
|
||||
inc dx
|
||||
mov [bpb+BPBNOS], dx
|
||||
; multiply with sectors per track
|
||||
mov ax, dx
|
||||
mul cx
|
||||
; store sectors per cylinder
|
||||
mov [drvspc], ax
|
||||
; test if DPT ptr is non-zero
|
||||
.nochs mov ax, es
|
||||
or ax, di
|
||||
@ -87,98 +81,128 @@ getprm test byte [dskflag], 4
|
||||
; IN dl drive number
|
||||
; dont do anything if drive already selected
|
||||
select cmp dl, [drvnum]
|
||||
je logfdd.ret
|
||||
je getprm.ret
|
||||
; clear out current contents
|
||||
push dx
|
||||
call flush
|
||||
mov ax, 0xFFFF
|
||||
mov [dskseek], ax
|
||||
mov [dskseek+2], ax
|
||||
mov byte [dskflag], 0
|
||||
mov [drvseek], ax
|
||||
mov [drvseek+2], ax
|
||||
and word [dflags], ~(DRVLOG|DRVCTL|DRVEXT|DIRTY|DRVCHS)
|
||||
pop dx
|
||||
; set current drive number
|
||||
mov [dsknum], dl
|
||||
mov [drvnum], 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
|
||||
and dx, 0x0D
|
||||
; query bios for geometry and DPT
|
||||
call getprm
|
||||
; load boot sector
|
||||
; assume 512 bytes per sector
|
||||
; TODO: read this from DPT
|
||||
mov byte [drvss], 2
|
||||
; fill partition offset with zeroes
|
||||
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
|
||||
mov di, drvoff
|
||||
stosw
|
||||
stosw
|
||||
; fill partition end with 1's
|
||||
not ax
|
||||
stosw
|
||||
stosw
|
||||
; shared code with loghdd
|
||||
jmp rdbpb
|
||||
|
||||
loghdd sub dl, 2
|
||||
cmp dl, 4
|
||||
jnc logerr
|
||||
push dx
|
||||
mov dl, 0x80
|
||||
; Log in a drive on a hard disk
|
||||
; IN dl bits 0-1: partition number
|
||||
; bits 2-7: drive number
|
||||
; Partition offset is read from MBR
|
||||
; split drive & partition number
|
||||
loghdd mov dh, dl
|
||||
and ah, 0x3
|
||||
shr dl, 1
|
||||
shl dl, 1
|
||||
add dl, 0x80
|
||||
; partition number in DH
|
||||
mov byte [biosnum], dl
|
||||
; test for ebios extensions
|
||||
push dx
|
||||
; 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 [dflags], DRVCTL | DRVEXT
|
||||
; get chs data (needed or we cant load vbr)
|
||||
.chs call getprm
|
||||
; read mbr
|
||||
jnz .noeb
|
||||
; enable EBIOS and assume controller is configured
|
||||
or word [dflags], DRVCTL | DRVEXT
|
||||
; hard disks are always assumed to be 512 bytes / sector
|
||||
.noeb mov byte [drvss], 2
|
||||
; query BIOS for geometry
|
||||
call getprm
|
||||
or word [dflags], DRVCHS
|
||||
; read MBR
|
||||
xor ax, ax
|
||||
xor dx, dx
|
||||
call mapabs
|
||||
call map
|
||||
; get partition number
|
||||
pop bx
|
||||
xor bh, bh
|
||||
mov cl, 4
|
||||
sal bx, cl
|
||||
; bail out if no partition
|
||||
; bail out if partition undef
|
||||
cmp byte [dskbuf+0x1be+bx+4], 0
|
||||
je logerr
|
||||
je .ret
|
||||
; 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
|
||||
; store partition offset
|
||||
mov [drvoff], ax
|
||||
mov [drvoff+2], dx
|
||||
; add partition length
|
||||
add ax, [dskbuf+0x1be+bx+12]
|
||||
adc dx, [dskbuf+0x1be+bx+12+2]
|
||||
; partitions after 4 TB mark not allowed
|
||||
jc .ret
|
||||
; store partition end
|
||||
mov [drvend], ax
|
||||
mov [drvend+2], dx
|
||||
.ret ret
|
||||
|
||||
logerr stc
|
||||
ret
|
||||
; parse bios parameter block from drvoff
|
||||
; drvoff and biosnum need to be set up
|
||||
rdbpb mov ax, [drvoff]
|
||||
mov dx, [drvoff+2]
|
||||
call map
|
||||
; read partition start
|
||||
mov ax, [drvoff]
|
||||
mov dx, [drvoff+2]
|
||||
; add reserved sectors
|
||||
add ax, [dskbuf+BPBOFF+BPBRSC]
|
||||
adc dx, 0
|
||||
jc .ret
|
||||
; save offset of fat table
|
||||
mov [drvfat], ax
|
||||
mov [drvfat+2], dx
|
||||
; calculate length of all fat tables
|
||||
mov ah, 0
|
||||
mov al, [dskbuf+BPBOFF+BPBFN]
|
||||
mov dx, [dskbuf+BPBOFF+BPBFS]
|
||||
mov [drvfn], dx
|
||||
mul dx
|
||||
add ax, [drvfat]
|
||||
adc dx, [drvfat+2]
|
||||
; save offset of root directory
|
||||
mov [drvrd], ax
|
||||
mov [drvrd+2], dx
|
||||
; calculate length of root directory
|
||||
mov ax, [dskbuf+BPBOFF+BPBRDE]
|
||||
mov cl, [drvss]
|
||||
add cl, 2
|
||||
shr ax, cl
|
||||
; read offset to cluster area
|
||||
; read cluster size
|
||||
.ret ret
|
||||
|
||||
; map sector into dskbuf
|
||||
; skip doing a read if sector number matches
|
||||
@ -227,13 +251,13 @@ diskio mov cl, 1 ; read len
|
||||
mov si, dap
|
||||
jmp .do
|
||||
; check if we can skip controller reset
|
||||
.noext test word [dflags], DRVRST
|
||||
.noext test word [dflags], DRVCTL
|
||||
jnz .norst
|
||||
; do controller reset
|
||||
mov dl, [biosnum]
|
||||
mov ah, 0
|
||||
call int13
|
||||
or word [dflags], DRVRST
|
||||
or word [dflags], DRVCTL
|
||||
; put linear sector num into dx:ax
|
||||
.norst mov ax, [drvseek]
|
||||
mov dx, [drvseek+2]
|
||||
@ -272,16 +296,58 @@ diskio mov cl, 1 ; read len
|
||||
clc
|
||||
ret
|
||||
; assume controller is misconfigured
|
||||
.err and word [dflags], ~DRVRST
|
||||
.err and word [dflags], ~DRVCTL
|
||||
; exit with carry flag set
|
||||
stc
|
||||
ret
|
||||
|
||||
; Get interrupt vector
|
||||
; IN al interrupt number
|
||||
; OUT es:bx vector
|
||||
getint mov bl, al
|
||||
mov bh, 0
|
||||
; multiply with 4
|
||||
add bx, bx
|
||||
add bx, bx
|
||||
les bx, [cs:bx]
|
||||
ret
|
||||
|
||||
; Set interrupt vector
|
||||
; IN al interrupt number
|
||||
; ds:dx vector
|
||||
setint mov bl, al
|
||||
mov bh, 0
|
||||
; multiply with 4
|
||||
add bx, bx
|
||||
add bx, bx
|
||||
mov [cs:bx], dx
|
||||
mov [cs:bx+2], ds
|
||||
ret
|
||||
|
||||
init mov ax, cs
|
||||
; boot failure if loaded wrong
|
||||
cmp ax, cseg
|
||||
je $+4
|
||||
int 0x18
|
||||
call rstseg
|
||||
; fetch current DPT
|
||||
les bx, [4*0x1E]
|
||||
mov dx, dpt
|
||||
mov cx, 11
|
||||
call lodfar
|
||||
; set interrupt vector
|
||||
mov word [4*0x1E], dpt
|
||||
mov word [4*0x1E+2], ds
|
||||
; save int 13 handler
|
||||
les bx, [4*0x13]
|
||||
mov [i13isp+2], bx
|
||||
mov [i13isp+4], es
|
||||
; install ours
|
||||
mov word [4*0x13], int13i
|
||||
mov [4*0x13+2], cs
|
||||
|
||||
mov ax, 0x0e37
|
||||
int 0x10
|
||||
halt hlt
|
||||
jmp halt
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user