Another attempt on disk i/o

This commit is contained in:
Nero 2020-05-02 23:57:23 +02:00
parent 404825387b
commit 36f4673c91
3 changed files with 101 additions and 129 deletions

View file

@ -1,11 +1,23 @@
section .bss
chsspt: equ 0 ; word sectors per track
chsnos: equ 2 ; word number of sides
chspo: equ 4 ; dword partition offset
chssiz: equ 8
disk_buffer:
resb 512
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
dapps: equ 0 ; byte packet size
@ -28,121 +40,77 @@ dncl: rcl dl, 1
xchg dh, dl
ret
fndchs: ; find CHS table entry
; IN dl DOS drive number (A=0, B=1, ...)
; OUT cs:si ptr to chs table entry
push ax
mov ax, chssiz
mul dl
add ax, chstab
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
; Select a drive for I/O
; IN dl 0=A, 1=B, 2=C, 3=D
select: mov byte [disk_current], 0xFF
mov byte [lba_supported], 0
cmp dl, 0x02
jc select_floppy
; detect EBIOS/LBA extensions
call dnconv
mov byte [disk_chs], dl
mov ah, 0x41
mov bx, 0x55AA
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 ds
pop bp
retf
int 3
int 0x13
int 3
ret
; Write a sector into buffer
write:
ret