Site copyright © 2006-2022 Jennifer Taylor.
Creating a Settings file For Monkey Ball
February 12th 2022, 8:26 am
The Naomi Settings Patcher I wrote about recently is pretty cool, but it is ultimately useless without settings definition files. I designed the format to be human-readable and easy to create but somebody still has to go about creating the files themselves! When I created the settings definition file for Monkey Ball I took notes so that I could write up a blog post on my methods for figuring out various settings in an EEPROM image. Note that you can see the finished settings definition file for Monkey Ball here: https://github.com/DragonMinded/netboot/blob/trunk/naomi/settings/definitions/BDF0.settings. The tools I refer to across this blog post are available here: https://github.com/DragonMinded/netboot/. With all that that out of the way, lets get started figuring out the settings for Monkey Ball!First, I made sure my BIOS, region and controls were all correct in demul. I also deleted thedummy.sram
and dummy.eeprom
files in the nvram folder just in case. This meant that I would be starting off completely fresh. Next, I loaded up the net boot ROM for Monkey Ball using the "Naomi/Naomi2 Boot" option in demul and waited for the game to finish loading completely. Once it showed the attract screen I completely closed demul (it doesn't seem to write the eeprom files until its closed) and then I took the "dummy.eeprom" file out of the nvram folder and ran it through eeprominfo
to get this output:$ ./eeprominfo dummy.eepromOkay, so the game serial is BDF0 and the length of the game settings is 32 bytes. That's enough to start a settings file. I created a new file using
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00
eeprominfo
named "BDF0.settings" with the following command:$ ./eeprominfo --generate-default-settings-file dummy.eepromThen I opened it up to look at what was generated:
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00
Settings file BDF0.settings created with defaults from EEPROM!
$ vim naomi/settings/definitions/BDF0.settings
The eeprominfo
utility generated a read-only setting for each byte in the EEPROM that it found:Setting00: byte, read-only, default is 00If you compare the bytes, you can see that all it did was make a single-byte setting for each byte in the eeprom and write down the defaults. It also set them all to read-only since I didn't know what any of them did yet. To test that I got the defaults right, I ran the following:
Setting01: byte, read-only, default is 03
Setting02: byte, read-only, default is 00
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00
Setting08: byte, read-only, default is 00
Setting09: byte, read-only, default is 00
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, read-only, default is ff
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00
Setting16: byte, read-only, default is 00
Setting17: byte, read-only, default is 80
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, read-only, default is 00
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00
Setting24: byte, read-only, default is 00
Setting25: byte, read-only, default is ff
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 00
Setting29: byte, read-only, default is 80
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00
./edit_settings mbdefault.eeprom --serial BDF0
Its important to note that the "mbdefault.eeprom" file did not exist when I ran this command, which is why I gave it the "--serial BDF0" argument. I made no changes and exited out, saying yes to write the EEPROM image and then I compared the newly written "mbdefault.eeprom" against "dummy.eeprom". They were exactly the same so I knew that edit_settings
created the file properly.Now it was time to start changing settings and seeing what happened to the EEPROM file. I could try to reverse-engineer the test code for Monkey Ball, but that would take a long time and its not something that very many people can do. I booted up demul again, immediately going into the test menu right when I saw the Naomi splash screen and headed to game test mode. There's three sections that looked like they were persistent: game assignments which is probably stored in the eeprom, joystick calibration which is also probably stored in the eeprom, and bookkeeping which might be stored in the eeprom or sram. I didn't really care about how the bookkeeping was stored, so I made a note to myself to just ignore it. I headed to game assignments first and looked at what was available:
$ ./eeprominfo dummy.eepromAs expected, the second byte changed to 05 and the rest were the same as before. So that's for sure the "Number of Monkeys" setting. I updated "Setting1" to this instead:
Serial: BDF0
Game Settings Hex: 00 05 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00
Number of Monkeys: byte, default is 03, values are 2 to 5
Then I tested that it was right by doing the following:$ ./eeprominfo dummy.eeprom --display-parsed-settingsIt looked good to me, so I tackled the other two settings by doing the exact same thing, narrowing down the byte that each setting used and updating the definitions file accordingly when I figured each one out. Here's what I came up with:
Serial: BDF0
Game Settings Hex: 00 05 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 80 00 00 00 00 00 00 00 ff 00 00 00 80 00 00
Parsed Game Settings:
Number of Monkeys: 5
Game Difficulty: byte, default is 00, 0 - Normal, 1 - HardNow it was on to the calibration screen. I did the same thing on that screen as I did for game assignments: took a screenshot of the defaults then saved them and exited demul. This is what I got when I ran the eeprominfo utility:
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00
Setting08: byte, read-only, default is 00
Setting09: byte, read-only, default is 00
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, read-only, default is ff
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00
Setting16: byte, read-only, default is 00
Setting17: byte, read-only, default is 80
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, read-only, default is 00
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00
Setting24: byte, read-only, default is 00
Setting25: byte, read-only, default is ff
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 00
Setting29: byte, read-only, default is 80
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00
$ ./eeprominfo dummy.eepromAnd here's what the settings looked like before I saved:
Serial: BDF0
Game Settings Hex: 01 05 01 00 00 00 00 00 00 60 00 00 00 a0 00 00 80 7f 00 00 00 60 00 00 00 a0 00 00 80 7f 00 00

60
and a0
values that were displayed on the screen in a few places of the eeprom so I was willing to bet those were the calibration options. At this point I decided to try something a little bit different from the first section to see if I could narrow each setting down faster. I added the settings to the settings definition file "BDF0.settings", set them to four different unique values using edit_settings
and then copied "dummy.eeprom" back into the demul nvram folder. What I was hoping would happen is that the values I set would show up on the screen, allowing me to correlate the settings.Here's how I set the settings file to do this:Game Difficulty: byte, default is 00, 0 - Normal, 1 - HardThen I ran:
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00
Setting08: byte, read-only, default is 00
Setting09: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00
Setting16: byte, read-only, default is 00
Setting17: byte, read-only, default is 80
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00
Setting24: byte, read-only, default is 00
Setting25: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 00
Setting29: byte, read-only, default is 80
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00
./edit_settings dummy.eeprom
And after setting the values I copied the eeprom back to demul and re-started it. When I loaded game settings, nothing was changed though... Hmmmm. Maybe I was missing something? But wait, when I went into joystick calibration, changed nothing and chose the "exit with save" option, it didn't just change the 4 bytes that I messed with. It also messed with several other bytes as well. And when the game wrote defaults way back at the top, it didn't write 60
and a0
for the spots I thought were calibration, it wrote 00
and ff
. I figured those other bytes that changed were related as well. So I changed the definition file to this:Game Difficulty: byte, default is 00, 0 - Normal, 1 - HardStill no dice. The calibration screen only showed the defaults. That's a bummer. At this point I decided to just configure some values on the configuration screen in demul and then print out what the eeprom looked like after calibrating:
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00
Setting08: byte, read-only, default is 00
Setting09: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Setting13: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00
Setting16: byte, read-only, default is 80
Setting17: byte, read-only, default is 7f
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Setting21: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00
Setting24: byte, read-only, default is 00
Setting25: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 80
Setting29: byte, read-only, default is 7f
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00
$ ./eeprominfo dummy.eeprom --displaySo It looked like my guesses were sorta right. I went back in with a fresh EEPROM, ran the calibration one more time and set some unique values for each setting.
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 39 39 00 00 ff fe 00 00 80 7f 00 00 00 60 00 00 ff fe 00 00 80 7f 00 00
Parsed Game Settings:
Game Difficulty: Normal
Number of Monkeys: 3
Ball Velocity Boost: Off
Setting09: 39
Setting13: fe
Setting21: 60
Setting25: fe

$ ./eeprominfo dummy.eeprom --displayIt was then that I realized the 7f values were pretty suspicious. They were the same as our Now H/Now V values on the calibration screen. I bet those were the joystick center values. For some reason, the game was storing the low values twice, the center values twice (with the first value equal to the second value plus 1), and the high values twice (with the first value equal to the second value plus 1). I can work with that.I started with the following settings modifications:
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 26 26 00 00 e6 e5 00 00 80 7f 00 00 59 59 00 00 b9 b8 00 00 80 7f 00 00
Parsed Game Settings:
Game Difficulty: Normal
Number of Monkeys: 3
Ball Velocity Boost: Off
Setting09: 26
Setting13: e5
Setting21: 59
Setting25: b8
Game Difficulty: byte, default is 00, 0 - Normal, 1 - HardPrinting out the eeprom I had gave me this:
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00
Setting08: byte, read-only, default is 00
Left: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
Setting12: byte, read-only, default is 00
Right: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00
Setting16: byte, read-only, default is 80
Horizontal Center (Now H): byte, default is 7f, values are 00 to ff in hex
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
Setting20: byte, read-only, default is 00
Push: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00
Setting24: byte, read-only, default is 00
Pull: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
Setting28: byte, read-only, default is 80
Vertical Center (Now V): byte, default is 7f, values are 00 to ff in hex
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00
$ ./eeprominfo dummy.eeprom --displayOkay, so I knew that these were the right settings but I still had to handle the other bytes. In situations like this, you can do a fancy trick in "BDF0.settings" where you state that a setting default is dependent on another setting's value. Here's what my settings definition looked like after making that change:
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 26 26 00 00 e6 e5 00 00 80 7f 00 00 59 59 00 00 b9 b8 00 00 80 7f 00 00
Parsed Game Settings:
Game Difficulty: Normal
Number of Monkeys: 3
Ball Velocity Boost: Off
Left: 26
Right: e5
Horizontal Center (Now H): 7f
Push: 59
Pull: b8
Vertical Center (Now V): 7f
Game Difficulty: byte, default is 00, 0 - Normal, 1 - HardIn the process of figuring all this out I also realized that the game does not display the current calibration on the screen. It always resets back to
Number of Monkeys: byte, default is 03, values are 2 to 5
Ball Velocity Boost: byte, default is 00, 0 - Off, 1 - On
Setting03: byte, read-only, default is 00
Setting04: byte, read-only, default is 00
Setting05: byte, read-only, default is 00
Setting06: byte, read-only, default is 00
Setting07: byte, read-only, default is 00
LeftUnknown: byte, read-only, default is value of Left
Left: byte, default is 60, values are 00 to ff in hex
Setting10: byte, read-only, default is 00
Setting11: byte, read-only, default is 00
RightUnknown: byte, read-only, default is value of Right + 1
Right: byte, default is a0, values are 00 to ff in hex
Setting14: byte, read-only, default is 00
Setting15: byte, read-only, default is 00
HCenterUnknown: byte, read-only, default is value of Horizontal Center (Now H) + 1
Horizontal Center (Now H): byte, default is 7f, values are 00 to ff in hex
Setting18: byte, read-only, default is 00
Setting19: byte, read-only, default is 00
PushUnknown: byte, read-only, default is value of Push
Push: byte, default is 60, values are 00 to ff in hex
Setting22: byte, read-only, default is 00
Setting23: byte, read-only, default is 00
PullUnknown: byte, read-only, default is value of Pull + 1
Pull: byte, default is a0, values are 00 to ff in hex
Setting26: byte, read-only, default is 00
Setting27: byte, read-only, default is 00
VCenterUnknown: byte, read-only, default is value of Vertical Center (Now V) + 1
Vertical Center (Now V): byte, default is 7f, values are 00 to ff in hex
Setting30: byte, read-only, default is 00
Setting31: byte, read-only, default is 00
60
/a0
for both left/right and push/pull if you exit the calibration and re-enter it. So my strategy of setting values and seeing what happened would never have worked for Monkey Ball. I figured that out by running the calibration, saving and exiting and immediately re-entering the screen at which point the calibration values were back to their defaults again. However, it lead me down the path of figuring out that there were other settings bytes that mattered. Now that I had this all figured out, I tested it by going into demul, setting the values for the calibration to some random values, then making a copy of the eeprom. I edited the copy and changed some of the calibrations, and then looked at the output of eeprominfo:$ ./eeprominfo dummy.eeprom --displayCool, its adjusting those other bytes the way it should! Finally, I set the values back to what they were before using
Serial: BDF0
Game Settings Hex: 00 03 00 00 00 00 00 00 39 39 00 00 ff fe 00 00 80 7f 00 00 00 00 00 00 ff fe 00 00 80 7f 00 00
Parsed Game Settings:
Game Difficulty: Normal
Number of Monkeys: 3
Ball Velocity Boost: Off
Left: 39
Right: fe
Horizontal Center (Now H): 7f
Push: 00
Pull: fe
Vertical Center (Now V): 7f
edit_settings
and then compared it to the copy of the EEPROM file that I made above. Everything matched byte-for-byte which meant the settings definition was adjusting the correct bytes in the correct manner!And that's it! After going through all that, I had a settings editor for Monkey Ball: