2020-04-27 15:56:41 +02:00
|
|
|
section .bss
|
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
disk_buffer:
|
|
|
|
resb 512
|
2020-04-27 15:56:41 +02:00
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
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
|
|
|
|
|
2020-05-06 22:28:30 +02:00
|
|
|
disk_spc: ; sectors per cylinder = heads * spt
|
2020-05-02 23:57:23 +02:00
|
|
|
resw 1
|
|
|
|
disk_spt:
|
|
|
|
resb 1
|
2020-04-27 15:56:41 +02:00
|
|
|
|
2020-05-06 22:28:30 +02:00
|
|
|
part_offset:
|
|
|
|
resd 1
|
|
|
|
part_size:
|
|
|
|
resd 1
|
|
|
|
|
2020-04-28 22:09:56 +02:00
|
|
|
; 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
|
|
|
|
|
2020-04-27 15:56:41 +02:00
|
|
|
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
|
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
; 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
|
2020-05-06 22:28:30 +02:00
|
|
|
jz select_hdd
|
2020-05-02 23:57:23 +02:00
|
|
|
cmp bx, 0xAA55
|
2020-05-06 22:28:30 +02:00
|
|
|
jnz select_hdd
|
2020-05-02 23:57:23 +02:00
|
|
|
mov byte [lba_supported], 1
|
2020-05-06 22:28:30 +02:00
|
|
|
jmp select_hdd
|
2020-04-27 15:56:41 +02:00
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
select_floppy:
|
2020-05-06 22:28:30 +02:00
|
|
|
call seek_zero
|
2020-05-02 23:57:23 +02:00
|
|
|
call read
|
2020-05-06 22:28:30 +02:00
|
|
|
; load disk geometry
|
2020-05-04 21:49:26 +02:00
|
|
|
mov ax, [disk_buffer+0x0B+bpb_spt]
|
|
|
|
mov [disk_spt], ax
|
|
|
|
mul word [disk_buffer+0x0B+bpb_nos]
|
2020-05-06 22:28:30 +02:00
|
|
|
mov [disk_spc], ax
|
|
|
|
; set partition size
|
|
|
|
; we dont rely on the 'total sectors' given in the BPB
|
|
|
|
; instead, we assume maximum cylinder
|
|
|
|
; 1023 is the maximum encodable for int 13h
|
|
|
|
mov di, 1023
|
|
|
|
mul di
|
|
|
|
mov [part_size], ax
|
|
|
|
mov [part_size+2], dx
|
|
|
|
; set partition offset to zero
|
|
|
|
xor ax, ax
|
|
|
|
mov [part_offset], ax
|
|
|
|
mov [part_offset+2], ax
|
|
|
|
ret
|
|
|
|
|
|
|
|
select_hdd:
|
|
|
|
call seek_zero
|
|
|
|
call read
|
|
|
|
mov bx, disk_buffer+0x1BE
|
|
|
|
lea si, [bx+8]
|
|
|
|
lea di, [part_offset]
|
|
|
|
mov cx, 4
|
|
|
|
rep movsw
|
2020-04-27 15:56:41 +02:00
|
|
|
ret
|
2020-05-02 23:57:23 +02:00
|
|
|
|
|
|
|
; Set absolute sector number
|
|
|
|
; IN dx:ax 32-bit sector number
|
|
|
|
seek: push ax
|
|
|
|
or ax, dx
|
2020-04-27 15:56:41 +02:00
|
|
|
pop ax
|
2020-05-02 23:57:23 +02:00
|
|
|
jz seek_zero
|
|
|
|
|
|
|
|
; dx:ax = lba
|
2020-05-06 22:28:30 +02:00
|
|
|
div word [disk_spc]
|
2020-05-02 23:57:23 +02:00
|
|
|
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
|
2020-05-04 21:49:26 +02:00
|
|
|
inc dx
|
2020-05-02 23:57:23 +02:00
|
|
|
; 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
|
2020-04-27 15:56:41 +02:00
|
|
|
ret
|
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
seek_zero:
|
2020-05-06 22:28:30 +02:00
|
|
|
; set chs data to first sector
|
2020-05-02 23:57:23 +02:00
|
|
|
mov byte [disk_chs+1], 0
|
|
|
|
mov word [disk_chs+2], 1
|
2020-05-06 22:28:30 +02:00
|
|
|
; set lba data to first sector
|
|
|
|
lea di, [disk_dap+dapsec]
|
|
|
|
mov cx, 4
|
|
|
|
xor ax, ax
|
|
|
|
rep stosw
|
2020-05-02 23:57:23 +02:00
|
|
|
ret
|
2020-04-27 15:56:41 +02:00
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
; Read a sector into buffer
|
|
|
|
read: mov ax, 0x0201
|
|
|
|
mov dx, [disk_chs]
|
|
|
|
mov cx, [disk_chs+2]
|
|
|
|
lea bx, [disk_buffer]
|
2020-04-28 22:09:56 +02:00
|
|
|
push cs
|
2020-05-02 23:57:23 +02:00
|
|
|
pop es
|
2020-04-27 15:56:41 +02:00
|
|
|
int 0x13
|
2020-05-02 23:57:23 +02:00
|
|
|
ret
|
2020-04-27 15:56:41 +02:00
|
|
|
|
2020-05-02 23:57:23 +02:00
|
|
|
; Write a sector into buffer
|
2020-05-04 21:49:26 +02:00
|
|
|
write: stc
|
2020-05-02 23:57:23 +02:00
|
|
|
ret
|