169 lines
2.5 KiB
NASM
169 lines
2.5 KiB
NASM
|
disk_num: equ 0x40 ; BYTE drive number (A=0)
|
||
|
disk_heads: equ 0x41 ; BYTE number of heads/sides
|
||
|
disk_parm: equ 0x42 ; 11 BYTES for int 0x1E
|
||
|
disk_spt: equ 0x46 ; - BYTE
|
||
|
|
||
|
disk_parm_init:
|
||
|
push ax
|
||
|
push si
|
||
|
push di
|
||
|
push ds
|
||
|
|
||
|
; invalidate existing data
|
||
|
mov byte [disk_num], 0xFF
|
||
|
|
||
|
xor ax, ax
|
||
|
mov ds, ax
|
||
|
|
||
|
; if int 0x1E is already pointing to us,
|
||
|
; we have nothing to copy
|
||
|
mov di, disk_parm
|
||
|
lds si, [0x1E*4]
|
||
|
cmp si, di
|
||
|
je .correctparm
|
||
|
|
||
|
; copy bios table into our location
|
||
|
mov cx, 11
|
||
|
rep movsb
|
||
|
|
||
|
; make the interrupt vector point to our address
|
||
|
xor ax, ax
|
||
|
mov ds, ax
|
||
|
mov [0x1E*4], di
|
||
|
mov ax, cs
|
||
|
mov [0x1E*4+2], ax
|
||
|
|
||
|
.correctparm:
|
||
|
pop ds
|
||
|
pop di
|
||
|
pop si
|
||
|
pop ax
|
||
|
ret
|
||
|
|
||
|
disk_load_bpb:
|
||
|
mov ax, 0x0201
|
||
|
mov cx, 0x0001
|
||
|
xor dh, dh
|
||
|
mov bx, diskbuf
|
||
|
stc
|
||
|
|
||
|
int 0x13
|
||
|
jnc .end
|
||
|
|
||
|
; try a second time
|
||
|
mov ax, 0x0201
|
||
|
int 0x13
|
||
|
jnc .end
|
||
|
|
||
|
; try a third time
|
||
|
mov ax, 0x0201
|
||
|
int 0x13
|
||
|
.end:
|
||
|
ret
|
||
|
|
||
|
disk_select:
|
||
|
push ax
|
||
|
push cx
|
||
|
push dx
|
||
|
push bx
|
||
|
|
||
|
cmp byte [disk_num], dl
|
||
|
je .end
|
||
|
mov byte [disk_num], dl
|
||
|
call disk_load_bpb
|
||
|
jc .end
|
||
|
|
||
|
; Validate and apply sector size
|
||
|
mov ax, [diskbuf+fdc_ss]
|
||
|
; test ax, 0xF87F
|
||
|
; jnz .nobpd
|
||
|
call log2
|
||
|
sub al, 7
|
||
|
mov [disk_parm+3], al
|
||
|
|
||
|
; fetch sectors per track
|
||
|
mov al, [diskbuf+fdc_spt]
|
||
|
mov [disk_parm+4], al
|
||
|
|
||
|
; fetch number of sides/heads
|
||
|
mov ax, [diskbuf+fdc_nos]
|
||
|
mov [disk_heads], al
|
||
|
|
||
|
xor ah, ah
|
||
|
int 0x13
|
||
|
.end:
|
||
|
pop bx
|
||
|
pop dx
|
||
|
pop cx
|
||
|
pop ax
|
||
|
ret
|
||
|
|
||
|
; Setup CX, DX and BX for int 13h transfer
|
||
|
; IN BX ptr to 32-bit number
|
||
|
; OUT CL Sector number
|
||
|
; CH Cylinder number
|
||
|
; DL Drive number
|
||
|
; DH Head number
|
||
|
; BX Sector buffer
|
||
|
disk_prepare_chs:
|
||
|
mov ax, word [bx]
|
||
|
mov dx, word [bx+2]
|
||
|
|
||
|
xor bh, bh
|
||
|
mov bl, byte [disk_spt]
|
||
|
|
||
|
div word bx ; ax:temp = (lba / spt)
|
||
|
inc dx ; dx:sector = (lba % spt) + 1
|
||
|
mov cl, dl ; sector number
|
||
|
|
||
|
xor bx, bx
|
||
|
mov bl, byte [disk_heads]
|
||
|
|
||
|
xor dx, dx
|
||
|
div word bx ; ax:cylinder = (temp / nos)
|
||
|
; dx:head = (temp % nos)
|
||
|
mov ch, al ; cylinder number
|
||
|
mov dh, dl ; head number
|
||
|
|
||
|
mov dl, byte [disk_num]
|
||
|
mov bx, diskbuf
|
||
|
ret
|
||
|
|
||
|
; Read a sector into diskbuf
|
||
|
; IN BX ptr to DWORD giving sector number
|
||
|
disk_read:
|
||
|
push ax
|
||
|
push cx
|
||
|
push dx
|
||
|
push bx
|
||
|
|
||
|
call disk_prepare_chs
|
||
|
|
||
|
mov ax, 0x0201
|
||
|
int 0x13
|
||
|
|
||
|
pop bx
|
||
|
pop dx
|
||
|
pop cx
|
||
|
pop ax
|
||
|
ret
|
||
|
|
||
|
; Write a sector from diskbuf
|
||
|
; IN BX ptr to DWORD giving sector number
|
||
|
disk_write:
|
||
|
push ax
|
||
|
push cx
|
||
|
push dx
|
||
|
push bx
|
||
|
|
||
|
call disk_prepare_chs
|
||
|
|
||
|
mov ax, 0x0301
|
||
|
int 0x13
|
||
|
|
||
|
pop bx
|
||
|
pop dx
|
||
|
pop cx
|
||
|
pop ax
|
||
|
ret
|