Ocarina of Time - Debug Code
Video Gamer X of The Oddesy of Hyrule is attributed with releasing the Debug code for OoT, back in May of 1999. An improved input sequence was discovered by mzxrules in September of 2016.
- Using the Crooked Cartridge trick, or another method (see Miscellaneous Glitches), crash the game.
- Wait a few seconds and a small yellow bar should appear in the top left corner of the screen (if it doesn't, try again, or crash the game using a different glitch).
- Now input the Debug code:
- L + R, then while holding both press Z
- D-pad Up
- D-pad DOWN
- D-pad LEFT
- D-pad RIGHT
- A + B, then while holding both press Start
The debug screen will not appear unless you press each button in the correct order. E.g.: In the first step you must press and hold 'L' then while still holding 'L' press and hold 'R' then while still holding both of them press 'Z', now let go of the buttons and do step two.
The debug code does not work on the Gamecube releases (Ocarina of Time and Master Quest) or the 3DS version. With the Gamecube versions, the N64 emulator used does not emulate the frame buffer accurately, thus the error bar and any messages won't appear on screen. Additionally, there appears to be some sort of fatal bug with the crash debugger itself, which causes all crashes to become undebuggable red bar crashes.
Debug Code Information
And now an explanation of the debug screens by dvdmth.
The Register Information Screen
Both OoT and MM use the same first screen. This is the most important one, as it provides the most basic information concerning the status of the system at the time of the crash. Most (if not all) of the information shown comes from a register, either on the System Control Processor (top), the main CPU, or the Floating-Point Unit (bottom).
At the upper-left corner is the ID of the faulting thread. Often, different pieces of code will "take turns" using the CPU. Whichever piece of code, called a "thread", was being executed at the time of the crash is displayed. This number is usually 4 (which seems to indicate an unidentified thread). I'm not sure where this number is stored, be it in a register or somewhere else.
The top of the screen also shows the type of exception that crashed. Each exception has an associated number, between 0 and 31, that is used to identify what is going on. Note that not all exceptions result in a crash -- in fact, exceptions are a regular part of the life of the system. Those exceptions that actually cause a crash are known as "fatal exceptions" (for obvious reasons). It isn't until an exception becomes fatal that the debugger actually is invoked. (Sometimes an exception can crash one process while leaving others untouched, while other times an exception can bring everything to a halt. This is why sometimes you can still hear music after a crash, and other times you can't.)
Next, the debugger shows the values of three registers from the System Control Processor (a coprocessor that keeps track of system status and performs some basic system tasks). There are actually 32 registers (at least) on this processor, but only three are important.
- Exception Program Counter (EPC) - This is a pointer to the instruction that caused the crash. (Technically, the EPC holds whatever the Program Counter (PC) was set to at the time of the crash. The PC always points to the instruction currently being executed.)
- Status Register (SR) - This holds the status of the system, including what coprocessors are available and whether it's running in 32-bit or 64-bit mode (for example).
- Bad Virtual Address (VA) - This holds the memory address that the program tried to access and failed (assuming the crash is due to a memory error). On the N64, possible values range from $80000000-807FFFFF (with the Expansion Pak). Anything outside of this range is bad.
Beneath those three registers, the debugger displays 30 out of the 35 registers on the main CPU. Some registers, such as the Stack Pointer (SP), are used by the operating system. Others, however, are open for the program to use however it sees fit. The idea is to put the most often referenced data on a register, since registers are accessible at really high speeds (compared to RAM).
The only two registers I can identify in this group are the Stack Pointer (SP), which holds a pointer to the stack (a section of memory that holds temporary data, like local function variables), and the "LO" register (which is used in multiplication and division operations).
Finally, the Floating-Point Unit (FPU) has its share of registers. The first register shown is the Floating-Point Control/Status Register (FPCSR), which keeps track of the status of the FPU, as well as providing any errors that occur during calculations. (The most recent error is displayed to the right of the value, if applicable. Note that this error is ONLY important if a Floating-Point Exception occurred.)
The remaining values show the various floating-point numbers being stored currently on the FPU. Floating-point numbers are numbers that have a fractional part (i.e. they have a decimal point). They are generally shown in scientific notation (instead of the usual hexadecimal), unless the value happens to be an integer. Only half of the registers are shown, since these are the only ones that actually hold data (for technical reasons). It is up to the program how to use these registers.
OoT Debug Screens
Zelda OoT's debugger has 10 additional screens beyond the standard screen listed above. Most of them, however, aren't very helpful. To advance these screens you can press A, B Start, or any of the C buttons.
Segment Information - I really don't know what this screen's about. It may have to do with the ROM itself, or it may have to do with how pieces of code are divided (or something).
ROM Debug - This screen is not exciting in the final versions of OoT, since all values are set to zero. During testing, however, the developers may have set these values to reflect the contents of certain variables during gameplay. This way, if the program crashed, they may be able to figure out what went wrong from these variable settings.
Stack Dump - (NOTE: I'm careful not to use the term "trace," as the debug screen uses, since it's more of a dump than a trace.) This screen shows the contents of the Stack, a section of memory used to hold temporary data. The left column shows the address in memory, and the other columns show what's actually there. (Those who've used a hex editor know how this is like.) The farther down you go, the older the information (since the Stack Pointer is reduced as new items are added and increased as items are taken off).
PC Dump - This screen shows the code being executed at the time of the crash. Somewhere on the screen is the instruction that failed (pointed to by the Exception Program Counter). This screen is displayed the same way as the previous one.
Actor List - This appears to be a list of the "actors" currently in memory. What exactly counts as an "actor" will vary from game to game. Occasionally a PC value appears next to an entry on the list (most likely referring to the piece of code that runs that actor, or perhaps the piece of code that installed it).
Version Info - Finally, the most famous screen from OOT's debugger. The "I LOVE YOU" message is on here, as well as a bunch of zeroes. The date of compilation is also on this screen, helpful in determining the version of the ROM you have. As far as I know, the possible dates are:
- 98-10-21 04:56:31 = North America (NTSC) 1.0
- 98-10-21 04:56:31 = Japan (NTSC) 1.0
- 98-10-26 10:58:45 = North America (NTSC) 1.1
- 98-10-26 10:58:45 = Japan (NTSC) 1.1
- 98-11-10 14:34:22 = International (PAL) 1.2
- 98-11-12 18:17:03 = North America (NTSC) 1.2
- 98-11-18 17:36:49 = International (PAL) 1.2