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]
* CALL nn takes 6 cycles on the GBZ80, but 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.
Flags can differ too: * RLCA, RRCA, RLA, RRA clear ZF in the GBZ80, but not in the Z80* DAA instruction clears HF in the GBZ80, 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. [https://www.chibiakumas.com/z80/Gameboy.php Learn GBZ80 Assembly Programming with ChibiAkumas]
<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:
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| ld r,s || 01rrrsss || 1 || rowspan=1315|- || rowspan=1315|- || rowspan=1315|- || rowspan=1315|- || r := s ||rowspan=1315|8-bit Load
|-
| ld (hl),r || 01110rrr || 2 || (hl) := r
| ld a,(hld) || 00111010 || 2 || a := (hl), hl -= 1
|-
|ld (cnn),a || 11100010 11101010 lolololo hihihihi || 2 || rowspan=4|- || rowspan=4|- || rowspan=4|- || rowspan=4|- || (FF00h + cnn) := a || rowspan=4|8-bit I/O Load
|-
|ld a,(cnn) || 11110010 11111010 lolololo hihihihi || 2 4 || a := (FF00h + cnn)
|-
|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 pp(c),nn a || 00pp0001 lolololo hihihihi 11100010 || 3 2 || rowspan=3|- || rowspan=3|- || rowspan=3|- || rowspan=3|- || pp (FF00h + c) := nn ||rowspan=4|16-bit Loada
|-
| ld a,(nnc),sp || 00001000 11110010 || 5 2 || (nn) a := sp(FF00h + c)
|-
| ld sppp,hl nn || 11111001 00pp0001 lolololo hihihihi || 2 3 || sp rowspan=3|- || rowspan=3|- || rowspan=3|- || rowspan=3|- || pp := hlnn ||rowspan=3|16-bit Load
|-
| ldhl spld (nn),e sp || 11111000 eeeeeeee 00001000 lolololo hihihihi || 3 5 || 0 (nn) := sp|-| 0 ld sp,hl || + 11111001 || + 2 || hl sp := sp + ehl
|-
| pop qq || 11qq0001 || 3 || - || - || - || - || qq := (sp), sp += 2 ||Pop a value from the stack
| dec pp || 00pp1011 || 2 || - || - || - || - || pp -= 1 || Decrement
|-
| add hl,pp || 00pp1001 || 2 || - || 0 || + || + || hl += pp ||rowspan=23|Add
|-
| add sp,e || 11101000 eeeeeeee || 4 || 0 || 0 || + || + || sp += e
|-
| ldhl sp,e || 11111000 eeeeeeee || 3 || 0 || 0 || + || + || hl := sp + e
|}
|-
| 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 || 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
|-
| daa || 00100111 || 1 || + || - || 0 || X || tmp := a,
! Instruction !! Opcode !! Cycles !! Z !! N !! H !! C !! Effect !! Description
|-
| rlca || 00000111 || 1 || rowspan=4|- 0 || rowspan=4|0 || rowspan=4|0 || rowspan=4|X || cf := a.7, a := [a << 1] + cf ||rowspan=4|Fast Rotate
|-
| rrca || 00001111 || 1 || cf := a.0, a := [a >> 1] + [cf << 7]
| 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)]
|}
| ret cc || 110cc000 || 5/2 || if cc then pc := (sp), sp += 2
|-
| reti || 11011001 || 4 || pc := (sp), sp += 2 , ime := 1 || Return from Interrupt
|}
| di || 11110011 || 1 || - || - || - || - || ime := 0 || Disable Interrupts
|-
| ei || 11111011 || 1 || - || - || - || - || ime := 1 after the next instruction || 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
| 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
== 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 has . The Z80 does not. [https://rgbds.gbdev.io/docs/master/gbz80.7#RETI Source]* STOP is normally a 12-byte instruction delay. It where the second byte is necessary for doing EIignored. [https:/RETI without any danger of nested interrupt routines/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>