• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[ASM & Hex] Adding a new type [GS]

4
Posts
5
Years
    • Seen Feb 21, 2019
    The main question I have is how do I make a pointer to an address in another bank work?

    For the past couple days I've been fiddling with an Hex Editor and checking the inner workings of Pokémon Gold. With the help of this very forum, I found the type effectiveness chart in address 0x34D01. The type chart is composed of three bytes for each type effectiveness to consider. (Those not in the list are assumed by the game to be normal effectiveness.)

    Problem
    In normal circumstances this list has length of 332 bytes, which includes a "Foresight demarcation" byte FE and a termination byte FF, totalling 110 type interactions. The two pointers that make use of this list, as far as I can tell, are in addresses 0x34891 and 0x34935 in the same memory bank. It's attractive to add more types into the engine, which is what I am looking into. Adding the Fairy-type, for example, would yield 12 more type interactions to consider, which would mean adding 36 new bytes to the list. This is impossible where the list stands in the memory since it's tightly surrounded on both ends by relevant engine data.

    Possible solution
    The bank this list is allocated in is unusually tight and not flexible at all. There is no space at the end to copy the list and expand it. The only other option is to write it in another free space in a different bank and have the pointers point to them. This is where I hit a brick wall. Doing so in, for example, the free space in the bank right after (address 0x3B6A0) means setting the pointers to A0 76, which does not work at all. Am I missing something in doing this? I'm guessing it needs another byte to specify the bank number, but this would write over bytes right after the pointers.
     

    miksy91

    Dark Energy is back in action! ;)
    1,480
    Posts
    15
    Years
  • You can only point to addresses within the same rom bank. For example pointer A0 76 in this case refers to address 0x376A0 (and not 0x3B6A0) because the rom bank is 0x4000 bytes long starting at 0x34000.

    In order to expand the table, you could either:
    1) try moving the table to another rom bank (requires at least some asm hacking),
    2) try moving most of the asm routine handling the table along with the table to another rom bank,
    3) try finding some other data to move to another rom bank, or
    4) try moving data following the type effectiveness table at the end of the rom bank. I take it you would need to move 36 bytes of data at the minimum.

    Unfortunately none of the previous options are easy to take. The fourth one might be easiest thing to do, but that wouldn't generalize for example for adding two new types.

    In my own hack, I happened to re-locate all the trainer data along with around 0x200 bytes of code handling the data to another, originally empty rom bank (and thus did what I mentioned as option 2 here). It wasn't easy though and required quite a lot of debugging and "backtracking" code handling the trainer data pointer table in such way that it was possible. I basically had to understand at least somewhat properly, what the original routine was like and where it was initially accessed from and in what situations. After understanding these, it was possible to move the data by changing pointers pointing to the "start points" of the actual code handling the trainer data.

    I can't unfortunately give a clear solution for you to overcome this issue. You could however think about moving to editing pokecrystal disassembly because it provides for example more flexibility in tackling issues such as you have right here. With disassembly, you could easily expand the table in place getting the 12 interactions for Fairy type. This would mean that all the following data in the same rom bank would just end up 36 bytes ahead of their original location. And thus you would only run into the same issue with there not being enough space in this rom bank if there wasn't originally 36 bytes of free space at the end of it.
     
    Last edited:
    4
    Posts
    5
    Years
    • Seen Feb 21, 2019
    Thank you very much for the detailed reply miksy91.

    The reason I wanted to do the binary hacking in the first place is because I am doing a simple randomizer, that will consist of a program that takes as input ROM data, and through lookup tables of its own, would know which bits to flip according to another lookup table. After all it's done I would like an option to update move data to newer generations and add the new type chart, including Fairy-type.

    I understand the options available now, after digging into ASM documentation and such. I did get pokecrystal in my PC and tested it out for myself in a Pokémon Crystal ROM. And in fact it does add onto the list at the end and repoint all the pointers to that bank. So what I did was I only added one type interaction through pokecrystal (insert 3 bytes into the end of the list), effectively shifting everything coming afterwards in the bank, and compared with a source ROM. Apart from the bank in question (bank 13), which has differences too numerous to enumerate, here's a list of all addresses of the pointers affected (with the 3-byte shift):

    Bank 1:
    Spoiler:


    Bank 9:
    Spoiler:


    Bank 10:
    Spoiler:


    (Bank 13)

    Bank 14:
    Spoiler:


    Bank 62:
    Spoiler:


    Additionally, right at the start, in bank 0, there's a 2 byte change which I don't know the significance of:

    0x14E - 18 D2 -> F5 52

    So my mode of attack will be to create a ROM with the interactions plugged in pokecrystal (I changed the target ROM from Gold to Crystal), and have my program look into all those addresses, repoint them all accordingly, and completely rewrite bank 13 for ease of implementation. As of right now that is the only tangible method I can think of and it shouldn't be too much of a hassle.

    If it is a matter of public interest, I may post bank 13 in its entirety with the Gen VI interactions built in, then all the value of all the pointers in those addresses I listed, in case someone in the future wants to implement this method. Though doing so in the disassembler is simple enough, so maybe it's not that interesting a deal.
     
    Last edited:

    miksy91

    Dark Energy is back in action! ;)
    1,480
    Posts
    15
    Years
  • And in fact it does add onto the list at the end and repoint all the pointers to that bank.
    I can't tell if you just wrote this in a lazy way here, but I'm pretty sure no references / pointers to bank 13, that point to offsets in front of the type effectiveness table, are changed. Just by expanding the table, you're not really touching any of the previous data in the same rom bank.

    Additionally, right at the start, in bank 0, there's a 2 byte change which I don't know the significance of:

    0x14E - 18 D2 -> F5 52
    Address 0x14E contains the "Global checksum" over the whole rom data. GB / GBC / GBA console might work so that it first calculates checksum over the whole rom data and compares it to the global checksum. If these two wouldn't match, it would know that the rom is corrupted and refuse to start its execution (= let the player play the game). Apparently GB doesn't verify the checksum.

    More info here: http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header

    Nevertheless, I would just assume that during compilation of pokecrystal, the global checksum is always calculated to be correct. Some rom editing tools I've been using for hacking Dark Energy (Silver rom hack) seem to also touch this without me knowing it which I've been quite surprised of. Haven't noticed which tool has been modifying it on the background without me ever accessing that address though.

    But yeah, sounds like a reasonable way to tackle this issue :)
    Best of luck! I believe you can make it!
     
    Last edited:
    Back
    Top