It didn’t take long after I first became interested in NES homebrew to notice that there were basically no Game Genie codes available for any of the homebrew titles. That just seems wrong to me; why no cheat code love for the homebrewers? So, I’m taking it upon myself to help fill this void and I’m hoping this post will be the first in an occasional series each devoted to a new game.
One of the very first homebrew titles I played was The Incident by KHAN Games and it was actually this game which first made me think about wanting some homebrew cheat codes. Seems like the logical place to start and so without further ado here are some Game Genie codes for The Incident. The remainder of this post will just discuss the codes in detail and explain more about how they were created and how they work.
Standard disclaimer: I provide these codes with the hope they are useful but I make no warranty to their usefulness, fitness for any purpose, or safety. You assume all risk associated with their use including but not limited to liability for any and all damages.
SXNSYXVK
OXXONIEN |
Purchase solutions for free |
| PAVNELAA |
Auto-play from next puzzle to end of floor |
SZOGXTEY
SZNYKPEY |
Purchased solutions still give credit for solving |
XZKUUIEI
OXVTVYES |
Enable sound test |
| EYKYPYAY |
Turn off both LEDs |
| ALKYPYAY |
Turn on both LEDs |
| ELKYPYAY |
Turn on the red LED only |
| SZUVPAAX |
Skip loading saved data |
I don’t currently have functioning vintage hardware so these codes have been created and tested using an emulator and a RetroUSB AVS system. I believe they’d work with an original Game Genies and NES but have no means to test them at present.
Purchase solutions for free
I think this is the most obvious code for The Incident which allows you to “purchase” the solution for the current puzzle without spending any solution points. Solution purchasing is a built-in feature where you are awarded one point for every three puzzles you solve manually that you can spend to see a pre-recorded solution played back without having to solve it yourself. The codes SXNSYXVK and OXXONIEN allow you to do that without actually spending a point.
There’s two codes for this since there’s actually two operations involved with spending the point. The first is to check that you actually have at least one point to spend and so the code OXXONIEN suppresses this check. The number of solution points the player has is stored at $00A5 in RAM and when the player attempts to spend the point the following instructions execute to check that the value isn’t zero. The BEQ instruction jumps around the code immediately after it if the value is zero which is what skips starting the auto-play if you don’t have any points.
9DAA LDA $00A5
9DAD CMP #$00
9DAF BEQ $9DC1
9DB1 LDA #$01
...
9DC1 RTS
The cheat code changes the byte at $9DAF from $F0 for the BEQ instruction to $A9 for the LDA instruction (immediate mode). This prevents the jump regardless of the value so that the code to start the auto-solution playing always executes. The side effect is that the accumulator register gets set to $10 which was the offset being used by the BEQ instruction to jump down to $9DC1. This doesn’t matter since the next instruction is another LDA so the value is immediately valid again.
9DAF LDA #$10
9DB1 LDA #$01
The SXNSYXVK code suppresses the actual subtraction from the number of solution points owned. A single instruction at $D2FF accomplishes this by directly decrementing the RAM address using a DEC instruction:
D2FF DEC $00A5
D302 RTS
The cheat code replaces the $CE byte for the DEC instruction with $AD which also transforms it into a LDA instruction. This stops the decrement but has the side effect of setting the accumulator register to the number of solution points. This is not a problem since the subroutine exits immediately afterward and the caller doesn’t expect any particular value in the accumulator.
D2FF LDA $00A5
D302 RTS
You’ll always want the decrement cheat code since that actually prevents the solution count from being altered. The first code which skips the check is only necessary if the available points count is actually zero since the check it skips is satisfied anyway in any other case. If you suppress the check but not the decrement and have zero points then the 8-bit value wraps around and you end up with 255 points. This also works but is way more than you ever should be able to get and it doesn’t display correctly in the menu. It would also wrap around to again to zero if you happened to earn another point.
Auto-play from next puzzle to end of floor
This one is a little kludgy, I think, but its very important if your goal is to get The Incident to play itself. What this cheat code does is engage the same auto-play mode used by the game when you purchase a solution so that each puzzle just solves itself in continuous succession all the way to the end of the floor. The catch is that it doesn’t engage until you complete the initial or current puzzle so you have to either solve the first one manually or purchase the solution from the menu.
There’s a function located at $FB29 which is called every frame but just quits without doing anything except at the end of a level transition animation. This function does various things but one of those things is to clear the RAM byte stored at $007A which is the flag that indicates that a solution is being auto-played. This flag gets set when you select purchase-solution from the menu and then it stays set all through the auto-solving until this function clears it.
The clearing of this flag is the only thing that prevents the auto-play from continuing on the next level so if this doesn’t happen then the next level starts playing itself automatically as soon as it starts just the same as if you had selected it from the menu. That’s why these two instructions near the end of the function clear the flag after each puzzle is completed:
FB67 LDA #$00
FB69 STA $007A
Together the two instructions clear the accumulator register and then write that cleared value to the flag address in RAM to clear it out as well. The PAVNELAA code changes the value set into accumulator to one instead of zero so that the next instruction always turns the flag on instead of off which is why it causes all the remaining puzzles to solve themselves regardless if the flag was on or off before.
FB67 LDA #$01
If you are using this code then you must want the levels to auto-play so the fact that this unconditionally sets the flag is no big deal. However, this kind of rubs me the wrong way which is why I called it kludgy. The code I wanted to create was one that just left the flag alone so that it stayed turned off if it was off or stayed turned on if it was on. This means you’d actually have to start the auto-playing going by selecting it from the menu before it would auto-play the current and all subsequent puzzles on the floor.
The reason I didn’t make the code work that way is because there’s no way to accomplish that using only a single code and it seemed better to a have a little wonkiness than to require a whole extra code be entered and have an additional code slot be consumed. The reason for this is because the function actually clears the flag in two different places:
FB32 STA $007A
...
FB69 STA $007A
We could neuter the store instructions by changing them to something else so they don’t write the value like we did with the purchase-for-free code to get this effect but since there are two writes we’d have to do it twice which means two codes. I don’t know why the game does this twice but my best guess was just that it was done on accident since clearing it twice doesn’t have any added effect that the first write wouldn’t have already. The double clear is also the reason the PAVNELAA code attacks the second write since if we did the first one then the second one would just clear it and there’d be no net effect. Anyway, if you want the codes to just nullify the two writes they are ILUYXUSE and ILVNOUSE.
Purchased solutions still give credit for solving
These two codes are kind of my favorite since when used in combination with the codes from the previous sections it basically can be used to get the game to play itself all the way through and reach a “perfect game” end state. The same as if you actually played the game all the way through without ever purchasing a solution (assuming you start from freshly erased saved data). This is a god-send for those of us (me!) who are too stupid and/or lazy to accomplish this feat on our own.
At $CE0D there’s a function that awards credit for solving the puzzle that is called after a puzzle is completed and advancing to the next puzzle on the same floor. There’s a similar block of code starting at $F96F which does the same job when it’s the last puzzle on the floor being solved. In both cases the first thing the code does is check the $007A flag discussed earlier which is set if a solution is being auto-played and just skips to the end if it was set so that the player doesn’t get any credit.
CE0D LDA $007A
CE10 CMP #$01
CE12 BEQ $CE3E
...
CE3E RTS
F96F LDA $007A
F972 CMP #$01
F974 BEQ $F998
...
F998 ...
We want both of these blocks to always execute regardless of the state of the flag so that we get credit even if we didn’t actually solve the puzzle manually. Like with the check for zero solution points we can just convert the branch instructions into a load accumulator instruction so that the code always falls through. This has the same side effect of affecting the accumulator value but again it doesn’t matter since subsequent code resets it before the register is used again.
CE12 LDA $002A
F974 LDA $0022
It’s unfortunate we have to do this twice and use two codes but since the game does it in two different places we can’t avoid it; otherwise we wouldn’t get credit for “solving” every stage. I think the reason the game duplicates the logic is because its part of the level-completed animation which is different for the end of floor so it has to happen in this second place in the program also. Alternatively, it might have been possible for the second block to just JSR the first function but that’s just not how it’s coded.
Enable sound test
After completing all 120 puzzles a sound test option appears in the menu on the title screen I guess as a kind of prize for beating the game. The codes XZKUUIEI and OXVTVYES will enable this option without actually completing the game first. The first code causes the menu option text to appear where as the second actually allows it to be selected. If only one of the codes is used then the option can be seen but not used or (more interestingly) can be used but not seen. This requires two codes because the two separate operations each perform the is-the-game-completed check independently on their own.
After finishing the last stage the flag at $00EB is set in RAM. I’m not sure if this value is used just for the sound test or if it also controls something else but this is the variable that gets checked for the sound test option. For the display code, there’s a function at $BD46 which is responsible for actually drawing the menu option text. The first thing it does is check the flag then jumps to the end if its not set.
BD46 LDA $00EB
BD49 CMP #$01
BD4B BNE $BD67
BD4D LDX #$00
...
BD67 RTS
Just as before, we can change the branch instruction into a load and then the code always falls through and paints the text even if the flag isn’t set. The side effect of setting the accumulator register doesn’t matter since the next instruction resets it to something else.
BD4B LDX #$1A
BD4D LDX #$00
For the selection cheat code, there’s a set of instructions starting at $EFE1 which decides whether you can select the sound test option in a long block that executes each time you press select on the title screen. Again, this code just tries to jump down if the flag isn’t set.
EFE1 LDA $00EB
EFE4 CMP #$01
EFE6 BNE $EFF5
EFE8 LDA $004A
...
EFF5 ...
So, we convert the instruction in the same way. There’s no side effect since the next instruction resets the accumulator. Yawn.
EFE6 LDA #$0D
EFE8 LDA $004A
Manipulate the cartridge LEDs
The Incident cartridge uses a GTROM circuit board and mapper. This particular board includes two LED lights, one red and one green, which can be switched on and off by the game at pretty much any time. This was probably intended more as a debugging or diagnostic tool for developers but it could also conceivably be used by a game as some kind of indicator to the player. The Incident chooses to just leave the green LED turned on and the red LED turned off pretty much all the time except for brief periods when saved data is being updated on the cartridge (which is so quick that it’s pretty imperceptible).
Since a single piece of code controls this we can manipulate it to turn either light on or off to suit our preferences (just because we can). The GTROM board contains a single register located at $5000 to control bank switching and the control bits for the LED are combined into this register. The Incident uses a single function located at $F73F to update the register for bank switching and it also contains the logic for controlling the LEDs.
F73F TAX
F740 ORA #$70
F742 STA $5000
F745 RTS
The lower nybble (4 bits) of the GTROM register select the page for bank switching. The left-most (most significant) bit controls the green LED and then the next one to the right controls the red one. The remaining two serve other purposes that aren’t important here. The function expects the caller to set the desired page in the lower nybble of the X register which then gets copied to the accumulator by the TAX instruction. Then it sets 3 of the four upper bits leaving the most significant bit as zero using the ORA instruction. Finally, the combined values are written to the register which actually updates things on the cartridge board.
The $70 value (0111 0000 in binary) is what controls the LEDs. For the two LED bits zero means turned on and one means off. The green bit is left zero and the red bit it turned to one and so that’s why we normally end up with only the green one turned on most of the time. The code EYKYPYAY changes the $70 to $F0 (1111 0000 in binary) so that both bits are set and so both lights are off.
F740 ORA #$F0
The code ALKYPYAY changes it to $30 (0011 0000 in binary) so that both bits are turned off which turns on both lights.
F740 ORA #$30
Finally, the code ELKYPYAY changes the value to $B0 (1011 0000 in binary) so that just the red LED is turned on because only its bit is cleared.
F740 ORA #$B0
Obviously, it only makes sense to use one of these three codes at a time since they all affect the same address in memory.
Skip loading saved data
You might think that this last one is a little odd–and maybe it is. As you know, The Incident saves your progress to the cartridge so you can resume playing from the same previous state even if you powered off the console between sessions. The way it accomplishes this though struck me as a little odd.
The 6502 processor that powers the NES has a special region of memory known as the “zero page” which really just amounts to the first 256 bytes of RAM. Accessing this memory is a little faster than the rest of RAM and it has some other super-powers that make it prime real estate. So, not terribly surprisingly, The Incident keeps pretty much all the vital game data in this space like the current level, solution points, and everything else that gets stored between play sessions.
What I’d generally expect to see from any program is that, when saving important data, the information gets neatly packaged in a dedicated data structure and then written to the storage medium just as a desktop application would store data to a file. The Incident doesn’t do this and instead just writes the entire zero page directly to the flash chip. This does write out all the vital information it wants to save but it also stores lot of other more tenuous state information that inhabits the zero page that really doesn’t need to be saved, is not useful when restored, and it just along for the ride.
From a purely efficiency based perspective this is quite clever since there’s no need for fancy packing and unpacking subroutines–the information is just loaded directly back into the zero page when the game is rebooted. There is a theoretical danger with this approach though since the game is not merely reloading the game but its actually reloading parts of it previous state of execution. Generally, a program likes to start from a cleanly initialized state but this causes it to have information restored that might then need to be handled or just otherwise explicitly discarded. In principle, if the game had a malfunction and stored bad state data then it might prevent itself from running again even after a reboot since it wold just continue to load and run in an invalid state.
In practice, I’ve never actually encountered this so it’s not a real problem at this point as far as I know. More to the point though is that The Incident has a built-in function to erase the saved data but all it does is reset the data points associated with the game progression. It doesn’t actually wipe completely clean the portion of the cartridge storing the data like it is again brand new and this just rubs me the wrong way for no particularly good reason.
So, to bring this all together, the purpose of the SZUVPAAX code is to let you “start fresh” by skipping the load of the zero page data when the game first starts. Since all of RAM is erased at the very start of the boot process (pretty much all games do this) it means we end up starting from a zero-page that is completely zeroed out just like it would have been when the game was run for the first time. This really has no practical effect that’s any different than just using the erase function beyond soothing my paranoid psyche. However, if you did ever end up with a corrupted zero-page that prevented the game from rebooting this code could potentially rescue the cartridge by effectively purging the bad data.
The code itself is pretty simple. Early in the startup sequence at $E039, a call to the function located at $D3DA is made. The purpose of this function is just to copy the saved data from flash memory on the cartridge back into the zero page.
E039 JSR $D3DA
Again, we just change the JSR instruction to load the accumulator register from that address instead of jumping to the subroutine. The side effect of changing the register doesn’t matter since the function itself would have left the register in an undefined state after it returned anyway.
E039 LDA $D3DA
Wrap-up
Thanks for reading this far! I figure if anyone actually looks at this post then most will stop after the codes. I wanted to explain the codes a little bit but I didn’t mean to write this to be as long and it ended up being. If this does become a series of posts then I might just skip the explanations in the future but I hoped you enjoyed them none-the-less; writing Game Genie codes really is kind of a neat process.
You must be logged in to post a comment.