• 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?".
  • Forum moderator applications are now open! Click here for details.
  • 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.

Research: The art of Z80

Coolboyman

Veteran Hacker
471
Posts
20
Years
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: http://www.romhacking.net/docs/gbchardware.html

Chapter 2: Z80's command set.

Command set based on hex value: http://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:

Sawakita

Not Invented Here
181
Posts
13
Years
  • Age 34
  • Seen Nov 17, 2019
That's exactly what i'm studying now, z80 CPU. I hope that later you're going to teach us LZ77 and that kind of stuff. thank you CBM!!
 

Coolboyman

Veteran Hacker
471
Posts
20
Years
Chapter 3: Basic Use of Z80's Command set.

Write a byte to RAM:
ld a,n $01: 3E 01
ld de,nn $D000: 11 00 D0
ld (de),a: 12

Move a byte to another location in the RAM:
ld de,nn $D000: 11 00 D0
ld hl,nn $D001: 21 01 D0
ld a,(de): $1A
ld (hl),a: $77

Add a byte in the RAM:
ld de,nn $D000: 11 00 D0
ld c,$20: 0E 20
ld a,(de): 1A
ADD a,c: 81
ld (de),a: 12

Checks byte in RAM. If true, branch off to a new location.
ld de,nn $D000: 11 00 D0
ld a,(de): 1A
jp nz,nn: C2 00 50
function 1

Location $5000:
function 2

Writes bytes $00-7F to $D000-$D080 using a loop
ld de,nn $D000: 11 00 D0
ld a,$00: 3E 00
ld c,$80: 0E 80
ld (de),a: 12
inc a: 3C
inc de: 13
dec c: 0D
jp nz,nn: C2 00 50 (to fourth line of this function)
ret

Next chapter: Putting your functions in the game.
 

Sawakita

Not Invented Here
181
Posts
13
Years
  • Age 34
  • Seen Nov 17, 2019
I can't wait to learn more about z80!! I think it's a Must, for everyone who's interested in rom hacking, to learn gbASM. Also for those for whom there seems to be only the gba and ds....
In my opinion (and not only mine, I guess!) it's the foundation of everything that follows.
 
24
Posts
14
Years
Might be important to note that the GB doesn't actually use a Z80. It's similar to a Z80 but some of the features of the Z80 are missing and other features are present. It's important to take this into account when writing and compiling your code.
 

Sawakita

Not Invented Here
181
Posts
13
Years
  • Age 34
  • Seen Nov 17, 2019
Might be important to note that the GB doesn't actually use a Z80. It's similar to a Z80 but some of the features of the Z80 are missing and other features are present. It's important to take this into account when writing and compiling your code.

Yes but it's just few added or removed commands, and IY&IX registers have been removed.

(I found a document about this, but I can't find it right now. When I eventually find it I'm going to post it)
 

Sawakita

Not Invented Here
181
Posts
13
Years
  • Age 34
  • Seen Nov 17, 2019
Yes but it's just few added or removed commands, and IY&IX registers have been removed.

(I found a document about this, but I can't find it right now. When I eventually find it I'm going to post it)

Here are the differences:


The following are added instructions:
ADD SP,nn ;nn = signed byte
LDI (HL),A ;Write A to (HL) and increment HL
LDD (HL),A ;Write A to (HL) and decrement HL
LDI A,(HL) ;Write (HL) to A and increment HL
LDD A,(HL) ;Write (HL) to A and decrement HL
LD A,($FF00+nn)
LD A,($FF00+C)
LD ($FF00+nn),A
LD ($FF00+C),A
LD (nnnn),SP
LD HL,SP+nn ;nn = signed byte
STOP ;Stop processor & screen until
button press
SWAP r ;Swap high & low nibbles of r

The following instructions have been removed:
Any command that uses the IX or IY registers.
All IN/OUT instructions.
All exchange instructions.
All commands prefixed by ED (except remapped RETI).
All conditional jumps/calls/rets on parity/overflow
and sign flag.

The following instructions have different opcodes:
LD A,[nnnn]
LD [nnnn],A
RETI
---------------------
credits go to:
Pan of Anthrox, GABY, Marat Fayzullin,
Pascal Felber, Paul Robson, Martin Korth, kOOPa, Bowser
(authors of "Game BoyTM CPU Manual")
 
Last edited:
1
Posts
13
Years
  • Seen Aug 9, 2010
I just found this, it seemed extremely useful to me. Like the reference sheet for the Z80 but it's specifically for the LR35902 in the gameboy.

world wide web pastraiser com /cpu/gameboy/gameboy_opcodes.html

I apologize, I haven't made enough posts on this site to post a real link, I think you know what to do!
 

miksy91

Dark Energy is back in action! ;)
1,480
Posts
15
Years
Heh, I've been trying to avoing Z80 and that kind of stuff before because they felt too much for me to handle but this isn't actually so bad after all :D

Btw, a very tutorial KBM, as always.
 
Back
Top