Gameboy: Everything under the hood.
By: Abhinav Srivastava
Tags: Electronics, Gaming, Microprocessor, Computer Architecture

Stronger than you think.

I don’t like consumerism. One of my favorite Scholars, Bertrand Russell, once said

“It is preoccupation with possessions, more than anything else, that prevents us from living freely and nobly.”

But you can bet I have a soft spot in my heart for Nintendo products. Pokemon on Game Boy Advance was one the only games I have ever truly enjoyed before being dragged by the dark, drab realities of life. I’d love to have a shelf with Pokemon merch, but I digress.

Now that we are done with that segment, let’s get started by looking at the beautiful, beautiful Game Boy Classic!

The Game Boy is as old as me, and it has more processing power than me. It has an 8-bit processor called the SHARP LR35902, which is a “hybrid” between Intel 8080 and Zilog Z80. Z80 is considered an enhancement of the 8080. Z80 had an enhanced instruction set that had single-bit addressing, shifts/rotates on memory and registers other than accumulator. You had program looping, program counter relative jumps, block I/O and byte search instructions. Z80 also had new IX and IY index registers and a better interrupt system. SHARP LR3590 had a little bit of both.

8080’s registers are used (Single Register file)

Z80’s Coding Syntax and Instruction Extender was used.

However, neither IX, IY nor 8080’s I/O scheme were used. SHARP used a completely memory scheme, so these were not needed.

Like 8080, a 8-bit data bus and 16-bit address were used, where a memory of 64 KB of Memory could be addressed.

The memory map had: Cartridge ROM, WRAM, Display RAM, I/O and interrupt enabler.

We had a clock speed of about 4.2 MHz, which is achieved by a Crystal Oscillator. All of this worked on 3V DC, 0.6W supply.

(That’s CPU + Power Processing Unit + Audio Processing Unit)

Gameboy’s 8-bit CPU is called DMG CPU, equipped with 6 registers of 16 bit each: AF, BC, DE, HL, SP and PC. Here’s what they mean -

AF: AF are two 8-bit registers, A and F. A is the Accumulator (arithmetic operations usually take place here)

If you dial back to your Microcontrollers class, this is the Von Neumann Architecture and there is the accumulator. F is the Flag Register, it’s a special purpose register where each of the 8-bit have different purposes.

Zero Flag (Z): This bit is set when the result of a math operation is zero or two values match when using the CP (call If Positive) instruction.

Subtract Flag (N): This bit is set if a subtraction was performed in the last math instruction.

Half Carry Flag (H): This bit is set if a carry occurred from the lower nibble in the last math operation.

Carry Flag: This bit is set if a carry occurred from the last math operation or if register A is the smaller value when executing the CP instruction.

BC, HL, DE are General Purpose Registers. They’re used for 16-bit operations such as temporary storage, copy during execution of the program. Mostly memory stuff.

PC is the program counter, which points to the next instruction in the memory. The CPU uses PC to fetch the next operation that needs to be executed.

SP is the Stack Pointer, which points to the current stack position in the memory. This can get a little hairy, grab your closest notebook if it gets overwhelming. With a fair bit of Googling, if you’ve followed the article thus far, I’m sure you know what a Stack is.

The stack in GameBoy usually keeps the variables and return addresses. It is also used to pass arguments to subroutines. So, to push information to the stack you would use PUSH, CALL and RST instructions. POP, RET and RETI are used to take information off the stack. The GameBoy stack pointer (SP) is used to keep track of the top of Stack. Remember, the Stack is a first-in, first-out data structure, so the top of the Stack will be the most recent data.

Now in GameBoy, execution starts at location 0, which is where GameBoy’s boot ROM is located. You’ll find the first instruction for the cartridges at the location 0000000100000000 , and we'll talk more about this in a minute.

A typical way to fetch the instruction from memory would look like this charming little self-explanatory pseudocode.

Now, remember, Z80 and GB’s CPU use syntactically similar languages, so when we look at some real GB codes, don’t be too surprised to discover that Z80 and LR35902 have similar looking codes. For example, the instruction extender is same in both (opcode 0xcb).

An important note on commands

Alright, now that these commands have been fetched, we need to execute these commands. There are 8-bit load commands and 16-bit load commands. They do the work of loading things from place A to place B (eg. loading the content of a register to a stack). Finally, there are 8-bit Arithmetical and Logical Operations (eg. increment a value stored in register). In the DMG CPU, there’s not a lot of 16-bit arithmetical operations to start with, and they just operate on the 16-bit registers. There’s also shifting and rotation (shifting but the bits wrap around the edges) commands (eg. 00010000 -> 00100000 ).

There are a few couple other control operations as well: HALT (Halt until interrupt), NOP (Don’t do anything), Enable/Disable Interrupts. Then you’ve got Jump operations, using which you can jump to any location in the memory.