Zelda 64 Filesystem

From z64 wiki
Jump to: navigation, search

See also: Zelda 64 Filesystem/Hacks.
Ocarina of Time, Majora's Mask, and all of their seperate versions & ports use an identical filesystem. The filesystem helps the game differentiate between compressed and decompressed data, and keep the files in order. It also allows for quick editing should something be misplaced. The filesystem (rather the file offset table part) begins right after the ROM creator and build date. If you would like to see for yourself, you can find the filesystem at the following offsets:

Debug ROM:  OoT 1.0 (U):  MM (U):     MM (J):
0x00012F40  0x00007400    0x0001A4D0  0x0001C0E0

If you, for some reason, have a different version, just search for "zelda@", and with any luck, you'll find it! An interesting note: the filename table refers to the file offset table as "dmadata". The file offset table also refers to itself, which is quite extraordinary.

File Offset Table

The file offset table begins exactly 0x30 bytes (48 bytes in decimal) from the creator/build date. The first entry of the file table is always (I have yet to find an exception) the locations 0x00000000 - 0x00001060, which is referred to as "makerom" in the filename table. This is not related to this article, but that file it the header for the N64 ROM. It contains region info, cart title, country, and boot code. The next few entries should be constant as well, but it could vary, for all I know.

One entry for a file is 16 bytes (or 0x10 bytes; one line in a hex editor). You can split this up into 2 parts to find out the two offset pairs, and then you can split those two pairs in half to find the start/end offset for said pair. Here is a tiny diagram:

 Virtual Mapping   Physical Mapping
00000000 00000000   00000000 00000000

When working with a compressed ROM, the "virtual mapping" will contain the decompressed offset to the file. IE, if all of the ROM's resources were decompressed and stuck together, that's where it would be. The "physical mapping" in these files will then either point to an uncompressed file or a Yaz0 block (basically a file compressed with the Yaz0 algorithm). To determine if a file hasn't been compressed, you can simply check if the second offset in the "physical mapping" is 00000000. Otherwise, it is compressed. For example:


Offset 0x0001C1C0 in the debug ROM
 Virtual Mapping     Physical Mapping
00A3A000 00A3EB80   009BA6B0 009BBA50
00A3F000 00A42300   009BBA50 009BD150
00A43000 00A4A780   009BD150 009C0310


Offset 0x0001C1F0 in MM Jap
 Virtual Mapping     Physical Mapping
00A4B000 00A4C310   009C0310 00000000
00A4C310 00A55660   009C1620 00000000
00A55660 00A68270   009CA970 00000000

As you can see in the decompressed data example, these three files are decompressed and mapped to a certain location, with their last pointer being set to 00000000. Since the file size of the file in the ROM is identical to the mapped one, the last pointer can be set to 00000000 without losing data. In short: the game calculates the size of the block via the virtual mapping (when dealing with decompressed data). In the compressed data example, however, the physical mapping points to a Yaz0 block in the ROM, which is then decompressed and mapped to the location in the first offset pair.

Filename Table

Since the debug ROM is in fact a debugger's ROM, the developers were nice enough to leave all of the filenames for OoT's resources intact. They can be found in the main code block or at offset 0xBE80. The filenames are separated by 1-4 null (0x00) bytes (for four-byte alignment), and they match up perfectly with the data referenced by the file offset table. The debug ROM is the only Zelda 64 game to have a complete file listing. Majora's Mask has one too (following a similar format), but it only lists the names of the scene files, and some of the scenes it refers to are removed.