1 ; =============================================================================
2 ; Pure64 -- a 64-bit OS loader written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2011 Return Infinity -- see LICENSE.TXT
6 ; =============================================================================
9 ; -----------------------------------------------------------------------------
10 ; readcluster -- Read a cluster from the FAT16 partition
12 ; RDI - (memory location to store at least 32KB)
13 ; OUT: AX - (next cluster)
14 ; RDI - points one byte after the last byte read
21 and rax
, 0x000000000000FFFF ; Clear the top 48 bits
22 mov rbx
, rax
; Save the cluster number to be used later
24 cmp ax, 2 ; If less than 2 then bail out...
25 jl near readcluster_bailout
; as clusters start at 2
27 ; Calculate the LBA address --- startingsector = (cluster-2) * clustersize + data_start
29 mov cl, byte [fat16_SectorsPerCluster
]
30 push rcx
; Save the number of sectors per cluster
32 imul
cx ; EAX now holds starting sector
33 add eax, dword [fat16_DataStart
] ; EAX now holds the sector where our cluster starts
34 add eax, [fat16_PartitionOffset
] ; Add the offset to the partition
36 pop rcx
; Restore the number of sectors per cluster
37 call readsectors
; Read one cluster of sectors
39 ; Calculate the next cluster
41 ; tint1 = Cluster / 256 <- Dump the remainder
42 ; sector_to_read = tint1 + ReservedSectors
43 ; tint2 = (Cluster - (tint1 * 256)) * 2
45 mov rdi
, hdbuffer1
; Read to this temporary buffer
46 mov rsi
, rdi
; Copy buffer address to RSI
47 push rbx
; Save the original cluster value
48 shr rbx
, 8 ; Divide the cluster value by 256. Keep no remainder
49 movzx ax, [fat16_ReservedSectors
] ; First sector of the first FAT
50 add eax, [fat16_PartitionOffset
] ; Add the offset to the partition
51 add rax
, rbx
; Add the sector offset
54 pop rax
; Get our original cluster value back
55 shl rbx
, 8 ; Quick multiply by 256 (RBX was the sector offset in the FAT)
56 sub rax
, rbx
; RAX is now pointed to the offset within the sector
57 shl rax
, 1 ; Quickly multiply by 2 (since entries are 16-bit)
59 lodsw ; AX now holds the next cluster
73 ; -----------------------------------------------------------------------------
76 ; -----------------------------------------------------------------------------
78 ; IN: RSI(Pointer to file name, must be in 'FILENAMEEXT" format)
79 ; OUT: AX(Staring cluster), 0x0 if not found
80 ; Notes: Only searches the root sector.. not the following sectors.
90 mov eax, [fat16_RootStart
] ; eax points to the first sector of the root
91 add eax, [fat16_PartitionOffset
] ; Add the offset to the partition
92 mov rdx
, rax
; Save the sector value
94 os_fat16_find_file_read_sector:
100 mov rbx
, 16 ; Each record is 32 bytes. 512 (bytes per sector) / 32 = 16
102 os_fat16_find_file_next_entry:
103 cmp byte [rdi
], 0x00 ; end of records
104 je os_fat16_find_file_notfound
110 mov ax, [rdi
+15] ; AX now holds the starting cluster # of the file we just looked at
111 jz os_fat16_find_file_done
; The file was found. Note that rdi now is at dirent+11
117 jne os_fat16_find_file_next_entry
119 ; At this point we have read though one sector of file names. We have not found the file we are looking for and have not reached the end of the table. Load the next sector.
123 jmp os_fat16_find_file_read_sector
125 os_fat16_find_file_notfound:
129 os_fat16_find_file_done:
130 cmp ax, 0x0000 ; BUG HERE
131 jne wut
; Carry is not being set properly in this function
140 ; -----------------------------------------------------------------------------
143 ; =============================================================================