PSF files are used in various places on the PSP to store metadata about other files. It contains a list of keys, and the values associated with these keys. This can be information such as parental level, and language.
Numerical data is stored in little endian format, I will use the notation ul32 for "unsigned little endian 32 bit" etc.
The file starts with a header, giving the number of key/value pairs and the offsets for the main parts of the file:
Offset | Contents | Description |
---|---|---|
0..3 | 0 "PSF" | A file type identification cookie. A zero byte is followed by the three uppercase ASCII characters "PSF". |
4..7 | 1 1 0 0 | This might be some kind of indication of the PSF version. Currently it's always two 1 bytes followed by two 0 bytes. |
8..11 | ul32 | Offset from the start of the file to the start of the key table (in bytes) |
12..15 | ul32 | Offset from the start of the file to the start of the value table (in bytes) |
16..19 | ul32 | Number of key/value pairs in the index |
This header is immediately followed by the index table, which has one entry per key/value pair. This table seems to always be sorted alphabetically on the key string, allowing binary search to be used, although it is unknown if this is actually guaranteed. The entries look like this:
Offset | Contents | Description |
---|---|---|
0..1 | ul16 | Offset of the key name into the key table (in bytes) |
2 | 4 | Unknown, always 4. Maybe alignment requirement for the data? |
3 | ul8 | Datatype of the value, see below. |
4..7 | ul32 | Size of value data, in bytes |
8..11 | ul32 | Size of value data plus padding, in bytes |
12..15 | ul32 | Offset of the data value into the value table (in bytes) |
Value data is always aligned to a 4 byte boundary, so if the size of the data is not dividable by four, the data is padded with zero bytes. The two size fields in the index entry gives the size with and without this padding, respectively. It is allowed to add arbitrary amounts of extra padding (as long as alignment is ensured), which makes it easier to modify data in place. Some games seem to take advantage of this to update the text descriptions as the player progresses in the game.
After the index table comes the key table, at the offset (from the beginning of the file) indicated in the file header. Each key is a NUL-terminated ASCII string. The keys are referenced from the index table by offset from tge key table start, so the first key will have offset 0.
The last part of the file is the value table, again at an offset indicated in the file header. Since value data is required to be aligned, zero padding may exist between the key table and the value table. The offset in the file header will indicate the true start of the value table though.
The type of data in the value table depends on the type field of the index entry that references that particular value. The known types are:
Code | Type | Description |
---|---|---|
0 | BIN | Arbitrary binary data, interpretation depending on key |
2 | TXT | UTF-8 text string, NUL-terminated. (The NUL is included in the data size.) |
4 | INT | An sl32 integer |
Before listing the various known keys, the key CATEGORY should be mentioned. This key exists in all PSF files, and indicate the type of entity described by the PSF file. It has TXT data, and the currertly known values are:
CATEGORY | Description |
---|---|
MS | MemoryStick Save, i.e. a savegame |
MG | MemoryStick Game, a game runnable from MemoryStick |
UG | UMD Game, a game runnable from UMD |
Depending on the category, different keys may be relevant. In the following table of observed keys, an * indicates that the key occurs in that category of PSF.
Key | Type | MS | MG | UG | Description |
---|---|---|---|---|---|
BOOTABLE | INT | * | * | Setting this to 1 seems to indicate that the game should be autolaunched at bootup. | |
CATEGORY | TXT | * | * | * | Category of PSF, as per the table above |
DISC_ID | TXT | * | * | Product number of the game(?), e.g. "ABCD-00000" | |
DISC_NUMBER | INT | * | Which disc (out of DISC_TOTAL) is this? (Counts from 1.) | ||
DISC_TOTAL | INT | * | Total number of UMD discs for this game. | ||
DISC_VERSION | TXT | * | * | Version of the game(?), e.g. "1.00" | |
DRIVER_PATH | TXT | * | Unknown. | ||
LANGUAGE | TXT | * | Language of the game. "JP" indicates Japanese, even though this is not the proper ISO 639 code... | ||
PARENTAL_LEVEL | INT | * | * | * | Minimum parental control level needed to access this file (1-11, 1=general audience, 5=12 years, 7=15 years, 9=18 years) |
PSP_SYSTEM_VER | TXT | * | * | Version of PSP system software required to run the game(?), e.g. "1.00" | |
REGION | INT | * | * | Bitmask of allowed regions. 0x8000 is region 2? | |
SAVEDATA_DETAIL | TXT | * | Text shown under the "Details" heading in the save game menu. Can contain multiple lines of text by embedding CR LF. | ||
SAVEDATA_DIRECTORY | TXT | * | The name of the subdirectory to savedata where this game stores its savefiles (e.g. UCJS10001) | ||
SAVEDATA_FILE_LIST | BIN | * | A list of filenames the game uses for the actual save data (typically something like "DATA.BIN"). Data format currently unknown. | ||
SAVEDATA_PARAMS | BIN | * | Additional parameters of unknown function and data format. | ||
SAVEDATA_TITLE | TXT | * | Text shown under the "Saved Data" heading in the save game menu. | ||
TITLE | TXT | * | * | * | Text shown under the "Game" heading in the save game menu. |
TITLE_0 | TXT | * | * | * | Localized version of the TITLE attribute: Japanese |
TITLE_2 | TXT | * | * | * | Localized version of the TITLE attribute: French |
TITLE_3 | TXT | * | * | * | Localized version of the TITLE attribute: Spanish |
TITLE_4 | TXT | * | * | * | Localized version of the TITLE attribute: German |
TITLE_5 | TXT | * | * | * | Localized version of the TITLE attribute: Italian |
TITLE_6 | TXT | * | * | * | Localized version of the TITLE attribute: Dutch |
TITLE_7 | TXT | * | * | * | Localized version of the TITLE attribute: Portuguese |
TITLE_8 | TXT | * | * | * | Localized version of the TITLE attribute: Russian |
UPDATER_VER | TXT | * | Used by the firmware updater program to denote the version it upgrades the firmware to. |