Coolboyman
Veteran Hacker
- 471
- Posts
- 21
- Years
- Age 37
- The East Bay
- Seen Apr 19, 2025
Needed:
Intermediate knowledge of Gameboy ROMS.
A good debugger (No$gmb works good)
Chapter 1: The RAM of the Gameboy ROM
Gameboy's RAM is 65536 (FFFF) bytes in size.
0000-3FFF - ROM - Bank 0
4000-7FFF - ROM - Switchable Bank
8000-97FF - Tile Graphics
9800-9B5F - BG Map 1
9C00-9F5F - BG Map 2
A000-BFFF - .Sav File
C000-DF00 - Internal RAM
DF01-DFFF - Reserved for the Stack
E000-FDFF - Echo RAM
FE00-FE9F - OAM Data
FEA0-FEFF - Garbage
FF00-FF7F - Hardware I/O Registers
FF80-FFFF - Empty
ROM - Bank 0: Contains bytes 0-3FFF from the ROM
ROM - Bank 1: Contains bytes from a bank. Can be switched to any other bank.
Tile Graphcs: Basically, the graphics.
BG Maps: How the tiles are arranged on screen
.Sav File: Holds the contents of the SAV file in this area.
Internal RAM: Holds the RAM for just about everything else.
Stack: Stack begins at DFFF, and goes down everytime something is pushed. Goes up everytime something is popped. (Will get into these later)
Echo RAM: A copy of the Internal RAM.
OAM Data: Holds the data for the Sprites displayed on screen.
Garbage: Just various unusable bytes, don't do anything here.
Hardware I/O Registers: Has all the control registers. (Will get into these later)
More information regarding the Gameboy Hardware: https://www.romhacking.net/docs/gbchardware.html
Chapter 2: Z80's command set.
Command set based on hex value: https://www.zophar.net/fileuploads/2/10807fvllz/z80-1.txt For example, (ADD a,c)'s hexadecimal identifier is 81.
Registers:
a, b, c, d, e, h, l - registers to store bytes in for temporary use.
n - Digit used with the command.
z - Will only execute command if the last modified register is false.
nz - Will only execute command if the last modified register is true.
(bc), (de), (hl) - when in (), these are treated as pointers rather than variables. EXAMPLE: if de is C000, and it uses ld (de), a, it will write a to the RAM instead of the actual d or e registers.
Commands:
NOP - No action is performed. It's recommended to get rid of these if writing code, because even though nothing happens, it still treats it as a command, thus slowing down your function.
LD, loads a variable into a register. (ld a,b) this takes whatever it in b and copies it into a.
INC - Increases register(s) by 1
DEC - Decreases register(s) by 1
JR - Jumps ahead a certain amount of bytes right after the command.
JP - Jumps to another function.
CALL: Similar to JP, except once the called function is complete it continues afterwards.
ADD - Adds two numbers.
SUB - Subtracts two numbers.
AND: Turns off all bits in A except for B.
OR: Merges the bits between A and B
XOR: Turns off all the bits that A and B share. Then merges the rest.
PUSH: Pushes a pair of registers onto the stack.
POP: Takes two bytes from the stack, puts them into the registers, then clears them off the stack.
AND Example:
A = 6, B = 2
A and B = 2 (Because bit 01 is on)
A = 30, B = 10
A and B = 10 (Because bit 04 is on)
A = 22, B = 60
A and B = 20 (Because bit 05 is on, but bit 06 is not)
OR Example:
A = 6, B = 2
A or B = 6
A = 24, B = 3B
A or B = 3F
XOR Example:
A = 6, B = 2
A xor B = 4
A = FF, B = 1F
A xor B = E0
Next chapter: Using Z80's command set.
Intermediate knowledge of Gameboy ROMS.
A good debugger (No$gmb works good)
Chapter 1: The RAM of the Gameboy ROM
Gameboy's RAM is 65536 (FFFF) bytes in size.
0000-3FFF - ROM - Bank 0
4000-7FFF - ROM - Switchable Bank
8000-97FF - Tile Graphics
9800-9B5F - BG Map 1
9C00-9F5F - BG Map 2
A000-BFFF - .Sav File
C000-DF00 - Internal RAM
DF01-DFFF - Reserved for the Stack
E000-FDFF - Echo RAM
FE00-FE9F - OAM Data
FEA0-FEFF - Garbage
FF00-FF7F - Hardware I/O Registers
FF80-FFFF - Empty
ROM - Bank 0: Contains bytes 0-3FFF from the ROM
ROM - Bank 1: Contains bytes from a bank. Can be switched to any other bank.
Tile Graphcs: Basically, the graphics.
BG Maps: How the tiles are arranged on screen
.Sav File: Holds the contents of the SAV file in this area.
Internal RAM: Holds the RAM for just about everything else.
Stack: Stack begins at DFFF, and goes down everytime something is pushed. Goes up everytime something is popped. (Will get into these later)
Echo RAM: A copy of the Internal RAM.
OAM Data: Holds the data for the Sprites displayed on screen.
Garbage: Just various unusable bytes, don't do anything here.
Hardware I/O Registers: Has all the control registers. (Will get into these later)
More information regarding the Gameboy Hardware: https://www.romhacking.net/docs/gbchardware.html
Chapter 2: Z80's command set.
Command set based on hex value: https://www.zophar.net/fileuploads/2/10807fvllz/z80-1.txt For example, (ADD a,c)'s hexadecimal identifier is 81.
Registers:
a, b, c, d, e, h, l - registers to store bytes in for temporary use.
n - Digit used with the command.
z - Will only execute command if the last modified register is false.
nz - Will only execute command if the last modified register is true.
(bc), (de), (hl) - when in (), these are treated as pointers rather than variables. EXAMPLE: if de is C000, and it uses ld (de), a, it will write a to the RAM instead of the actual d or e registers.
Commands:
NOP - No action is performed. It's recommended to get rid of these if writing code, because even though nothing happens, it still treats it as a command, thus slowing down your function.
LD, loads a variable into a register. (ld a,b) this takes whatever it in b and copies it into a.
INC - Increases register(s) by 1
DEC - Decreases register(s) by 1
JR - Jumps ahead a certain amount of bytes right after the command.
JP - Jumps to another function.
CALL: Similar to JP, except once the called function is complete it continues afterwards.
ADD - Adds two numbers.
SUB - Subtracts two numbers.
AND: Turns off all bits in A except for B.
OR: Merges the bits between A and B
XOR: Turns off all the bits that A and B share. Then merges the rest.
PUSH: Pushes a pair of registers onto the stack.
POP: Takes two bytes from the stack, puts them into the registers, then clears them off the stack.
AND Example:
A = 6, B = 2
A and B = 2 (Because bit 01 is on)
A = 30, B = 10
A and B = 10 (Because bit 04 is on)
A = 22, B = 60
A and B = 20 (Because bit 05 is on, but bit 06 is not)
OR Example:
A = 6, B = 2
A or B = 6
A = 24, B = 3B
A or B = 3F
XOR Example:
A = 6, B = 2
A xor B = 4
A = FF, B = 1F
A xor B = E0
Next chapter: Using Z80's command set.
Last edited: