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"
|
%include "farptr.inc"
|
||||||
|
|
||||||
; dflags bitfields
|
; dflags bitfields
|
||||||
DRVLOG equ 0x01 ; bit 0 (1) - drive logged in (see drvnum)
|
DRVLOG equ 0x01 ; bit 0 - drive logged in (see drvnum)
|
||||||
DRVRST equ 0x02 ; bit 1 (2) - controller configured
|
DRVCTL equ 0x02 ; bit 1 - controller configured
|
||||||
DRVEXT equ 0x04 ; bit 2 (4) - EBIOS supported
|
DRVEXT equ 0x04 ; bit 2 - EBIOS supported
|
||||||
DIRTY equ 0x08 ; bit 3 (8) - dskbuf dirty
|
DIRTY equ 0x08 ; bit 3 - dskbuf dirty
|
||||||
|
DRVCHS equ 0x10 ; bit 4 - CHS geometry known
|
||||||
; 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
|
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
; IBM Interrupt Sharing Protocol structure
|
; IBM Interrupt Sharing Protocol structure
|
||||||
@ -52,8 +39,11 @@ int13 pushf
|
|||||||
; read BIOS int13h/AH=8 values
|
; read BIOS int13h/AH=8 values
|
||||||
; DPT data gets copied over our dpt
|
; DPT data gets copied over our dpt
|
||||||
; CHS data gets inserted into our bpb
|
; CHS data gets inserted into our bpb
|
||||||
getprm test byte [dskflag], 4
|
getprm test byte [dflags], DRVEXT
|
||||||
jnz .ret
|
jnz .ret
|
||||||
|
; fallback non-zero values (5 1/4", 160kB)
|
||||||
|
mov word [drvspt], 8
|
||||||
|
mov word [drvspc], 8
|
||||||
; do the query
|
; do the query
|
||||||
mov ah, 8
|
mov ah, 8
|
||||||
mov dl, [biosnum]
|
mov dl, [biosnum]
|
||||||
@ -65,12 +55,16 @@ getprm test byte [dskflag], 4
|
|||||||
jz .nochs
|
jz .nochs
|
||||||
; get and store sector number
|
; get and store sector number
|
||||||
and cx, 0x3F
|
and cx, 0x3F
|
||||||
mov word [bpb+BPBSPT], cx
|
mov word [drvspt], cx
|
||||||
; get and store number of heads
|
; get and store number heads
|
||||||
xchg dl, dh
|
xchg dl, dh
|
||||||
and dx, 0xFF
|
and dx, 0xFF
|
||||||
inc dx
|
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
|
; test if DPT ptr is non-zero
|
||||||
.nochs mov ax, es
|
.nochs mov ax, es
|
||||||
or ax, di
|
or ax, di
|
||||||
@ -87,98 +81,128 @@ getprm test byte [dskflag], 4
|
|||||||
; 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, [drvnum]
|
select cmp dl, [drvnum]
|
||||||
je logfdd.ret
|
je getprm.ret
|
||||||
; clear out current contents
|
; clear out current contents
|
||||||
push dx
|
push dx
|
||||||
call flush
|
call flush
|
||||||
mov ax, 0xFFFF
|
mov ax, 0xFFFF
|
||||||
mov [dskseek], ax
|
mov [drvseek], ax
|
||||||
mov [dskseek+2], ax
|
mov [drvseek+2], ax
|
||||||
mov byte [dskflag], 0
|
and word [dflags], ~(DRVLOG|DRVCTL|DRVEXT|DIRTY|DRVCHS)
|
||||||
pop dx
|
pop dx
|
||||||
; set current drive number
|
; set current drive number
|
||||||
mov [dsknum], dl
|
mov [drvnum], dl
|
||||||
; fork off if hdd
|
; fork off if hdd
|
||||||
cmp dl, 2
|
cmp dl, 2
|
||||||
jnc loghdd
|
jnc loghdd
|
||||||
|
|
||||||
logfdd mov [biosnum], dl
|
logfdd mov [biosnum], dl
|
||||||
; assume some default values
|
and dx, 0x0D
|
||||||
xor ax, ax
|
; query bios for geometry and DPT
|
||||||
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
|
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 ax, ax
|
||||||
xor dx, dx
|
mov di, drvoff
|
||||||
call mapabs
|
stosw
|
||||||
; copy bios parameter block
|
stosw
|
||||||
; TODO: guess from first byte of FAT if BPB invalid
|
; fill partition end with 1's
|
||||||
call rstseg
|
not ax
|
||||||
mov si, dskbuf+BPBOFF
|
stosw
|
||||||
mov di, bpb
|
stosw
|
||||||
mov cx, BPBSIZ
|
; shared code with loghdd
|
||||||
rep movsb
|
jmp rdbpb
|
||||||
; copy SPT to DPT
|
|
||||||
mov al, [bpb+BPBSPT]
|
|
||||||
mov [dpt+4], al
|
|
||||||
.ret ret
|
|
||||||
|
|
||||||
loghdd sub dl, 2
|
; Log in a drive on a hard disk
|
||||||
cmp dl, 4
|
; IN dl bits 0-1: partition number
|
||||||
jnc logerr
|
; bits 2-7: drive number
|
||||||
push dx
|
; Partition offset is read from MBR
|
||||||
mov dl, 0x80
|
; 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
|
mov byte [biosnum], dl
|
||||||
; test for ebios extensions
|
push dx
|
||||||
|
; test for EBIOS extensions
|
||||||
mov ah, 0x41
|
mov ah, 0x41
|
||||||
mov bx, 0x55AA
|
mov bx, 0x55AA
|
||||||
call int13
|
call int13
|
||||||
sbb bx, 0xAA55
|
sbb bx, 0xAA55
|
||||||
jnz .chs
|
jnz .noeb
|
||||||
; enable ebios and assume controller is configured
|
; enable EBIOS and assume controller is configured
|
||||||
or byte [dflags], DRVCTL | DRVEXT
|
or word [dflags], DRVCTL | DRVEXT
|
||||||
; get chs data (needed or we cant load vbr)
|
; hard disks are always assumed to be 512 bytes / sector
|
||||||
.chs call getprm
|
.noeb mov byte [drvss], 2
|
||||||
; read mbr
|
; query BIOS for geometry
|
||||||
|
call getprm
|
||||||
|
or word [dflags], DRVCHS
|
||||||
|
; read MBR
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
xor dx, dx
|
xor dx, dx
|
||||||
call mapabs
|
call map
|
||||||
; get partition number
|
; get partition number
|
||||||
pop bx
|
pop bx
|
||||||
xor bh, bh
|
xor bh, bh
|
||||||
mov cl, 4
|
mov cl, 4
|
||||||
sal bx, cl
|
sal bx, cl
|
||||||
; bail out if no partition
|
; bail out if partition undef
|
||||||
cmp byte [dskbuf+0x1be+bx+4], 0
|
cmp byte [dskbuf+0x1be+bx+4], 0
|
||||||
je logerr
|
je .ret
|
||||||
; load partition offset
|
; load partition offset
|
||||||
mov ax, [dskbuf+0x1be+bx+8]
|
mov ax, [dskbuf+0x1be+bx+8]
|
||||||
mov dx, [dskbuf+0x1be+bx+8+2]
|
mov dx, [dskbuf+0x1be+bx+8+2]
|
||||||
; save to to stack
|
; store partition offset
|
||||||
push dx
|
mov [drvoff], ax
|
||||||
push ax
|
mov [drvoff+2], dx
|
||||||
; load vbr
|
; add partition length
|
||||||
call mapabs
|
add ax, [dskbuf+0x1be+bx+12]
|
||||||
; copy bpb
|
adc dx, [dskbuf+0x1be+bx+12+2]
|
||||||
mov si, dskbuf+BPBOFF
|
; partitions after 4 TB mark not allowed
|
||||||
mov di, bpb
|
jc .ret
|
||||||
mov cx, BPBSIZ
|
; store partition end
|
||||||
rep movsb
|
mov [drvend], ax
|
||||||
; fix CHS data
|
mov [drvend+2], dx
|
||||||
call getprm
|
.ret ret
|
||||||
; fix partition offset
|
|
||||||
pop word [bpb+BPBHS]
|
|
||||||
pop word [bpb+BPBHS+2]
|
|
||||||
;pop [bpb+BPBNOS]
|
|
||||||
;pop [bpb+BPBSPT]
|
|
||||||
ret
|
|
||||||
|
|
||||||
logerr stc
|
; parse bios parameter block from drvoff
|
||||||
ret
|
; 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
|
; map sector into dskbuf
|
||||||
; skip doing a read if sector number matches
|
; skip doing a read if sector number matches
|
||||||
@ -227,13 +251,13 @@ diskio mov cl, 1 ; read len
|
|||||||
mov si, dap
|
mov si, dap
|
||||||
jmp .do
|
jmp .do
|
||||||
; check if we can skip controller reset
|
; check if we can skip controller reset
|
||||||
.noext test word [dflags], DRVRST
|
.noext test word [dflags], DRVCTL
|
||||||
jnz .norst
|
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 word [dflags], DRVRST
|
or word [dflags], DRVCTL
|
||||||
; put linear sector num into dx:ax
|
; put linear sector num into dx:ax
|
||||||
.norst mov ax, [drvseek]
|
.norst mov ax, [drvseek]
|
||||||
mov dx, [drvseek+2]
|
mov dx, [drvseek+2]
|
||||||
@ -272,16 +296,58 @@ diskio mov cl, 1 ; read len
|
|||||||
clc
|
clc
|
||||||
ret
|
ret
|
||||||
; assume controller is misconfigured
|
; assume controller is misconfigured
|
||||||
.err and word [dflags], ~DRVRST
|
.err and word [dflags], ~DRVCTL
|
||||||
; exit with carry flag set
|
; exit with carry flag set
|
||||||
stc
|
stc
|
||||||
ret
|
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
|
init mov ax, cs
|
||||||
; boot failure if loaded wrong
|
; boot failure if loaded wrong
|
||||||
cmp ax, cseg
|
cmp ax, cseg
|
||||||
je $+4
|
je $+4
|
||||||
int 0x18
|
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
|
halt hlt
|
||||||
jmp halt
|
jmp halt
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user