diff --git a/kernel/diskio.asm b/kernel/diskio.asm index e3bab31..1536985 100644 --- a/kernel/diskio.asm +++ b/kernel/diskio.asm @@ -14,11 +14,16 @@ disk_chs: ; DL, DH, CL, CH for int 13h CHS functions disk_dap: ; disk access packet for int 13h EBIOS functions resb 0x10 -disk_tracks: ; heads * spt +disk_spc: ; sectors per cylinder = heads * spt resw 1 disk_spt: resb 1 +part_offset: + resd 1 +part_size: + resd 1 + ; Disk access packet for EBIOS extensions dapps: equ 0 ; byte packet size dapnum: equ 2 ; word number of sectors to transfer @@ -53,22 +58,42 @@ select: mov byte [disk_current], 0xFF mov bx, 0x55AA int 0x13 test cx, 1 - jz .nolba + jz select_hdd cmp bx, 0xAA55 - jnz .nolba + jnz select_hdd mov byte [lba_supported], 1 -.nolba: call seek_zero - ret + jmp select_hdd select_floppy: - xor dx, dx - xor ax, ax - call seek + call seek_zero call read + ; load disk geometry mov ax, [disk_buffer+0x0B+bpb_spt] mov [disk_spt], ax mul word [disk_buffer+0x0B+bpb_nos] - mov [disk_tracks], ax + 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 ret ; Set absolute sector number @@ -79,7 +104,7 @@ seek: push ax jz seek_zero ; dx:ax = lba - div word [disk_tracks] + div word [disk_spc] xchg ax, dx ; dx = cylinder, ax = head * spt + sector div byte [disk_spt] @@ -98,8 +123,14 @@ seek: push ax ret seek_zero: + ; set chs data to first sector mov byte [disk_chs+1], 0 mov word [disk_chs+2], 1 + ; set lba data to first sector + lea di, [disk_dap+dapsec] + mov cx, 4 + xor ax, ax + rep stosw ret ; Read a sector into buffer