2 ; BOOT_DRIVE, si and bp must be set up by the code using this driver.
3 ; (Specifically, si must be a pointer to the partition's partition
4 ; table entry and bp must be a pointer to the BPB.)
5 ; Before reading any cluster chains, callers must call get_1st_data_sec
6 ; and must be careful not to trash ecx after calling it.
8 ; eax - start cluster number
9 ; es:di - where to load the cluster chain
10 ; RETURN: CF set = error
11 ; NOTE: Cluster chain might be the root directory or a file.
27 ; eax - cluster number
28 ; es:di - where to load the cluster (incremented automatically)
29 ; RETURN: eax - next cluster number
36 ; get the first sector of the cluster to read
40 mov bl, BPB_SecPerClus
48 movzx cx, BPB_SecPerClus
54 ; increment the load offset (and segment if needed)
57 movzx ax, BPB_SecPerClus
58 mul word BPB_BytsPerSec
67 ; get FAT sector number and offset containing the next cluster number
69 mov bl, 4 ; put 4 in EBX, doing this instead of "mov ebx, 4" saves us an entire byte
71 movzx ebx, word BPB_BytsPerSec
73 movzx ebx, word BPB_RsvdSecCnt
77 ; reminder for myself: EAX is FAT sector number, (E)BX is offset into FAT sector
79 ; load the FAT sector we're looking for
82 push es ; we want to read at 0:800, not STAGE3_SEGMENT:800
83 push eax ; desired LBA
86 pop ebx ; pop LBA into EBX
91 ; find the cluster we're looking for
92 pop es ; restore STAGE3_SEGMENT
93 pop ebx ; pop FAT offset back into EBX for cmp
106 ; es:di - where to load the sector(s)
107 ; ebx - start LBA address
108 ; cx - how many sectors to read
109 ; RETURN: DL=0 means error
133 ; ds:si - pointer to partition table entry
134 ; RETURN: ecx - first data sector
138 movzx ax, BPB_NumFats
139 mul dword BPB_FatSz32 ; space occupied by all FATs
140 movzx ebx, word BPB_RsvdSecCnt
141 add eax, ebx ; space occupied by the reserved area
142 add eax, [si] ; space before the partition
148 read_error: db "Read error", 0