’Cause all games were better on the GBC

You are not logged in.

#1 2012-07-21 13:50:20

Registered: 2010-10-16
Post 985/2,348

GB/C Pointer Tutorial

Sure, there is already a tutorial by Sawakita around but I figured I should also post this here as there has been a tutorial by me in Pokecommunity since 2010 and it had some oddities and stuff wasn't explained properly in it so today, I remade the whole thing.

Let's get started with the basics. Pointers are basically two-byte values and as you may be able to guess, they're used to pointing to different kinds of data. What you probably want to know is how to calculate them.

Calculating the offsets where pointers point to is easy. For example 2A 88 points to $882A but this offset here is a memory address in RAM. Same way, 13 3A points to $3A13 and 10 D0 to $D010. The problem is, how to calculate pointers which are used for looking data inside ROM ?

GB/C RAM works like this
$0000-3FFF - ROM bank 0x0
$4000-7FFF - Variable ROM bank
$8000-9FFF - Video RAM
$A000-BFFF - Save RAM
$C000-CFFF - RAM
$E000-FEFF - Echo RAM
$FF00-FF7F - I/O Registers

Basically, the RAM area between $4000 and $7FFF is the one you want to access with pointers pointing inside ROM (in case you're not calling some assembly code from ROM bank 0 for instance but you should know all this if you're even planning to do that). This RAM area between $4000-7FFF is 0x4000 bytes long which is as large as each ROM bank inside a ROM file.

For example in Pokemon Gold (U) ROM, there is lots of blank data (data filled with 00 00 00...) starting at 0x109DCA. If we for example wanted to input some script data in there and make the script pointer of some random person look for the script data in this rom area, we'd have to find the right pointer to it. This rom bank we're in starts at:

0x109DCA / 0x4000 = 0x42 (if your Calculator shows some digits after a comma here, ignore them and just use the integer in the following calculation)
0x42 * 0x4000 = 0x108000

So our rom bank starts at 0x108000 and as rom banks are 0x4000 bytes long (as explained above), this rom bank ends at 0x10BFFF. Basically, when data is looked for in this rom bank, 0x4000 bytes starting at 0x108000 are copied to $4000 in RAM ($4000-7FFF).

Basically, we can use a calculation like this to find the pointer leading to 0x109DCA:
0x109DCA - 0x108000 + 0x4000 = 0x5DCA --> 5D CA

And as explained way above, we'll have to rotate the bytes around to find the pointer that leads to the wanted ram address and so we'll get: CA 5D.

So to look for script in 0x109DCA, you'll have to change the script pointer of this random person, I was talking about earlier, to CA 5D. This of course demands that the script pointer (along with his other event data which is no way related to this thread) is in the same rom bank (between 0x108000-10BFFF).

Because there are more rom banks than just rom banks 0x0 and 0x1, there has to be a way for moving on from rom bank to another. This is often done by calling a specific assembly routine by loading a register with the value of the bank and another register pair with the pointer to the address in ram.

Anyway, in the explanation above, I explained how to define the 2-byte pointer pointing to a specific rom/ram address. This time, let's define where a specific "3-byte pointer" points to (we like calling them 3-byte pointers because they also consist of a byte of the accessed rom bank).

Let's pretend we had a pointer of this kind:
A7 48 3A in which A7 48 is the pointer to the accessed rom data and 3A the byte of the accessed rom bank. The offset where this pointer leads is then:

0x3A * 0x4000 + 0x48A7 - 0x4000 = 0xE88A7

Of course when this rom address is accessed, $E8000-EBFFF is again copied into RAM ($4000-7FFF), and we're currently pointing to ram address $48A7.

Notice that all GB/C pointers are formed with two bytes! The rom bank byte itself is used in a specific assembly routine to define the accessed rom bank and doesn't have to be next to the two-byte pointer. Basically in rom you could also find a 3-byte pointer this way:
[2-byte pointer] [xx bytes data] [Rom bank]

Last edited by Miksy91 (2012-07-21 13:56:09)


Board footer

Powered by FluxBB