section .bss disk_buffer: resb 512 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 dapnum: equ 2 ; word number of sectors to transfer dapbuf: equ 4 ; dword transfer buffer dapsec: equ 8 ; qword absolute sector number dapsiz: equ 16 section .text ; Convert between drive number and BIOS dl ; Bidirectional mapping ; 0 <-> 0, 1 <-> 1, 2 <-> 0x80, 3 <-> 0x81 dnconv: mov cx, 7 ror dx, 1 rol dl, 1 dncl: rcl dl, 1 rcr dh, 1 loop dncl xchg dh, dl ret ; 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 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 int 3 int 0x13 int 3 ret ; Write a sector into buffer write: ret