FAT (Memory Card File System): Difference between revisions
| Revision as of 02:46, 23 October 2026 RemmyLee (SPU and CD-ROM at register depth; CPU overview rewritten) | Revision as of 02:47, 23 October 2026 RemmyLee (Formats: Sony paragraph voice; HMD, RSD extended files, full BS code book; sprite editor formats) | ||
| Line 11: | Line 11: | ||
| ## Overview | ## Overview | ||
| − | A Memory Card holds 1 Mbit (128 KB) of flash memory. The memory is organized in blocks of 8 KB.[^ff53] | + | A Memory Card contains 1 Mbit (128 KB) of flash memory and is organized in blocks of 8 KB. The card is managed with an independent file system known as the FAT, and PDA application data is also managed in the blocks. Writes to flash memory are performed in 128-byte units known as sectors, so each block holds 64 sectors (8192 bytes / 128 bytes).[^ff53] |
| − | The Memory Card is managed with its own file system. Sony calls it the FAT. PDA application data is also managed in the blocks.[^ff53] | ||
| − | |||
| − | Writes to flash memory are made in 128-byte units known as sectors. Each block has 64 sectors.[^ff53] | ||
| − | |||
| ## Block Layout | ## Block Layout | ||
| − | The blocks of a Memory Card are as follows:[^ff53] | + | Block 0 holds the FAT, and blocks 1 to 15 hold data:[^ff53] |
| Table: Layout of Memory Card blocks | Table: Layout of Memory Card blocks | ||
| Line 32: | Line 28: | ||
| ## FAT Block | ## FAT Block | ||
| − | The sectors of the FAT block are as follows:[^ff53] | + | The 64 sectors of the FAT block are assigned as follows:[^ff53] |
| Table: FAT block memory map | Table: FAT block memory map | ||
| Line 47: | Line 43: | ||
| ### Format ID Sector | ### Format ID Sector | ||
| − | The first 2 bytes of the format ID are 'M' and 'C'. The remaining bytes are 0 up to the checksum in the 128th byte.[^ff54] | + | The first 2 bytes of the format ID are 'M' and 'C', and the remaining bytes are 0 except for the checksum in the 128th byte. When the first 2 bytes are 'MC' the card is identified as a formatted Memory Card. Otherwise it is considered unformatted.[^ff54] |
| − | A card whose first 2 bytes are 'MC' is a formatted Memory Card. Any other card is unformatted.[^ff54] | ||
| − | |||
| ### Block Information Sector | ### Block Information Sector | ||
| − | Each data block has one block information sector:[^ff54] | + | Each data block has one block information sector, whose first field gives the state of the block. The sector has the following structure:[^ff54] |
| Table: Structure of block information sector | Table: Structure of block information sector | ||
| Line 68: | Line 62: | ||
| | Checksum | unsigned char | 1 | | | Checksum | unsigned char | 1 | | ||
| − | The block list information gives the state of the block:[^ff54] | + | The block list information takes the following values:[^ff54] |
| Table: Meaning of block list information | Table: Meaning of block list information | ||
| Line 82: | Line 76: | ||
| | A3 | End block with delete mark | | | A3 | End block with delete mark | | ||
| − | Formatting sets every block list information field to A0. A new file gets the values 51 to 53.[^ff54] | + | Immediately after formatting, every block list information field is A0. When a file is created its blocks take the values 51 to 53, and when it is deleted they take the values A1 to A3. A deleted file can therefore be restored by restoring the original values. However, a file created after a deletion can break the chain from header block to end block. In this case the next FAT read sets every block of the broken chain to A0.[^ff54] |
| − | A deleted file keeps its blocks with the values A1 to A3. Restoring the original values restores the file.[^ff54] | + | A file of 1 block has only the value 51 (or A1). A file of 2 blocks has 51 and 53 (or A1 and A3), and in this case no block has the value 52 (or A2).[^ff54] |
| − | A new file can break the chain from header block to end block.[^ff54] | ||
| − | |||
| − | The next FAT read then sets every block of the broken chain to A0.[^ff54] | ||
| − | |||
| − | A 1-block file has only the value 51 (or A1). A 2-block file has 51 and 53 (or A1 and A3) and no 52.[^ff54] | ||
| − | |||
| ### Block Information Fields | ### Block Information Fields | ||
| − | File size is in bytes. It equals 8192 bytes times the number of blocks given when the file is created.[^ff55] | + | File size is in bytes. It is computed as the number of blocks specified when the file is created times 8192 bytes.[^ff55] |
| − | Next block points to the next block of a file.[^ff55] | + | When a file spans several blocks, Next block holds a pointer to the next block that is 1 less than the block number. Blocks 1 to 15 are therefore stored as 0 to 14, and 0xFFFF is stored when there is no next block. Filename holds the file name, and the string must end with a NULL (0x00).[^ff55] |
| − | The pointer is 1 less than the block number. Blocks 1 to 15 are stored as 0 to 14.[^ff55] | + | McxExecFlag() sets the PDA application flag to 1 for a PDA application, and the flag is cleared otherwise. libcard and libmcrd do not copy this flag. Consequently a PDA application that is copied, rather than downloaded from the PlayStation, has the flag set to 0.[^ff55] |
| − | Next block is 0xFFFF when there is no next block.[^ff55] | + | The checksum in the last byte is the XOR of the first 127 bytes of the sector.[^ff55] |
| − | Filename holds the file name. The string ends with a NULL (0x00).[^ff55] | ||
| − | |||
| − | McxExecFlag() sets the PDA application flag to 1 for a PDA application. Otherwise the flag is clear.[^ff55] | ||
| − | |||
| − | libcard and libmcrd do not copy the PDA application flag. A PDA application copied from the PlayStation has the flag set to 0.[^ff55] | ||
| − | |||
| − | The checksum is the XOR of the first 127 bytes of the sector.[^ff55] | ||
| − | |||
| ### Alternate Sectors | ### Alternate Sectors | ||
| − | An alternate information sector holds a substituted sector number and a checksum.[^ff55] | + | An alternate information sector holds a substituted sector number and a checksum. When a sector is named in an alternate information sector, the alternate sector of the same number is used in its place. For example, if alternate information sector 3 contains 123, a read or write of sector 123 goes to alternate sector 3 instead.[^ff55] |
| − | The alternate sector replaces the sector named in its alternate information sector.[^ff55] | + | The alternate sector holds the data of the sector it replaces. The dummy write sector is used for dummy writes that clear unidentified flags.[^ff55] |
| − | If alternate information sector 3 holds 123, reads and writes of sector 123 go to alternate sector 3.[^ff55] | ||
| − | |||
| − | The dummy write sector takes dummy writes that clear unidentified flags.[^ff55] | ||
| − | |||
| ## FAT Operation | ## FAT Operation | ||
| − | The format operation writes the following values (hex):[^ff55] | + | The format operation sets up each sector as shown in the following table (hex). In each row the sum in byte 127 is the XOR of bytes 0 to 126. Sectors from alternate sector 1 to the dummy write sector need no initial value.[^ff55][^ff56][^ff57] |
| Table: State of formatted FAT | Table: State of formatted FAT | ||
| Line 132: | Line 108: | ||
| | 16..35 | FF | FF | FF | FF | 00 | FF | FF | 00 | sum | | | 16..35 | FF | FF | FF | FF | 00 | FF | FF | 00 | sum | | ||
| − | The sum in byte 127 is the XOR of bytes 0 to 126.[^ff56] | + | The delete operation changes the high-order 4 bits of the first byte of each block information sector of the file from 5 to A. The undelete operation changes them back from A to 5 and thereby restores the file. Both operations leave all other data unchanged except the checksum.[^ff56] |
| − | Sectors from alternate sector 1 to the dummy write sector need no initial value.[^ff57] | ||
| − | |||
| − | Delete changes the high 4 bits of the first byte of each block information sector of the file from 5 to A.[^ff56] | ||
| − | |||
| − | Undelete changes the same bits from A back to 5. Delete and undelete leave all other data unchanged except the checksum.[^ff56] | ||
| − | |||
| ## PDA Processing | ## PDA Processing | ||
| − | A write to the FAT sector of a block that holds a running PDA application is refused with an error.[^ff56] | + | A write to the FAT sector of a block that holds a running PDA application is inhibited, and an error is generated. The library takes this state to mean that the Memory Card has been swapped.[^ff56] |
| − | The library takes this state to mean that the Memory Card was swapped.[^ff56] | + | While the libmcx command "display while transferring file" runs, writes to the alternate information sectors (16 to 35) and the alternate sectors (36 to 55) are disabled. An attempt to write to them generates an error.[^ff56] |
| − | The libmcx command "display while transferring file" disables writes to sectors 16 to 55. A write to them gives an error.[^ff56] | ||
| − | |||
| ## References | ## References | ||