Why does this game genie code work? (The Legend of Zelda)

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

AzimuthFE
Posts: 17
Joined: Thu Jun 09, 2016 4:46 pm

Why does this game genie code work? (The Legend of Zelda)

Post by AzimuthFE »

Hello, everyone.

I have been playing around with game genie codes trying to create my own using an emulator. I looked up some codes online and found one for Legend of Zelda: AVVLAUSZ - Don't take damage from anything. Inserting this code (using FCE-UX's gg bios functionality) works perfectly. Now I'm trying to work out why.

Putting the code into a decoder brings up the result:

Address: $33e0
Value: $60
Compare: $ad

Fair enough, it's replacing a LDA instruction with an RTS. The trouble is, I'm assuming that the rom address is ($8000+$33e0=$b3e0), but when I go to that address during gameplay (without inputting the gg code) the code there doesn't contain any LDA instruction. Does the game really switch out rom banks just for Link taking damage? or am I missing something?

Something else that's confusing me; sometimes when I stop the game to look at code, the game seems to be executing from the $6000-$7fff range. I was under the impression that this range is SRAM. Does the game copy code here for execution and, if so, why?
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by Quietust »

AzimuthFE wrote:Does the game really switch out rom banks just for Link taking damage?
I'm willing to bet that the game is changing banks quite frequently, and you were looking there at the wrong time (e.g. while the Sound code was running).
AzimuthFE wrote:Something else that's confusing me; sometimes when I stop the game to look at code, the game seems to be executing from the $6000-$7fff range. I was under the impression that this range is SRAM. Does the game copy code here for execution and, if so, why?
There's nothing unusual about running code from SRAM - if your cartridge board provides you with 8KB but you only need a small amount for stuff like saved games and persistent level data, it's quite advantageous to use the rest for code storage so you don't have to switch banks as often.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Why does this game genie code work? (The Legend of Zelda

Post by dougeff »

Looking at FCEUX Game Genie Encoder/Decoder...type in AVVLAUSZ, and it says...

Possible Affected Rom File Addresses
0073f0

Hex Editor, view = ROM, 0073f0 = AD 70 06

Debugger, breakpoint on reads from $670 (when hit with an enemy)...it breaks at..

> :7B70:AD 70 06 LDA $0670 = #$FE
:7B73:C5 0E CMP $000E = #$80
:7B75:90 19 BCC $7B90
:7B77:38 SEC
:7B78:E5 0E SBC $000E = #$80
:7B7A:8D 70 06 STA $0670 = #$FE
:7B7D:AD 6F 06 LDA $066F = #$21
:7B80:29 0F AND #$0F
:7B82:C5 0D CMP $000D = #$00
:7B84:90 23 BCC $7BA9
:7B86:AD 6F 06 LDA $066F = #$21
:7B89:38 SEC
:7B8A:E5 0D SBC $000D = #$00
:7B8C:8D 6F 06 STA $066F = #$21
:7B8F:60 RTS

:7B90:A5 0E LDA $000E = #$21
:7B92:38 SEC
:7B93:ED 70 06 SBC $0670 = #$7E
:7B96:85 0E STA $000E = #$21
:7B98:AD 6F 06 LDA $066F = #$21
:7B9B:29 0F AND #$0F
:7B9D:F0 0A BEQ $7BA9
:7B9F:CE 6F 06 DEC $066F = #$21
:7BA2:A9 FF LDA #$FF
:7BA4:8D 70 06 STA $0670 = #$7E
:7BA7:D0 BE BNE $7B67
:7BA9:AD 6F 06 LDA $066F = #$21
:7BAC:29 F0 AND #$F0
:7BAE:8D 6F 06 STA $066F = #$21
:7BB1:20 A3 EB JSR $EBA3
:7BB4:8D 70 06 STA $0670 = #$7E
:7BB7:85 AC STA $00AC = #$00
:7BB9:A9 11 LDA #$11
:7BBB:85 12 STA $0012 = #$05
:7BBD:A9 04 LDA #$04
:7BBF:85 98 STA $0098 = #$02
:7BC1:60 RTS

I don't have any idea what any of this is, but for health, I always look for a DEC, which there is one on 66f.

Let's check out Data Crystal to see what's there...
https://datacrystal.romhacking.net/wiki ... da:RAM_map

066F Heart Containers Low Nibble = how many hearts are filled. High Nybble = Number of heart containers - 1
Ex: $10 = 2 Heart Containers with none filled
0670 Partial heart $00 = empty, $01 to $7F = half full, $80 to $FF = full.

Now it seems a bit more clear.

Also, note, there is a disassembly of Zelda, somewhere on the internets. I always forget where. It's not a one file .txt file, it's a multi-page html.


EDIT -
http://www.bwass.org/romhack/zelda1/
--it's the pages maked 'zelda1bank0.txt' 'zelda1bank1.txt' (etc)

The bit you were looking at is on bank1, at 73E0:
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by thefox »

AzimuthFE wrote:Fair enough, it's replacing a LDA instruction with an RTS. The trouble is, I'm assuming that the rom address is ($8000+$33e0=$b3e0), but when I go to that address during gameplay (without inputting the gg code) the code there doesn't contain any LDA instruction. Does the game really switch out rom banks just for Link taking damage? or am I missing something?

Something else that's confusing me; sometimes when I stop the game to look at code, the game seems to be executing from the $6000-$7fff range. I was under the impression that this range is SRAM. Does the game copy code here for execution and, if so, why?
Try setting a READ breakpoint at $B3E0. You'll find code which copies the routine to $7B70.

I guess the game might be executing from SRAM more than most games because it's an FDS conversion. (FDS has RAM at $6000..$DFFF.)
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Why does this game genie code work? (The Legend of Zelda

Post by dougeff »

By the way, making Game Genie codes is something of a hobby of mine.

I spend a lot of time staring at RAM addresses at the exact moment something happens. First make a save state just prior to that event, and reload it over and over while staring at the RAM.

Once you have a guess which RAM address is involved, put a freeze on that RAM address, see if the event fails to happen. Unfreeze.

Then set breakpoint for writes to that address. Inserting a RTS is standard, or modifying a branch so it skips the code (either change the destination, or change the condition from BEQ to BNE, etc).

I feel a good GameGenie Coee should only use 1 or 2 lines, so at most you can change only 2 bytes, which is a tall order.

Let's say you want to add a LDA #, STA zp. That's 4 bytes. No good. A real Game Genie can only handle 3 codes.

So, ideally, you would have to find, somewhere in code a LDA #,STA zp that already exists and only change the # and the zp address. And, it has to be some extraneous code that doesn't break the game if it's missing.

Very hard. But, it's like a fun puzzle to me.
nesdoug.com -- blog/tutorial on programming for the NES
AzimuthFE
Posts: 17
Joined: Thu Jun 09, 2016 4:46 pm

Re: Why does this game genie code work? (The Legend of Zelda

Post by AzimuthFE »

I think I understand now. My mistake was to assume that the code to change health would be in a rom bank when it was called into action (I didn't know that games commonly execute from SRAM). So when I checked the code during gameplay the correct bank had been switched out a long time ago. This also explains why my own attempts to patch the code failed (I'm guessing that gg codes don't work on SRAM?).
dougeff wrote:By the way, making Game Genie codes is something of a hobby of mine.

I spend a lot of time staring at RAM addresses at the exact moment something happens. First make a save state just prior to that event, and reload it over and over while staring at the RAM.

Once you have a guess which RAM address is involved, put a freeze on that RAM address, see if the event fails to happen. Unfreeze.

Then set breakpoint for writes to that address. Inserting a RTS is standard, or modifying a branch so it skips the code (either change the destination, or change the condition from BEQ to BNE, etc).

I feel a good GameGenie Coee should only use 1 or 2 lines, so at most you can change only 2 bytes, which is a tall order.

Let's say you want to add a LDA #, STA zp. That's 4 bytes. No good. A real Game Genie can only handle 3 codes.

So, ideally, you would have to find, somewhere in code a LDA #,STA zp that already exists and only change the # and the zp address. And, it has to be some extraneous code that doesn't break the game if it's missing.

Very hard. But, it's like a fun puzzle to me.
This is great advice, and I agree that it's fun to try and find codes. I can't imagine how Galoob found these codes at the time, without an emulator, though.

Anyway, thank you everyone for the great advice and swift replies!
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by thefox »

AzimuthFE wrote:(I'm guessing that gg codes don't work on SRAM?).
Yeah, they can only patch at $8000..$FFFF.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by Dwedit »

Zelda copies from ROM to SRAM, so the game genie code that modifies the code still works.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by tepples »

Which makes me wonder why Nintendo never tried making games with a "Genie-proof" memory map like one of these:
  • Three 4K windows at $5000-$5FFF, $6000-$6FFF, and $7000-$7FFF into which ROM or WRAM banks can be switched
  • Bootstrap ROM at $FFC0-$FFFF, WRAM at $6000-$7FFF, and an interface in the mapper to seek and read from a larger SPI ROM
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by rainwarrior »

Why would Nintendo want to stop Game Genie? This device added a lot of value to their system and games.

...and the 3 byte limitation already prevented it from being useful for significant patches/hacking/overlay.

It would be a serious security violation on a modern system, but on an NES it looks like a 100% win for everyone involved to me.
User avatar
toggle switch
Posts: 139
Joined: Fri Sep 30, 2016 8:57 pm

Re: Why does this game genie code work? (The Legend of Zelda

Post by toggle switch »

nintentdo should have embraced game genie, no argument there.

however, didn't they sue the developers of the game genie? pretty sure they did.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by rainwarrior »

Heh, I mean, yes they did apparently want to stop it. I just think that overall the existence of the Game Genie was very good for business.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Why does this game genie code work? (The Legend of Zelda

Post by dougeff »

Wasn't there some games that mapped extra ROM to $6000-7fff? The game genie couldn't affect those portions of the game.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by rainwarrior »

FME-7 could do that. (Not sure if any FME-7 games did use that feature though.)
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Why does this game genie code work? (The Legend of Zelda

Post by Dwedit »

Gimmick! maps ROM to 6000, but that's technically not FME-7.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Post Reply