The GBZ80 (Sharp SM83) is the CPU that powers the original Nintendo Gameboy and Gameboy Color handheld consoles. It is kind of an in-between the [[Intel 8080]] and [[Z80]]. [https://gbdev.io/resources.html Awesome Gameboy resources] [https://gbdev.gg8.se/wiki/ GBDev wiki] [https://emudev.de/ Emudev (q00.gb)]
The GBZ80 lacks the alternate register set, the dedicated I/O bus, the R register(thus no M1), the index registers (thus no DD and FD prefixed opcodes), the ED prefixed opcodes (including block transfer), the sign and parity/overflow flags (and all conditional instructions that used them), the undocumented flags (thus no leaking of WZ and Q internal registers). [https://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html GBZ80 opcodes]
The GBZ80 also lacks the NMI pin (thus no IFF2 and no RETN), the IM instructions and the I register. It has a different interrupt system than the Z80. [https://gbdev.io/pandocs/Interrupts.html Source]
The Nintendo documentation does not mention M-cycles or T-states at all. They only mention CPU cycles, which are always equal to 4 T-states (like NOPs in the CPC world). Also, the GBZ80 has different timings than the Z80. For example, :* CALL nn takes 6 cycles on the GBZ80, but only 5 NOPs on the Z80* ADD HL,ss takes 2 cycles on the GBZ80, but 3 NOPs on the Z80* JP cc,nn has different timings depending on whether the jump is taken. This is not the case on Z80.
Fun factFlags can differ too: Way more * RLCA, RRCA, RLA, RRA clear ZF in the GBZ80 cores were produced for Gameboy hardware (118 million Gameboys and 81 million GBA) than all , but not in the Z80 chips produced for home computers and game consoles. [https://www.chibiakumas.com/z80/Gameboy.php Learn * DAA clears HF in the GBZ80 Assembly Programming with ChibiAkumas], but not in the Z80
Fun fact: Way more GBZ80 cores were produced for Gameboy hardware (118 million Gameboys and 81 million GBA) than all the Z80 chips produced for home computers and game consoles. <br> == RegistersRegister File ==
{| class="wikitable" style="white-space: nowrap;"
| PC (Program Counter) || 16-bit || Points to the next instruction || Automatically increments as instructions execute
|}
<br>
== GBZ80 instructions ==
[https://rgbds.gbdev.io/docs/master/gbz80.7 CPU opcode reference]
Legend:
* r,s: 000=B, 001=C, 010=D, 011=E, 100=H, 101=L, 111=A (110 is treated separately)
* pp: 00=BC, 01=DE, 10=HL, 11=SP
* qq: 00=BC, 01=DE, 10=HL, 11=AF
* cc: 00=NZ, 01=Z, 10=NC, 11=C
=== Load group ===
{| class="wikitable" style="white-space: nowrap;"
|-
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| ld r,s || 01rrrsss || 1 || rowspan=15|- || rowspan=15|- || rowspan=15|- || rowspan=15|- || r := s ||rowspan=15|8-bit Load
|-
| ld (hl),r || 01110rrr || 2 || (hl) := r
|-
| ld r,(hl) || 01rrr110 || 2 || r := (hl)
|-
| ld r,n || 00rrr110 nnnnnnnn || 2 || r := n
|-
| ld (hl),n || 00110110 nnnnnnnn || 3 || (hl) := n
|-
| ld (bc),a || 00000010 || 2 || (bc) := a
|-
| ld a,(bc) || 00001010 || 2 || a := (bc)
|-
| ld (de),a || 00010010 || 2 || (de) := a
|-
| ld a,(de) || 00011010 || 2 || a := (de)
|-
| ld (hli),a || 00100010 || 2 || (hl) := a, hl += 1
|-
| ld a,(hli) || 00101010 || 2 || a := (hl), hl += 1
|-
| ld (hld),a || 00110010 || 2 || (hl) := a, hl -= 1
|-
| ld a,(hld) || 00111010 || 2 || a := (hl), hl -= 1
|-
| ld (nn),a || 11101010 lolololo hihihihi || 4 || (nn) := a
|-
| ld a,(nn) || 11111010 lolololo hihihihi || 4 || a := (nn)
|-
|ld (n),a || 11100000 nnnnnnnn || 3 || rowspan=4|- || rowspan=4|- || rowspan=4|- || rowspan=4|- || (FF00h + n) := a || rowspan=4|8-bit I/O Load
|-
|ld a,(n) || 11110000 nnnnnnnn || 3 || a := (FF00h + n)
|-
|ld (c),a || 11100010 || 2 ||(FF00h + c) := a
|-
|ld a,(c) || 11110010 || 2 || a := (FF00h + c)
|-
| ld pp,nn || 00pp0001 lolololo hihihihi || 3 || rowspan=3|- || rowspan=3|- || rowspan=3|- || rowspan=3|- || pp := nn ||rowspan=3|16-bit Load
|-
| ld (nn),sp || 00001000 lolololo hihihihi || 5 || (nn) := sp
|-
| ld sp,hl || 11111001 || 2 || sp := hl
|-
| pop qq || 11qq0001 || 3 || - || - || - || - || qq := (sp), sp += 2 ||Pop a value from the stack
|-
| push qq || 11qq0101 || 4 || - || - || - || - || sp -= 2, (sp) := qq ||Push a value onto the stack
|}
=== 16-bit Arithmetic group ===
{| class="wikitable" style="white-space: nowrap;"
|-
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| inc pp || 00pp0011 || 2 || - || - || - || - || pp += 1 || Increment
|-
| dec pp || 00pp1011 || 2 || - || - || - || - || pp -= 1 || Decrement
|-
| add hl,pp || 00pp1001 || 2 || - || 0 || + || + || hl += pp ||rowspan=3|Add
|-
| add sp,e || 11101000 eeeeeeee || 4 || 0 || 0 || + || + || sp += e
|-
| ldhl sp,e || 11111000 eeeeeeee || 3 || 0 || 0 || + || + || hl := sp + e
|}
=== 8-bit ALU group ===
|-
| sbc a,n || 11011110 nnnnnnnn || 2 || a -= n + cf
|-
| cp r || 10111rrr || 1 || rowspan=3|+ || rowspan=3|1 || rowspan=3|+ || rowspan=3|+ || tmp := a - r ||rowspan=3|Compare
|-
| cp (hl) || 10111110 || 2 || tmp := a - (hl)
|-
| cp n || 11111110 nnnnnnnn || 2 || tmp := a - n
|-
| and r || 10100rrr || 1 || rowspan=3|+ || rowspan=3|0 || rowspan=3|1 || rowspan=3|0 || a := a and r ||rowspan=3|Logical AND
| or n || 11110110 nnnnnnnn || 2 || a := a or n
|-
| cp r daa || 10111rrr 00100111 || 1 || rowspan=3|+ || rowspan=3- |1 |0 | rowspan=3|+ X || rowspantmp :=3|a,if nf: if hf or [a and 0x0f > 9]: tmp -= 0x06 if cf or [a > 0x99]: tmp -= 0x60else: if hf or [a and 0x0f > 9]: tmp + || = 0x06 if cf or [a > 0x99]: tmp += 0x60 tmp => flags, cf := cf or [a - r > 0x99], a := tmp||rowspanDecimal Adjust Accumulator|} =3== ROT group === {|Compareclass="wikitable" style="white-space: nowrap;"
|-
| cp (hl) || 10111110 || 2 || tmp := a - (hl)! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| cp n rlca || 11111110 nnnnnnnn 00000111 || 2 1 || tmp rowspan=4|0 || rowspan=4|0 || rowspan=4|0 || rowspan=4|X || cf := a .7, a := [a << 1] + cf ||rowspan=4|Fast Rotate|- n| rrca || 00001111 || 1 || cf := a.0, a := [a >> 1] + [cf << 7]|-| rla || 00010111 || 1 || ocf := cf, cf := a.7, a := [a << 1] + ocf|-| rra || 00011111 || 1 || ocf := cf, cf := a.0, a := [a >> 1] + [ocf << 7]|-| rl r || CB 00010rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || ocf := cf, cf := r.7, r := [r << 1] + ocf ||rowspan=2|Rotate Left|-| rl (hl) || CB 00010110 || 4 || ocf := cf, cf := (hl).7, (hl) := [(hl) << 1] + ocf|-| rlc r || CB 00000rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || cf := r.7, r := [r << 1] + cf ||rowspan=2|Rotate Left Carry|-| rlc (hl) || CB 00000110 || 4 || cf := (hl).7, (hl) := [(hl) << 1] + cf|-| rr r || CB 00011rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || ocf := cf, cf := r.0, r := [r >> 1] + [ocf << 7] ||rowspan=2|Rotate Right|-| rr (hl) || CB 00011110 || 4 || ocf := cf, cf := (hl).0, (hl) := [(hl) >> 1] + [ocf << 7]|-| rrc r || CB 00001rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || cf := r.0, r := [r >> 1] + [cf << 7] ||rowspan=2|Rotate Right Carry|-| rrc (hl) || CB 00001110 || 4 || cf := (hl).0, (hl) := [(hl) >> 1] + [cf << 7]|-| sla r || CB 00100rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || cf := r.7, r := r << 1 ||rowspan=2|Shift Left Arithmetic|-| sla (hl) || CB 00100110 || 4 || cf := (hl).7, (hl) := (hl) << 1|-| sra r || CB 00101rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || cf := r.0, r := r >> 1, r.7 := r.6 ||rowspan=2|Shift Right Arithmetic|-| sra (hl) || CB 00101110 || 4 || cf := (hl).0, (hl) := (hl) >> 1, (hl).7 := (hl).6|-| srl r || CB 00111rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|X || cf := r.0, r := r >> 1 ||rowspan=2|Shift Right Logical|-| srl (hl) || CB 00111110 || 4 || cf := (hl).0, (hl) := (hl) >> 1|-| swap r || CB 00110rrr || 2 || rowspan=2|+ || rowspan=2|0 || rowspan=2|0 || rowspan=2|0 || r := [[r and 0x0f] << 4] + [r >> 4] ||rowspan=2|Swap nibbles|-| swap (hl) || CB 00110110 || 4 || (hl) := [[(hl) and 0x0f] << 4] + [(hl) >> 4]
|}
=== BCD Bitwise group ===
{| class="wikitable" style="white-space: nowrap;"
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| daa bit b,r || 00100111 CB 01bbbrrr || 1 2 || rowspan=2| + || - rowspan=2|0 | X |rowspan=2| X 1 || rowspan=2|- || tmp := a,r and [1 << b] ||rowspan=2|Test Bitif nf then|- if hf or [a | bit b,(hl) || CB 01bbb110 || 3 || tmp := (hl) and 0x0f > 9[1 << b] then tmp |-= 0x06 if cf or | res b,r || CB 10bbbrrr || 2 || rowspan=2|- || rowspan=2|- || rowspan=2|- || rowspan=2|- || r := r and ~[a > 0x991 << b] then tmp -||rowspan= 0x602|Reset Bitelse|- if hf or [a | res b,(hl) || CB 10bbb110 || 4 || (hl) := (hl) and 0x0f > 9~[1 << b] then tmp += 0x06 if cf |-| set b,r || CB 11bbbrrr || 2 || rowspan=2|- || rowspan=2|- || rowspan=2|- || rowspan=2|- || r := r or [a > 0x991 << b] then tmp +||rowspan= 0x602|Set Bitendif,|-tmp => flags| set b, cf (hl) || CB 11bbb110 || 4 || (hl) := cf (hl) or [a > 0x991 << b],hf := a.4 xor tmp.4, |-| cpl || 00101111 || 1 || - || 1 || 1 || - || a := tmp~a || Decimal Adjust AccumulatorComplement
|}
=== Control flow group ===
{| class="wikitable" style="white-space: nowrap;"
|-
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| rst t || 11ttt111 || 4 || rowspan=3|- || rowspan=3|- || rowspan=3|- || rowspan=3|- || sp -= 2, (sp) := pc, pc := t || Restart
ttt: 000=#0, 001=#8, 010=#10, 011=#18, 100=#20, 101=#28, 110=#30, 111=#38
|-
| call nn || 11001101 lolololo hihihihi || 6 || sp -= 2, (sp) := pc, pc := nn || rowspan=2|Call
|-
| call cc,nn || 110cc100 lolololo hihihihi || 6/3 || if cc then sp -= 2, (sp) := pc, pc := nn
|-
| jp nn || 11000011 lolololo hihihihi || 4 || rowspan=3|- || rowspan=3|- || rowspan=3|- || rowspan=3|- || pc := nn || rowspan=3|Jump
|-
| jp (hl) || 11101001 || 1 || pc := hl
|-
| jp cc,nn || 110cc010 lolololo hihihihi || 4/3 || if cc then pc := nn
|-
| jr e || 00011000 eeeeeeee || 3 || rowspan=2|- || rowspan=2|- || rowspan=2|- || rowspan=2|- || pc += e || rowspan=2|Relative jump
|-
| jr cc,e || 001cc000 eeeeeeee || 3/2 || if cc then pc += e
|-
| ret || 11001001 || 4 || rowspan=4|- || rowspan=4|- || rowspan=4|- || rowspan=4|- || pc := (sp), sp += 2 || rowspan=2|Return
|-
| ret cc || 110cc000 || 5/2 || if cc then pc := (sp), sp += 2
|-
| reti || 11011001 || 4 || pc := (sp), sp += 2, ime := 1 || Return from Interrupt
|}
=== CPU control group ===
{| class="wikitable" style="white-space: nowrap;"
|-
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| di || 11110011 || 1 || - || - || - || - || ime := 0 || Disable Interrupts
|-
| ei || 11111011 || 1 || - || - || - || - || ime := 1 || Enable Interrupts
|-
| halt || 01110110 || 1 || - || - || - || - || wait for interrupt || Suspends CPU operation
|-
| stop || 00010000 00000000 || 1 || - || - || - || - || wait for reset signal || Stops the system clock and LCD controller
|-
| nop || 00000000 || 1 || - || - || - || - || nothing || No Operation
|-
| scf || 00110111 || 1 || - || 0 || 0 || 1 || nothing else || Set Carry Flag
|-
| ccf || 00111111 || 1 || - || 0 || X || X || hf := cf, cf := ~cf || Complement Carry Flag
|}
<br>
== Opcodes ==
Opcode differences with Z80 are in bold. The unused ('''—''') opcodes will lock up the Game Boy CPU when used. The asssembler assembler syntax is from the official Nintendo [https://archive.org/details/GameBoyProgManVer1.1/ Gameboy programming manual].
=== Standard opcodes ===
! Opcode !! Mnemonic
|-
| 10 xx || '''STOP'''
|-
| 11 xx xx || LD DE,nn
|}
|}
Note: Storing a register into itself is a no-op; however, some Game Boy emulators (such as BGB) interpret LD B,B as a breakpoint, or LD D,D as a debug message.
=== CB-prefixed opcodes ===
|}
|}
<br>
== Oddities ==
* On GBZ80, when an interrupt is triggered, the CPU automatically performs a DI before jumping to the interrupt handler. The Z80 does not.
* On GBZ80, RETI automatically performs an EI. The Z80 does not. [https://rgbds.gbdev.io/docs/master/gbz80.7#RETI Source]
* STOP is normally a 2-byte instruction where the second byte is ignored. [https://gbdev.io/pandocs/Reducing_Power_Consumption.html#using-the-stop-instruction Source]
* STOP is used on Gameboy Color to switch between normal speed and double speed CPU modes.
* RST instructions are just a CALL instruction to a fixed address baked in the instruction itself.
* Despite what the syntax of the instructions JP (HL/IX/IY) suggests, PC will be loaded with the contents of the register itself, not the indexed value. Those instructions should be understood as JP HL/IX/IY.
* The instructions LD A,A, LD B,B, LD C,C, LD D,D, LD E,E, LD H,H and LD L,L are useless. Their existence is just a side effect of how instructions are encoded as opcodes in the CPU. However, some Game Boy emulators (such as BGB) interpret LD B,B as a breakpoint, or LD D,D as a debug message.
* While the syntax of the 8-bit ADD, ADC and SBC instructions all explicitly mention the A register, the SUB instruction does not mention it.
* Arithmetic can only really be done on the A register.
* PUSH and POP instructions utilize a 16-bit operand and the high-order byte is always pushed first and popped last. PUSH HL is PUSH H then L. POP HL is POP L then H.
* ADD SP,e takes 4 cycles, while LDHL SP,e takes only 3 cycles.
<br>
== Weblinks ==
*[https://www.chibiakumas.com/z80/Gameboy.php Learn GBZ80 Assembly Programming with ChibiAkumas]
*[https://gbdev.io/resources.html Awesome Gameboy resources]
*[https://gbdev.gg8.se/wiki/ GBDev wiki]
*[https://emudev.de/ Emudev (q00.gb)]
*[https://gekkio.fi/files/gb-docs/gbctr.pdf Game Boy Complete Technical Reference]
*[https://github.com/SingleStepTests Tom Harte's SingleStepTests]
<br>
[[Category:Non CPC Computers]]
[[Category:Electronic Component]]