Controller Pak/Filesystem

From N64brew Wiki
Jump to navigation Jump to search

Save data management on the Controller Pak is facilitated through a simple proprietary filesystem. Most games that support this Pak have a menu that can be accessed by holding START while turning on the N64. In all official and unofficial Controller Paks, there are 32,768 bytes of SRAM available, which is split into 256-byte sectors referred to as "pages". This allows for a maximum capacity of 128 pages, 5 of which are reserved for the filesystem data, and the remaining 123 for user software. A software can create one or more save files, up to a total of 16 files, referred to as "notes".

Filesystem data format

Overall Structure

Overall structure
Page no. Description
Page 0 ID Sector - critical sanity and identification
Page 1 Index Table - allocation of user data sectors
Page 2 Backup Index Table - exact copy of Index Table
Page 3-4 Note Table - allocation of Note entries
Page 5-127 Note data sectors

Page 0: ID Sector

The ID sector primarily houses basic identifying and system information for the file system and the specific Controller Pak.

ID sector structure (256 bytes)
Offset Size Description
0x00 32 Label area
0x20 32 ID Block (Primary)
0x40 32 unused
0x60 32 ID Block (Backup 1)
0x80 32 ID Block (Backup 2)
0xA0 32 unused
0xC0 32 ID Block (Backup 3)
0xE0 32 unused

The first 32-bytes of the ID Sector is known as the Label. It was never officially used nor were its specifications ever supplied to developers. It is implied to be a sort of text-based label or tag. In practice, only garbage data is ever written here during a repair operation, or as a side-effect from example code being copy-pasted to produce the numbers 0 to 32.

The 32-byte ID block provides system information such as the serial number, device ID, the capacity of the media, and two protective checksums. In total, four identical copies of the ID block are stored in this sector in case one or more become corrupted.

ID Block structure (32 bytes)
Offset Size Description
0x00 24 Serial number
0x18 1 unused (always 0)
0x19 1 Device ID (always 1)
0x1A 1 Bank size (always 1)
0x1B 1 unused (always 0)
0x1C 2 Checksum 1
0x1E 2 Checksum 2

The serial number uniquely identifies the particular controller pak. It can be filled with random bytes or any other value that is unique across all extant controller paks.

The device ID field identifies the type of device. This is always set to 1 indicating a controller pak.

The bank size describes the capacity of the controller pak. This is always set to 1 to indicate 256 kilobits which is the only size ever produced.

The first checksum is a 16-bit big endian word computed by summing the first fourteen 16-bit words in the structure. That is every word in the block that is not either of the checksums.

The second checksum is also a 16-bit word computed by subtracting the first checksum from the value 0xFFF2.

Page 1+2: Index Table

The Index Table is used as the allocation table for the file system utilizing a sector chaining strategy similar to FAT16. The table consists of one full page representing an array of 128 two-byte words, known as I-Nodes, where the index of the word in the array corresponds to the page with the same index number on the controller pak.

Index Table structure (256 bytes)
Offset Size Description
0x00 1 unused (always 0)
0x01 1 Checksum
0x01 8 unused (always 0)
0x0A 246 I-Nodes for pages 5-127

The first 5 I-Nodes are reserved because the first 5 pages on the pak are reserved and never part of any note.

All of the bytes for the five reserved I-Nodes are set to zero except for the lower-byte of the I-Node at index 0 which stores the (8-bit) checksum for the entire table. The checksum is computed by summing all the bytes for all of the 123 remaining I-Nodes (i.e. starting at byte offset 0x0A through the end of the page).

Otherwise, the I-Node contains a value indicating that it is unallocated (not used by a note), a value indicating it is the last in a chain (the last page at the end of a note), or the index of the next page in a multiple page chain. The first page for a note is always stored in the note entry data structure and the entire note can then be found by walking the chain in the index table until the end value is encountered.

I-Node values
Value Description
1 Indicates this is the last node in sequence.
3 Indicates this node is unallocated free space.
5-127 Indicates the next node in the sequence

Two identical copies of the Index Table are stored in case of data corruption. The primary is stored in page 1 and the backup is stored in page 2.

Page 3+4: Note Table

The Note Table is simply a list of 16 Note entries. Each entry consists of 32 bytes and identifies the start page, game code and other data. The positions in the list correspond to the slot numbers displayed in the memory card manager. Unused entries are zeroed out.

Note entry format (32 bytes)
Offset Size Description
0x00 4 Game Code - ASCII, e.g. NSME
0x04 2 Publisher Code - ASCII, e.g. 01
0x06 2 Start page - Index number of the first page of the note
0x08 1 Status - Bit field of flags
0x09 1 Reserved - Unused, contains garbage data?
0x0A 2 "Data sum" - Always zero. Unimplemented checksum?
0x0C 4 File extension - Text using custom encoding
0x10 16 File name - Text using custom encoding

The game code is a short ASCII encoded string that identifies the specific game that created and owns the note. This is the same code as the media format code that appears in the ROM header for each game. These codes are specific not only to the particular game but also to the type of media (e.g. cartridge) and geographic region.

The publisher code are unique codes that were assigned by Nintendo to their licensed partners. The publisher codes and are also typically ASCII characters but do not appear in the ROM header and so are more difficult to catalogue.

The status field contains bit flags. The flag 0x02 should always be set.

The file extension is optional and uses the same custom character encoding used by the file name. Four characters are reserved but the stock controller pak manager used by most games only displays the first character. Some games, such as Ogre Battle 64, which implement their own manager do display the extended characters when present. Unused characters should be padded with NUL.

The file name appears as the primary text string describing the contents of the note in the slot when the note is displayed in the controller pak manager of any game. The note text is encoded using a custom character encoding specific to the controller pak file system that includes punctuation plus basic Latin and Japanese characters. Unused characters should be padded with NUL.

Note name text encoding
_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _A _B _C _D _E _F
1_ 0 1 2 3 4 5 6 7 8 9 A B C D E F
2_ G H I J K L M N O P Q R S T U V
3_ W X Y Z ! " # ' * + , - . / : =
4_ ? @

Additional Documentation

Official N64 Programming Manual