libdragon
libdragon copied to clipboard
Improve format_mempak repair function
libdragon currently overwrites the first 256 bytes of a mempak using Mupen64's template data. Many emulators use unique templates for the initialized data of an emulated .MPK file, and Project64/cen64/mupen64plus borrowed this from the original Mupen64 emulator.
This is bad for a few reasons.
- Changes more data than is necessary to repair any corrupted data. The original contents of the label and ID area are effectively erased on the user's mempak.
- Uses the exact same data each time, which can cause issues with a game's ability to detect when a different mempak has been inserted/replaced.
Also, the concept of 'formatting' a mempak (such as preparing it in the factory) is separate from what N64 software actually do through libultra, which is a simpler 'repair' operation, which includes a permanent indicator in the data that a repair had been done.
I suggest emulating libultra's repair functions to some extent, incorporating a random element to the data.
Here is the general structure of the 32-byte ID block, according to libultra (Using the Mupen64 data as an anti-example):
The only bytes that matter are:
-
checksum
andinverted_checksum
must be correct. -
banks
must be set to0x01
to specify the correct mempak size. - Bit 0 of
deviceid
must be set -
random
is intended to be random (libultra uses CP0 Register 9, Timer count for this) -
repaired
is written withFF FF FF FF
to indicate a repair was performed, but has no function.
Everything else is not checked, used or overwritten in any way. However version
is always 0 in over 300 DexDrive and legitimate dumps I have checked. Here are some examples of libultra repaired data found in real mempaks:
And how it fits into page 0 (first 256 bytes of the mempak):
- Backup priority is 1, 2, 3 until found. When found, backup is overwritten to all other locations.
-
0x81
is written in the first byte of the label area during a repair, but it has no functional purpose.
Also, I did a bit of research into the initial factory state of the mempak contents here: https://rentry.co/mpk_serials. In summary, the first 24 bytes can vary wildly, and differ between manufacturers. Even all zeroes is valid. But games rely on the final checksum to detect if a different mempak is inserted. Unfortunately there are too few samples of official controller pak data to make any conclusions as to how to generate fresh serial data. But the only requirement is that the serial data changes sufficiently during a reformat or repair operation, so that the checksum is different.