2 ; BOOT_DRIVE, part_table_entry and bp must be set up by the code using this driver.
3 ; first_data_sec is to be set up by calling get_1st_data_sec.
5 ; eax - start cluster number
6 ; es:di - where to load the cluster chain
7 ; NOTE: Cluster chain might be the root directory or a file.
11 ; get the first sector of the cluster to read
15 mov bl, BPB_SecPerClus
17 add eax, [first_data_sec]
22 movzx cx, BPB_SecPerClus
25 ; increment the load offset (and segment if needed)
28 movzx ax, BPB_SecPerClus
29 mul word BPB_BytsPerSec
38 ; get FAT sector number and offset containing the next cluster number
42 movzx ebx, word BPB_BytsPerSec
44 movzx ebx, word BPB_RsvdSecCnt
47 mov bp, [part_table_entry]
48 add eax, [bp+part_entry.lba_start]
51 ; reminder for myself: EAX is FAT sector number, (E)BX is offset into FAT sector
53 ; load the FAT sector we're looking for
56 push es ; we want to read at 0:1000, not STAGE3_SEGMENT:1000
57 push eax ; desired LBA
60 pop ebx ; pop LBA into EBX
65 ; find the cluster we're looking for
66 pop es ; restore STAGE3_SEGMENT
67 pop ebx ; pop FAT offset back into EBX for cmp
68 cmp dword [di+bx], 0xffffff7
69 jge .done ; if cluster number is greater than or equal to the defective cluster value, we're done
70 ; TODO: should this perhaps be changed so that equal makes it error out?
71 ; otherwise, load the next sector number in eax and read again
79 ; es:di - where to load the sector(s)
80 ; ebx - start LBA address
81 ; cx - how many sectors to read
109 movzx ax, BPB_NumFats
110 mul dword BPB_FatSz32 ; space occupied by all FATs
111 movzx ebx, word BPB_RsvdSecCnt
112 add eax, ebx ; space occupied by the reserved area
113 mov bx, [part_table_entry]
114 add eax, [bx+part_entry.lba_start] ; space before the partition
115 mov [first_data_sec], eax
120 read_error: db "Read error", 0
123 part_table_entry: dw 0