Announcement

Collapse
No announcement yet.

I've started making GG codes for the SNES!

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • I've started making GG codes for the SNES!

    I've made some Game Genie codes starting from PAR codes:

    Code:
    Spriggan Powered (J)
    Infinite lives
    3CB6-34D9
    3CB6-3409
    3CB6-3469
    
    BS F-Zero Grand Prix 2 (J) (BS) [h1C]
    Inifinite continues
    3C64-0DA4
    3C64-0FD4
    
    Kendo Rage (U)
    Infinite HP
    3C3C-D1EE
    3C3C-D57E
    
    Infinite Lives
    3CBF-055A
    3CBF-058A
    3CBF-05EA
    The procedure i've used is this:
    1. load the target rom in snes9x debugger
    2. start the game, then set a write breakpoint at the PAR RAM address
    3. play the game until that address is written (eg. lose a life)
    4. the debug console will show a single new record:
    Code:
    $AA/AAAA:II O1 O2    DEC $ABBE  [$7F:ABBE]   A:0090 X:0026 Y:0002 P:envmxdizc
    "AAAAAA" is the ROM address containing the code
    "II" is the instruction code (eg. "CE" means decrement)
    "O1" is the operator 1 (may not be present)
    "O2" is the operator 2 (may not be present)
    5. now encode the new GG code with ucon64:
    Code:
    ucon64 --snes --gge=AAAAAA:EA
    if there was "O1" add another code:
    Code:
    ucon64 --snes --gge=AAAAAA+1:EA
    if there was "O2" add another code:
    Code:
    ucon64 --snes --gge=AAAAAA+2:EA
    6. test the new codes with another accurate emulator like bsnes and see if they works.

    This is dead simple and works in most simple cases (eg. infinite lives/health etc.).
    I think anyone can make GG codes this way!

    Now i have some questions:
    • according to this guide using AD is probably a better choice than EA (for replacing CE) But i don't understand why, "AD" means "Load Accumulator from Memory" - shouldn't have side-effects?
    • according to this guide "if it's going to take more than 2 codes, you can use a 'Branch Always' instruction". But it does not provide an example.

    For instance, in the above case i would do:
    Code:
    ucon64 --snes --gge=AAAAAA:80
    ucon64 --snes --gge=AAAAAA+1:02
    (O2 will be skipped)

    Branching this way should also be faster because it takes 3 cycles vs 3*NOPs will need 3*2=6 cycles.
    Last edited by eadmaster; 04-25-2015, 11:05:19 AM.
    Codes and requests made by me

  • #2
    I'm certain that you can shorten some, if not all of those codes. After looking at the first code for inf lives (Spriggan Powered), I'm pretty sure that can be shortened to a single code. What were the original values at the 3 addresses?...

    819788
    819789
    81978A

    If the first address was a DEC instruction (CE), then your Game Genie code would be C2B6-34D9 for inf lives.

    EDIT: I don't have the ROM, so no idea if the code will work or not.

    EDIT2: Almost forgot to mention... congrats on making SNES Game Genie codes. I still remember when I first started making them.
    Last edited by Tony H; 04-25-2015, 01:44:17 PM.
    The Code Hut: http://codehut.gshi.org/

    Comment


    • #3
      Yes, there was a DEC instruction there.
      According to ucon64 "C2B6-34D9" decodes to "019788:AD".
      So, if i get it right, you are writing an "AD" instruction at the address "019788", using the next 2 bytes as arguments.
      According to this reference it means "Load Accumulator from Memory" + the next 2 bytes contains the absolute address.
      Now my doubt is that the original game code may have stored some value in the accumulator and it is not expecting to be altered at that point...

      Also, i am thinking that writing instructions that alter the previous number of cycles could break some timing in the game.
      For instance, if i replace an instruction that was using 3 cycles with another using 6 i could slow down the game a bit... Obviously it depends on how often the instruction is executed, but even a small change could accumulate over time and become significant.
      So, could it be a good idea to match the number of cycles the replaced instruction was using in order to avoid altering the game timing?
      Last edited by eadmaster; 04-25-2015, 05:47:44 PM.
      Codes and requests made by me

      Comment


      • #4
        I haven't done SNES codes in ages, so I don't remember the details. If your original DEC instruction was "CE", then I believe "AD" will work as a replacement. Test it and see if it works.

        Maybe someone here that's more familiar with SNES can give some input.
        The Code Hut: http://codehut.gshi.org/

        Comment


        • #5
          I guess a possible explanation is that the original "DEC" instruction is using the accumulator to perform the decrement, so the following code IS expecting the accumulator to be altered.
          On the other side "AE" (NOP) could have side-effects, because the accumulator is left unchanged.

          EDIT:
          I've hacked a few more codes and i've come across the "STA" instruction (85 an 91 hex values).
          Sometimes it can be replaced with NOPs, sometimes it makes the game crash.
          For instance with Super Back to the Future Part II (J), i've set a breakpoint at "7E009A" and i've got this in the logger:
          Code:
          $01/972B 85 9A       STA $9A    [$00:009A]   A:9702 X:0001 Y:0000 P:eNvMxdizc
          NOPing the addresses 01972B,C,an D does not work, what should i do then?

          These are the new codes i've made:
          Kendo Rage (U) [!]
          Code:
          Infinite Lives (better than the previous)
          C2BF-055A
          Nankoku Shounen Papuwa-kun (J) [T+Eng1.00_FH]
          Code:
          Infinite Lives
          C26C-170D
          
          Infinite Energy
          C36C-3DD9
          C36C-3D09
          C36C-3D69
          
          Infinite Special
          C26C-4DD1
          Brain Lord (U) [!].smc
          Code:
          Infinite HP
          C38C-7F07
          C38C-7F67
          C38C-7FA7

          Side question:
          could you enable me posting new codes in the site database?
          Now i should be able to fill some of my own requests...
          Last edited by eadmaster; 04-26-2015, 07:56:38 AM.
          Codes and requests made by me

          Comment


          • #6
            For your Back to the Future part II code, try this: C9B4-A4A9

            I don't have the ability to add you to the hacker's list, so you'll need to ask an adm.

            But before you add any of your codes to the site, you should go thru ALL of them very carefully. I noticed that your codes for Brain Lord (inf HP) are probably incorrect. You have 3 consecutive addresses all with a new value of "AE"...

            C0BCA5:AE
            C0BCA6:AE
            C0BCA7:AE

            First off, I assume you want all 3 to have a NOP instruction? If so, the correct value for NOP is EA, not AE. Secondly, any time you have 3 consecutive addresses, you can usually shorten the number of codes to 1 or 2.

            EDIT: I only checked the Brain Lord codes, so not sure about the rest.
            Last edited by Tony H; 04-26-2015, 08:50:55 AM.
            The Code Hut: http://codehut.gshi.org/

            Comment


            • #7
              oh your are right about the NOP code, i've just swapped the letters by mistake!
              I am going to fix the codes soon, thank you for pointing that out.

              Originally posted by Tony Hedstrom View Post
              Secondly, any time you have 3 consecutive addresses, you can usually shorten the number of codes to 1 or 2.
              Can you make me an example?

              Also i think i've found the correct way to replace those STA codes. Basically you use the corresponding load instruction (so, instead of writing to memory you read the previous value back).
              I've made this quick replacement table:
              Code:
              CE -> AD
              C6 -> A5
              91 -> B1
              8D -> AD
              9D -> BD
              85 -> A5
              The only problem i see with these is that the load instructions will alter some flags (n,z), so they could possibly have some unwanted side effects.

              EDIT: fixed and new codes made using this method:
              Super Back to the Future Part II (J)
              Code:
              Infinite Life
              C9B4-A4A9
              
              Infinite Lives
              C9B4-D4D1
              Brain Lord (U) [!]
              Code:
              Infinite HP
              8B8C-7F07
              8B8A-7DD7
              Wild Guns (U)
              Code:
              Infinite Lives P1
              8264-DFB4
              
              Infinite Time (except while using bombs)
              C28F-0F64
              
              Infinite Bombs
              8282-0F64
              Firemen, The (U) (Prototype)
              Code:
              Infinite Energy
              C263-37D1
              
              Infinite Extingushing Bombs
              C2B8-14D7
              Uchuu Race - Astro Go! Go! (J)
              Code:
              Infinite Continues
              C2B3-1F95
              Trinea (J)
              Code:
              Infinite Health (almost?)
              C2DC-57D0
              BS F-ZERO Grand Prix 2 (J)
              Code:
              Infinite Continues
              C964-0DA4
              
              Infinite energy (almost?)
              C969-04AF
              All the codes i've posted were shortly tested with bsnes and are working. I am going to try these on the real hardware with my fashcart soon.

              This one is weird:
              Nankoku Shounen Papuwa-kun (J) [T+Eng1.00_FH]
              The instruction to replace for infinite energy should be this:
              Code:
              $81/87A0 9D 20 01    STA $0120,x[$80:0120]   A:00F1 X:0000 Y:0002 P:envMXdizC
              Replacing with a "BD" i get "826C-3DD9", which is not working.
              Replacing with 3 NOPs (3C6C-3DD9, etc.) is not working too
              Now the funny thing is, the previous "wrong" codes where i wrote AE instead of EA by mistake are actually working! (C36C-3DD9, etc.)
              Last edited by eadmaster; 04-26-2015, 12:50:43 PM.
              Codes and requests made by me

              Comment


              • #8
                Looks like you are getting it figured out. Nice work.

                As far as Nankoku Shounen Papuwa-kun goes, you'll need to look at the assembly before and after that address to see if you can figure out the problem. Try running the game with the "BD" code active and set a breakpoint so it breaks there and see if you can figure out why it isn't working. Then do the same thing using the "AE" codes and see if you can figure out why it IS working.

                EDIT: Here is a link to some good info. Look in the "Making codes from binary files" section...

                http://web.archive.org/web/200210190...nk.net/~zazer/
                Last edited by Tony H; 04-26-2015, 05:00:07 PM.
                The Code Hut: http://codehut.gshi.org/

                Comment


                • #9
                  Many of your codes are what people new to hacking SNES make and use but like Tony said you need to actually look at the assembly and a trace log is the way to do it (press * on SNES9X Debugger). Using the trace log you can find your address that had the break and see exactly what happened before and after the break and usually there is some conditional branch that can be altered with a simple 1 line code and you have infinite health without any problems.

                  The Game name should be Nangoku Syonen Papuwa Kun (J).

                  Here is a trace log snippet I made and will explain a little bit of how I made the code for infinite health.

                  Code:
                  $81/80CB E2 30       SEP #$30                A:0000 X:0000 Y:004B P:envMXdiZc
                  $81/80CD A9 80       LDA #$80                A:0000 X:0000 Y:004B P:envMXdiZc
                  $81/80CF 9D C0 08    STA $08C0,x[$80:08C0]   A:0080 X:0000 Y:004B P:eNvMXdizc
                  $81/80D2 A9 03       LDA #$03                A:0080 X:0000 Y:004B P:eNvMXdizc
                  $81/80D4 9D 40 07    STA $0740,x[$80:0740]   A:0003 X:0000 Y:004B P:envMXdizc
                  $81/80D7 BC A0 06    LDY $06A0,x[$80:06A0]   A:0003 X:0000 Y:004B P:envMXdizc
                  $81/80DA B9 80 01    LDA $0180,y[$80:0182]   A:0003 X:0000 Y:0002 P:envMXdizc
                  $81/80DD 20 87 87    [B]JSR $8787[/B]  [$81:8787]   A:000F X:0000 Y:0002 P:envMXdizc [U][COLOR=#ff0000]A jump to a subroutine aka the health decrease routine[/COLOR][/U]
                  
                  
                  [B][U][COLOR=#008000]$81/8787 E2[/COLOR][/U][/B] 30       SEP #$30                A:000F X:0000 Y:0002 P:envMXdizc
                  $81/8789 64 01       STZ $01    [$00:0001]   A:000F X:0000 Y:0002 P:envMXdizc
                  $81/878B 85 00       STA $00    [$00:0000]   A:000F X:0000 Y:0002 P:envMXdizc
                  $81/878D BD 00 0A    LDA $0A00,x[$80:0A00]   A:000F X:0000 Y:0002 P:envMXdizc
                  $81/8790 EB          XBA                     A:0000 X:0000 Y:0002 P:envMXdiZc
                  $81/8791 BD 20 01    LDA $0120,x[$80:0120]   A:0000 X:0000 Y:0002 P:envMXdiZc
                  $81/8794 C2 20       REP #$20                A:00DD X:0000 Y:0002 P:eNvMXdizc
                  $81/8796 38          SEC                     A:00DD X:0000 Y:0002 P:eNvmXdizc
                  $81/8797 E5 00       SBC $00    [$00:0000]   A:00DD X:0000 Y:0002 P:eNvmXdizC
                  $81/8799 10 03       BPL $03    [$879E]      A:00CE X:0000 Y:0002 P:envmXdizC
                  $81/879E E2 30       SEP #$30                A:00CE X:0000 Y:0002 P:envmXdizC
                  [B]$81/87A0 9D 20 01    STA $0120,x[$80:0120]   A:00CE X:0000 Y:0002 P:envMXdizC[/B] [COLOR=#ff0000][U]Your break[/U][/COLOR]
                  $81/87A3 EB          XBA                     A:00CE X:0000 Y:0002 P:envMXdizC
                  $81/87A4 9D 00 0A    STA $0A00,x[$80:0A00]   A:CE00 X:0000 Y:0002 P:envMXdiZC
                  $81/87A7 BD 20 01    LDA $0120,x[$80:0120]   A:CE00 X:0000 Y:0002 P:envMXdiZC
                  $81/87AA 1D 00 0A    ORA $0A00,x[$80:0A00]   A:CECE X:0000 Y:0002 P:eNvMXdizC
                  $81/87AD D0 17       BNE $17    [$87C6]      A:CECE X:0000 Y:0002 P:eNvMXdizC
                  [B]$81/87C6 60          RTS [/B]                    A:CECE X:0000 Y:0002 P:eNvMXdizC [U][COLOR=#ff0000]This is the return from subroutine instruction[/COLOR][/U]
                  
                  
                  [COLOR=#0000ff][I][B][U]$81/80E0[/U][/B][/I][/COLOR] 60          RTS                     A:CECE X:0000 Y:0002 P:eNvMXdizC [U][COLOR=#ff0000]This is the address directly AFTER the Jump that went to the subroutine
                  [/COLOR][/U]
                  
                  $81/8029 28          PLP                     A:CECE X:0000 Y:0002 P:eNvMXdizC
                  $81/802A 6B          RTL                     A:CECE X:0000 Y:0002 P:envMxdiZC
                  So my code is this 818787:60 which is this in GG:

                  Infinite Health
                  1D66-3FA9


                  Now I'll explain what is happening and why I did what I did:
                  I looked at the trace log and looked up a bit before the break address and saw the gap of space between sets of assembly which means that it's another routine and it was safe to assume that everything after that Jump instruction all the way to the RTL was one routine that involved health.

                  After seeing this is a small routine and that it jumped back to the the previous routine and not to another subroutine I made an educated guess and skipped the whole routine by jumping back to the address after the JUMP using the RTL which it normally would do anyways and skipped all the assembly that checks and decreases the health. Now this can be used for many games but sometimes games use the same routines for player and enemy health and this will affect enemies too but this game isn't like this thankfully.

                  The code doesn't protect you from that umbrella enemy grab but for everything else it works (tried it till level 3).
                  Spoiler Alert! Click to view...

                  THE BAD GUY!!!!!!

                  Comment


                  • #10
                    Interesting, but i am not sure why in general it should be better than the previous methods.
                    Basically you are voiding a whole subroutine that could be used by other parts of the code, so i think there is an higher risk of side-effects.
                    Simply NOPing the jump to the subroutine could be safer (in this case, write 8180DD:EA, 8180DE:EA and 8180DF:EA),
                    but this still feel like a "Plan B" to me.

                    Finally, tracing with Snes9xD isn't very fun: the emulator keeps writing all the processed instructions in the "Logs" directory, slowing down a lot, and filling hundreds of MBs very quickly (a GUI window with a circular buffer would be much better).
                    Last edited by eadmaster; 05-02-2015, 02:31:27 PM.
                    Codes and requests made by me

                    Comment


                    • #11
                      Like I said above I tested it in various levels and against the bosses and nothing bad happened and since there wasn't another routine jump in that subroutine it's safe to say that is the health decrease routine and no one else uses it. I don't see why you would want to use 2 or 3 codes to this when one will do the same, all I did was avoid the whole health routine by returning to the jump location which occurs normally in the assembly anyways.

                      The whole thing with the logs is that you turn the trace on before there is a break then turn it off after the break.
                      Spoiler Alert! Click to view...

                      THE BAD GUY!!!!!!

                      Comment


                      • #12
                        NOPing the entire jump to the routine may perhaps be safer, however it requires 3 codes which is a no-no for those of us on real hardware and limited to 5 lines. The next instruction is a RTS, so you could just place the RTS at 8180DD. (8180DD:60) This is the kind of thinking Helder is talking about, better understanding the code so you can better manipulate it.
                        Please put all complaints in writing and submit them here.

                        Above link not working? Try here.

                        Comment


                        • #13
                          I understand the need for shorter codes for those still using the real GameGenie, but i guess most people now are simply copy-pasting the codes in emulators or cheat sheets.
                          Also i am statically patching the codes for use with a flashcart, so for me avoiding crashes is the most important thing.

                          If i have to void a whole subroutine then i guess i should disassemble the whole ROM and look for all the jumps to it.
                          If there are only a few jumps and i know when they are triggered, then i would assume it is safe to void it.
                          Again, this procedure looks more time-wasting than the previous one, so i will resort to it only if the previous fails (or for educational purposes )...
                          Last edited by eadmaster; 05-04-2015, 08:51:23 PM.
                          Codes and requests made by me

                          Comment

                          Working...
                          X