Another attempt on disk i/o
This commit is contained in:
parent
404825387b
commit
36f4673c91
@ -3,6 +3,7 @@
|
|||||||
jmp 0:(init+0x7C00-$$)
|
jmp 0:(init+0x7C00-$$)
|
||||||
|
|
||||||
%include "inc/bpb.asm"
|
%include "inc/bpb.asm"
|
||||||
|
%include "inc/mbr.asm"
|
||||||
|
|
||||||
; Far call via interrupt vector
|
; Far call via interrupt vector
|
||||||
%macro intcall 1
|
%macro intcall 1
|
||||||
@ -195,7 +196,7 @@ fputc: push ax
|
|||||||
%include "kernel/diskio.asm"
|
%include "kernel/diskio.asm"
|
||||||
|
|
||||||
vects: dw int20h, int21h, retf, retf
|
vects: dw int20h, int21h, retf, retf
|
||||||
dw retf, int25h, int26h, int20h
|
dw retf, retf, retf, int20h
|
||||||
dw idle, fputc
|
dw idle, fputc
|
||||||
|
|
||||||
main: ; zero out first 64kb except our code
|
main: ; zero out first 64kb except our code
|
||||||
@ -222,12 +223,7 @@ intlp: movsw
|
|||||||
|
|
||||||
call dnconv
|
call dnconv
|
||||||
mov al, dl
|
mov al, dl
|
||||||
mov cx, 1
|
call select
|
||||||
mov dx, 0
|
|
||||||
mov bx, buffer
|
|
||||||
int 3
|
|
||||||
intcall 0x25
|
|
||||||
int 3
|
|
||||||
|
|
||||||
loop: int 0x28
|
loop: int 0x28
|
||||||
jmp loop
|
jmp loop
|
||||||
@ -250,6 +246,3 @@ init: cli
|
|||||||
section .bss
|
section .bss
|
||||||
; stack to be used during init and disk i/o
|
; stack to be used during init and disk i/o
|
||||||
stack: resw stacks
|
stack: resw stacks
|
||||||
; default int 25h/26h handler use a cache to keep geometry for
|
|
||||||
; the first 4 drives
|
|
||||||
buffer: resb 512
|
|
||||||
|
11
inc/mbr.asm
Normal file
11
inc/mbr.asm
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
mbrtab: equ 0x1BE ; start of partition table
|
||||||
|
mbrsig: equ 0x1FE ; start of signature
|
||||||
|
mbrmn: equ 0x55AA ; signature value
|
||||||
|
|
||||||
|
pardn: equ 0x00 ; byte: partition active flag
|
||||||
|
parchs: equ 0x01 ; 3 bytes: CHS for first sector
|
||||||
|
partyp: equ 0x04 ; byte: partition type
|
||||||
|
parend: equ 0x05 ; 3 bytes: CHS for last sector
|
||||||
|
paroff: equ 0x08 ; dword: partition offset in sectors
|
||||||
|
parlen: equ 0x0C ; dword: partition length in sectors
|
||||||
|
parsiz: equ 0x10
|
@ -1,11 +1,23 @@
|
|||||||
section .bss
|
section .bss
|
||||||
|
|
||||||
chsspt: equ 0 ; word sectors per track
|
disk_buffer:
|
||||||
chsnos: equ 2 ; word number of sides
|
resb 512
|
||||||
chspo: equ 4 ; dword partition offset
|
|
||||||
chssiz: equ 8
|
|
||||||
|
|
||||||
chstab: resw (4*chssiz)
|
disk_current:
|
||||||
|
resb 1
|
||||||
|
|
||||||
|
lba_supported:
|
||||||
|
resb 1
|
||||||
|
|
||||||
|
disk_chs: ; DL, DH, CL, CH for int 13h CHS functions
|
||||||
|
resb 4
|
||||||
|
disk_dap: ; disk access packet for int 13h EBIOS functions
|
||||||
|
resb 0x10
|
||||||
|
|
||||||
|
disk_tracks: ; heads * spt
|
||||||
|
resw 1
|
||||||
|
disk_spt:
|
||||||
|
resb 1
|
||||||
|
|
||||||
; Disk access packet for EBIOS extensions
|
; Disk access packet for EBIOS extensions
|
||||||
dapps: equ 0 ; byte packet size
|
dapps: equ 0 ; byte packet size
|
||||||
@ -28,121 +40,77 @@ dncl: rcl dl, 1
|
|||||||
xchg dh, dl
|
xchg dh, dl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
fndchs: ; find CHS table entry
|
; Select a drive for I/O
|
||||||
; IN dl DOS drive number (A=0, B=1, ...)
|
; IN dl 0=A, 1=B, 2=C, 3=D
|
||||||
; OUT cs:si ptr to chs table entry
|
select: mov byte [disk_current], 0xFF
|
||||||
push ax
|
mov byte [lba_supported], 0
|
||||||
mov ax, chssiz
|
cmp dl, 0x02
|
||||||
mul dl
|
jc select_floppy
|
||||||
add ax, chstab
|
; detect EBIOS/LBA extensions
|
||||||
mov si, ax
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; compare sector number in disk access packet with zero
|
|
||||||
; sets zero flag accordingly
|
|
||||||
iszero: push ax
|
|
||||||
mov ax, [bx]
|
|
||||||
or ax, [bx+2]
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; calculate CHS from dap and CHS table entry
|
|
||||||
; IN ds:bx disk access packet
|
|
||||||
; cs:si chstab table entry
|
|
||||||
; OUT cx,dh chs data for int 13h
|
|
||||||
calchs: push ax
|
|
||||||
; load linear sector number
|
|
||||||
mov dx, [bx+2]
|
|
||||||
mov ax, [bx]
|
|
||||||
; if any word of it is non-zero, we need to do calculation
|
|
||||||
call iszero
|
|
||||||
jz .zero
|
|
||||||
; ax is track number (lba / spt)
|
|
||||||
; dx is sector (lba % spt) + 1
|
|
||||||
div word [cs:si+chsspt]
|
|
||||||
inc dx
|
|
||||||
; sector number
|
|
||||||
mov cl, dl
|
|
||||||
; ax is cylinder (track / heads)
|
|
||||||
; dx is head (track % heads)
|
|
||||||
xor dx, dx
|
|
||||||
div word [cs:si+chsnos]
|
|
||||||
; set up cylinder and head number
|
|
||||||
mov ch, al
|
|
||||||
mov dh, dl
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
; set up CHS data for int 13h for reading sector zero
|
|
||||||
.zero: mov cx, 1 ; C=0, S=1
|
|
||||||
mov dh, 0 ; H=0
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ABSOLUTE DISK READ / DISK WRITE
|
|
||||||
int25h: mov ah, 2
|
|
||||||
jmp adisk
|
|
||||||
int26h: mov ah, 3
|
|
||||||
adisk: push bp
|
|
||||||
push ds
|
|
||||||
push es
|
|
||||||
mov bp, sp
|
|
||||||
|
|
||||||
push ax
|
|
||||||
|
|
||||||
cmp cx, 0xFFFF
|
|
||||||
je .lrg
|
|
||||||
|
|
||||||
; build ebios DAP from registers supplied
|
|
||||||
; qword sector number
|
|
||||||
push cs
|
|
||||||
push cs
|
|
||||||
push cs
|
|
||||||
push dx
|
|
||||||
; dword target buffer
|
|
||||||
push ds
|
|
||||||
push bx
|
|
||||||
; word number of sectors
|
|
||||||
push cx
|
|
||||||
jmp .psz
|
|
||||||
|
|
||||||
.lrg: ; build ebios DAP from int 25h DAP
|
|
||||||
; qword sector number
|
|
||||||
push cs
|
|
||||||
push cs
|
|
||||||
mov ax, [bx+2]
|
|
||||||
push ax
|
|
||||||
mov ax, [bx]
|
|
||||||
push ax
|
|
||||||
; dword target buffer
|
|
||||||
mov ax, [bx+8]
|
|
||||||
push ax
|
|
||||||
mov ax, [bx+6]
|
|
||||||
push ax
|
|
||||||
; word number of sectors
|
|
||||||
mov ax, [bx+4]
|
|
||||||
push ax
|
|
||||||
.psz: ; word packet size
|
|
||||||
mov ax, dapsiz
|
|
||||||
push ax
|
|
||||||
|
|
||||||
; DS:SI = SS:SP (ptr to dap)
|
|
||||||
push ss
|
|
||||||
pop ds
|
|
||||||
mov si, sp
|
|
||||||
|
|
||||||
; set up int 13h subfunction number
|
|
||||||
mov ax, [si+dapsiz]
|
|
||||||
add ah, 0x40
|
|
||||||
|
|
||||||
; get BIOS drive number
|
|
||||||
mov dl, al
|
|
||||||
call dnconv
|
call dnconv
|
||||||
|
mov byte [disk_chs], dl
|
||||||
|
mov ah, 0x41
|
||||||
|
mov bx, 0x55AA
|
||||||
int 0x13
|
int 0x13
|
||||||
|
test cx, 1
|
||||||
|
jz .nolba
|
||||||
|
cmp bx, 0xAA55
|
||||||
|
jnz .nolba
|
||||||
|
mov byte [lba_supported], 1
|
||||||
|
.nolba: call seek_zero
|
||||||
|
ret
|
||||||
|
|
||||||
.ret: mov sp, bp
|
select_floppy:
|
||||||
|
xor dx, dx
|
||||||
|
xor ax, ax
|
||||||
|
call seek
|
||||||
|
call read
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Set absolute sector number
|
||||||
|
; IN dx:ax 32-bit sector number
|
||||||
|
seek: push ax
|
||||||
|
or ax, dx
|
||||||
|
pop ax
|
||||||
|
jz seek_zero
|
||||||
|
|
||||||
|
; dx:ax = lba
|
||||||
|
div word [disk_tracks]
|
||||||
|
xchg ax, dx
|
||||||
|
; dx = cylinder, ax = head * spt + sector
|
||||||
|
div byte [disk_spt]
|
||||||
|
; dx = cylinder, al = head, ah = sector
|
||||||
|
xchg dl, dh
|
||||||
|
ror dl, 1
|
||||||
|
ror dl, 1
|
||||||
|
or dl, ah
|
||||||
|
;inc dx
|
||||||
|
; dh bit 0-7: cylinder 0-7
|
||||||
|
; dl bit 0-5: sector number 0-5
|
||||||
|
; dl bit 6-7: cylinder 8-9
|
||||||
|
; store
|
||||||
|
mov byte [disk_chs+1], al
|
||||||
|
mov word [disk_chs+2], dx
|
||||||
|
int 3
|
||||||
|
ret
|
||||||
|
|
||||||
|
seek_zero:
|
||||||
|
mov byte [disk_chs+1], 0
|
||||||
|
mov word [disk_chs+2], 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Read a sector into buffer
|
||||||
|
read: mov ax, 0x0201
|
||||||
|
mov dx, [disk_chs]
|
||||||
|
mov cx, [disk_chs+2]
|
||||||
|
lea bx, [disk_buffer]
|
||||||
|
push cs
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
int 3
|
||||||
pop bp
|
int 0x13
|
||||||
retf
|
int 3
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Write a sector into buffer
|
||||||
|
write:
|
||||||
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user