📅September 15th, 2026
This is about the game Contra III: The Alien Wars for Super Nintendo.

The game shipped with some weird quirks.
One quirk is that USA version is harder than the Japanese version in a way:
- In the Japanese version, you get the "true" ending when you beat the game on any difficulty.
- In the USA version, you get the "true" ending only when you beat the game on Hard.
For casual play / non-competitive purposes, it'd be nice to get the gameplay of the Japanese version but with the text and localization of the USA version.
To do that, use these cheat codes (e.g., in an emulator):
05FD9DB3
1DB0F280
1DBB3C80
1DBBADEA
1DBBAEEA
For info about where these came from, see below.
First I did a quick Internet search to see if someone already had gotten something like this, and nothing showed up. There were codes and things to get increased ammo, lives, things like that. Maybe anyone who cares about this simply plays the Japanese version.
I opened the game in a debugger. Something must store the difficulty setting, and read off of it in order to load the ending.
The problem is, we don't know how it is stored or where. Values like "difficulty" can be more annoying than ordinary numeric values like e.g., health or experience points, because usually you know what numeric quantity health points are, so you can look them up in system memory. Here, I don't know if Easy=0, Normal=1, Hard=2, or some other system.
As a shot in the dark, I opened a live memory window and cycled through the difficulty ratings in the Options. Very quick and dirty approach. I like to mention this because I'm being honest about what worked but also what didn't work. Anyway, for given values I saw them change in a way that corresponded to the current setting:

So, that's encouraging. But when I exited out of the menu, those values in memory got immediately clobbered. So, scratch that. What must be happening is those values get read and written to the "real" place.
For this situation, I could do a break-on-read for the above highlighted areas and try to follow through what the net effect write is, what write takes an effect for gameplay. The thing is, I don't know how complicated that code path is, it could be super simple or not. We don't know. My reflex is to not pull on that piece of string just yet, unless we need to.
So scratch that, and try a different way.
I start the game, once on Easy, once on Normal and once on Hard.
For each, pause immediately upon entering gameplay and take a memory dump:

This produced 3 dump files, I gave them names:

The reason for pausing immediately is to reduce noise and random other processing the game is doing, that scrambles memory. There will still be noise but at least we can minimize it.
Then I did a diff of the 'easy' and 'normal' dumps in a hex editor (I used HxD) and used the 'hard' one to corroborate.
For example, if Easy=A and Normal=B and Hard=B, then it's not a candidate value, because Normal and Hard should be different. There's some baked-in assumptions about things being done in a non-insane way, obviously you can revisit those assumptions if you ever need to.
The diff is noisy, any RAM diff is going to be noisy, but it produced a bunch of candidate values.
After ruling out the first few candidates, I found this:

That's 0x84 in the dump file which corresponds to 0x7E0084 in RAM.
The diff shows that offset contains 0x00 for Easy difficulty, 0x02 for Normal, and 0x04 for Hard. I did a couple tests and it reproduces. So it seems like we have the right value and location. Success.
Something probably reads that value, and uses it to control the 'ending' logic (again, making assumptions about things being done in non-insane ways).
So the next step is to do a break-on-read on that value in memory when you get to the ending. This is assuming that it does the check fairly late and just-in-time, which ended up being true.

After the brain exploding animation finishes and Jimbo is carried away on the helicopter, the breakpoint hits:

From there if you do a pretty straightforward local disassembly you will find this code. I added some comments.
$1D/B0ED A5 84 LDA $84 [$00:0084] ; Load the difficulty setting
$1D/B0EF C9 04 00 CMP #$0004 ; Is it set to Hard?
$1D/B0F2 F0 0B BEQ $0B [$B0FF] ; If so, go to DifficultyIsHard
DifficultyIsEasyOrNormal:
$1D/B0F4 A9 00 01 LDA #$0100
$1D/B0F7 95 24 STA $24,x [$00:0924]
$1D/B0F9 A9 25 00 LDA #$0025
$1D/B0FC 95 12 STA $12,x [$00:0912] ; Cue up the teaser ending
$1D/B0FE 6B RTL
DifficultyIsHard:
$1D/B0FF F6 12 INC $12,x [$00:0912] ; Cue up the final form of the boss
$1D/B101 6B RTL
To get to the final form of the boss, a pretty simple way then is to change
$1D/B0F2 F0 0B BEQ $0B
to
$1D/B0F2 80 0B BRA $0B
In other words, use the code
1DB0F280
since PAR codes take the form aaaaaavv where aaaaaaaa=24bit hex address, vv = 8bit hex value.
Great, so we can apply that patch and see it unlocks the final form of the boss:

The only problem is once you beat the boss, if you change nothing else, you'll still get the 'bad' ending.


So there must be subsequent reads of the difficulty value, and those get used to trigger the ending logic.
I set another break-on-read and found those. There were a few.
First, here:
$1D/BAF4 A4 84 LDY $84 [$00:0084] ; Load the difficulty setting
$1D/BAF6 BE 9B FD LDX $FD9B,y[$05:FD9D] ; Load a value from some array, indexed at the difficulty setting.
; In this case,
; for Easy = 0x0, we load 0xFDA1
; for Normal = 0x2, we load 0xFDAA
; for Hard = 0x4, we load 0xFDB3
; These are all located at ROM 05:FD9B
$1D/BAF9 22 A8 90 00 JSL $0090A8[$00:90A8] ; Proceed with the arg loaded.
The value that gets loaded from the array determines the control flow of the ending. E.g., the 'Press Start Key' prompt. It seems very coupled to other uses of the difficulty setting. If you simply change the load from the array to always map to the 'hard' one, it gets further along, showing the 'congrats' screen, but not the full ending. So it is necessary but there's a further change needed.
Setting another break-on-read, there's this:
$1D/BB37 A5 84 LDA $84 [$00:0084] ; Load the difficulty setting
$1D/BB39 C9 04 00 CMP #$0004 ; Is it set to 'Hard'?
$1D/BB3C F0 07 BEQ $07 [$BB45]
DifficultyIsEasyOrNormal:
$1D/BB3E A9 29 00 LDA #$0029
$1D/BB41 95 12 STA $12,x [$00:0912] ; Cue up the next part of the ending
$1D/BB43 80 02 BRA $02 [$BB47]
DifficultyIsHard:
$1D/BB45 F6 12 INC $12,x [$00:0912]
General:
$1D/BB47 DA PHX
$1D/BB48 A2 C3 F4 LDX #$F4C3
$1D/BB4B 22 D4 98 00 JSL $0098D4[$00:98D4]
And changing the above BEQ to a BRA like the first change almost fixes it, except the photos during the ending are invisible!

There's one final check for difficulty that determines visibility of the photos (?)
$1D/BBA8 A5 84 LDA $84 [$00:0084] A:BB90 X:0900 Y:01BF P:envmxdizc
$1D/BBAA C9 04 00 CMP #$0004 A:0002 X:0900 Y:01BF P:envmxdizc
$1D/BBAD D0 2A BNE $2A [$BBD9] A:0002 X:0900 Y:01BF P:eNvmxdizc <-- change this to NOP?
DifficultyIsHard:
$1D/BBAF A5 BC LDA $BC [$00:00BC] A:0002 X:0900 Y:01BF P:eNvmxdizc
$1D/BBB1 F0 26 BEQ $26 [$BBD9] A:0001 X:0900 Y:01BF P:envmxdizc
DifficultyIsEasyOrNormal:
$1D/BBD9 6B RTL A:0002 X:0900 Y:01BF P:eNvmxdizc ; No photo
After changing the above BNE-on-hard-difficulty to NOPs, letting it fall through, we are treated to the ending:

This kind of implies some Easter Egg like they were maybe going to have different photo images show up for different difficulty settings. Or maybe there already is something like that, I honestly haven't spent a ton of time with this game. If I did maybe I would play it on Hard.
The full set of codes, which do the skips described above are:
05FD9DB3
1DB0F280
1DBB3C80
1DBBADEA
1DBBAEEA
or, you can play the Japanese version.