Sega Master System / Game Gear / SG-1000 Debugging with Gearsystem
April 24, 2026 · View on GitHub
Overview
Debug Sega Master System, Game Gear, and SG-1000 games using the Gearsystem emulator as an MCP server. Control execution (pause, step, breakpoints), inspect the Z80 CPU and hardware (VDP, PSG, YM2413), read/write memory across multiple areas (ROM+RAM, VRAM, CRAM), disassemble code, trace instructions, rewind to earlier states, view sprites, and capture screenshots — all through MCP tool calls. Hardware documentation is available in the references/ directory and also at SMS Power! Development Documents.
MCP Server Prerequisite
IMPORTANT — Check before installing: Before attempting any installation or configuration, you MUST first verify if the Gearsystem MCP server is already connected in your current session. Call debug_get_status — if it returns a valid response, the server is active and ready.
Only if the tool is not available or the call fails, you need to help install and configure the Gearsystem MCP server:
Installing Gearsystem
Run the bundled install script (macOS/Linux):
bash scripts/install.sh
This installs Gearsystem via Homebrew on macOS or downloads the latest release on Linux. It prints the binary path on completion. You can also set INSTALL_DIR to control where the binary goes (default: ~/.local/bin).
Alternatively, download from GitHub Releases or install with brew install --cask drhelius/geardome/gearsystem on macOS.
Connecting as MCP Server
Configure your AI client to run Gearsystem as an MCP server via STDIO transport. Example for Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"gearsystem": {
"command": "/path/to/gearsystem",
"args": ["--mcp-stdio"]
}
}
}
Replace /path/to/gearsystem with the actual binary path from the install script. Add --headless before --mcp-stdio on headless machines.
Hardware Documentation (References)
SMS/GG/SG-1000 hardware documentation is available in the references/ directory. Load them into your context when investigating specific hardware. Additional community documentation is available at SMS Power! Development Documents.
| Reference | File | Quality | Load when... |
|---|---|---|---|
| SMS VDP (MacDonald) | references/msvdp.md | PRIMARY — hardware-tested, definitive | VDP registers, display modes, Mode 4, CRAM, sprites, scrolling, display timing, interrupts, GG/Genesis VDP |
| SMS/GG Hardware (MacDonald) | references/smstech.md | PRIMARY — hardware-tested, definitive | I/O ports, memory map, memory control, nationalization, interrupts (IM 0/1/2), BIOS, GG stereo, YM2413 detection |
| SMS Technical Info (Talbot-Watkins) | references/richard.md | HIGH — comprehensive, best YM2413 detail | YM2413 FM registers, SN76489 PSG, paging registers, line interrupt examples, VDP overview |
| TMS9918A VDP (Sean Young) | references/tms9918a.md | HIGH — detailed TMS9918 reference | SG-1000 video modes, TMS9918 legacy modes on SMS, Graphic I/II, Text, Multicolor, undocumented modes |
| SG-1000 Specs (Cornut) | references/sg1000.md | MEDIUM — concise SG-1000 quick ref | SG-1000 memory map, TMS9918 palette, basic VDP/PSG, SG-1000 specifics |
| SMS/GG Technical (Jon) | references/jon.md | MEDIUM — unique GG serial link info | Game Gear Gear-to-Gear cable protocol, GG Start button, GG serial communication |
Debugging Workflow
1. Load and Orient
load_media → get_media_info → get_z80_status → get_screenshot
Start every session by loading the ROM, confirming it loaded correctly (file path, type, size, mapper, zone, system), then checking Z80 CPU state and taking a screenshot to understand the current game state. If a .sym file exists alongside the ROM, symbols are loaded automatically. Gearsystem supports sjasmplus/Pasmo (EQU), SDCC/NoICE (.noi), wla-dx, and vasm/generic symbol formats.
Load additional symbols with load_symbols or add individual labels with add_symbol.
2. Pause and Inspect
Always call debug_pause before inspecting state. While paused:
- CPU state:
get_z80_status— registers AF, BC, DE, HL, AF', BC', DE', HL', IX, IY, SP, PC, WZ, I, R, flags (S, Z, H, P/V, N, C), interrupt state, halt status, interrupt mode (0/1/2) - Disassembly:
get_disassemblywith a start/end address range - Call stack:
get_call_stack— current subroutine hierarchy - Memory:
read_memorywith area name and address/length. Uselist_memory_areasto see all available areas - Sprites:
list_sprites— all 64 sprites with position, size, pattern index
3. Set Breakpoints
Use breakpoints to stop execution at points of interest:
| Breakpoint Type | Tool | Use Case |
|---|---|---|
| Execution | set_breakpoint (type: exec) | Stop when PC reaches address |
| Read | set_breakpoint (type: read) | Stop when memory address is read |
| Write | set_breakpoint (type: write) | Stop when memory address is written |
| Range | set_breakpoint_range | Cover an address range (exec/read/write) |
| IRQ | toggle_irq_breakpoints | Break on RESET, NMI, or INT interrupts |
Breakpoints support 4 memory areas: rom_ram, vram, cram, vdp_reg. Use the appropriate area depending on what you're debugging.
Important: Read/write breakpoints stop with PC at the instruction after the memory access.
Manage breakpoints with list_breakpoints and remove_breakpoint.
4. Step Through Code
After hitting a breakpoint or pausing:
| Action | Tool | Behavior |
|---|---|---|
| Step Into | debug_step_into | Execute one Z80 instruction, enter subroutines |
| Step Over | debug_step_over | Execute one instruction, skip CALL subroutines |
| Step Out | debug_step_out | Run until RET returns from current subroutine |
| Step Frame | debug_step_frame | Execute until next frame |
| Run To | debug_run_to_cursor | Continue until PC reaches target address |
| Continue | debug_continue | Resume normal execution |
After each step, call get_z80_status and get_disassembly to see where you are.
5. Trace Execution
The trace logger records Z80 instructions interleaved with hardware events (VDP, PSG, YM2413, I/O, bank switching).
set_trace_logwithenabled: trueto start recording (optionally filter event types)- Let the game run or step through code
set_trace_logwithenabled: falseto stop (entries are preserved)get_trace_logto read recorded entries
Tracing is essential for understanding timing-sensitive code, interrupt handlers, VDP timing, and hardware interaction sequences.
Rewind (Time Travel Debugging)
get_rewind_statusreports whether rewind is enabled, how many snapshots are available, total capacity, and how many seconds are currently buffered.rewind_seekjumps to a specific buffered snapshot. The emulator must be paused first.- Use rewind when you need to compare two nearby execution points without managing manual save states.
Typical flow:
debug_pauseget_rewind_statusrewind_seekto an earlier snapshotget_z80_statusandget_disassemblyto inspect the restored pointdebug_continueor keep stepping from there
Hardware Inspection
VDP (Video Display Processor)
get_vdp_registers— all 11 VDP registers (R0-R10) with hex values and descriptionsget_vdp_status— status flags, counters, mode, SG-1000 mode, extended mode 224list_sprites— all 64 sprites with position, size, pattern indexget_sprite_image— get a specific sprite as base64 PNG
PSG (SN76489 Sound)
get_psg_status— all 4 channels (3 tone + 1 noise): volume, period, frequency, GG stereo panning
YM2413 FM Synthesis (Master System only)
get_ym2413_status— 9 FM channels with instruments, key-on state, f-number, block, envelope, rhythm mode, user instrument definition
Screen Capture
get_screenshot— current rendered frame as PNG
Use screenshots after stepping or continuing to see the visual impact of changes.
Memory Areas
Use list_memory_areas to discover all available areas. Breakpoints and memory operations support these key areas:
| Area | Description |
|---|---|
rom_ram | Full Z80 64K address space (ROM + RAM) |
vram | Video RAM — tile patterns, nametable, sprite attribute table |
cram | Color RAM — palette entries |
vdp_reg | VDP register file |
Additional areas for read_memory/write_memory include individual ROM banks, external RAM, BIOS, and more — use list_memory_areas for the complete list.
Common Debugging Scenarios
Finding an Interrupt Handler
toggle_irq_breakpointsto enable breaking on NMI (VBlank) or INT (scanline)debug_continueto run until the interrupt firesget_z80_status+get_disassemblyto see the handler codeget_call_stackto see the call hierarchyadd_symbolto label the handler address and any subroutines it calls
Note: The Z80 NMI vector is fixed at $0066. The INT handler depends on interrupt mode (IM 0/1/2). In IM 1 (most common for SMS), INT jumps to $0038.
Diagnosing Graphics Corruption
debug_pause→get_vdp_registers— check mode, nametable, sprite table, and pattern addressesget_vdp_status— verify status flags, line counter, interrupt stateread_memory(area: vram) — inspect tile patterns, nametable, and sprite attribute tableread_memory(area: cram) — check palette datalist_sprites— verify sprite positions, patterns, and ordering- Set read/write breakpoints (area: vram) on display data addresses to catch corruption source
Analyzing a Subroutine
set_breakpointat the subroutine entry pointdebug_continue→ when hit,get_z80_status- Step through with
debug_step_into/debug_step_over - After each step: check registers, read relevant memory
add_symbolfor the routine and any called subroutinesadd_disassembler_bookmarkto mark interesting locations
Tracking a Variable
add_memory_watchon the variable's address — watches are visible in the emulator GUI- Set a write breakpoint with
set_breakpoint(type: write) on that address - When hit,
get_disassemblyreveals what code is modifying it get_call_stackshows the call chain leading to the write
Inspecting VDP Timing
toggle_irq_breakpointsto break on INT (scanline interrupt)get_vdp_statusto check the line counter and flagsget_trace_logto see interleaved Z80 + VDP events- Check VDP register writes in the trace for mid-frame register changes (raster effects)
Debugging Sound
get_psg_status— check all 4 PSG channels (tone frequencies, volumes, noise mode)get_ym2413_status— check FM synthesis state (instruments, key-on, channels)- Set write breakpoints on PSG I/O port ($7E-$7F) or YM2413 ports (F1) to catch sound writes
- Step through the sound driver code and correlate register writes with audio output
Organizing Your Debug Session
- Symbols: Use
add_symbolliberally to label addresses — makes disassembly readable - Bookmarks: Use
add_disassembler_bookmarkfor code locations andadd_memory_bookmarkfor data regions - Watches: Use
add_memory_watchfor variables you're tracking across steps - Save states: Use
save_state/load_stateto snapshot and restore emulator state at interesting points - Screenshots: Capture visual state with
get_screenshotafter significant changes - Modify registers: Use
write_z80_registerto change register values live (AF, BC, DE, HL, IX, IY, SP, PC, etc.)