; eax - start cluster number
; es:di - where to load the cluster chain
+; RETURN: CF set = error
; NOTE: Cluster chain might be the root directory or a file.
read_cluster_chain:
push eax
push di
.loop:
call read_cluster
+ jc .done
cmp eax, 0xffffff7
jl .loop
+.done:
pop di
pop es
pop eax
; eax - cluster number
; es:di - where to load the cluster (incremented automatically)
; RETURN: eax - next cluster number
+; CF set = error
read_cluster:
push ebx
push ecx
movzx cx, BPB_SecPerClus
call read_sectors
pop cx
+ cmp dl, 0
+ je .error
; increment the load offset (and segment if needed)
push eax
xor ax, ax
mov es, ax
pop ebx ; pop LBA into EBX
- mov di, 0x1000
+ mov di, 0x6000
mov cx, 1
call read_sectors
-
+ cmp dl, 0
; find the cluster we're looking for
pop es ; restore STAGE3_SEGMENT
pop ebx ; pop FAT offset back into EBX for cmp
mov eax, [di+bx]
pop di
+ jne .end
; cleanup and return
+.error:
+ stc
+.end:
pop edx
pop ecx
pop ebx
; es:di - where to load the sector(s)
; ebx - start LBA address
; cx - how many sectors to read
+; RETURN: DL=0 means error
read_sectors:
- pusha
+ clc
+ push ax
+ push si
mov ah, 0x42
push dword 0
push dword ebx
mov si, sp
mov dl, [BOOT_DRIVE]
int 0x13
- jc .error
+ mov dl, 1
+ jnc .done
+ mov dl, 0
+.done:
add sp, 16
- popa
+ pop si
+ pop ax
ret
- .error:
- mov si, read_error
- call print
- hlt
- jmp $-1
; ds:si - pointer to partition table entry
; RETURN: ecx - first data sector