Changes

2,585 bytes added ,  21:30, 3 May 2019
Copy FAT info from savegame
Line 71: Line 71:  
** file entry table as well
 
** file entry table as well
 
** title entries (title info or ticket) are allocated as normal files in the data region as well.
 
** title entries (title info or ticket) are allocated as normal files in the data region as well.
 +
 +
== File Allocation Table ==
 +
 +
The file allocation table is an array of a 8-byte entry shown below. The array size is actually ''one larger than'' the size recorded in the filesystem header. Each entry corresponds to a block in the data region (the block size is defined in filesystem header). However, the 0th entry corresponds to nothing, so the corresponding block index is off by one. e.g. entry 31 in this table corresponds to block 30 in the data region.
 +
 +
{| class="wikitable" border="1"
 +
! Offset
 +
! Length
 +
! Description
 +
|-
 +
| 0x00
 +
| 4
 +
| bit[0:30]: Index U; bit[31]: Flag U
 +
|-
 +
| 0x04
 +
| 4
 +
| bit[0:30]: Index V; bit[31]: Flag V
 +
|}
 +
 +
Entries in this table forms several chains, representing how blocks in the data region should be linked together. However, unlike normal FAT systems, which uses chains of entries, 3DS savegames use chain of ''nodes''. Each node spans one or multiple entries.
 +
 +
One node spanning <code>n</code> entries starting from <code>FAT[k]</code> is in the following format:
 +
 +
<pre>FAT[k + 0]:
 +
    Index_U = index of the first entry of the previous node. 0 if this is the first node.
 +
    Index_V = index of the first entry of the next node. 0 if this is the last node.
 +
    Flag_U set if this is the first node.
 +
    Flag_V set if this node has multiple entries.
 +
 +
FAT[k + 1]:
 +
    Index_U = k (the first entry index of this node)
 +
    Index_V = k + n - 1 (the last entry index of this node)
 +
    Flag_U always set
 +
    Flag_V always clear
 +
 +
FAT[k + 2] ~ FAT[k + n - 2]:
 +
    All these entries are uninitialized
 +
 +
FAT[k + n - 1]:
 +
    Index_U = k
 +
    Index_V = k + n - 1
 +
    Flag_U always set
 +
    Flag_V always clear
 +
    (Same values as FAT[k + 1])
 +
</pre>
 +
* Note: all indices above are entry indices (block index + 1)
 +
 +
All free blocks that are not allocated to any files also form a node chain in the allocation table. The head index of this &quot;free chain&quot; is recorded in <code>FAT[0].Index_V</code>. Other fields of <code>FAT[0]</code> are all zero
 +
 +
Here is an example: [https://raw.githubusercontent.com/wwylele/3ds-save-tool/master/disa-fat.png]
 +
 +
For extdata, because only two "files" (directory and file entry tables) are allocated in the data region, and their size never changes once the extdata is created, they are guaranteed continuous in the data region, and the FAT degenerates to two big nodes. Therefore, instead of going through FAT, the offset and size of directory / file entry table can be found directly by offset = entry_table_starting block * data_region_block_size + data_region_offset and size = entry_table_block_count * data_region_block_size.
242

edits