Mechanisms of infinite money

Regardless of their name, all cheat devices work in the same way: they write values to the memory.

For instance, if one were to look up an "Infinite Money" code for the GameBoy game Pokémon RED, the very first result would be the following list of numbers:

Not just rich, infinitely rich!
Not just rich, infinitely rich!
019947D3
019948D3
019949D3

Using these as a GameShark code in an emulator, and starting a new game, we get the desired outcome: our character is now rich and will stay that way until we disable the code.

Codes for some consoles may have sophisticated specifications, some even including actual programming code in them, but the GameShark for Gameboy is simple: an eight-number code is meant to be split into the arguments for a function with the prototype writeValueToOffset(u8 rombank, u8 value, u16 offset), giving us the following pseudo-code:

writeValueToOffset(0x01, 0x99, 0x47D3)
writeValueToOffset(0x01, 0x99, 0x48D3)
writeValueToOffset(0x01, 0x99, 0x49D3)

Attention!

The GameBoy being a low-endian game system, the addresses 0x47D3, 0x48D3, and 0x49D3, are respectively: 0xD347, 0xD348, and 0xD349, and therefore follow each other.

But now this code just drives more questions: what would happen if we only used one of those three codes? Let's try again with something else:

Another kind of rich
Another kind of rich
011247D3 # writeValueToOffset(0x01, 0x12, 0x47D3)
013448D3 # writeValueToOffset(0x01, 0x34, 0x48D3)
015649D3 # writeValueToOffset(0x01, 0x56, 0x49D3)

After disabling the previous code, and trying this one, we can see the results and make our deductions: each of the three memory addresses from 0xD347 to 0xD349 is responsible for two digits of the player money.

Actually, we could just write 99 in 0xD347 and make our hero very close to being a millionaire, but a pretty number is way more satisfying, isn't it?

Did you notice?

Astute readers may notice something strange: the value is written in hexadecimal as 0x99 (equal to 153 in decimal), but the number displayed is 99 in decimal. This is because in Pokémon Red, money is stored as a Binary-Coded Decimal1, and not as hexadecimal. Storing big numbers as Binary-Coded Decimals is a method that was popular on older processors, like the SM53 the GameBoy uses.

Another interesting thing to notice is that as long as the code is enabled, our money will stay fixated on the same number no matter how many times we decide to go on a shopping spree. This is because the ActionReplay devices work by writing values to memory each time a frame is rendered2, resetting our money around 60 times per second.


1

As evidenced in the disassembly code.

2

If you want to get really technical about it: they are hooking themselves to the VBlank Interrupt handler.