You are not logged in.
REPOINTING: THE SIMPLEST CASE
- a Gameboy(Color) game to hack (here we'll use Pokemon Blue);
- a debugger (BGB works fine);
- a hex editor with a decent search function(I use HexWorkshop);
- to know what a pointer is;
- very basic ASM understandings (registers, common commands like "call" and "ld");
One of the most frequent tasks in a ROM hack is data expansion; since most of the times we won't have a fully disassembled game to deal with, we have to repoint data somewhere else, or in the same bank or in a different bank.
ABOUT BANKS AND MEMORY MAP
If you don't know about this stuff, you can learn more HERE.
PART 1 - FIND:
Let's say we are adding monsters to the game and want to expand the table of cries. If our data locations is documented in a ROM map, as it is, we already know its address (maybe I'll write a tutorial to find undocumented data, some other time); it's at $39446, so the pointer to look for is $4654 ($5446 in big-endian).
[Bank number is $0E ( = $39446/$4000), this information will help later.]
Using Hex Workshop's search function we'll get 8 results (none of them in the data's bank, i.e. $38000-$3BFFF range):
All of them are anonymous data (not being part of structured data) except the first one ($13DE), which isn't part of structured data, but is actually part of code. In fact the byte before the pointer is $21, an opcode (or operation command) for "ld hl,HHLL", which means "load a 2-byte value into register hl" (when you find that a value between 4000-7FFF is loaded into register hl you can fairly suspect that it's a pointer that points to some interesting data, like data-tables).
Now, since we have figured out where the code that deals with Cries is located, we can open our debugger to see what that code actually is, and to find the information for the bank switching, since code and data are in two different banks (by the way this condition is great because we are able to move Cries data anywhere in the ROM not limiting inside a certain bank, without big work, since the bankSwitching is already implemented in the original code).
PART 2 - REVERSE:
Once we've loaded our ROM in BGB we open "Debug->breakpoint" and type 13dd in the "PC=" textbox (alternatively we could go to (ctrl+G) address 13dd ("ld hl,5446") and double click it). Now the line should be red.
Note: this routine actually starts at $13d9 and ends at $13fb
;a = pokemon index value ROM0:13d9 3d dec a ;a = a - 1 because first cry index is actually 0 ROM0:13da 4f ld c,a ROM0:13db 06 00 ld b,00 ;bc = pokemon index value - 1 ROM0:13dd 21 46 54 ld hl,5446 ;get cries' table starting point ROM0:13e0 09 add hl,bc ROM0:13e1 09 add hl,bc ;added 3 times because every ROM0:13e2 09 add hl,bc ;cry info is 3 byte long ROM0:13e3 3e 0e ld a,0e ;bank where data is ROM0:13e5 cd bc 35 call 35bc ;this function switches bank to value in a ROM0:13e8 2a ldi a,(hl) ;load cry's data ROM0:13e9 47 ld b,a ;b = byte1 ROM0:13ea 2a ldi a,(hl) ROM0:13eb ea f1 c0 ld (c0f1),a ;[$c0f1] = byte 2 ROM0:13ee 7e ld a,(hl) ROM0:13ef ea f2 c0 ld (c0f2),a ;[$c0f2] = byte 3 ROM0:13f2 cd cd 35 call 35cd ;restores previous bank ROM0:13f5 78 ld a,b ROM0:13f6 0e 14 ld c,14 ROM0:13f8 07 rlca ROM0:13f9 80 add b ROM0:13fa 81 add c ;a = byte1 * 3 + 14 ROM0:13fb c9 ret
Let's make the game run (press F9 if the game isn't running already). It will break at the titlescreen when you press A (since it's supposed to play the currently viewed pokemon's cry): so it conferms that the address we found locates the routine that plays cries.
PART 3 - REPOINT:
Repointing is the act of moving data and update their pointers to the new location of the moved data. Now, once you have placed your data-table in a new location you have to edit the pointer, and the bank info too.
So get your address, calculate the 2-byte pointer + bank value:
pointer = address \ $4000
bank = address (MOD $4000)
overwrite the pointer at $13de-$13df (remember to write it in little-endian format, i.e. the least significant byte first and the most significant byte secondly), and overwrite the bank value at $13e4.
P.S.:remember that you will not always have pointer and data in two different banks so if you want to repoint data to a different bank, you'll have much more work than this to achieve your goal. Also, often data is pointed by more than one single pointer. (an example in Red/Blue is Evolution/Attacks learned that are pointed by four different pointers, therefore there are four different routines that use that data).