Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve format_mempak repair function #105

Open
bryc opened this issue Jun 15, 2020 · 0 comments
Open

Improve format_mempak repair function #105

bryc opened this issue Jun 15, 2020 · 0 comments

Comments

@bryc
Copy link

bryc commented Jun 15, 2020

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.

  1. 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.
  2. 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):

image

The only bytes that matter are:

  1. checksum and inverted_checksum must be correct.
  2. banks must be set to 0x01 to specify the correct mempak size.
  3. Bit 0 of deviceid must be set
  4. random is intended to be random (libultra uses CP0 Register 9, Timer count for this)
  5. repaired is written with FF 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:

image

And how it fits into page 0 (first 256 bytes of the mempak):

image

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant