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 chstab: resw (4*chssiz) ; 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 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 call dnconv int 0x13 .ret: mov sp, bp pop es pop ds pop bp retf