Sprint: Game Boy DMG Assembly Mastery - Real World Projects

Goal: Build deep, first-principles mastery of the original Game Boy (DMG-01) hardware and its SM83/LR35902 assembly by constructing a full game toolchain, graphics/audio/input subsystems, and production-ready game loops. You will internalize the DMG memory map, CPU timing, PPU constraints, and cartridge banking models to ship accurate, performant games and safe ROM modifications. By the end, you will be able to build original DMG games from scratch and create clean, legal ROM patches for games you own. You will also develop a disciplined hardware-first debugging workflow that mirrors professional retro development practices.

Introduction

  • What is Game Boy DMG assembly? It is programming the original 1989 Game Boy (DMG-01) directly in its native instruction set (Sharp SM83/LR35902), talking to memory-mapped I/O, and respecting precise hardware timing, memory banking, and video/audio constraints.
  • Core hardware facts you will design around: ~4.19 MHz CPU clock, 160x144 LCD, 4 grayscale shades, 8 KB VRAM, 8 KB work RAM, and a sprite system capped at 40 sprites total with 10 per scanline.
  • What problem does it solve today? It lets you create ultra-efficient, low-level games that run on original hardware, gives you deep insight into embedded systems, and teaches you how to reason about performance and correctness with extremely tight constraints.
  • What will you build across the projects? A complete DMG game stack: boot/header correctness, tile/sprite pipeline, input system, audio driver, banked content system, save RAM, debug tooling, and two full games. You will also build a lawful ROM modification pipeline that outputs patch files instead of ROMs.
  • In scope vs out of scope: DMG (monochrome) hardware only, no Color-only features (CGB). Emulation, reverse engineering, and patching for owned ROMs is in scope. Piracy, distributing ROMs, or using proprietary assets is out of scope.

Big picture view (DMG game as a set of cooperating subsystems):

+------------------------+        +------------------------+
|        Cartridge       |        |        DMG-01           |
|  ROM + (MBC) + RAM     |<------>| CPU (SM83) + Bus        |
+------------------------+        |  - Memory Map          |
        |                         |  - Interrupts          |
        |                         |  - Timers              |
        |                         |  - PPU (LCD)           |
        |                         |  - APU (Sound)         |
        |                         +------------------------+
        |                                      |
        v                                      v
+------------------------+        +------------------------+
|     Toolchain/Build    |        |  Output & Validation   |
|  Assembler + Linker    |        |  - Emulator/Hardware   |
|  ROM Header + Checks   |        |  - Visual/Audio Check  |
+------------------------+        |  - Patch Files         |
                                  +------------------------+

How to Use This Guide

  • Read the Theory Primer first; it is the mental map for the rest of the projects.
  • Pick a learning path that matches your goal: game development, ROM hacking, or low-level mastery.
  • After each project, validate against the Definition of Done and compare behavior in two emulators.

Prerequisites & Background Knowledge

Essential Prerequisites (Must Have)

  • Comfortable with low-level programming concepts (registers, memory, pointers, stacks)
  • Basic understanding of binary/hexadecimal and bitwise operations
  • Familiarity with build tooling (CLI, make-like workflows)
  • Recommended Reading: “The Art of Assembly Language” by Randall Hyde - Ch. 1-3

Helpful But Not Required

  • Familiarity with C and memory layout (learn during Projects 5-8)
  • Basic graphics concepts (tiles, sprites, palettes)

Self-Assessment Questions

  1. Can you explain how a stack grows and how return addresses work?
  2. Can you interpret a memory map and locate I/O registers by address?
  3. Do you understand the difference between polling and interrupts?

Development Environment Setup Required Tools:

  • RGBDS (assembler/linker) - current stable release
  • A DMG-accurate emulator (BGB or SameBoy)
  • GBDev Pan Docs (hardware reference)
  • A hex editor (for ROM inspection)

Recommended Tools:

  • A disassembler or analysis tool for ROM hacking (for later projects)
  • A graphics tile editor that supports 2bpp Game Boy tiles
  • Mooneye GB test suite ROMs (accuracy and regression testing)

Testing Your Setup: $ rgbasm -V RGBDS version information…

$ rgbfix -V RGBDS version information…

Launch a Mooneye GB test ROM in your emulator:

  • The test output should show PASS for timing/interrupt sanity checks.

Time Investment

  • Simple projects: 4-8 hours each
  • Moderate projects: 10-20 hours each
  • Complex projects: 20-40 hours each
  • Total sprint: 4-6 months

Important Reality Check This is not a “quick” skill. DMG assembly is unforgiving: every frame and byte matters. Expect to debug memory maps, timing edge-cases, and hardware quirks. The reward is deep mastery of hardware-first programming.

Big Picture / Mental Model

A DMG game is a tight real-time loop that feeds three constrained devices: the CPU, the PPU (graphics), and the APU (sound). The central job is to update memory at the right time (VBlank/HBlank) and not exceed the tight per-frame budget.

            +------------------- Frame (59.7 Hz) -------------------+
            |                                                       |
            v                                                       |
+------------------+     +------------------+     +-----------------+
| Read Input       | --> | Update Game      | --> | Render/Audio     |
| (Joypad)         |     | State            |     | (VBlank/HBlank)  |
+------------------+     +------------------+     +-----------------+
            ^                                                       |
            |                                                       |
            +----------------- Interrupts & Timers -----------------+

Theory Primer

Chapter 1: DMG Hardware Overview and Memory Map

Fundamentals The DMG is a memory-mapped system. The CPU sees ROM, RAM, VRAM, OAM, and I/O registers as address ranges on a 16-bit bus. Understanding the memory map is foundational: ROM (0000-7FFF) provides program and data, VRAM (8000-9FFF) holds tile/sprite data, and I/O registers (FF00-FF7F) control the PPU, APU, timers, and input. The boot sequence and cartridge header determine how the system starts and which memory bank controller (MBC) you can use. In DMG development, “where” is as important as “what”; a correct value written to the wrong address is as bad as incorrect logic. Mastery here prevents silent failures and makes debugging deterministic.

Deep Dive The DMG memory map divides the 64KB address space into regions with strict roles. Two ROM banks occupy 0000-3FFF (fixed) and 4000-7FFF (switchable). This is how large games exceed 32KB: an MBC remaps the upper ROM window, letting you page in different banks. VRAM (8000-9FFF) is not general RAM; it is interpreted by the PPU as tiles and tile maps. External RAM (A000-BFFF) is optional and backed by battery for save files. Internal work RAM lives at C000-DFFF; an echo region E000-FDFF mirrors it but is prohibited for use.

OAM (FE00-FE9F) holds sprite attributes. A small HRAM (FF80-FFFE) is fast scratch space near I/O. The interrupt enable register is at FFFF. The I/O range is dense: FF00 for joypad, FF04-FF07 for timers, FF40-FF4B for LCD control and scrolling, FF10-FF26 for audio, and FF46 for OAM DMA. Understanding these ranges is the shortest path to doing meaningful work on DMG.

The cartridge header (0100-014F) includes the Nintendo logo bytes, title, cartridge type, ROM/RAM size, and checksums. A real DMG boots only if the logo is correct; this is why correct header construction matters for real hardware. The boot ROM initializes CPU registers and then disables itself by writing to the boot mapping register. Emulators often simulate this, but correct behavior is still important if you plan to run on hardware.

Because the DMG is monochrome, many CGB-specific registers are irrelevant and should be ignored. Keep your focus on DMG registers, DMG-compatible cartridge types (e.g., MBC1), and DMG timing. The memory map is the mental map of all projects: if you can visualize it, you can design your system architecture, decide where data lives, and implement predictable update pipelines.

Definitions and key terms

  • Memory-mapped I/O: Hardware registers appear as memory addresses.
  • VRAM: Video RAM, used for tiles and tile maps.
  • OAM: Object Attribute Memory for sprite metadata.
  • MBC: Memory Bank Controller enabling banked ROM/RAM.
  • HRAM: High RAM near the I/O range, often used for fast variables.

Mental model diagram

0000-3FFF  [ROM Bank 0]  Fixed program/data
4000-7FFF  [ROM Bank N]  Switchable via MBC
8000-9FFF  [VRAM]        Tile data + tile maps
A000-BFFF  [Ext RAM]     Save data (if present)
C000-DFFF  [WRAM]        Working RAM
E000-FDFF  [Echo]        Mirror of WRAM (avoid)
FE00-FE9F  [OAM]         Sprites
FF00-FF7F  [I/O]         PPU/APU/Input/Timers
FF80-FFFE  [HRAM]        Fast RAM
FFFF-FFFF  [IE]          Interrupt Enable

How it works (step-by-step)

  1. CPU fetches instructions from ROM (usually fixed bank).
  2. Code reads/writes I/O registers to control PPU, timers, and input.
  3. During VBlank/HBlank, code writes to VRAM/OAM safely.
  4. If the game uses more than 32KB of ROM, MBC swaps banks into 4000-7FFF.
  5. Save data is written to external RAM if cartridge supports it.
  6. Interrupts signal VBlank, LCD status, timers, serial, and joypad events.

Minimal concrete example (pseudocode)

if address in 0xFF00..0xFF7F:
    write_to_hardware_register(address, value)
else if address in 0x8000..0x9FFF and lcd_is_on:
    write_tile_or_map_data(value)

Common misconceptions

  • “VRAM is just RAM” (it is interpreted by the PPU and has access rules).
  • “Echo RAM is safe” (official docs say not to use it).
  • “All cartridges are the same” (MBCs change memory behavior).

Check-your-understanding questions

  1. Why can a 32KB ROM bank be “fixed” and another be switchable?
  2. What makes VRAM different from WRAM?
  3. Why is OAM a special region?

Check-your-understanding answers

  1. The fixed bank holds interrupt vectors and core code; switching is only allowed in the upper ROM window for stability.
  2. VRAM is interpreted by the PPU and has access timing restrictions.
  3. OAM is the sprite attribute table with hardware-defined layout and DMA rules.

Real-world applications

  • Correctly structuring game code and assets across ROM banks
  • Designing a memory layout that supports level streaming
  • Creating save systems using external RAM

Where you will apply it Projects 1-6, 9-13, 16-20

References

  • Pan Docs: Memory Map, I/O Registers, Cartridge Header
  • Pan Docs: Power-Up Sequence

Key insight If you can see the memory map in your head, you can reason about every bug.

Summary The DMG is defined by its address space. ROM, VRAM, OAM, I/O, and RAM are all visible to the CPU, but each has different rules. Most “mystery” bugs are misunderstandings of these rules.

Homework/exercises to practice the concept

  • Draw the memory map from memory and label each region with its purpose.
  • Explain where tile data lives vs where tile maps live.
  • Explain why the interrupt enable register is at FFFF.

Solutions to the homework/exercises

  • Compare your drawing to the canonical map and ensure all address ranges align.
  • Tile data lives in VRAM; tile maps are also in VRAM but at different offsets.
  • IE at FFFF is a fixed, always-visible register for enabling interrupts.

Chapter 2: CPU Core, Registers, and Instruction Timing (SM83/LR35902)

Fundamentals The DMG CPU is a Sharp SM83 (LR35902-class) core, often described as a Z80-like but not Z80-compatible. It has 8-bit registers that can be paired into 16-bit registers, a flags register for arithmetic results, and a stack pointer for subroutines and interrupts. Instruction timing is critical because the PPU and timers tick at fixed rates. You must understand how instructions consume cycles, how interrupts preempt execution, and how the stack is used for returning from interrupts. This is where “performance” and “correctness” are the same thing.

Deep Dive The SM83 is a small, deterministic CPU. It has registers A, F, B, C, D, E, H, L, along with paired 16-bit registers AF, BC, DE, HL. The program counter (PC) points to the next instruction, and the stack pointer (SP) points to memory where return addresses and saved state are stored. On interrupts, the CPU pushes the current PC to the stack and jumps to a fixed vector. This is why stack discipline is non-negotiable.

Unlike higher-level systems, the DMG has no memory protection, no OS, and no scheduler. Your code is the entire system. This is why instruction timing matters: for example, writing to VRAM outside safe windows can silently fail or cause visual corruption. Timing is controlled through careful scheduling: do large VRAM transfers during VBlank, do small safe updates during HBlank, and keep per-frame CPU usage within budget.

The SM83 instruction set includes load/store operations, arithmetic and logic (add, subtract, compare, bit ops), shifts/rotates, jumps/calls/returns, and special instructions for interrupts and HALT. There is also a prefixed instruction set for bit operations. Understanding cycles per instruction, the effect on flags, and the size of instructions is crucial for predicting timing and memory usage.

A stable DMG game loop uses a predictable cadence: wait for VBlank interrupt, update state, write graphics/audio updates, and return to a low-power or idle state if needed. If you ignore timing, you will see tearing, flicker, or inconsistent input. The CPU is simple, but its simplicity makes it brutally honest: you either keep the system on time, or you do not.

Definitions and key terms

  • Registers: Small CPU storage locations used for arithmetic and addressing.
  • Flags: Bits indicating results (zero, carry, half-carry, subtract).
  • PC/SP: Program counter and stack pointer.
  • Cycles: The clock units a CPU instruction consumes.
  • Interrupt vector: Fixed address jumped to on an interrupt.

Mental model diagram

         +-----------------+
         |   Instruction   |
         |   Fetch/Decode  |
         +--------+--------+
                  |
          +-------v-------+
          |   Registers   |
          | A F B C D E   |
          | H L  SP  PC   |
          +-------+-------+
                  |
          +-------v-------+
          |  ALU + Flags  |
          +-------+-------+
                  |
          +-------v-------+
          | Memory / I/O  |
          +---------------+

How it works (step-by-step)

  1. Fetch instruction at PC from ROM.
  2. Decode instruction and determine required cycles.
  3. Read/write registers and memory as needed.
  4. Update flags based on result.
  5. Increment PC to next instruction.
  6. If an interrupt is pending and enabled, push PC and jump to vector.

Minimal concrete example (pseudocode)

A = A + value
if A == 0: set_zero_flag()
if carry_out: set_carry_flag()
PC = PC + instruction_length

Common misconceptions

  • “Z80 code runs on DMG” (it is similar but not compatible).
  • “Timing is only for graphics” (audio and input are also time-sensitive).
  • “Interrupts are optional” (reliable games almost always use them).

Check-your-understanding questions

  1. What happens to the PC and SP when an interrupt fires?
  2. Why do you need to budget CPU cycles per frame?
  3. Why is the flags register essential for conditional logic?

Check-your-understanding answers

  1. The PC is pushed to the stack, then the CPU jumps to the interrupt vector; SP is decremented accordingly.
  2. The PPU and APU advance regardless of your code; exceeding the budget causes missed safe windows.
  3. Flags encode results of arithmetic, enabling efficient branching without extra comparisons.

Real-world applications

  • Smooth frame-locked game loops
  • Deterministic collision detection and physics
  • Precise timing for sound and animation

Where you will apply it Projects 1-5, 7-12, 15-20

References

  • Pan Docs: CPU Comparison with Z80
  • Pan Docs: Interrupts and Instruction Set
  • “The Art of Assembly Language” by Randall Hyde - Ch. 1-6

Key insight On DMG, correctness is timing.

Summary The SM83 is small but powerful. Understanding registers, flags, and cycles gives you total control over the system. The CPU is the conductor; your job is to keep the orchestra in time.

Homework/exercises to practice the concept

  • Sketch a call stack diagram for nested subroutines.
  • Describe how an interrupt changes the flow of execution.
  • Estimate how many cycles you can spend per frame if you target 60 fps.

Solutions to the homework/exercises

  • Your diagram should show return addresses stacking with each call.
  • Execution jumps to a fixed vector, then returns to the previous PC.
  • Use the system clock and frame rate to approximate a per-frame cycle budget.

Chapter 3: Cartridge Format and Memory Banking (MBCs)

Fundamentals Most non-trivial Game Boy games exceed 32KB and require memory banking. MBCs allow the CPU to map different ROM or RAM banks into a fixed address window. This lets you keep core logic in a fixed bank while swapping data or code banks in and out. On DMG, MBC1 is common, and its banking modes affect how ROM and external RAM are mapped. Understanding the cartridge header, bank selection rules, and battery-backed RAM is essential for large games and for ROM modification.

Deep Dive The cartridge header defines the cartridge type, ROM size, and RAM size. The console reads these fields to understand what banking hardware exists and how much memory is available. MBC1 supports two modes: ROM banking mode (for larger ROMs) and RAM banking mode (for larger external RAM). In ROM banking mode, you can select a 16KB ROM bank mapped into 4000-7FFF. In RAM banking mode, you can select external RAM banks while limiting ROM banking to a smaller range. This tradeoff shapes how you store assets and game logic.

Banking is not free. Every bank switch is a state change; you must ensure you return to the correct bank when calling code or reading data. A common strategy is to keep all interrupt handlers in bank 0 and build bank-switching macros or routines that preserve the previous bank. You also need to manage persistence: battery-backed RAM must be explicitly enabled and disabled using the MBC control registers, and you must avoid corrupting saves by writing during unstable power.

From a design perspective, banking is an architecture problem. Do you organize assets per level? Do you keep core logic in one bank and only swap data? These decisions influence loading times, memory usage, and the complexity of your code. This is why banking appears both in original game development and in ROM hacking: if you know how banks are used, you can find and modify data or code safely.

Definitions and key terms

  • Cartridge header: ROM metadata at 0100-014F.
  • MBC: Memory Bank Controller.
  • Bank switch: Changing which ROM/RAM bank maps into a window.
  • Battery-backed RAM: External RAM that persists across power cycles.

Mental model diagram

ROM Bank 0 (fixed)  -> 0000-3FFF
ROM Bank N (switch) -> 4000-7FFF  <--- MBC selects N
Ext RAM Bank R      -> A000-BFFF  <--- MBC selects R

How it works (step-by-step)

  1. Read cartridge header to know type and size.
  2. Initialize MBC mode (ROM or RAM banking).
  3. Select ROM bank for code/data window.
  4. Enable external RAM when saving/loading.
  5. Switch banks carefully around calls and data reads.

Minimal concrete example (pseudocode)

select_rom_bank(bank_id)
call_function_in_swapped_bank()
restore_previous_bank()

Common misconceptions

  • “Bank switches are free” (they change global state and can break code flow).
  • “All MBCs behave the same” (MBC1 has unique modes and quirks).

Check-your-understanding questions

  1. Why keep interrupt handlers in bank 0?
  2. What is the risk of forgetting to restore a bank after a call?
  3. How does RAM banking change your save strategy?

Check-your-understanding answers

  1. Interrupts can fire at any time; bank 0 is always visible.
  2. You may execute the wrong code or read wrong data, causing crashes or corruption.
  3. Saves must select the correct RAM bank before read/write.

Real-world applications

  • Large games with multiple levels and large assets
  • Save systems with multiple slots
  • ROM mods that add new data banks

Where you will apply it Projects 6, 10, 11, 16-20

References

  • Pan Docs: The Cartridge Header
  • Pan Docs: MBC1

Key insight Bank switching is a controlled illusion: you see a different 16KB window, but the CPU never moves.

Summary MBCs turn a tiny address space into a large game world. If you manage banks carefully, you can build complex games; if you do not, you will crash in ways that are hard to debug.

Homework/exercises to practice the concept

  • Sketch a bank plan for a 256KB game with 4 levels.
  • List which data belongs in fixed bank 0.

Solutions to the homework/exercises

  • Ensure each level’s graphics and map data are grouped in the same bank.
  • Keep interrupt handlers, bank switching routines, and core loop in bank 0.

Chapter 4: PPU Rendering, Tiles, Sprites, and LCD Control

Fundamentals The DMG PPU renders a 160x144 pixel display using 8x8 tiles and sprites. Backgrounds are built from tile maps, and sprites are defined by OAM entries. The LCD controller is configured via registers, especially LCDC and STAT, which control display enable, tile data selection, and sprite sizes. Rendering is time-critical: VRAM and OAM access are restricted during certain LCD modes, and incorrect updates can cause visual artifacts. Understanding the rendering pipeline is essential for every visible game system.

Deep Dive The DMG PPU is a fixed-function pipeline. It fetches background tiles from VRAM, overlays sprites from OAM, and outputs 4-shade grayscale pixels. Backgrounds are assembled using tile maps (32x32 tiles) that index into tile data blocks. Sprites are limited to 40 total, with a maximum of 10 per scanline. The LCDC register selects tile data regions, background/window maps, and sprite size (8x8 or 8x16). The STAT register signals LCD modes and can trigger interrupts for precise timing.

Rendering happens line by line. Each scanline progresses through modes: OAM scan, pixel transfer, HBlank, and then VBlank at the end of the frame. In DMG, safe VRAM/OAM access depends on the mode; typically, large updates are done during VBlank. Understanding these modes is critical for flicker-free updates.

Graphics data is stored in a 2bpp format where each tile row is two bytes representing bitplanes. This layout affects how you design art pipelines and tile editors. Palettes map the four color indices to actual grayscale shades. Because DMG has only one background palette and two sprite palettes, you must design art with these constraints in mind.

The PPU is unforgiving: if you update tile maps or OAM at the wrong time, you will see sprites disappear, lines flicker, or data corruption. The safest strategy is to build a rendering pipeline that schedules all VRAM and OAM writes during VBlank or small, controlled HBlank windows. This is the core of DMG graphics architecture.

Definitions and key terms

  • LCDC: LCD control register.
  • STAT: LCD status register; tracks modes and triggers interrupts.
  • Tile map: 32x32 grid of tile indices.
  • 2bpp: Two-bit-per-pixel tile encoding (4 colors).
  • Sprite: Movable 8x8 or 8x16 graphic.

Mental model diagram

Tile Data (VRAM) ---> Tile Map (VRAM) ---> Background Pixels
          \                               /
           \--> OAM (Sprites) -----------/
                    |
                 LCDC/STAT

How it works (step-by-step)

  1. LCDC enables display and selects tile data/map regions.
  2. For each scanline, PPU fetches background tiles.
  3. PPU overlays up to 10 sprites per scanline from OAM.
  4. Pixel data is mapped through palettes to 4 shades.
  5. STAT updates mode flags and can trigger interrupts.

Minimal concrete example (pseudocode)

if lcd_mode == VBLANK:
    update_tile_map()
    update_sprite_oam()

Common misconceptions

  • “You can update VRAM at any time” (you cannot).
  • “Sprites are unlimited” (40 total, 10 per line).
  • “Tile maps are pixel maps” (they are indices into tile data).

Check-your-understanding questions

  1. What role does LCDC play in selecting tile data?
  2. Why is the sprite-per-line limit important?
  3. Why do updates go in VBlank?

Check-your-understanding answers

  1. LCDC chooses which tile data region the PPU interprets.
  2. It enforces hardware limits that affect flicker and sprite priority.
  3. VRAM/OAM access is safe and stable during VBlank.

Real-world applications

  • Smooth scrolling backgrounds
  • Stable sprite animation
  • HUD windows and overlays

Where you will apply it Projects 2-9, 12-18, 20

References

  • Pan Docs: LCDC, OAM, Rendering, Palettes

Key insight Your art pipeline is only as good as your timing pipeline.

Summary The PPU turns tile data and sprite metadata into pixels, but it enforces strict timing. Once you respect the pipeline, you gain reliable control over every pixel.

Homework/exercises to practice the concept

  • Draw the LCD modes across a frame and mark safe update windows.
  • Explain how a 2bpp tile encodes four colors.

Solutions to the homework/exercises

  • Mark OAM scan, pixel transfer, HBlank, and VBlank with appropriate access rules.
  • Each pixel uses two bits from two bitplanes; four combinations map to four shades.

Chapter 5: VRAM/OAM Access Rules and DMA

Fundamentals The DMG restricts access to VRAM and OAM during rendering. Attempting to write to these regions outside safe windows can fail or corrupt data. The system provides a hardware DMA transfer mechanism to copy sprite data into OAM quickly. Understanding these access rules and DMA behavior is essential for reliable sprite updates and clean graphics.

Deep Dive The PPU cycles through distinct modes. During OAM scan and pixel transfer, OAM and VRAM are effectively locked. HBlank is a short window after a scanline where VRAM access is usually safe, but it is limited in time. VBlank is the longest safe window, occurring after the last visible scanline.

OAM DMA is a hardware feature that copies 160 bytes into OAM from a source aligned on a 256-byte page boundary. This is the canonical way to update all sprite attributes in one burst. However, DMA stalls the CPU for the duration of the transfer, so you must schedule it carefully in your frame budget. A common design is to build a shadow OAM table in WRAM, then trigger DMA during VBlank to copy it to OAM.

If you ignore these rules, you will encounter OAM corruption and flicker that only appear on real hardware. Many emulators are forgiving; this is why you must validate with DMG-accurate emulators and, if possible, real hardware. Clean DMA usage is the difference between “it runs” and “it is correct.”

Definitions and key terms

  • HBlank: Horizontal blanking period after each scanline.
  • VBlank: Vertical blanking period after the last visible line.
  • DMA: Direct memory access transfer to OAM.
  • Shadow OAM: A copy of sprite data in RAM, used for safe updates.

Mental model diagram

Frame:
[Scanline 0..143] -> OAM Scan -> Pixel Transfer -> HBlank
[Scanline 144..153] -> VBlank (safe for bulk updates)

OAM DMA:
Shadow OAM (WRAM) --DMA--> OAM (FE00-FE9F)

How it works (step-by-step)

  1. Build sprite list in WRAM (shadow OAM).
  2. Wait for VBlank (interrupt or polling).
  3. Trigger OAM DMA to copy 160 bytes.
  4. Resume CPU work after DMA completes.

Minimal concrete example (pseudocode)

if in_vblank():
    copy_shadow_oam_to_oam()

Common misconceptions

  • “DMA is optional” (for stable sprite updates, DMA is essential).
  • “HBlank is always enough” (not for large transfers).

Check-your-understanding questions

  1. Why is DMA aligned to 256-byte boundaries?
  2. Why does DMA stall the CPU, and why is that acceptable?
  3. Why do we keep a shadow OAM?

Check-your-understanding answers

  1. The DMA hardware uses the high byte of the source address as a page.
  2. Hardware takes control of the bus to move data quickly; schedule during VBlank.
  3. It lets you update sprites freely in WRAM without risking OAM access rules.

Real-world applications

  • Stable sprite animation systems
  • Large enemy crowds without flicker
  • Clean HUD sprite updates

Where you will apply it Projects 5-9, 12-18, 20

References

  • Pan Docs: OAM DMA Transfer
  • Pan Docs: Accessing VRAM and OAM

Key insight DMA is not an optimization; it is the correct way to update sprites.

Summary VRAM/OAM access rules are non-negotiable. DMA gives you a safe, deterministic way to update sprites and keep the display stable.

Homework/exercises to practice the concept

  • Sketch a frame timeline and mark DMA placement.
  • Explain why a partial OAM update can cause flicker.

Solutions to the homework/exercises

  • DMA should occur during VBlank for a full 160-byte update.
  • Partial writes can change sprites mid-scanline, creating visible artifacts.

Chapter 6: Interrupts, Timers, and Input as a Real-Time System

Fundamentals The DMG uses interrupts to signal time-critical events like VBlank and timers. The joypad register is read through I/O, but it is most reliable when sampled consistently, often in VBlank. Timers provide predictable ticks for game logic, sound, and animation. Together, these systems form the real-time backbone of a DMG game.

Deep Dive There are five main interrupt sources: VBlank, LCD STAT, Timer, Serial, and Joypad. Each has a fixed vector. The interrupt enable (IE) register controls which interrupts can fire, and the interrupt flag (IF) indicates which interrupts are pending. A common architecture uses VBlank as the frame sync, while the timer interrupt drives smaller periodic tasks such as animation or music updates.

The DMG timer is controlled by the divider (DIV) and timer counter (TIMA), modulo (TMA), and control (TAC) registers. The DIV register increments continuously, and TIMA increments based on a selected divider. When TIMA overflows, it reloads from TMA and triggers a timer interrupt. This allows you to build a stable tick rate independent of game logic.

Input is read via the joypad register, which multiplexes button groups (direction vs action). You must select which group to read, then interpret active-low bits. Debouncing and edge detection (pressed vs held) should be handled in software by comparing current and previous states. Because input is time-sensitive, reading it at consistent points (like VBlank) yields the most stable behavior.

This is the heart of a DMG game loop. If you do not understand interrupts and timers, you will have unpredictable input, unstable animations, and jittery music. If you master them, you can build deterministic systems that feel smooth and professional.

Definitions and key terms

  • IE/IF: Interrupt enable and interrupt flag registers.
  • VBlank: Vertical blank interrupt for frame sync.
  • TIMA/TMA/TAC: Timer counter, modulo, and control registers.
  • Active-low: A bit value of 0 means “pressed” or “active”.

Mental model diagram

[DIV] --> [TIMA] --overflow--> [Timer Interrupt]

[VBlank Interrupt] --> Frame Update
[Joypad Read] --> Input State (current/previous)

How it works (step-by-step)

  1. Enable IE bits for VBlank and Timer.
  2. Configure TAC for desired timer frequency.
  3. On VBlank, read input and update core game state.
  4. On Timer interrupt, update animations/music timing.
  5. Use IF to detect and clear pending interrupts.

Minimal concrete example (pseudocode)

on_vblank():
    current = read_joypad()
    pressed = current & ~previous
    previous = current

Common misconceptions

  • “Polling is enough” (interrupts give deterministic timing).
  • “Timer is optional” (fine-grained timing improves responsiveness).

Check-your-understanding questions

  1. Why does TIMA reload from TMA on overflow?
  2. Why is active-low input easy to misread?
  3. Why is VBlank a good time to read input?

Check-your-understanding answers

  1. It creates a periodic timer interrupt at a stable interval.
  2. A 0 bit means pressed; it is inverted from typical logic.
  3. It is a consistent, frame-aligned time slice.

Real-world applications

  • Stable game loops and animation pacing
  • Responsive input systems
  • Music tick scheduling

Where you will apply it Projects 2-8, 10-12, 15-20

References

  • Pan Docs: Interrupts
  • Pan Docs: Timer and Divider Registers
  • Pan Docs: Joypad Input

Key insight Interrupts are the heartbeat of the DMG.

Summary Timers and interrupts turn raw hardware into a reliable cadence. Input, animation, and game logic become predictable only when you harness these signals.

Homework/exercises to practice the concept

  • Diagram the flow of a VBlank-driven game loop.
  • Explain how you would detect a “just pressed” event.

Solutions to the homework/exercises

  • VBlank interrupt triggers input read, state update, and render updates.
  • Compare current and previous input states; pressed = current AND NOT previous.

Chapter 7: Audio System (APU) and Music Driver Design

Fundamentals The DMG audio system (APU) provides four channels: two pulse channels, one wave channel, and one noise channel. Each channel has registers to control frequency, envelope, and length. The sound system is powerful but register-heavy; it demands careful state management and a timing-driven update loop. Building audio on DMG is a core skill for real games.

Deep Dive The APU is configured entirely through I/O registers. Each channel has a control block and global registers set master volume and panning. Channel 1 and 2 generate pulse waves; channel 1 also supports frequency sweep. Channel 3 uses a programmable wave table, and channel 4 generates noise using a linear feedback shift register. The APU is sensitive to update timing; many registers only take effect when channels are triggered.

A minimal music driver structures music as patterns or events scheduled on a timer tick. Each tick, you update channel registers based on a sequence (notes, durations, volumes). Sound effects can be treated as higher-priority overrides. Managing channel allocation (which channel plays music vs SFX) is a key design challenge. Because the APU is a finite resource, you must design for constraints: if all channels are busy, your SFX should either override a less important channel or be dropped.

Audio is also a performance and correctness issue. If your driver updates registers inconsistently, notes will glitch. If you write to registers while the APU is off, it may ignore updates. If you manage the envelope incorrectly, channels can be silent. This is why building a clean driver with consistent timing is essential.

Definitions and key terms

  • APU: Audio processing unit.
  • Envelope: Automatic volume change over time.
  • Wave table: Custom waveform data for channel 3.
  • Noise channel: Pseudo-random noise generation for percussion.

Mental model diagram

Tick Timer --> Music Driver --> Channel Registers
                |                    |
                +-> SFX Overrides ---+

How it works (step-by-step)

  1. Initialize global audio registers (master on, volume, panning).
  2. Load wave table data for channel 3 if used.
  3. On each music tick, update channel registers to new notes.
  4. Trigger channels as needed to start notes.
  5. Mix SFX by temporarily overriding channels.

Minimal concrete example (pseudocode)

if music_tick:
    note = pattern[next_index]
    set_channel_frequency(note)
    trigger_channel()

Common misconceptions

  • “Audio is set-and-forget” (it needs regular updates).
  • “All channels are equal” (they have different capabilities).

Check-your-understanding questions

  1. Why is a timer tick useful for audio updates?
  2. What happens if you trigger a channel without enabling its DAC?
  3. Why does channel 3 require wave table data?

Check-your-understanding answers

  1. It provides a regular schedule for note changes.
  2. The channel will not output sound.
  3. Channel 3 plays custom waveforms stored in wave RAM.

Real-world applications

  • Music engines for retro games
  • Sound effect systems
  • Audio-driven gameplay timing

Where you will apply it Projects 8, 9, 15-20

References

  • Pan Docs: Audio Registers
  • Game Boy hardware audio resources

Key insight Audio is stateful and time-driven, not a one-time configuration.

Summary The APU is a compact synthesizer. With discipline and timing, you can build rich audio despite extreme constraints.

Homework/exercises to practice the concept

  • Design a channel allocation plan for music + SFX.
  • Sketch how a wave table is used for a melody line.

Solutions to the homework/exercises

  • Reserve channels 1/2 for melody, 3 for bass, 4 for noise/SFX (or similar).
  • The wave table holds a 32-sample waveform that is pitched by frequency registers.

Chapter 8: Toolchain, Debugging, and ROM Modification Workflow

Fundamentals DMG development depends on a reliable toolchain: assembler, linker, ROM fixer, and emulator. You must validate ROM headers and checksums, and you must debug at the memory/register level. ROM modification (romhacking) is a disciplined process: inspect, disassemble, annotate, modify, and output a patch rather than a ROM file. This keeps the work legal and shareable.

Deep Dive RGBDS is the most common open-source toolchain for DMG development. It assembles source into object files, links them into a ROM, and can fix headers and checksums. Your build pipeline should include validation steps that verify header correctness and ensure predictable ROM sizes. Emulators like BGB or SameBoy provide debugging features such as breakpoints, memory viewers, and PPU viewers. These tools allow you to inspect VRAM, OAM, and I/O registers to verify correctness.

ROM modification is best approached like software archaeology. You start by identifying the ROM header and banking scheme, then extract assets (tiles, maps, text) to understand data layouts. You use a disassembler to convert code into labeled assembly, then add annotations until you can navigate the program. Modifications should be minimal and reversible; you record the original bytes, modify your targets, and generate a patch file that applies cleanly to the original ROM. For robust distribution, prefer well-defined delta formats (e.g., VCDIFF/xdelta for larger changes) and include a base-ROM hash check so the patch applies only to the correct cartridge image. This preserves legality: you do not distribute copyrighted ROMs, only the difference.

A professional ROM hacking workflow also uses version control, deterministic patch generation, and validation in multiple emulators. Always validate that the modified ROM still passes checksum expectations (or update them) and that it behaves correctly across different emulators. Finally, document your changes so future you (or collaborators) can audit and reproduce the work.

Definitions and key terms

  • Assembler/Linker: Tools that build a ROM from source.
  • ROM header: Metadata required for boot and identification.
  • Disassembly: Converting machine code to readable assembly.
  • Patch file: A difference file (e.g., IPS/BPS/VCDIFF) applied to a base ROM.

Mental model diagram

Source Assets -> Assembler/Linker -> ROM -> Emulator/Hardware
                     |
                     +-> Header Fix/Checksum

ROM -> Disassemble -> Annotate -> Modify -> Patch File

How it works (step-by-step)

  1. Assemble and link into a ROM.
  2. Fix header/checksums and verify boot.
  3. Debug using memory and register inspection.
  4. For mods: disassemble, annotate, and make minimal changes.
  5. Produce patch file and validate on clean ROM.

Minimal concrete example (pseudocode)

build_rom()
verify_header()
run_in_emulator()
if modifying:
    produce_patch(original, modified)

Common misconceptions

  • “Emulator-only testing is enough” (timing bugs appear on real hardware).
  • “Sharing ROMs is okay if you own them” (share patches instead).

Check-your-understanding questions

  1. Why is header validation required for hardware?
  2. Why use patches instead of distributing ROMs?
  3. Why is disassembly annotation important?

Check-your-understanding answers

  1. Hardware checks the Nintendo logo and header fields before boot.
  2. Patches avoid distributing copyrighted content.
  3. Labels and annotations turn opaque code into navigable structure.

Real-world applications

  • Building a professional DMG build pipeline
  • Creating fan translations and fixes responsibly
  • Debugging performance and timing issues

Where you will apply it Projects 1, 12-14, 18-20

References

  • RGBDS documentation
  • Pan Docs: Cartridge Header
  • VCDIFF (RFC 3284) and xdelta documentation

Key insight Tooling discipline is what makes low-level work repeatable.

Summary A clean toolchain and a legal patch workflow let you build and modify DMG games with confidence. This is how real retro dev and ROM hacking is done.

Homework/exercises to practice the concept

  • Write a build checklist for a DMG project.
  • List the steps required to create a legal ROM patch.

Solutions to the homework/exercises

  • Checklist includes assemble, link, header fix, checksum, emulator validation.
  • Steps include disassemble, modify, generate patch, test on clean ROM.

Glossary

  • DMG-01: The original Game Boy model.
  • SM83/LR35902: The CPU core used in DMG.
  • PPU: Pixel processing unit (graphics).
  • APU: Audio processing unit (sound).
  • VBlank/HBlank: Safe windows for graphics updates.
  • LCDC/STAT: LCD control and status registers.
  • MBC: Memory bank controller for ROM/RAM banking.
  • OAM: Sprite attribute memory.
  • ROM patch: File containing only differences to a ROM.

Why Game Boy DMG Assembly Matters

  • Modern motivation and real-world use cases: Retro hardware development builds skills that map directly to embedded systems, performance engineering, and reverse engineering. It also enables creation of faithful homebrew games that run on original hardware.
  • Real-world statistics and impact: The DMG launched in Japan on April 21, 1989, and the combined Game Boy + Game Boy Color lifetime sales reached about 118.69 million units worldwide by discontinuation in 2003, making it one of the most influential gaming platforms ever. Its 160x144 display and low-power design set the standard for portable gaming. The continued popularity of DMG hardware and emulation keeps its development ecosystem active.
  • Context and evolution: The DMG’s success demonstrated that careful engineering and battery efficiency could beat raw power. The constraints you learn here are the same constraints faced by early handheld designers.

Old vs new development model:

Modern Engine Workflow            DMG Assembly Workflow
+------------------------+        +------------------------+
| High-level APIs        |        | Memory-mapped I/O       |
| Unlimited memory       |        | 8KB VRAM, 8KB RAM       |
| GPU abstraction        |        | Fixed-function PPU      |
| Debug symbols + logs   |        | Registers + hex dumps   |
+------------------------+        +------------------------+

Concept Summary Table

Concept Cluster What You Need to Internalize
DMG Memory Map Address ranges define behavior; VRAM/OAM/I/O have rules.
CPU Core & Timing Registers, flags, interrupts, and cycle budgeting.
Cartridge & Banking MBC logic, header fields, and save RAM behavior.
PPU Rendering Tiles, sprites, LCDC/STAT, and rendering timing.
VRAM/OAM Access & DMA Safe windows and DMA-driven sprite updates.
Interrupts/Timers/Input Deterministic frame loops and stable input.
Audio System Channel control, envelopes, and music tick scheduling.
Toolchain & ROM Modding Build pipeline, debugging, disassembly, patches.

Project-to-Concept Map

Project Concepts Applied
Project 1 DMG Memory Map, Toolchain & ROM Modding
Project 2 CPU Core & Timing, Interrupts/Timers/Input
Project 3 PPU Rendering, VRAM/OAM Access & DMA
Project 4 PPU Rendering, Interrupts/Timers/Input
Project 5 VRAM/OAM Access & DMA, PPU Rendering
Project 6 Cartridge & Banking, DMG Memory Map
Project 7 CPU Core & Timing, Interrupts/Timers/Input
Project 8 Audio System, Interrupts/Timers/Input
Project 9 PPU Rendering, VRAM/OAM Access & DMA
Project 10 Cartridge & Banking, Toolchain & ROM Modding
Project 11 Cartridge & Banking, CPU Core & Timing
Project 12 Toolchain & ROM Modding, CPU Core & Timing
Project 13 VRAM/OAM Access & DMA, PPU Rendering
Project 14 Toolchain & ROM Modding, DMG Memory Map
Project 15 PPU Rendering, Audio System
Project 16 Cartridge & Banking, PPU Rendering
Project 17 CPU Core & Timing, VRAM/OAM Access & DMA
Project 18 Toolchain & ROM Modding, Cartridge & Banking
Project 19 Toolchain & ROM Modding, DMG Memory Map
Project 20 All Concepts

Deep Dive Reading by Concept

Concept Book and Chapter Why This Matters
DMG Memory Map “Game Boy Coding Adventure” by Maximilien Dagois - Ch. 1-2 Hardware-first mental model and DMG specifics
CPU Core & Timing “The Art of Assembly Language” by Randall Hyde - Ch. 1-6 Registers, flags, and instruction timing
Cartridge & Banking “Low-Level Programming” by Igor Zhirkov - Ch. 7 Memory layout and bank switching mindset
PPU Rendering “Computer Organization and Design” by Patterson & Hennessy - Ch. 4 Pipeline mental model applied to PPU
VRAM/OAM Access & DMA “Making Embedded Systems” by Elecia White - Ch. 6 Timing, DMA, and hardware access rules
Interrupts/Timers/Input “Computer Systems: A Programmer’s Perspective” by Bryant & O’Hallaron - Ch. 4 Control flow, interrupts, and timing
Audio System “The Art of Assembly Language” by Randall Hyde - Ch. 7 Low-level timing applied to audio
Toolchain & ROM Modding “Practical Reverse Engineering” by Dang et al. - Ch. 1-3 Disassembly and analysis workflow

Quick Start: Your First 48 Hours

Day 1:

  1. Read Theory Primer Chapters 1-3
  2. Install RGBDS and a DMG-accurate emulator
  3. Start Project 1 and get a ROM header check passing

Day 2:

  1. Validate Project 1 against Definition of Done
  2. Read Theory Primer Chapters 4-6
  3. Begin Project 2 (input + timer loop)

Path 1: The Homebrew Builder

  • Projects 1 -> 2 -> 3 -> 5 -> 7 -> 9 -> 10 -> 15 -> 16 -> 20

Path 2: The ROM Hacker

  • Projects 1 -> 6 -> 10 -> 12 -> 14 -> 18 -> 19 -> 20

Path 3: The Low-Level Purist

  • Projects 1 -> 2 -> 4 -> 6 -> 8 -> 11 -> 13 -> 17 -> 20

Success Metrics

  • You can build a DMG ROM that boots correctly on real hardware or strict emulators.
  • You can explain and prove why each VRAM/OAM write happens during safe windows.
  • You can design a banked ROM layout for a multi-level game.
  • You can build a ROM patch for a game you own and validate it on a clean base ROM.

Appendix: DMG Timing & Register Quick Reference

Core clocks and frame math

  • CPU clock: ~4.194304 MHz (SM83/LR35902).
  • Frame: 154 scanlines * 456 dots/line = 70,224 dots per frame (~59.7 Hz).
  • Visible area: lines 0-143 (144 lines); VBlank: lines 144-153 (10 lines).
  • PPU modes per visible line:
    • Mode 2 (OAM search): 80 dots
    • Mode 3 (pixel transfer): 172-289 dots (variable)
    • Mode 0 (HBlank): remainder of the 456-dot line

Memory map (high-signal) | Range | Purpose | Notes | |——-|———|——-| | 0000-3FFF | ROM bank 0 | Fixed bank; vectors + core code | | 4000-7FFF | ROM bank N | Switchable bank via MBC | | 8000-9FFF | VRAM | Tile data + tile maps | | A000-BFFF | External RAM | Save RAM (battery-backed) | | C000-DFFF | Work RAM | General-purpose WRAM | | E000-FDFF | Echo RAM | Mirror of C000-DDFF (avoid) | | FE00-FE9F | OAM | Sprite attribute table | | FEA0-FEFF | Not usable | Hardware-reserved | | FF00-FF7F | I/O registers | PPU/APU/Timers/Serial/Joypad | | FF80-FFFE | HRAM | High RAM (fast scratch) | | FFFF | IE | Interrupt enable register |

LCDC essentials (FF40)

  • Bit 7: LCD enable
  • Bit 6: Window tile map area (9C00/9800)
  • Bit 5: Window enable
  • Bit 4: BG/Window tile data area (8000/8800)
  • Bit 3: BG tile map area (9C00/9800)
  • Bit 2: Sprite size (8x8 or 8x16)
  • Bit 1: Sprite enable
  • Bit 0: BG/Window enable (DMG)

Timer & divider quick facts

  • DIV (FF04) increments at 16,384 Hz; writing any value resets it.
  • TIMA (FF05) increments at frequencies selected by TAC (FF07):
    • 4096 Hz, 262,144 Hz, 65,536 Hz, or 16,384 Hz.
  • TIMA overflow reloads from TMA (FF06) and requests the timer interrupt.

OAM DMA

  • Write a source high byte to FF46 to start DMA.
  • Copies 160 bytes from XX00-XX9F to FE00-FE9F.
  • Takes 160 M-cycles; CPU can only access HRAM during the transfer.

Interrupts

  • IE at FFFF enables interrupts; IF at FF0F holds requests.
  • Priority order: VBlank -> LCD STAT -> Timer -> Serial -> Joypad.
  • Interrupt dispatch takes 5 M-cycles once IME is enabled.

Joypad register (FF00)

  • Active-low matrix: select direction/button row, then read lower nibble.
  • Always debounce input; treat reads as time-sensitive.

Project Overview Table

# Project Core Outcome Difficulty Estimated Time
1 Toolchain and ROM Header Verification Bootable ROM + verified header Level 2 1 weekend
2 Frame Loop + Input Sampler Stable input & frame sync Level 2 1 weekend
3 Tile Renderer + Background Test Render static background Level 3 1-2 weeks
4 Scrolling Playground Smooth scroll with bounds Level 3 1-2 weeks
5 Sprite Pipeline + DMA Stable sprite updates Level 3 1-2 weeks
6 Save RAM + Banking Persistent save system Level 4 2 weeks
7 Timer-Driven Animation Deterministic animation Level 3 1-2 weeks
8 Audio Driver Mini Play simple music + SFX Level 4 2-3 weeks
9 HUD + Window Layer In-game HUD overlay Level 3 1-2 weeks
10 Banked Asset Loader Stream assets from banks Level 4 2-3 weeks
11 Banked Code Loader Call code in other banks Level 4 2-3 weeks
12 Debug Overlay & Profiler In-game perf counter Level 4 2-3 weeks
13 Raster/Scanline Effects Advanced visual timing Level 5 3-4 weeks
14 ROM Data Explorer Extract tiles/text from ROM Level 3 1-2 weeks
15 Mini Game: Puzzle Complete small game Level 4 3-4 weeks
16 Large Map Streaming Multi-bank world Level 4 3-4 weeks
17 Performance Budgeter Frame-time enforcement Level 5 3-4 weeks
18 ROM Patch Pipeline Legal patch creation Level 4 2 weeks
19 ROM Hack: Content Swap Modify owned ROM safely Level 5 4-6 weeks
20 Final Game Project Full DMG game Level 5 6-10 weeks

Project List

The following projects guide you from basic toolchain mastery to full DMG game development and responsible ROM modification.

Project 1: Toolchain and ROM Header Verification

  • File: P01-toolchain-rom-header-verification.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 3
  • Business Potential: Level 1
  • Difficulty: Level 2
  • Knowledge Area: Toolchain, ROM format, boot process
  • Software or Tool: RGBDS, BGB or SameBoy, hex editor
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A minimal DMG ROM that boots, shows a stable screen state, and passes header validation.

Why it teaches Game Boy assembly: You will learn the exact constraints of the DMG boot process, header requirements, and the ROM build pipeline that everything else depends on.

Core challenges you will face:

  • Header correctness -> Cartridge header and checksum knowledge
  • Memory layout discipline -> Fixed vs switchable ROM banks
  • Toolchain trust -> Verifying outputs in emulator and hex

Real World Outcome

You have a ROM that boots in strict emulators without warnings, shows a stable background color or logo tile, and reports header validity.

CLI output example: $ rgbasm -V RGBDS version information…

$ rgbfix -V RGBDS version information…

Emulator verification (described):

  • Emulator loads ROM without header errors
  • Nintendo logo bytes are correct
  • The screen remains stable (no flicker)

The Core Question You Are Answering

“How do I produce a DMG-bootable ROM with a correct header and deterministic memory layout?”

This matters because every other project will fail if your ROM does not boot predictably on DMG hardware.

Concepts You Must Understand First

  1. Cartridge Header Fields
    • What fields are required for DMG boot?
    • Book Reference: “Game Boy Coding Adventure” by Maximilien Dagois - Ch. 1
  2. Memory Map Basics
    • Where do vectors and startup code live?
    • Book Reference: “Computer Systems: A Programmer’s Perspective” by Bryant & O’Hallaron - Ch. 1

Questions to Guide Your Design

  1. ROM Layout
    • Where should interrupt vectors and startup code reside?
    • How will you reserve space for future data tables?
  2. Verification Strategy
    • Which emulator gives the strictest header validation?
    • What will you check in the hex view to confirm correctness?

Thinking Exercise

Boot Sequence Trace

Trace the first 256 bytes of ROM and the cartridge header. Explain why each field must be correct for DMG boot.

Questions to answer:

  • What happens if the Nintendo logo bytes are incorrect?
  • Why is the header checksum required?

The Interview Questions They Will Ask

  1. “What fields in the Game Boy header are required for boot?”
  2. “Why is a fixed ROM bank necessary?”
  3. “What does a memory map tell you that a ROM size does not?”
  4. “How do you validate a ROM without running code?”
  5. “Why does incorrect checksum cause boot failures on hardware?”

Hints in Layers

Hint 1: Starting Point Start by creating a minimal ROM layout with vectors and a simple entry point.

Hint 2: Next Level Use the ROM fixer tool to generate checksums and verify the header in a hex editor.

Hint 3: Technical Details Ensure the header fields (title, type, size) match your intended ROM layout and that the Nintendo logo bytes are exact.

Hint 4: Tools/Debugging Use emulator header validation and compare bytes to Pan Docs header spec.

Books That Will Help

Topic Book Chapter
ROM header & boot “Game Boy Coding Adventure” by Maximilien Dagois Ch. 1
Memory layout “Computer Systems: A Programmer’s Perspective” Ch. 1

Common Pitfalls and Debugging

Problem 1: “ROM fails to boot”

  • Why: Incorrect logo bytes or checksum
  • Fix: Re-run ROM fixer and verify header in hex editor
  • Quick test: Load ROM in strict emulator and check header report

Problem 2: “Emulator shows warnings”

  • Why: Mismatch between header type and actual ROM size
  • Fix: Update header fields to match ROM size
  • Quick test: Compare ROM size in bytes with header size code

Definition of Done

  • ROM boots in strict emulator without warnings
  • Header fields and checksums are validated
  • Memory map plan is documented
  • Baseline ROM layout is stable for future projects

Project 2: Frame Loop + Input Sampler

  • File: P02-frame-loop-input-sampler.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 3
  • Business Potential: Level 1
  • Difficulty: Level 2
  • Knowledge Area: Interrupts, timers, input
  • Software or Tool: RGBDS, emulator with input logging
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A stable, VBlank-driven main loop that reads joypad input and tracks pressed/held states.

Why it teaches Game Boy assembly: You learn to synchronize with hardware timing and interpret the active-low input register correctly.

Core challenges you will face:

  • Interrupt handling -> Understanding VBlank cadence
  • Input decoding -> Active-low bit logic
  • State tracking -> Pressed vs held transitions

Real World Outcome

When you press buttons, the on-screen indicators update reliably every frame. You can also log input transitions in a debug view.

CLI output example: $ emulator –log-input [frame 0123] A pressed [frame 0124] A held [frame 0125] A released

The Core Question You Are Answering

“How do I sample input predictably on DMG hardware without missing or duplicating presses?”

This matters because every gameplay system depends on responsive, consistent input.

Concepts You Must Understand First

  1. Interrupts and VBlank
    • Why use VBlank as a heartbeat?
    • Book Reference: “Computer Systems: A Programmer’s Perspective” - Ch. 4
  2. Active-Low Input Bits
    • How do you interpret a 0 as “pressed”?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 2

Questions to Guide Your Design

  1. Input Sampling
    • How will you store previous and current input states?
    • How will you detect “just pressed” vs “held”?
  2. Timing Model
    • Will you poll during VBlank or use an interrupt?
    • How do you handle rapid input changes within a frame?

Thinking Exercise

Input State Machine

Draw a state machine for a single button: up -> pressed -> held -> released.

Questions to answer:

  • What transitions happen in a single frame?
  • What happens if the user taps faster than one frame?

The Interview Questions They Will Ask

  1. “Why is input on Game Boy active-low?”
  2. “How do you implement ‘just pressed’ detection?”
  3. “What is the best time to read input each frame?”
  4. “How do interrupts affect input timing?”
  5. “Why do you need previous state tracking?”

Hints in Layers

Hint 1: Starting Point Use VBlank as a fixed point to read input once per frame.

Hint 2: Next Level Store previous state and compute transitions with bitwise operations.

Hint 3: Technical Details Remember the joypad register is multiplexed and active-low.

Hint 4: Tools/Debugging Log input bits each frame and verify transitions visually in emulator.

Books That Will Help

Topic Book Chapter
Interrupts “Computer Systems: A Programmer’s Perspective” Ch. 4
Input systems “Game Boy Coding Adventure” Ch. 2

Common Pitfalls and Debugging

Problem 1: “Input feels laggy”

  • Why: Sampling only every few frames
  • Fix: Sample every VBlank and use stable frame loop
  • Quick test: Tap buttons quickly and log frames

Problem 2: “Buttons seem inverted”

  • Why: Active-low bits not inverted
  • Fix: Invert input bits before interpretation
  • Quick test: Verify that 0 means pressed

Definition of Done

  • Input is sampled once per frame using VBlank
  • Pressed/held/released states are tracked
  • Input log matches real button presses
  • No missed presses at normal input speed

Project 3: Tile Renderer + Background Test

  • File: P03-tile-renderer-background.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 3
  • Knowledge Area: PPU, tiles, VRAM
  • Software or Tool: RGBDS, tile editor, emulator with VRAM viewer
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A background renderer that loads tiles into VRAM and displays a static test screen.

Why it teaches Game Boy assembly: It forces you to respect VRAM timing and understand the 2bpp tile format.

Core challenges you will face:

  • Tile encoding -> 2bpp format understanding
  • VRAM access -> Safe windows only
  • Tile map layout -> Background composition

Real World Outcome

A static scene is displayed, such as a checkerboard or title screen built from tiles, with no corruption or flicker.

Emulator verification (described):

  • VRAM viewer shows correct tile patterns
  • Background map contains expected tile indices

The Core Question You Are Answering

“How do I transform tile data into a visible background on DMG hardware?”

This matters because all DMG games are built from tile maps.

Concepts You Must Understand First

  1. 2bpp Tile Format
    • How do two bitplanes encode four colors?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 3
  2. VRAM Access Rules
    • When is it safe to write tile data?
    • Book Reference: “Making Embedded Systems” by Elecia White - Ch. 6

Questions to Guide Your Design

  1. Tile Pipeline
    • Where will you store tiles in ROM vs VRAM?
    • How do you map tile IDs to background positions?
  2. Update Timing
    • Will you load tiles once at boot or stream them?
    • How do you ensure updates happen during VBlank?

Thinking Exercise

Tile Encoding Walkthrough

Pick a simple 8x8 pattern and describe how it becomes two bytes per row in 2bpp.

Questions to answer:

  • How do you encode four colors using two bitplanes?
  • How would you invert a tile without re-encoding?

The Interview Questions They Will Ask

  1. “Why are Game Boy tiles 2bpp?”
  2. “What is the difference between tile data and tile maps?”
  3. “When can you safely update VRAM?”
  4. “How does LCDC select tile data regions?”
  5. “What causes background corruption?”

Hints in Layers

Hint 1: Starting Point Use a tile editor to create a small set of tiles and map them on a 32x32 grid.

Hint 2: Next Level Load tile data into VRAM during VBlank only.

Hint 3: Technical Details Keep tile IDs consistent between ROM data and the tile map.

Hint 4: Tools/Debugging Use the emulator VRAM viewer to inspect tile data live.

Books That Will Help

Topic Book Chapter
Tile rendering “Game Boy Coding Adventure” Ch. 3
Memory timing “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Tiles look scrambled”

  • Why: Wrong bitplane order or incorrect byte layout
  • Fix: Re-encode tiles in correct 2bpp format
  • Quick test: Inspect one tile row in hex vs expected pixels

Problem 2: “Background flickers”

  • Why: VRAM updated during rendering
  • Fix: Move VRAM writes into VBlank
  • Quick test: Toggle LCD off, update VRAM, then re-enable

Definition of Done

  • Tile data loads correctly into VRAM
  • Background map displays expected scene
  • No flicker or corruption across frames
  • VRAM writes happen only in safe windows

Project 4: Scrolling Playground

  • File: P04-scrolling-playground.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 3
  • Knowledge Area: PPU, scrolling, input
  • Software or Tool: RGBDS, emulator with PPU debugger
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A scrolling background playground with boundaries, controlled by input.

Why it teaches Game Boy assembly: It connects input, PPU scroll registers, and tile map layout into a real-time system.

Core challenges you will face:

  • Scroll registers -> Understanding SCX/SCY behavior
  • Edge handling -> Clamp or wrap logic
  • Timing -> Smooth movement without tearing

Real World Outcome

Using the D-pad, you can scroll a larger map smoothly across the screen. The map stops at boundaries or wraps cleanly.

Emulator verification (described):

  • SCX/SCY values change each frame
  • Map edges appear correctly without glitches

The Core Question You Are Answering

“How do I move the world under the camera without breaking the rendering pipeline?”

Scrolling is the core of most DMG games; mastering it unlocks level design.

Concepts You Must Understand First

  1. Scroll Registers (SCX/SCY)
    • How do they shift the background map?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 4
  2. Tile Map Layout
    • How do 32x32 maps map onto 160x144 screen?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 3

Questions to Guide Your Design

  1. Camera Logic
    • How will you clamp the camera to map bounds?
    • Will the map wrap or stop?
  2. Update Scheduling
    • When do you write SCX/SCY each frame?
    • How will you avoid tearing during scroll changes?

Thinking Exercise

Camera vs Map

Draw a 32x32 tile map and a 20x18 screen window. Show how SCX/SCY offsets move the window.

Questions to answer:

  • How many pixels can you scroll before updating tile data?
  • What happens when SCX exceeds 255?

The Interview Questions They Will Ask

  1. “How do SCX/SCY affect background rendering?”
  2. “Why is the background map larger than the screen?”
  3. “What is the relationship between pixel scroll and tile updates?”
  4. “How do you avoid tearing while scrolling?”
  5. “What happens when scroll wraps?”

Hints in Layers

Hint 1: Starting Point Treat the camera as a pair of pixel offsets applied each frame.

Hint 2: Next Level Update SCX/SCY only during VBlank to avoid mid-scanline changes.

Hint 3: Technical Details When pixel offsets cross tile boundaries, update the tile map edge.

Hint 4: Tools/Debugging Use the emulator background viewer to see map alignment.

Books That Will Help

Topic Book Chapter
Scrolling “Game Boy Coding Adventure” Ch. 4
Timing “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Scrolling jitters”

  • Why: Scroll registers updated outside safe windows
  • Fix: Update during VBlank only
  • Quick test: Freeze scroll updates and check stability

Problem 2: “Map edges glitch”

  • Why: Tile map edges not updated correctly when scrolling
  • Fix: Update edge tiles as camera moves
  • Quick test: Scroll slowly and inspect edge tiles

Definition of Done

  • Smooth scrolling at consistent speed
  • Boundaries handled correctly (wrap or clamp)
  • Scroll updates occur during safe windows
  • No visual tearing or corruption

Project 5: Sprite Pipeline + DMA

  • File: P05-sprite-pipeline-dma.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 3
  • Knowledge Area: Sprites, OAM, DMA
  • Software or Tool: RGBDS, emulator with OAM viewer
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A sprite system that updates positions, animations, and OAM via DMA each frame.

Why it teaches Game Boy assembly: It forces you to respect OAM rules and build a stable sprite update pipeline.

Core challenges you will face:

  • OAM layout -> Correct sprite attribute format
  • DMA timing -> Scheduling DMA transfers safely
  • Sprite limits -> 10-per-line constraint

Real World Outcome

Multiple sprites move around the screen without flicker. OAM updates are stable, and the sprite limit is respected.

Emulator verification (described):

  • OAM viewer shows updated sprite positions each frame
  • No missing sprites or flicker

The Core Question You Are Answering

“How do I update sprites reliably without corrupting the display?”

Sprites are the core of most gameplay elements; stable updates are essential.

Concepts You Must Understand First

  1. OAM Structure
    • What fields define a sprite?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 5
  2. DMA Transfers
    • Why is DMA the safest update path?
    • Book Reference: “Making Embedded Systems” - Ch. 6

Questions to Guide Your Design

  1. Sprite Management
    • How will you store sprite data in WRAM?
    • How do you handle sprite priority and order?
  2. DMA Scheduling
    • Where in the frame will you trigger DMA?
    • How do you ensure the CPU waits for DMA to finish?

Thinking Exercise

Sprite Budgeting

Design a scene with 20 sprites. Decide which sprites must be visible on each scanline to avoid exceeding the 10-per-line limit.

Questions to answer:

  • How would you prioritize critical sprites?
  • How would you cull or hide sprites that exceed the limit?

The Interview Questions They Will Ask

  1. “Why is OAM DMA necessary for stable sprites?”
  2. “What is the 10-sprites-per-line rule?”
  3. “How do you handle sprite priority?”
  4. “When can you update OAM safely?”
  5. “What causes sprite flicker on real hardware?”

Hints in Layers

Hint 1: Starting Point Keep a shadow OAM table in WRAM.

Hint 2: Next Level Populate shadow OAM from game state every frame.

Hint 3: Technical Details Trigger DMA during VBlank and copy the full 160 bytes.

Hint 4: Tools/Debugging Use OAM viewer to verify attributes and order.

Books That Will Help

Topic Book Chapter
Sprites/OAM “Game Boy Coding Adventure” Ch. 5
DMA “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Sprites flicker or disappear”

  • Why: OAM writes outside safe windows or exceeding per-line limit
  • Fix: Use DMA and prioritize sprites
  • Quick test: Reduce sprites and confirm stability

Problem 2: “Sprites show wrong tile”

  • Why: Incorrect tile index or attribute bytes
  • Fix: Validate OAM entry format
  • Quick test: Inspect OAM entries in emulator

Definition of Done

  • Shadow OAM updated every frame
  • DMA triggered during VBlank
  • Sprites display with correct tiles and attributes
  • No flicker in strict emulators

Project 6: Save RAM + Banking

  • File: P06-save-ram-banking.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: MBC, external RAM, persistence
  • Software or Tool: RGBDS, emulator with save RAM inspection
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A save system that writes and reads player progress from battery-backed external RAM using MBC1.

Why it teaches Game Boy assembly: It forces you to understand banking modes, RAM enable/disable, and persistence constraints.

Core challenges you will face:

  • MBC control -> Selecting ROM/RAM banks correctly
  • Persistence -> Avoiding save corruption
  • Testing -> Verifying saves across power cycles

Real World Outcome

You can save a player name and progress value, power-cycle the emulator, and load the exact saved state on boot.

Emulator verification (described):

  • Save RAM file is created and updated
  • Save values persist after reload

The Core Question You Are Answering

“How do I safely store and retrieve persistent game state on a DMG cartridge?”

This matters because save systems are required for anything beyond short sessions.

Concepts You Must Understand First

  1. MBC1 Banking Modes
    • How does ROM vs RAM banking change behavior?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 6
  2. External RAM Enable/Disable
    • Why must RAM be explicitly enabled?
    • Book Reference: “Low-Level Programming” by Igor Zhirkov - Ch. 7

Questions to Guide Your Design

  1. Save Data Layout
    • How will you structure save slots?
    • How will you validate save integrity?
  2. Bank Access Policy
    • When do you enable RAM writes?
    • How do you avoid accidental writes?

Thinking Exercise

Save Integrity Plan

Design a minimal checksum or signature system to detect corrupted saves.

Questions to answer:

  • Where should the checksum live?
  • How will you handle invalid saves on boot?

The Interview Questions They Will Ask

  1. “How does MBC1 enable external RAM?”
  2. “Why disable RAM after saving?”
  3. “How would you implement multiple save slots?”
  4. “What happens if you switch ROM banks during a save?”
  5. “How do you validate save data?”

Hints in Layers

Hint 1: Starting Point Define a save structure with a signature and version field.

Hint 2: Next Level Enable RAM, write data, then immediately disable RAM.

Hint 3: Technical Details Store save data at a fixed offset in external RAM bank 0.

Hint 4: Tools/Debugging Inspect the save file in a hex editor after each write.

Books That Will Help

Topic Book Chapter
MBC banking “Game Boy Coding Adventure” Ch. 6
Persistence “Low-Level Programming” Ch. 7

Common Pitfalls and Debugging

Problem 1: “Save file doesn’t change”

  • Why: RAM not enabled or wrong bank selected
  • Fix: Verify MBC control writes before save
  • Quick test: Toggle a known byte and inspect save file

Problem 2: “Save corrupt after reload”

  • Why: Writes interrupted or invalid data layout
  • Fix: Add checksum and versioning
  • Quick test: Validate signature on boot

Definition of Done

  • Save data persists across emulator reload
  • Save integrity checks detect corruption
  • RAM enable/disable handled correctly
  • Bank switching is documented and deterministic

Project 7: Timer-Driven Animation

  • File: P07-timer-driven-animation.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 3
  • Business Potential: Level 1
  • Difficulty: Level 3
  • Knowledge Area: Timers, animation, state machines
  • Software or Tool: RGBDS, emulator with frame stepping
  • Main Book: “The Art of Assembly Language” by Randall Hyde

What you will build: A timer-driven animation system that updates sprite frames at a stable rate independent of frame time.

Why it teaches Game Boy assembly: You learn to use hardware timers for deterministic pacing and decouple animation from input.

Core challenges you will face:

  • Timer configuration -> Choosing stable tick rates
  • State machines -> Managing animation states
  • Timing independence -> Avoiding frame-rate drift

Real World Outcome

A sprite animates at a constant speed even if the game loop workload changes. Animation timing is controlled by a timer interrupt.

Emulator verification (described):

  • Animation updates at a steady cadence
  • Timer interrupt count matches expected rate

The Core Question You Are Answering

“How do I make animation timing independent of variable frame workload?”

This matters because stable animation feels professional and consistent.

Concepts You Must Understand First

  1. Timer Registers
    • How do DIV/TIMA/TMA/TAC work together?
    • Book Reference: “Computer Systems: A Programmer’s Perspective” - Ch. 4
  2. Animation State Machines
    • How do you represent animation frames and transitions?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 7

Questions to Guide Your Design

  1. Tick Rate
    • What timer frequency matches your desired animation speed?
    • How do you convert ticks to frame changes?
  2. State Control
    • How do you handle idle vs walking animations?
    • What happens if multiple events request changes?

Thinking Exercise

Animation Timing Budget

Define a walking animation that cycles every 0.5 seconds. Compute how many timer ticks are needed at your chosen timer rate.

Questions to answer:

  • How will you handle variable CPU load?
  • How will you reset animation on state changes?

The Interview Questions They Will Ask

  1. “Why use a hardware timer instead of frame counting?”
  2. “How do you handle timer overflow?”
  3. “What is the role of TMA?”
  4. “How do you prevent animation jitter?”
  5. “How do you trigger state changes safely?”

Hints in Layers

Hint 1: Starting Point Use a timer interrupt to increment an animation tick counter.

Hint 2: Next Level Change animation frames when tick counter reaches a threshold.

Hint 3: Technical Details Reset tick counter and update frame index atomically.

Hint 4: Tools/Debugging Log tick counts and verify frame changes in emulator.

Books That Will Help

Topic Book Chapter
Timers “Computer Systems: A Programmer’s Perspective” Ch. 4
State machines “Game Boy Coding Adventure” Ch. 7

Common Pitfalls and Debugging

Problem 1: “Animation speeds up or slows down”

  • Why: Using frame count instead of timer tick
  • Fix: Base animation on timer interrupt
  • Quick test: Vary workload and watch animation rate

Problem 2: “Animation glitches on state change”

  • Why: Frame index not reset or transitions not atomic
  • Fix: Reset frame on state entry
  • Quick test: Rapidly toggle states and observe

Definition of Done

  • Animation rate stable under varying load
  • Timer interrupt configured correctly
  • State transitions are smooth and deterministic
  • Animation timing documented and reproducible

Project 8: Audio Driver Mini

  • File: P08-audio-driver-mini.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: Audio registers, timing, music sequencing
  • Software or Tool: RGBDS, emulator with audio inspection
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A minimal music and SFX driver that plays a short melody and a button-triggered sound effect.

Why it teaches Game Boy assembly: You will manage APU registers, scheduling, and channel conflicts.

Core challenges you will face:

  • APU control -> Correct register sequences
  • Timing -> Music ticks and note durations
  • Channel mixing -> Music vs SFX priority

Real World Outcome

A short melody plays in the background, and pressing a button plays a distinct sound effect without breaking the melody.

Emulator verification (described):

  • APU registers show expected changes per tick
  • No audio dropouts during SFX

The Core Question You Are Answering

“How do I schedule audio updates on DMG without glitches?”

Sound is a core part of game feel; glitch-free audio is a sign of mastery.

Concepts You Must Understand First

  1. APU Channel Types
    • What are the four channels and their roles?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 8
  2. Timer-Driven Sequencing
    • How do you schedule note events reliably?
    • Book Reference: “The Art of Assembly Language” - Ch. 7

Questions to Guide Your Design

  1. Channel Allocation
    • Which channels are reserved for music vs SFX?
    • How do you prioritize SFX?
  2. Sequencer Format
    • How will you represent notes and durations?
    • How do you step through a pattern?

Thinking Exercise

Channel Budgeting

Design a simple allocation plan: melody, harmony, bass, and noise.

Questions to answer:

  • Which channel is best for melody?
  • How do you handle a SFX that needs a channel currently in use?

The Interview Questions They Will Ask

  1. “What are the DMG audio channels?”
  2. “Why do you need a timer tick for music?”
  3. “How do you avoid audio glitches?”
  4. “What is a wave table used for?”
  5. “How do you prioritize sound effects?”

Hints in Layers

Hint 1: Starting Point Start with a single channel and a short pattern table.

Hint 2: Next Level Add a timer tick and advance pattern index on each tick.

Hint 3: Technical Details Trigger channels by writing control registers in the correct order.

Hint 4: Tools/Debugging Use emulator APU register view to confirm updates.

Books That Will Help

Topic Book Chapter
Audio basics “Game Boy Coding Adventure” Ch. 8
Timing “The Art of Assembly Language” Ch. 7

Common Pitfalls and Debugging

Problem 1: “No sound plays”

  • Why: APU not enabled or channel DAC off
  • Fix: Enable master sound and channel DACs
  • Quick test: Toggle master sound and listen

Problem 2: “SFX cuts out music”

  • Why: Channels not prioritized or not restored
  • Fix: Implement channel restore logic after SFX
  • Quick test: Play SFX repeatedly and listen

Definition of Done

  • Melody plays consistently at target tempo
  • SFX plays without breaking music
  • APU registers updated on a stable tick
  • Channel allocation documented

Project 9: HUD + Window Layer

  • File: P09-hud-window-layer.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 3
  • Knowledge Area: Window layer, tile maps, UI
  • Software or Tool: RGBDS, emulator with layer toggles
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A HUD overlay using the window layer that shows score, health, and debug info.

Why it teaches Game Boy assembly: You must manage two tile maps and control the window position precisely.

Core challenges you will face:

  • Window positioning -> WX/WY behavior
  • Tile map management -> Background vs window
  • Update budget -> Updating UI without flicker

Real World Outcome

A stable HUD appears over a scrolling background and updates numbers in real time.

Emulator verification (described):

  • Window layer toggles correctly
  • HUD stays fixed while background scrolls

The Core Question You Are Answering

“How do I build a stable UI overlay on DMG without breaking background scrolling?”

The window layer is the DMG’s native HUD system; mastering it is essential.

Concepts You Must Understand First

  1. Window Layer Registers
    • How do WX/WY control the window position?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 9
  2. Tile Map Updates
    • How do you update text without corrupting tiles?
    • Book Reference: “Making Embedded Systems” - Ch. 6

Questions to Guide Your Design

  1. UI Layout
    • Where will HUD elements be placed on the 20x18 grid?
    • How will you update numbers efficiently?
  2. Update Scheduling
    • Will HUD updates be incremental or full redraw?
    • How will you avoid VRAM access outside safe windows?

Thinking Exercise

HUD Update Strategy

Design a way to update a score counter without rewriting the entire HUD each frame.

Questions to answer:

  • Which tiles need to change when the score increments?
  • How will you handle multi-digit numbers?

The Interview Questions They Will Ask

  1. “What is the DMG window layer?”
  2. “How do WX/WY differ from SCX/SCY?”
  3. “Why is the HUD separate from the background?”
  4. “How do you update text efficiently?”
  5. “When can you update window tile data?”

Hints in Layers

Hint 1: Starting Point Create a small font tile set and map it in the window tile map.

Hint 2: Next Level Update only the digits that change each frame.

Hint 3: Technical Details Remember WX has a hardware offset (window appears at WX-7).

Hint 4: Tools/Debugging Toggle background and window layers in emulator to isolate issues.

Books That Will Help

Topic Book Chapter
Window layer “Game Boy Coding Adventure” Ch. 9
VRAM timing “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Window appears shifted”

  • Why: WX offset not accounted for
  • Fix: Subtract hardware offset in your position logic
  • Quick test: Move window and watch alignment

Problem 2: “HUD flickers”

  • Why: Updating window map outside safe windows
  • Fix: Update during VBlank only
  • Quick test: Freeze updates and verify stability

Definition of Done

  • HUD overlays background without jitter
  • Numbers update correctly
  • Window position behavior is documented
  • Updates happen during safe windows

Project 10: Banked Asset Loader

  • File: P10-banked-asset-loader.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: Banking, asset streaming
  • Software or Tool: RGBDS, emulator with memory map viewer
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A system that streams tile sets and maps from ROM banks into VRAM as you move between areas.

Why it teaches Game Boy assembly: You will orchestrate bank switching, asset formats, and VRAM update timing together.

Core challenges you will face:

  • Bank switching -> Avoiding wrong-bank reads
  • Asset streaming -> Loading only what is needed
  • VRAM scheduling -> Loading in VBlank without stutter

Real World Outcome

As you transition between zones, the background tiles and maps change seamlessly without crashing or corrupting graphics.

Emulator verification (described):

  • Bank switch logs show correct sequence
  • VRAM viewer shows new tiles after transition

The Core Question You Are Answering

“How do I load large amounts of art in a banked ROM without breaking the frame loop?”

This is essential for real games with multiple levels or zones.

Concepts You Must Understand First

  1. MBC Bank Switching
    • How do you select the correct ROM bank?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 6
  2. VRAM Update Budget
    • How many tiles can you load per VBlank?
    • Book Reference: “Making Embedded Systems” - Ch. 6

Questions to Guide Your Design

  1. Asset Organization
    • How will you group tiles by zone or level?
    • Where do you store map data and metadata?
  2. Streaming Strategy
    • Will you load all tiles at once or in chunks?
    • How do you avoid visual popping?

Thinking Exercise

Banked Asset Plan

Design a bank layout for 4 levels, each with unique tiles and maps.

Questions to answer:

  • Which assets are shared across levels?
  • How will you minimize bank switches?

The Interview Questions They Will Ask

  1. “How do you structure assets across ROM banks?”
  2. “What happens if you read data from the wrong bank?”
  3. “How do you avoid VRAM corruption during loading?”
  4. “What is your strategy for loading large tile sets?”
  5. “How do you validate bank switching logic?”

Hints in Layers

Hint 1: Starting Point Group assets by level and store bank IDs in a small table.

Hint 2: Next Level Stream tiles in chunks across multiple VBlanks.

Hint 3: Technical Details Always restore the previous bank after asset reads.

Hint 4: Tools/Debugging Log bank switches and verify tile data in VRAM viewer.

Books That Will Help

Topic Book Chapter
Banking “Game Boy Coding Adventure” Ch. 6
DMA/timing “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Tiles appear from wrong level”

  • Why: Bank not restored or wrong bank ID used
  • Fix: Save/restore bank around asset reads
  • Quick test: Force bank ID changes and observe VRAM

Problem 2: “Loading causes flicker”

  • Why: Too much VRAM data copied in one VBlank
  • Fix: Split loading across multiple frames
  • Quick test: Measure tiles loaded per frame

Definition of Done

  • Asset loads occur without visual corruption
  • Bank switching is stable and logged
  • VRAM writes respect safe windows
  • Level transitions are smooth and repeatable

Project 11: Banked Code Loader

  • File: P11-banked-code-loader.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: Banked code execution, calling conventions
  • Software or Tool: RGBDS, emulator with debugger
  • Main Book: “The Art of Assembly Language” by Randall Hyde

What you will build: A safe system for calling code located in non-fixed ROM banks and returning correctly.

Why it teaches Game Boy assembly: Banked code execution is essential for large games and requires careful stack and bank management.

Core challenges you will face:

  • Calling across banks -> Preserving return addresses
  • State restoration -> Bank save/restore rules
  • Interrupt safety -> Bank 0 handlers only

Real World Outcome

You can call a function stored in a switchable ROM bank, return to the caller safely, and confirm that interrupts continue to work.

Emulator verification (described):

  • Bank switches happen around function calls
  • Return addresses are correct

The Core Question You Are Answering

“How do I execute code in a different ROM bank without breaking control flow?”

This matters because real games store large systems and scripts in non-fixed banks.

Concepts You Must Understand First

  1. Stack and Return Addresses
    • How does the stack preserve return flow?
    • Book Reference: “The Art of Assembly Language” - Ch. 3
  2. Bank Switching Discipline
    • How do you prevent bank confusion during calls?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 6

Questions to Guide Your Design

  1. Call Wrapper
    • How do you preserve the previous bank ID?
    • How do you restore it after return?
  2. Interrupt Safety
    • How do you ensure interrupts always point to bank 0 code?
    • What happens if an interrupt fires mid-switch?

Thinking Exercise

Banked Call Trace

Trace a call from bank 0 to bank 3 and back. Show the stack and bank state at each step.

Questions to answer:

  • What state must be preserved before switching?
  • How do you restore the original bank safely?

The Interview Questions They Will Ask

  1. “Why must interrupt handlers live in bank 0?”
  2. “How do you preserve control flow across banks?”
  3. “What state must be saved before switching banks?”
  4. “What happens if you switch banks inside an interrupt?”
  5. “How do you debug banked code?”

Hints in Layers

Hint 1: Starting Point Create a call wrapper that saves the current bank before switching.

Hint 2: Next Level Ensure the wrapper restores the bank and returns cleanly.

Hint 3: Technical Details Store bank IDs in HRAM for fast access.

Hint 4: Tools/Debugging Set breakpoints before/after bank switch to verify flow.

Books That Will Help

Topic Book Chapter
Stack/calls “The Art of Assembly Language” Ch. 3
Banking “Game Boy Coding Adventure” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Return jumps to wrong code”

  • Why: Bank not restored
  • Fix: Always restore previous bank before return
  • Quick test: Log bank ID at entry/exit

Problem 2: “Interrupt crashes during bank switch”

  • Why: Interrupt handler in wrong bank
  • Fix: Keep handlers in bank 0
  • Quick test: Trigger interrupts during banked call

Definition of Done

  • Banked calls return correctly
  • Previous bank is restored reliably
  • Interrupts remain stable
  • Call wrapper documented and reusable

Project 12: Debug Overlay & Profiler

  • File: P12-debug-overlay-profiler.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: Diagnostics, performance, timing
  • Software or Tool: RGBDS, emulator with CPU profiler
  • Main Book: “Making Embedded Systems” by Elecia White

What you will build: An in-game debug overlay showing frame time, sprite count, and VRAM usage.

Why it teaches Game Boy assembly: You will track performance and build tooling inside strict hardware limits.

Core challenges you will face:

  • Instrumentation -> Measuring cycles per frame
  • HUD integration -> Displaying metrics via window layer
  • Low overhead -> Avoiding performance distortion

Real World Outcome

A toggleable debug overlay displays live metrics. You can identify when frame time is exceeded.

Emulator verification (described):

  • Overlay updates each frame
  • CPU usage logs match overlay values

The Core Question You Are Answering

“How can I measure and visualize DMG performance constraints inside the game itself?”

Performance visibility is critical for optimization and stability.

Concepts You Must Understand First

  1. Cycle Budgeting
    • How many cycles are available per frame?
    • Book Reference: “Making Embedded Systems” - Ch. 6
  2. Window Layer HUD
    • How to display numbers without heavy VRAM updates?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 9

Questions to Guide Your Design

  1. Metrics
    • Which metrics are most meaningful (frame time, sprites, VRAM)?
    • How will you compute each metric?
  2. Display Strategy
    • Will the overlay update every frame or every N frames?
    • How will you avoid flicker?

Thinking Exercise

Frame Budget Audit

Define a maximum cycle budget per frame and list where the cycles go (logic, render, audio).

Questions to answer:

  • Which subsystem can you simplify first?
  • How will you detect overruns?

The Interview Questions They Will Ask

  1. “How do you estimate cycles per frame on DMG?”
  2. “What does a performance budget protect you from?”
  3. “How do you avoid debug tools changing timing?”
  4. “Why show metrics in-game instead of emulator only?”
  5. “How do you measure sprite counts accurately?”

Hints in Layers

Hint 1: Starting Point Track frame start and end times using a timer or VBlank counter.

Hint 2: Next Level Display metrics with a minimal tile map update.

Hint 3: Technical Details Only update digits that changed to reduce VRAM writes.

Hint 4: Tools/Debugging Compare overlay values to emulator profiler output.

Books That Will Help

Topic Book Chapter
Embedded timing “Making Embedded Systems” Ch. 6
HUD systems “Game Boy Coding Adventure” Ch. 9

Common Pitfalls and Debugging

Problem 1: “Overlay causes slowdown”

  • Why: Too many VRAM updates
  • Fix: Update only changed digits
  • Quick test: Toggle overlay and compare frame time

Problem 2: “Metrics inconsistent”

  • Why: Timer read not synchronized
  • Fix: Sample at fixed points each frame
  • Quick test: Log values across frames

Definition of Done

  • Overlay displays accurate metrics
  • Overhead is low and documented
  • Metrics align with emulator profiling
  • Toggleable without side effects

Project 13: Raster/Scanline Effects

  • File: P13-raster-scanline-effects.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 5
  • Business Potential: Level 1
  • Difficulty: Level 5
  • Knowledge Area: LCD modes, STAT interrupts, timing
  • Software or Tool: RGBDS, emulator with scanline view
  • Main Book: “Making Embedded Systems” by Elecia White

What you will build: A raster effect that changes palettes or scroll mid-frame using LCD STAT interrupts.

Why it teaches Game Boy assembly: It forces precise timing and deep understanding of LCD modes and interrupts.

Core challenges you will face:

  • Scanline timing -> Precise interrupt timing
  • Mode handling -> STAT interrupts and safe writes
  • Visual design -> Stable effects without artifacts

Real World Outcome

You can create a split-screen effect (e.g., different palettes or scroll values on top/bottom) with stable timing.

Emulator verification (described):

  • Scanline breaks are clean
  • No flicker or misaligned lines

The Core Question You Are Answering

“How can I change display parameters mid-frame without breaking the renderer?”

Raster effects are the hallmark of advanced DMG development.

Concepts You Must Understand First

  1. LCD STAT Interrupts
    • How do you trigger interrupts at specific lines?
    • Book Reference: “Making Embedded Systems” - Ch. 6
  2. PPU Modes
    • Which modes allow safe register writes?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 5

Questions to Guide Your Design

  1. Effect Timing
    • Which scanline should trigger the change?
    • How will you handle late interrupts?
  2. Register Changes
    • Which registers will you modify mid-frame?
    • How do you restore defaults for next frame?

Thinking Exercise

Split-Screen Plan

Design a two-zone screen: top with one palette, bottom with another. Define the exact scanline to switch.

Questions to answer:

  • How will you avoid jitter if interrupts drift?
  • What happens if the CPU is delayed?

The Interview Questions They Will Ask

  1. “What is the purpose of STAT interrupts?”
  2. “Which LCD modes allow safe register changes?”
  3. “How do you achieve split-screen effects on DMG?”
  4. “What are common causes of raster glitches?”
  5. “How do you test raster effects in emulators?”

Hints in Layers

Hint 1: Starting Point Enable STAT interrupt on line compare and choose a scanline.

Hint 2: Next Level Change one register (like scroll or palette) at the interrupt.

Hint 3: Technical Details Keep the interrupt routine extremely short to avoid missing timing.

Hint 4: Tools/Debugging Use scanline view or tracing in emulator to validate timing.

Books That Will Help

Topic Book Chapter
Timing “Making Embedded Systems” Ch. 6
PPU modes “Game Boy Coding Adventure” Ch. 5

Common Pitfalls and Debugging

Problem 1: “Line split flickers”

  • Why: Interrupt timing not stable
  • Fix: Keep interrupt routine minimal and deterministic
  • Quick test: Disable other interrupts and re-test

Problem 2: “Registers change too late”

  • Why: Interrupt latency or excessive CPU work
  • Fix: Reduce work before scanline interrupt
  • Quick test: Move effect to later scanline

Definition of Done

  • Split-screen effect is stable
  • STAT interrupt timing is documented
  • No visual artifacts in strict emulators
  • Effect survives stress testing

Project 14: ROM Data Explorer

  • File: P14-rom-data-explorer.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: Python (host tooling), C (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 3
  • Knowledge Area: ROM analysis, data formats
  • Software or Tool: Hex editor, tile viewer, disassembler
  • Main Book: “Practical Reverse Engineering” by Dang et al.

What you will build: A repeatable workflow to extract tiles, maps, and text from a ROM you own.

Why it teaches Game Boy assembly: ROM analysis requires understanding memory layouts, banks, and data encoding.

Core challenges you will face:

  • Data identification -> Distinguishing code vs data
  • Tile extraction -> 2bpp decoding
  • Text encoding -> Custom encodings and tables

Real World Outcome

You can extract a tile set and a map from a ROM and view them as images, with notes about their offsets and banks.

Emulator verification (described):

  • Extracted tiles match in-game graphics
  • Map layout matches a known game area

The Core Question You Are Answering

“How do I safely locate and extract assets from a Game Boy ROM?”

This is the foundation for ROM hacking and data-driven mods.

Concepts You Must Understand First

  1. ROM Structure and Banking
    • How is data organized across banks?
    • Book Reference: “Practical Reverse Engineering” - Ch. 1
  2. 2bpp Graphics Encoding
    • How do tiles map to raw bytes?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 3

Questions to Guide Your Design

  1. Asset Discovery
    • How will you confirm that a data block is tile data?
    • How do you identify map data vs sprite data?
  2. Documentation
    • How will you record offsets and bank IDs for later mods?
    • How will you keep your findings reproducible?

Thinking Exercise

Tile Identification Heuristics

List three heuristics for detecting 2bpp tile data in a ROM dump.

Questions to answer:

  • What patterns indicate tile data?
  • How can you validate the guess without code execution?

The Interview Questions They Will Ask

  1. “How do you distinguish code from data in a ROM?”
  2. “What does 2bpp tile data look like in hex?”
  3. “Why is banking important for ROM analysis?”
  4. “How do you validate extracted assets?”
  5. “What documentation is essential for ROM hacking?”

Hints in Layers

Hint 1: Starting Point Start with known graphics and search for repeating 16-byte patterns.

Hint 2: Next Level Use a tile viewer to test candidate regions.

Hint 3: Technical Details Record bank IDs and offsets for every confirmed asset.

Hint 4: Tools/Debugging Compare extracted tiles to emulator VRAM viewer screenshots.

Books That Will Help

Topic Book Chapter
Reverse engineering “Practical Reverse Engineering” Ch. 1-2
Graphics formats “Game Boy Coding Adventure” Ch. 3

Common Pitfalls and Debugging

Problem 1: “Extracted tiles look garbled”

  • Why: Wrong bitplane interpretation or incorrect alignment
  • Fix: Adjust offsets and verify 16-byte tile boundaries
  • Quick test: Shift offset by 16 bytes and re-check

Problem 2: “Map data doesn’t line up”

  • Why: Wrong map dimensions or bank
  • Fix: Confirm map size and bank ID
  • Quick test: Try known 32x32 map size first

Definition of Done

  • At least one tile set extracted and verified
  • At least one map extracted and verified
  • Offsets/banks documented in a reproducible log
  • Workflow can be repeated on another ROM

Project 15: Mini Game - Puzzle

  • File: P15-mini-game-puzzle.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: Game loop, UI, state management
  • Software or Tool: RGBDS, emulator with save states
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A complete, small puzzle game with a title screen, gameplay screen, and win condition.

Why it teaches Game Boy assembly: It integrates input, rendering, and state machines into a full game slice.

Core challenges you will face:

  • State management -> Title, gameplay, win/lose
  • Rendering pipeline -> Updating tiles without flicker
  • Input logic -> Responsive controls

Real World Outcome

A playable puzzle game runs from start to finish with stable graphics and a clear win condition.

Emulator verification (described):

  • Title screen transitions to gameplay
  • Win condition triggers a result screen

The Core Question You Are Answering

“How do I combine core DMG systems into a complete, shippable game loop?”

This is your first real game, validating the fundamentals.

Concepts You Must Understand First

  1. Game State Machines
    • How do you structure multiple screens?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 10
  2. Tile and Sprite Updates
    • How do you update only what changes?
    • Book Reference: “Making Embedded Systems” - Ch. 6

Questions to Guide Your Design

  1. Game States
    • How will you represent title, game, and win screens?
    • How will you transition between states?
  2. Input Flow
    • How do you avoid repeated inputs across frames?
    • How do you map input to puzzle actions?

Thinking Exercise

State Transition Diagram

Draw a diagram of game states and transitions triggered by input or events.

Questions to answer:

  • Which state should reset the board?
  • How will you handle restart?

The Interview Questions They Will Ask

  1. “How do you structure game states in assembly?”
  2. “How do you prevent tearing when updating tiles?”
  3. “How do you implement a win condition efficiently?”
  4. “Why separate game logic from render updates?”
  5. “How do you test state transitions?”

Hints in Layers

Hint 1: Starting Point Define a small state enum and a per-state update routine.

Hint 2: Next Level Use VBlank to schedule visual changes when entering states.

Hint 3: Technical Details Keep puzzle logic separate from rendering data structures.

Hint 4: Tools/Debugging Use emulator save states to test transitions quickly.

Books That Will Help

Topic Book Chapter
Game structure “Game Boy Coding Adventure” Ch. 10
Timing “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “State transitions glitch”

  • Why: VRAM updates not synchronized
  • Fix: Clear screen and update maps during VBlank
  • Quick test: Add a frame delay between states

Problem 2: “Input repeats too fast”

  • Why: No edge detection for inputs
  • Fix: Use pressed vs held logic
  • Quick test: Log input transitions

Definition of Done

  • Full game loop from title to win screen
  • Stable graphics and input
  • Clear rules and win condition
  • No VRAM/OAM violations

Project 16: Large Map Streaming

  • File: P16-large-map-streaming.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: Map streaming, banking, scrolling
  • Software or Tool: RGBDS, emulator with memory viewer
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A streaming world system that loads map chunks from ROM banks as the player scrolls.

Why it teaches Game Boy assembly: It combines banking, scrolling, and VRAM update timing into a production-ready system.

Core challenges you will face:

  • Chunk loading -> Managing map segments
  • Banked data -> Cross-bank asset access
  • Performance -> Loading without frame drops

Real World Outcome

A large world scrolls smoothly, with new map data appearing seamlessly as you move.

Emulator verification (described):

  • No frame stutter during chunk loads
  • Map data appears correctly at boundaries

The Core Question You Are Answering

“How do I build a large world on DMG without loading everything at once?”

This is the core of real-world DMG game design.

Concepts You Must Understand First

  1. Banked Asset Streaming
    • How do you load data in chunks?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 6
  2. Scroll and Map Edges
    • How do you update tile map edges as the camera moves?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 4

Questions to Guide Your Design

  1. Chunk Size
    • How many tiles per chunk balance memory and update time?
    • How do you cache chunks in RAM?
  2. Load Scheduling
    • How many tiles can you update per frame?
    • How do you prevent visible popping?

Thinking Exercise

Chunk Strategy

Design a chunk size and explain how many chunks fit in your VRAM budget.

Questions to answer:

  • How do you handle diagonal movement across chunk boundaries?
  • How do you prefetch the next chunk?

The Interview Questions They Will Ask

  1. “How do you stream map data with banked ROM?”
  2. “What limits the size of a map chunk?”
  3. “How do you avoid tearing during chunk loads?”
  4. “How do you prefetch data?”
  5. “How do you validate chunk integrity?”

Hints in Layers

Hint 1: Starting Point Define chunk metadata that maps chunk IDs to ROM bank and offset.

Hint 2: Next Level Load only the edge tiles needed for the next scroll step.

Hint 3: Technical Details Use a ring buffer in WRAM to track active chunks.

Hint 4: Tools/Debugging Log chunk loads and verify in emulator map viewer.

Books That Will Help

Topic Book Chapter
Map streaming “Game Boy Coding Adventure” Ch. 6
Timing “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Chunks load too late”

  • Why: Loading triggered after crossing boundary
  • Fix: Prefetch before boundary
  • Quick test: Slow scroll and log chunk loads

Problem 2: “Frame drops”

  • Why: Too many tiles loaded per frame
  • Fix: Spread loads across frames
  • Quick test: Measure tile updates per VBlank

Definition of Done

  • Large world scrolls seamlessly
  • Chunk loads are prefetched and stable
  • No visible popping or flicker
  • Banked data access is correct

Project 17: Performance Budgeter

  • File: P17-performance-budgeter.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 5
  • Business Potential: Level 1
  • Difficulty: Level 5
  • Knowledge Area: Optimization, cycle counting, scheduling
  • Software or Tool: RGBDS, emulator with CPU trace
  • Main Book: “Making Embedded Systems” by Elecia White

What you will build: A performance budget system that enforces per-frame cycle limits and degrades gracefully when exceeded.

Why it teaches Game Boy assembly: You learn to quantify CPU cost, schedule work, and avoid frame drops.

Core challenges you will face:

  • Cycle accounting -> Estimating instruction cost
  • Scheduling -> Prioritizing tasks per frame
  • Graceful degradation -> Skipping non-critical work

Real World Outcome

The game detects frame overruns and logs or throttles non-critical tasks, keeping gameplay stable.

Emulator verification (described):

  • Frame overrun counter increments when load is high
  • Non-critical tasks are skipped as expected

The Core Question You Are Answering

“How do I keep a DMG game running smoothly under heavy load?”

This is the difference between a demo and a shippable game.

Concepts You Must Understand First

  1. Cycle Budgeting
    • How many cycles are available per frame?
    • Book Reference: “Making Embedded Systems” - Ch. 6
  2. Task Prioritization
    • How do you classify tasks by importance?
    • Book Reference: “Clean Code” by Robert C. Martin - Ch. 2

Questions to Guide Your Design

  1. Budget Model
    • How will you measure or estimate cycle costs?
    • How will you track budget usage per frame?
  2. Degradation Strategy
    • Which tasks can be skipped safely?
    • How will you detect critical overload?

Thinking Exercise

Frame Cost Breakdown

Estimate cycle cost for input, update, render, and audio steps. Decide which step is most flexible.

Questions to answer:

  • What happens if you skip animation update for one frame?
  • How do you ensure audio timing remains stable?

The Interview Questions They Will Ask

  1. “How do you estimate instruction cycles on DMG?”
  2. “What tasks must never be skipped?”
  3. “How do you detect a frame overrun?”
  4. “How do you measure performance without affecting it?”
  5. “What is the tradeoff between quality and stability?”

Hints in Layers

Hint 1: Starting Point Use a frame counter and a timer to approximate cycle usage.

Hint 2: Next Level Assign each subsystem a budget and track actual usage.

Hint 3: Technical Details Implement a queue that drops low-priority tasks when over budget.

Hint 4: Tools/Debugging Compare results with emulator CPU trace.

Books That Will Help

Topic Book Chapter
Embedded performance “Making Embedded Systems” Ch. 6
Prioritization “Clean Code” Ch. 2

Common Pitfalls and Debugging

Problem 1: “Overruns not detected”

  • Why: Incorrect timer sampling
  • Fix: Sample at a fixed point in the frame
  • Quick test: Force heavy workload and validate

Problem 2: “Audio glitches during load”

  • Why: Audio updates skipped
  • Fix: Treat audio as high priority
  • Quick test: Stress test with many sprites

Definition of Done

  • Frame overruns detected and logged
  • Low-priority tasks are skipped when needed
  • Gameplay remains stable under load
  • Performance budget documented

Project 18: ROM Patch Pipeline

  • File: P18-rom-patch-pipeline.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: Python (host tooling), C (GBDK-2020)
  • Coolness Level: Level 4
  • Business Potential: Level 1
  • Difficulty: Level 4
  • Knowledge Area: ROM patching, legal distribution
  • Software or Tool: Patch tools (IPS/BPS), disassembler
  • Main Book: “Practical Reverse Engineering” by Dang et al.

What you will build: A legal, reproducible pipeline that creates patch files from ROM modifications you made locally.

Why it teaches Game Boy assembly: It integrates ROM analysis, controlled modification, and legal distribution practices.

Core challenges you will face:

  • Patch formats -> IPS/BPS differences
  • Reproducibility -> Deterministic patch generation
  • Validation -> Ensuring patches apply cleanly

Real World Outcome

You can apply your patch to a clean base ROM and reproduce the exact modifications without distributing the ROM itself.

CLI output example: $ patch-tool –apply base.rom mod.bps Patch applied successfully

The Core Question You Are Answering

“How do I share modifications without distributing copyrighted ROMs?”

This is essential for responsible ROM hacking.

Concepts You Must Understand First

  1. Patch Formats (IPS/BPS)
    • What metadata do patch formats include?
    • Book Reference: “Practical Reverse Engineering” - Ch. 2
  2. ROM Integrity
    • How do you verify the base ROM matches expected version?
    • Book Reference: “Computer Systems: A Programmer’s Perspective” - Ch. 2

Questions to Guide Your Design

  1. Patch Workflow
    • How do you store original vs modified ROMs?
    • How do you verify the patch applies to the right base?
  2. Documentation
    • How do you document what the patch changes?
    • How do you verify it across emulators?

Thinking Exercise

Patch Validation Plan

Design a checklist to ensure a patch is safe and reproducible.

Questions to answer:

  • How will you detect a wrong base ROM?
  • What emulator checks do you require before release?

The Interview Questions They Will Ask

  1. “Why is distributing ROMs illegal but patches acceptable?”
  2. “What is the difference between IPS and BPS?”
  3. “How do you validate a patch applies cleanly?”
  4. “What is a reproducible ROM build?”
  5. “How do you document patch changes?”

Hints in Layers

Hint 1: Starting Point Keep a clean base ROM and a modified ROM in separate folders.

Hint 2: Next Level Generate a patch and test it on the clean base.

Hint 3: Technical Details Include a checksum check for the base ROM to avoid mismatch.

Hint 4: Tools/Debugging Test patch in two emulators to confirm behavior.

Books That Will Help

Topic Book Chapter
Reverse engineering “Practical Reverse Engineering” Ch. 2
Integrity checks “Computer Systems: A Programmer’s Perspective” Ch. 2

Common Pitfalls and Debugging

Problem 1: “Patch applies but game breaks”

  • Why: Base ROM mismatch or wrong version
  • Fix: Verify base checksum before patching
  • Quick test: Compare ROM hash to expected value

Problem 2: “Patch won’t apply”

  • Why: Patch format mismatch or corruption
  • Fix: Recreate patch from clean base
  • Quick test: Apply patch in a different tool

Definition of Done

  • Patch applies cleanly to base ROM
  • Modified ROM behaves as intended
  • Patch workflow is documented
  • No ROM distribution involved

Project 19: ROM Hack - Content Swap

  • File: P19-rom-hack-content-swap.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: Python (host tooling), C (GBDK-2020)
  • Coolness Level: Level 5
  • Business Potential: Level 1
  • Difficulty: Level 5
  • Knowledge Area: Reverse engineering, data formats
  • Software or Tool: Disassembler, hex editor, tile/map tools
  • Main Book: “Practical Reverse Engineering” by Dang et al.

What you will build: A controlled ROM hack that swaps a tile set or text block in a game you own, delivered as a patch.

Why it teaches Game Boy assembly: You learn to read existing code/data layouts and make safe, minimal modifications.

Core challenges you will face:

  • Data identification -> Finding the exact assets
  • Size constraints -> Replacing data without breaking layout
  • Regression testing -> Ensuring no unintended side effects

Real World Outcome

A patched ROM shows your modified tiles or text in-game, while all other behavior remains unchanged.

Emulator verification (described):

  • Modified asset appears in-game
  • No crashes or corrupted visuals

The Core Question You Are Answering

“How do I modify a commercial DMG game without breaking its internal data layout?”

This is the essence of safe ROM hacking.

Concepts You Must Understand First

  1. Data Encoding and Offsets
    • How do assets map to ROM addresses?
    • Book Reference: “Practical Reverse Engineering” - Ch. 3
  2. Banking Awareness
    • How do you avoid crossing bank boundaries?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 6

Questions to Guide Your Design

  1. Asset Replacement
    • Can you replace data in place without changing size?
    • How will you validate that pointers remain correct?
  2. Testing Strategy
    • Which game scenarios must be tested to confirm safety?
    • How will you detect subtle corruption?

Thinking Exercise

In-Place Replacement Plan

Define a strategy for replacing a tile set with the same byte length.

Questions to answer:

  • What happens if your new asset is larger?
  • How will you confirm you did not overwrite adjacent data?

The Interview Questions They Will Ask

  1. “How do you ensure a ROM hack doesn’t break pointers?”
  2. “Why is in-place replacement safer than relocation?”
  3. “How do you confirm asset offsets are correct?”
  4. “What does bank alignment mean in practice?”
  5. “How do you regression test a ROM hack?”

Hints in Layers

Hint 1: Starting Point Choose a small, well-isolated asset to replace (like a title tile).

Hint 2: Next Level Match the exact byte length and encoding of the original asset.

Hint 3: Technical Details Document the ROM offset, bank ID, and checksum before and after change.

Hint 4: Tools/Debugging Compare emulator screenshots of original vs modified ROM.

Books That Will Help

Topic Book Chapter
Reverse engineering “Practical Reverse Engineering” Ch. 3
Banking “Game Boy Coding Adventure” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Game crashes after modification”

  • Why: Overwrote code or corrupted pointers
  • Fix: Restore original ROM and re-apply in-place
  • Quick test: Verify offsets and compare byte lengths

Problem 2: “Graphics appear corrupted”

  • Why: Wrong 2bpp encoding or misalignment
  • Fix: Re-encode tiles and align to 16-byte boundaries
  • Quick test: Compare tile data with original format

Definition of Done

  • Modified asset appears correctly in-game
  • Patch applies cleanly and reproducibly
  • No crashes or visual corruption
  • Modification documented with offsets and bank IDs

Project 20: Final DMG Game Project

  • File: P20-final-dmg-game.md
  • Main Programming Language: Game Boy Assembly (SM83/LR35902)
  • Alternative Programming Languages: C (GBDK-2020), C++ (GBDK-2020)
  • Coolness Level: Level 5
  • Business Potential: Level 2
  • Difficulty: Level 5
  • Knowledge Area: Full game architecture, optimization
  • Software or Tool: RGBDS, emulator + optional flash cart
  • Main Book: “Game Boy Coding Adventure” by Maximilien Dagois

What you will build: A complete DMG game with title screen, gameplay, audio, save system, and optimized performance.

Why it teaches Game Boy assembly: It forces you to integrate every subsystem under real hardware constraints.

Core challenges you will face:

  • Systems integration -> Graphics, audio, input, save
  • Performance -> Frame budget enforcement
  • Polish -> Stability across hardware and emulators

Real World Outcome

A fully playable DMG game that boots cleanly, runs at stable frame timing, and persists progress.

Emulator verification (described):

  • No flicker, tearing, or audio glitches
  • Save data persists across reloads

The Core Question You Are Answering

“Can I build and ship a complete DMG game that feels professional and stable?”

This is the culmination of the entire sprint.

Concepts You Must Understand First

  1. Subsystem Integration
    • How do all subsystems communicate without conflicts?
    • Book Reference: “Game Boy Coding Adventure” - Ch. 10
  2. Performance and Optimization
    • How do you maintain frame stability under load?
    • Book Reference: “Making Embedded Systems” - Ch. 6

Questions to Guide Your Design

  1. Game Architecture
    • How will you structure code across banks?
    • How will you manage assets and saves?
  2. Production Quality
    • How will you test across multiple emulators?
    • How will you verify behavior on real hardware?

Thinking Exercise

Production Readiness Checklist

Write a checklist for release quality: stability, performance, and legal compliance.

Questions to answer:

  • What hardware tests are mandatory?
  • What metrics define “stable” performance?

The Interview Questions They Will Ask

  1. “How do you structure a full DMG game across ROM banks?”
  2. “What are the biggest performance risks in DMG games?”
  3. “How do you validate on real hardware?”
  4. “How do you manage save data safely?”
  5. “What steps make a project production-ready?”

Hints in Layers

Hint 1: Starting Point Start with a small vertical slice and scale out.

Hint 2: Next Level Integrate audio and save systems early to avoid late surprises.

Hint 3: Technical Details Use a consistent asset pipeline and strict bank boundaries.

Hint 4: Tools/Debugging Use your debug overlay and profiler to validate frame budget.

Books That Will Help

Topic Book Chapter
Full game design “Game Boy Coding Adventure” Ch. 10
Embedded performance “Making Embedded Systems” Ch. 6

Common Pitfalls and Debugging

Problem 1: “Late-game performance collapse”

  • Why: Too many assets or logic per frame
  • Fix: Enforce frame budget and reduce workload
  • Quick test: Enable profiler in heavy scenes

Problem 2: “Save system corrupts”

  • Why: Unverified writes or incorrect bank handling
  • Fix: Use checksums and strict save routines
  • Quick test: Power-cycle test with save/load

Definition of Done

  • Complete game loop with title, gameplay, and end state
  • Stable frame timing in strict emulators
  • Save system validated across reloads
  • Assets organized and documented

Project Comparison Table

Project Difficulty Time Depth of Understanding Fun Factor
1. Toolchain and ROM Header Verification Level 2 Weekend Medium *****
2. Frame Loop + Input Sampler Level 2 Weekend Medium *****
3. Tile Renderer + Background Test Level 3 1-2 weeks High *****
4. Scrolling Playground Level 3 1-2 weeks High *****
5. Sprite Pipeline + DMA Level 3 1-2 weeks High *****
6. Save RAM + Banking Level 4 2 weeks High *****
7. Timer-Driven Animation Level 3 1-2 weeks High *****
8. Audio Driver Mini Level 4 2-3 weeks High *****
9. HUD + Window Layer Level 3 1-2 weeks Medium *****
10. Banked Asset Loader Level 4 2-3 weeks High *****
11. Banked Code Loader Level 4 2-3 weeks High *****
12. Debug Overlay & Profiler Level 4 2-3 weeks High *****
13. Raster/Scanline Effects Level 5 3-4 weeks Very High *****
14. ROM Data Explorer Level 3 1-2 weeks High *****
15. Mini Game - Puzzle Level 4 3-4 weeks Very High *****
16. Large Map Streaming Level 4 3-4 weeks Very High *****
17. Performance Budgeter Level 5 3-4 weeks Very High *****
18. ROM Patch Pipeline Level 4 2 weeks High *****
19. ROM Hack - Content Swap Level 5 4-6 weeks Very High *****
20. Final DMG Game Project Level 5 6-10 weeks Mastery *****

Recommendation

If you are new to DMG development: Start with Project 1 and Project 2 to establish a correct boot pipeline and stable frame loop. If you are a ROM hacker: Start with Project 14 and Project 18, then move to Project 19 for a safe, legal modification workflow. If you want full mastery: Follow the Homebrew Builder path and finish with Project 20.

Final Overall Project: DMG Master Cartridge

The Goal: Combine Projects 10, 12, 16, and 20 into a single production-quality DMG game with streaming maps, performance profiling, and a robust save system.

  1. Build the full game loop with banking, audio, and a final level set.
  2. Integrate debug overlays and performance budgets for stability.
  3. Validate on strict emulators and, if possible, real hardware.

Success Criteria: The game boots on DMG hardware, runs at stable frame timing, and preserves save data reliably.

From Learning to Production: What Is Next

Your Project Production Equivalent Gap to Fill
Project 10 Production asset pipeline Automated asset compression and validation
Project 12 In-house performance tooling Automated regression benchmarks
Project 16 Streaming engine Robust asset paging and fallbacks
Project 20 Shipping DMG game Testing on hardware, QA, packaging

Summary

This learning path covers Game Boy DMG assembly through 20 hands-on projects.

# Project Name Main Language Difficulty Time Estimate
1 Toolchain and ROM Header Verification Assembly (SM83) Level 2 Weekend
2 Frame Loop + Input Sampler Assembly (SM83) Level 2 Weekend
3 Tile Renderer + Background Test Assembly (SM83) Level 3 1-2 weeks
4 Scrolling Playground Assembly (SM83) Level 3 1-2 weeks
5 Sprite Pipeline + DMA Assembly (SM83) Level 3 1-2 weeks
6 Save RAM + Banking Assembly (SM83) Level 4 2 weeks
7 Timer-Driven Animation Assembly (SM83) Level 3 1-2 weeks
8 Audio Driver Mini Assembly (SM83) Level 4 2-3 weeks
9 HUD + Window Layer Assembly (SM83) Level 3 1-2 weeks
10 Banked Asset Loader Assembly (SM83) Level 4 2-3 weeks
11 Banked Code Loader Assembly (SM83) Level 4 2-3 weeks
12 Debug Overlay & Profiler Assembly (SM83) Level 4 2-3 weeks
13 Raster/Scanline Effects Assembly (SM83) Level 5 3-4 weeks
14 ROM Data Explorer Assembly (SM83) Level 3 1-2 weeks
15 Mini Game - Puzzle Assembly (SM83) Level 4 3-4 weeks
16 Large Map Streaming Assembly (SM83) Level 4 3-4 weeks
17 Performance Budgeter Assembly (SM83) Level 5 3-4 weeks
18 ROM Patch Pipeline Assembly (SM83) Level 4 2 weeks
19 ROM Hack - Content Swap Assembly (SM83) Level 5 4-6 weeks
20 Final DMG Game Project Assembly (SM83) Level 5 6-10 weeks

Expected Outcomes

  • You can build a DMG game from a clean toolchain to a production-ready ROM.
  • You can reason about VRAM/OAM timing and frame budgets with confidence.
  • You can create legal ROM patches for games you own.

Additional Resources and References

Standards and Specifications

  • Pan Docs (Game Boy technical reference): https://gbdev.io/pandocs/
  • RGBDS toolchain documentation: https://rgbds.gbdev.io/
  • VCDIFF delta format (RFC 3284): https://www.rfc-editor.org/rfc/rfc3284

DMG Hardware References

  • Game Boy Memory Map (Pan Docs): https://gbdev.io/pandocs/Memory_Map.html
  • LCD Control (Pan Docs): https://gbdev.io/pandocs/LCDC.html
  • OAM DMA Transfer (Pan Docs): https://gbdev.io/pandocs/OAM_DMA_Transfer.html
  • Interrupts (Pan Docs): https://gbdev.io/pandocs/Interrupts.html
  • Joypad Input (Pan Docs): https://gbdev.io/pandocs/Joypad_Input.html
  • Audio Registers (Pan Docs): https://gbdev.io/pandocs/Audio_Registers.html
  • Cartridge Header (Pan Docs): https://gbdev.io/pandocs/The_Cartridge_Header.html
  • MBC1 (Pan Docs): https://gbdev.io/pandocs/MBC1.html
  • CPU Comparison with Z80 (Pan Docs): https://gbdev.io/pandocs/CPU_Comparison_with_Z80.html
  • PPU timing reference (gbdoc): https://gbdev.github.io/gbdoc/#/articles/graphics/index?id=ppu-timing

ROM Hacking and Patching

  • IPS patching overview: https://en.wikipedia.org/wiki/International_Patching_System
  • xdelta (VCDIFF) documentation: http://xdelta.org/

Historical Context

  • Game Boy sales figures and system overview: https://en.wikipedia.org/wiki/Game_Boy

Test Suites and Emulators

  • Mooneye GB test suite: https://github.com/Gekkio/mooneye-gb
  • BGB emulator: https://bgb.bircd.org/