| name | geargrafx-debugging |
| description | Debug and trace TurboGrafx-16 / PC Engine / SuperGrafx games using the Geargrafx emulator MCP server. Provides workflows for HuC6280 CPU debugging, breakpoint management, hardware inspection, disassembly analysis, and execution tracing. Use when the user wants to debug a PC Engine game, trace code execution, inspect CPU registers or hardware state, set breakpoints, analyze interrupts, step through HuC6280 instructions, reverse engineer game code, examine VDC/VCE/PSG registers, view the call stack, or diagnose rendering, audio, or timing issues. Also use when the user mentions PC Engine development, TurboGrafx-16 homebrew testing, SuperGrafx debugging, CD-ROM game debugging, or HuC6280 debugging with Geargrafx. |
| compatibility | Requires the Geargrafx MCP server. Before installing or configuring, call debug_get_status to check if the server is already connected. If it responds, the server is ready — skip setup entirely. |
| metadata | {"author":"drhelius","version":"1.0"} |
TurboGrafx-16 / PC Engine Game Debugging with Geargrafx
Overview
Debug TurboGrafx-16, PC Engine, and SuperGrafx games using the Geargrafx emulator as an MCP server. Control execution (pause, step, breakpoints), inspect the HuC6280 CPU and hardware (HuC6270 VDC, HuC6260 VCE, HuC6202 VPC, PSG), read/write memory, disassemble code, trace instructions, and capture screenshots — all through MCP tool calls. Hardware documentation is available in the references/ directory.
MCP Server Prerequisite
IMPORTANT — Check before installing: Before attempting any installation or configuration, you MUST first verify if the Geargrafx 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 Geargrafx MCP server:
Installing Geargrafx
Run the bundled install script (macOS/Linux):
bash scripts/install.sh
This installs Geargrafx 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/geargrafx on macOS.
Connecting as MCP Server
Configure your AI client to run Geargrafx as an MCP server via STDIO transport. Example for Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"geargrafx": {
"command": "/path/to/geargrafx",
"args": ["--mcp-stdio"]
}
}
}
Replace /path/to/geargrafx with the actual binary path from the install script. Add --headless before --mcp-stdio on headless machines.
Hardware Documentation (References)
PC Engine hardware documentation is available in the references/ directory. Load them into your context when investigating specific hardware.
| Reference | File | Load when... |
|---|
| HuC6280 CPU | references/huc6280_cpu.md | CPU registers, MPR mapping, timer, interrupts, I/O, speed modes |
| Instruction Set | references/huc6280_instructions.md | Opcode reference, addressing modes, cycle counts |
| PSG | references/huc6280_psg.md | 6-channel sound: waveform, noise, LFO, volume, DDA |
| HuC6270 VDC | references/huc6270_vdc.md | Video Display Controller: BAT, sprites, scroll, DMA, interrupts |
| HuC6260 VCE | references/huc6260_vce.md | Video Color Encoder: palette, dot clock, color format |
| HuC6202 VPC | references/huc6202_vpc.md | Video Priority Controller (SuperGrafx): window, priority |
| Memory Map | references/memory_map.md | Full memory map: MPR pages, I/O, WRAM, VRAM, ROM banking |
Debugging Workflow
1. Load and Orient
load_media → get_media_info → get_huc6280_status → get_screenshot
Start every session by loading the ROM, confirming it loaded correctly, then checking CPU state and taking a screenshot to understand the current game state. If a .sym, .lbl, or .noi file exists alongside the ROM, symbols are loaded automatically.
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_huc6280_status — registers A, X, Y, S, P (flags), PC, MPR mapping, timer, interrupts, I/O port, speed mode
- Disassembly:
get_disassembly with a start/end address range — only shows executed code paths
- Call stack:
get_call_stack — current subroutine hierarchy
- Memory:
read_memory with a memory area tab ID (use list_memory_areas to discover available areas and their IDs)
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) |
Breakpoints support 5 memory areas: rom_ram (default), vram, palette, huc6270_reg, huc6260_reg.
Important: Read/write breakpoints stop with PC at the instruction after the memory access.
Manage breakpoints with list_breakpoints, remove_breakpoint.
4. Step Through Code
After hitting a breakpoint or pausing:
| Action | Tool | Behavior |
|---|
| Step Into | debug_step_into | Execute one instruction, enter subroutines |
| Step Over | debug_step_over | Execute one instruction, skip JSR calls |
| Step Out | debug_step_out | Run until RTS/RTI returns from current subroutine |
| Step Frame | debug_step_frame | Execute until next VBlank |
| Run To | debug_run_to_cursor | Continue until PC reaches target address |
| Continue | debug_continue | Resume normal execution |
After each step, call get_huc6280_status and get_disassembly to see where you are.
5. Trace Execution
The trace logger records CPU instructions interleaved with hardware events (VDC, VCE, PSG, timer, CD-ROM, SCSI, ADPCM, input).
set_trace_log with enabled: true to start recording (optionally filter event types)
- Let the game run or step through code
set_trace_log with enabled: false to stop (entries are preserved)
get_trace_log to read recorded entries
Available trace event filters: cpu_irq, vdc, vce, psg, timer, input, cdrom, adpcm, scsi. CPU tracing is always on.
Tracing is essential for understanding timing-sensitive code, interrupt handlers, and hardware interaction sequences.
Hardware Inspection
HuC6270 VDC (Video Display Controller)
get_huc6270_status — VDC state: position, control, interrupt flags
get_huc6270_registers — all 20 VDC registers (0x00-0x13), Address Register (AR), Status Register (SR)
write_huc6270_register — write to a VDC register (0-19) or AR (20). Use vdc parameter (1 or 2) for SuperGrafx
list_sprites — all 64 sprites with position, size, pattern, palette
get_sprite_image — get a sprite as a PNG image
HuC6260 VCE (Video Color Encoder)
get_huc6260_status — VCE state: position, sync signals, dot clock, control
HuC6202 VPC (SuperGrafx only)
get_huc6202_status — VPC state: window settings, priority configuration
PSG (Programmable Sound Generator)
get_psg_status — all 6 PSG channels: waveform, frequency, volume, noise, LFO, DDA
CD-ROM Subsystems (CD games only)
get_cdrom_status — CD-ROM drive status
get_cdrom_audio_status — CD audio playback status
get_adpcm_status — ADPCM audio status
get_arcade_card_status — Arcade Card status
CPU
get_huc6280_status — full CPU state: registers, MPR, timer, interrupts, I/O, speed
write_huc6280_register — modify a register live
Screenshots
get_screenshot — current rendered frame as PNG
Use screenshots after stepping or continuing to see the visual impact of changes.
Common Debugging Scenarios
Finding an Interrupt Handler
- Set an execution breakpoint at the IRQ vector address (read the Memory Map resource for the vector table)
debug_continue to run until the IRQ fires
get_huc6280_status + get_disassembly to see the handler code
get_call_stack to see how deep you are
add_symbol to label the handler address and any subroutines it calls
Diagnosing Graphics Corruption
debug_pause → get_huc6270_registers — check BAT, sprite attributes, scroll, DMA settings
get_huc6260_status — verify dot clock, color mode
get_screenshot — capture the current visual state
read_memory on VRAM and SAT areas to inspect tile/sprite data
- Set read/write breakpoints (memory_area:
vram or huc6270_reg) on display buffer addresses to catch corruption source
Analyzing a Subroutine
set_breakpoint at the subroutine entry point
debug_continue → when hit, get_huc6280_status
- Step through with
debug_step_into / debug_step_over
- After each step: check registers, read relevant memory
add_symbol for the routine and any called subroutines
add_disassembler_bookmark to mark interesting locations
Tracking a Variable
add_memory_watch on 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_disassembly reveals what code is modifying it
get_call_stack shows the call chain leading to the write
Timing Analysis
set_trace_log with enabled: true to start recording timer and VDC events
- Let the game run through the section of interest
get_trace_log to see the interleaved CPU + hardware events
- Check VDC interrupt timing via
get_huc6270_status
- Correlate timer fires with code execution in the trace
CD-ROM Game Debugging
load_media with a .cue file to load a CD-ROM image
get_cdrom_status to verify drive state
set_trace_log with cdrom: true and scsi: true to trace CD access patterns
get_adpcm_status to inspect ADPCM audio state
- Set breakpoints on CD-ROM RAM areas to catch data loading
Memory Areas
Use list_memory_areas to get the full list with IDs and sizes. Common areas:
| Area | Description | Typical Size |
|---|
| WRAM | Working RAM | 8KB (32KB for SuperGrafx) |
| ZP | Zero Page (fast variables) | 256 bytes |
| ROM | Game ROM | Varies |
| CARD RAM | HuCard RAM | Varies |
| BRAM | Backup RAM (save data) | 2KB |
| PALETTES | VCE color table | 512 bytes |
| VRAM / VRAM 1 | VDC video RAM | 64KB |
| VRAM 2 | VDC 2 video RAM (SuperGrafx) | 64KB |
| SAT / SAT 1 | Sprite Attribute Table | 512 bytes |
| SAT 2 | SAT for VDC 2 (SuperGrafx) | 512 bytes |
| CDROM RAM | CD-ROM working RAM | Varies |
| ADPCM | ADPCM sample RAM | 64KB |
| ARCADE | Arcade Card RAM | Varies |
| MB128 | Memory Base 128 | 128KB |
Organizing Your Debug Session
- Symbols: Use
add_symbol liberally to label addresses you've identified — makes disassembly readable
- Bookmarks: Use
add_disassembler_bookmark for code locations and add_memory_bookmark for data regions
- Watches: Use
add_memory_watch for variables you're tracking across steps
- Save states: Use
save_state / load_state to snapshot and restore emulator state at interesting points
- Rewind: Use
get_rewind_status + rewind_seek to scrub back through recent execution history without manual save states
- Screenshots: Capture visual state with
get_screenshot after significant changes
Rewind (Time Travel Debugging)
The emulator continuously records snapshots into a ring buffer during gameplay. You can seek to any recorded snapshot to restore full emulator state at that point in time — like time travel debugging.
Workflow
- Check availability:
get_rewind_status — returns snapshot count, capacity, buffered seconds
- Pause:
debug_pause — the emulator must be paused before seeking
- Seek:
rewind_seek with a snapshot number (1 = oldest, snapshot_count = newest)
- Inspect:
get_huc6280_status, get_disassembly, get_screenshot, read_memory, etc.
- Iterate: Seek to different snapshots to narrow down when a bug first appeared
- Resume or continue debugging:
debug_continue to resume from the seeked state
Tools
| Tool | Description |
|---|
get_rewind_status | Snapshot count, capacity, buffered seconds, configuration |
rewind_seek | Jump to snapshot N (1=oldest, count=newest). Non-destructive — can seek repeatedly |
Key Details
- Non-destructive seeking:
rewind_seek loads a snapshot without removing it. You can seek to the same snapshot multiple times, or jump between different snapshots freely.
- Snapshot numbering: Snapshot 1 is the oldest available, snapshot_count is the newest (most recent).
- Buffer size: Configured by the user (default: 10 seconds). When full, oldest snapshots are overwritten.
- Granularity: Snapshots are taken every N frames (configurable). Default is every frame for maximum precision.
Bug Reproduction with Rewind
- Let the game run past the bug occurrence
debug_pause → get_rewind_status to see how far back you can go
- Binary search with
rewind_seek: try the midpoint, check if the bug is visible (get_screenshot), then narrow the range
- Once you find the exact snapshot where the bug appears, inspect CPU/memory state
- Set breakpoints at the relevant code, then
rewind_seek to a snapshot just before the bug and debug_continue