Changes

GBZ80

2,735 bytes added, 29 April
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.
An oddity is that ADD SP,e takes 4 cycles, while LDHL SP,e takes only 3 cyclesFun 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.
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
|}
 
=== 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]]
13,147
edits