I played this game to death as a kid. Let's find out what's inside!
These patches replace the options menu with a left-over debug menu, which is detailed below.
Download the patches:
These are xdelta patches. You can download xdelta here. Apply them like so:
xdelta3 -d -s original.z64 patch.xdelta out.z64
The Model Viewer is a full-fledged viewer of Pokemon models. It has a number of features:
The Screen Viewer is used for showing the various pre-made screens used throughout the game. Examples include the Stadium cup select screen and the many information cards shown in the Classroom. Screens can be viewed in low-rez and high-rez.
There are a few screens related to the Japan-only Mobile stadium that are translated into English in the USA version of the game. I believe these are totally unused.
Note that viewing some screens will freeze the game.
The POKéMON Editor lets you edit the Pokemon on the Game Boy Game Pak attached to Controller 1. Among the editable fields are:
There is a minor bug in this tool. A move will appear in red if the Pokemon cannot normally know that move. However, it flags the Dizzy Punch on my Elekid in red. However, Elekid CAN legitimately learn Dizzy Punch if it is hatched from the Odd Egg.
I think this is supposed to be the Backup Editor. It lets you toggle all the unlockables in the game, such as whether a certain cup has been beaten, or if the GB emulator speed boosts were won.
The "Mobile Stadium Appears" toggle is a left-over from the Japanese version of the game: in the Japanese version, the Mobile Stadium option will unlock once a Pokemon Crystal cartridge is inserted that has interacted with a GB Mobile Adapter. In the international versions, there is no way to make the Mobile Stadium menu option appear, and toggling this setting has no effect (although the setting is saved).
Pokemon icons are used as UI elements in many parts of Pokemon Stadium 2. This fragment lets you modify them.
Icons are stored in the ROM in two ways: first, as a set of coordinates used to position a Pokemon model inside a frame, and second, as a pre-rendered image. This tool lets you both change the coordinates, and re-render the images.
A simple music player.
Lets you view all of the Trainer head shots in both low-rez and high-rez.
This is one of only two debug fragments that was not translated into English. I have shown a screenshot of both the USA and Japanese versions for comparison.
The AI Editor can tweak the many AI opponent profiles used in the game. For example, a profile can be made to not exploit a Pokemon type advantage, or to want to use items more often.
The GB SRAM Editor is a hex editor that operates on the SRAM of the Game Boy game pak attached to Controller 1. It works just like any common hex editor, with one difference: the text on the right side uses the peculiar character set of the Game Boy Pokemon games, rather than ASCII.
This screen looks like it should toggle the various unlockables in the game, but none of the options have any noticeable effect.
Some text in the bottom left was not translated from Japanese: the top line should read 'Model', and the bottom line should read 'Animation'.
This is similar to the 'PokeMon Editor' above, except that it lets you change the Pokemon contained in registered sets that are stored on the Pokemon Stadium 2 cartridge.
I'm not too sure about this one. It seems to create some sort of battle record and save it to the GB game pak in Controller 1. In my testing, it only worked if that game pak was Pokemon Crystal. More research is needed!
This tool lets you view any battle or trainer message in the game. It can also cycle through all battle or trainer messages. Unknown what "checks" it performs on the messages.
The Clock Editor lets you set the clock of the Pokemon Gold, Silver, or Crystal game connected to Controller 1. These games have a real-time clock. Normally, the clock can be set only once when the game is first started, and never changed again, to prevent the player from time travelling. The Clock Editor bypasses this limitation to let you directly set the clock.
The "Break the clock" option will set the clock state to something invalid. If the Game Boy game is started while the clock is broken, it will detect this case and allow the player to reset the clock.
The Item Editor is not a full-fledged editor. Instead, it fills the Color and Metal Cases (item storage areas) with items.
Pokemon Stadium 2 is a 64 MB ROM image. As typical for N64 games, there's no filesystem and no obvious structure on the inside. We know that the initial program is going to start roughly at the beginning of the ROM, and be at most one megabyte in size; any more than that, and an intermediate bootloader would be necessary.
On bootup, the N64 will copy the first megabyte of ROM (after the header) into RAM and execute it. So, we at least know where the entry point is. We'll have to dig into it with IDA later. But first, let's look for any clues to the ROM structure.
In a typical (sane) computer system, you'll have some sort of filesystem that lets you find individual chunks of data. You might find a directory called "graphics", and if you're not interested in graphical stuff, we can skip looking through all the files in that directory. On N64 we're not so lucky: most games have no filesystem (although there are a small number of exceptions). Instead, during the build process of an N64 game, the raw address of all assets in the game are available at link time. Game code always knows where a needed asset is in ROM without looking up its location in a filesystem.
We need to find structure. Let's get digging.
Binwalk is a great tool for looking at firmware images, but when it comes to video games, it's basically useless. Let's try it anyway.
$ binwalk np3e0.z64 DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 663884 0xA214C Gameboy ROM,,[SGB], [ROM+MBC1+RAM+BATT], ROM: 256Kbit 2906713 0x2C5A59 Certificate in DER format (x509 v3), header length: 4, sequence length: 19587 19554941 0x12A627D StuffIt Deluxe Segment (data): fgpD3# 22647968 0x15994A0 Gameboy ROM,, [ROM ONLY], ROM: 256Kbit 22648304 0x15995F0 Gameboy ROM,, [ROM ONLY], ROM: 256Kbit 22649118 0x159991E MySQL MISAM index file Version 7 22738337 0x15AF5A1 MySQL MISAM index file Version 11 22739735 0x15AFB17 MySQL MISAM index file Version 9 22742911 0x15B077F MySQL MISAM index file Version 7 26992350 0x19BDEDE Certificate in DER format (x509 v3), header length: 4, sequence length: 9968 30877890 0x1D728C2 TROC filesystem, 1398099785 file entries 31021156 0x1D95864 LANCOM OEM file 31315505 0x1DDD631 Neighborly text, "neighborhood.>Ha, ha... Here's #26!" 31340945 0x1DE3991 Neighborly text, "neighborhood.>Ha, ha... Here's #26!" 31503361 0x1E0B401 Neighborly text, "neighborhood.>Ha, ha... Here's #26!" 31528721 0x1E11711 Neighborly text, "neighborhood.>Ha, ha... Here's #26!" 37472899 0x23BCA83 MySQL MISAM compressed data file Version 3 37482738 0x23BF0F2 MySQL MISAM compressed data file Version 3 37483991 0x23BF5D7 MySQL MISAM compressed data file Version 3 37490213 0x23C0E25 MySQL MISAM compressed data file Version 3 37502327 0x23C3D77 MySQL MISAM compressed data file Version 3 37502508 0x23C3E2C MySQL MISAM index file Version 1 37597623 0x23DB1B7 MySQL MISAM compressed data file Version 3 38399368 0x249ED88 MySQL MISAM compressed data file Version 7 38483462 0x24B3606 MySQL MISAM index file Version 1 38658728 0x24DE2A8 Unix path: /01/CGB-BXTJ/exchange/index.txt 38737416 0x24F1608 MySQL MISAM index file Version 3 39120016 0x254EC90 MySQL ISAM index file Version 5 46057099 0x2BEC68B Unix path: /E/5/0o5/5/e/ 47451318 0x2D40CB6 MySQL ISAM compressed data file Version 11
This is overall pretty hopeless. Let's go over the results:
/01/CGB-BXTJ/exchange/index.txtis certainly interesting! "CGB-BXTJ" is probably a reference to the Japanese version of Pokemon Crystal, which has a product code of BXTJ. Unfortunately, there's not much more to see around here.
Binwalk was a waste of time, as expected. Moving on...
The 'strings' program will walk a file and find any printable strings over a certain length. If we're lucky, we'll be able to find some landmarks in our ROM. The full output of 'strings' is enormous, but I'll point out some useful bits that I found.
We start off with the game name and product code, which are part of the ROM header:
$ strings -tx np3e0.z64 20 POKEMON STADIUM 2 3b NP3E [...]
There's some text for displaying the contents of registers. This same text is found in many of Nintendo's N64 games, and is typically used when the game crashes:
[...] a2744 THREAD:%d (%s) a2754 PC:%08XH SR:%08XH VA:%08XH a2774 AT:%08XH V0:%08XH V1:%08XH a2794 A0:%08XH A1:%08XH A2:%08XH a27b4 A3:%08XH T0:%08XH T1:%08XH a27d4 T2:%08XH T3:%08XH T4:%08XH a27f4 T5:%08XH T6:%08XH T7:%08XH a2814 S0:%08XH S1:%08XH S2:%08XH a2834 S3:%08XH S4:%08XH S5:%08XH a2854 S6:%08XH S7:%08XH T8:%08XH a2874 T9:%08XH GP:%08XH SP:%08XH a2894 S8:%08XH RA:%08XH [...]
The first few letters of all the Game Boy games that Pokemon Stadium 2 can interact with:
[...] a55b0 POKEMON R a55bc POKEMON G a55c8 POKEMON B a55d4 POKEMON Y a55e0 POKEMON_G a55ec POKEMON_S a55f8 PM_CRYSTA [...]
Finally, something interesting! There's an RSP microcode string, found in all N64 games, immediately followed by the word "FRAGMENT":
[...] a8738 RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto/Kawasedo 1999. a89cc 00@@ a8a6d vjnjn a8a88 FRAGMENT [...]
A search through the strings output shows many more instances of "FRAGMENT":
$ strings -tx np3e0.z64 | grep FRAGMENT | head a8a88 FRAGMENT ad268 FRAGMENT adca8 FRAGMENT ae5e8 FRAGMENT b4d98 FRAGMENT b5da8 FRAGMENT ba238 FRAGMENT cc6b8 FRAGMENT d0488 FRAGMENT d4c38 FRAGMENT [...]
In total, strings
found 762 instances of "FRAGMENT" in the ROM.
Most of them are found at addresses that end with -8, such as the first match,
a8a88
. Looks interesting! Let's take a closer look.
Here's what a fragment look like:
000a8a80: 08d4 0e46 0000 0000 4652 4147 4d45 4e54 ...F....FRAGMENT 000a8a90: 0000 0020 0000 3e80 0000 47e0 0000 40f0 ... ..>...G...@. 000a8aa0: 27bd ffd0 afbf 0014 afa5 0034 1480 0008 '..........4.... 000a8ab0: 0080 3025 2404 0136 0000 2825 0c01 3264 ..0%$..6..(%..2d 000a8ac0: afa6 0030 3c01 8350 ac22 40dc 8fa6 0030 ...0<..P."@....0 000a8ad0: 2401 0005 14c1 002f 3c05 800d 24a5 0510 $....../<...$... 000a8ae0: 8ca3 0000 3c0f e700 3c19 fa00 246e 0008 ....<...<...$n.. 000a8af0: acae 0000 ac6f 0000 ac60 0004 8ca3 0000 .....o...`...... 000a8b00: 2409 0080 3c0b fcff 2478 0008 acb8 0000 $...<...$x...... 000a8b10: ac79 0000 ac69 0004 8ca3 0000 3c0c fffc .y...i......<... [...]
I came to the conclusion that these fragments are code modules. Each fragment carries a main function and relocation information. Fragments are structured like so:
struct fragment_s { uint32_t ep1, ep2; // MIPS instructions to jump to the main function, // typically something like "j 0x8xx00020; nop" uint32_t magic1; // "FRAG" uint32_t magic2; // "MENT" uint32_t entrypoint; // typically 0x20 uint32_t relocations_offset; uint32_t size_in_rom; uint32_t size_in_ram; char data[]; };
Using the above struct, we can decode the fragment header:
.org 0x83500000 /* ep1 */ j 0x83500020 /* ep2 */ nop /* magic1 */ .word "FRAG" /* magic2 */ .word "MENT" /* entrypoint */ .word 0x20 // offset from start of fragment /* relocations */ .word 0x3e80 // ^^^ /* size_in_rom */ .word 0x47e0 // ^^^ /* size_in_ram */ .word 0x40f0 // ^^^ .org 0x83500020 /* data[] */ addiu $sp, -0x30 sw $ra, 0x30+var_1C($sp) sw $a1, 0x30+arg_4($sp) bnez $a0, loc_83500050 [...code continues...]
The entrypoint in this example is 0x83500000
. This address is
not used in the N64 memory map. It turns out that each fragment is pre-linked
to a bogus base address like this one. When a fragment is loaded, all address
references are change to point to its new location in RAM.
There's another interesting thing about this entrypoint. Each code fragment is given a unique fragment number. This number is used to derive the base address. The formula is:
fragment_number = ((base_address & 0x0ff00000) >> 20) - 0x10;
base_address = 0x80000000 | ((fragment_number + 0x10) << 20);
So for example, if the base address is 0x83500000
, then it's
fragment number 0x25
, or 37
.
I think there's a lot more to find in this game. I'll update this page as I find things!