rdos/kernel/drive.asm

70 lines
1.3 KiB
NASM

; Load a sector from drive.
; IN DX:AX sector number (lba)
; BX ptr to FCB
; OUT CL Sector number
; CH Cylinder number
; DH Head number
drive_chs_calc:
push bx ; backup fcb ptr
mov bx, [bx+fcb_spt] ; nos is in BH now
push bx ; backup nos
xor bh, bh ; zero out nos so spt is left
div word bx ; ax:temp = (lba / spt)
inc dx ; dx:sector = (lba % spt) + 1
mov cl, dl ; sector number
pop bx ; restore nos
xchg bl, bh ; put nos into bl
xor bh, bh ; zero out spt
div word bx ; ax:cylinder = (temp / nos)
; dx:head = (temp % nos)
mov ch, al ; cylinder number
mov dh, dl ; head number
pop bx ; restore fcb ptr
ret
; Load a sector from drive.
; IN DX:AX sector number
; BX ptr to FCB
drive_read:
push ax
push cx
push dx
push bx
push si
mov cx, dx
or cx, ax
jz .fast
call drive_chs_calc
mov si, 5 ; retry count
.try:
mov dl, [bx+fcb_drv] ; drive number
dec dl
mov ax, 0x0201
mov bx, diskbuf
; try read
int 0x13
jnc .end
; reset disk
mov ah, 0x00
int 0x13
; loop with si
dec si
test si, si
jnz .try
stc
.end:
pop si
pop bx
pop dx
pop cx
pop ax
ret
.fast: ; fast lane for boot sector
inc cl
jmp .try