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 ; NOTE: Cluster chain might be the root directory or a file.
24 ; eax - cluster number
25 ; es:di - where to load the cluster (incremented automatically)
26 ; RETURN: eax - next cluster number
32 ; get the first sector of the cluster to read
36 mov bl, BPB_SecPerClus
44 movzx cx, BPB_SecPerClus
48 ; increment the load offset (and segment if needed)
51 movzx ax, BPB_SecPerClus
52 mul word BPB_BytsPerSec
61 ; get FAT sector number and offset containing the next cluster number
63 mov bl, 4 ; put 4 in EBX, doing this instead of "mov ebx, 4" saves us an entire byte
65 movzx ebx, word BPB_BytsPerSec
67 movzx ebx, word BPB_RsvdSecCnt
71 ; reminder for myself: EAX is FAT sector number, (E)BX is offset into FAT sector
73 ; load the FAT sector we're looking for
76 push es ; we want to read at 0:1000, not STAGE3_SEGMENT:1000
77 push eax ; desired LBA
80 pop ebx ; pop LBA into EBX
85 ; find the cluster we're looking for
86 pop es ; restore STAGE3_SEGMENT
87 pop ebx ; pop FAT offset back into EBX for cmp
96 ; es:di - where to load the sector(s)
97 ; ebx - start LBA address
98 ; cx - how many sectors to read
121 ; ds:si - pointer to partition table entry
122 ; RETURN: ecx - first data sector
126 movzx ax, BPB_NumFats
127 mul dword BPB_FatSz32 ; space occupied by all FATs
128 movzx ebx, word BPB_RsvdSecCnt
129 add eax, ebx ; space occupied by the reserved area
130 add eax, [si] ; space before the partition
136 read_error: db "Read error", 0