diff --git a/README.md b/README.md new file mode 100644 index 0000000..fdb4837 --- /dev/null +++ b/README.md @@ -0,0 +1,313 @@ +# vice-mcp + +A Model Context Protocol (MCP) server for autonomous C64 debugging via the VICE emulator. + +## What is this? + +vice-mcp bridges AI agents to the VICE Commodore 64 emulator, enabling autonomous debugging of 6502 assembly programs. Unlike raw protocol wrappers, it provides a **semantic layer** that interprets C64-specific data structures and returns meaningful, actionable information. + +**Why this exists:** +- AI agents need more than hex dumps—they need interpreted data with context +- Debugging C64 code requires understanding VIC-II banks, PETSCII encoding, sprite pointers, and memory layouts +- Every response includes hints suggesting next steps and related tools + +**Key differentiators:** +- **Semantic output**: `readScreen` returns text, not screen codes. `readVicState` explains graphics modes, not register bits. +- **Actionable hints**: Every response suggests what to do next +- **Cross-references**: Tools point to related tools for common workflows +- **Agent-friendly errors**: Clear error codes and recovery suggestions + +## Prerequisites + +- **Node.js** 18 or later +- **VICE emulator** with binary monitor enabled + +### Starting VICE with Binary Monitor + +```bash +# x64sc is the accurate C64 emulator (recommended) +x64sc -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502 + +# Or with x64 (faster, less accurate) +x64 -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502 +``` + +The binary monitor listens on port 6502 by default. + +## Installation + +### From npm (when published) + +```bash +npx @simen/vice-mcp +``` + +### From GitHub + +```bash +npx github:simen/vice-mcp +``` + +### Local Development + +```bash +git clone https://github.com/simen/vice-mcp.git +cd vice-mcp +npm install +npm run build +npm start +``` + +## Configuration + +Add to your MCP client configuration (e.g., Claude Desktop, Cursor, or custom agent): + +```json +{ + "mcpServers": { + "vice": { + "command": "npx", + "args": ["@simen/vice-mcp"] + } + } +} +``` + +Or for local development: + +```json +{ + "mcpServers": { + "vice": { + "command": "node", + "args": ["/path/to/vice-mcp/dist/index.js"] + } + } +} +``` + +## Tool Reference + +### Connection & Status + +| Tool | Description | +|------|-------------| +| `connect` | Connect to VICE (default: 127.0.0.1:6502) | +| `disconnect` | Disconnect from VICE | +| `status` | Get connection state and emulation status | + +### Memory Operations + +| Tool | Description | +|------|-------------| +| `readMemory` | Read raw bytes with hex dump and ASCII | +| `writeMemory` | Write bytes to memory | + +### CPU & Execution + +| Tool | Description | +|------|-------------| +| `getRegisters` | Get A, X, Y, SP, PC, and flags (interpreted) | +| `step` | Single-step execution (with step-over option) | +| `continue` | Resume execution | +| `reset` | Soft or hard reset | +| `runTo` | Run until specific address (temporary breakpoint) | +| `disassemble` | Disassemble 6502 code with KERNAL labels | + +### Breakpoints & Watchpoints + +| Tool | Description | +|------|-------------| +| `setBreakpoint` | Set execution breakpoint | +| `deleteBreakpoint` | Remove breakpoint or watchpoint | +| `listBreakpoints` | List all breakpoints | +| `toggleBreakpoint` | Enable/disable breakpoint | +| `setWatchpoint` | Set memory read/write watchpoint | +| `listWatchpoints` | List all watchpoints | + +### Semantic Layer (Interpreted C64 Data) + +| Tool | Description | +|------|-------------| +| `readScreen` | Get screen as text (PETSCII decoded) with summary mode | +| `readColorRam` | Get color RAM with color names and usage stats | +| `readVicState` | Full VIC-II state: graphics mode, colors, banks, sprites | +| `readSprites` | All 8 sprites: position, visibility, colors, pointers | + +### Visual Feedback + +| Tool | Description | +|------|-------------| +| `screenshot` | Capture display buffer with palette | +| `renderScreen` | ASCII art rendering of display | + +### State Management + +| Tool | Description | +|------|-------------| +| `saveSnapshot` | Save complete machine state to file | +| `loadSnapshot` | Load machine state from file | +| `loadProgram` | Load and optionally run PRG/D64/T64 files | + +## Example Usage + +### Basic Debugging Session + +``` +1. connect() → Establish connection +2. loadProgram("game.prg") → Load the program +3. setBreakpoint(0x0810) → Break at main loop +4. continue() → Run until breakpoint +5. getRegisters() → Check CPU state +6. readScreen() → See what's on screen +7. step(count: 5) → Execute 5 instructions +8. disassemble() → See code at current PC +``` + +### Debugging Sprite Issues + +``` +1. readVicState() → Check sprite enable bits +2. readSprites(enabledOnly: true) → Get enabled sprite details + → Response includes visibility check and position analysis +3. If sprite not visible, hint tells you why (off-screen, wrong bank, etc.) +``` + +### Memory Watchpoint Workflow + +``` +1. setWatchpoint(startAddress: 0x0400, type: "store") + → Watch for writes to screen RAM +2. continue() + → Execution stops when something writes to screen +3. getRegisters() + → See PC to find the code that wrote +4. disassemble() + → Understand what the code is doing +``` + +### State Checkpoint Pattern + +``` +1. saveSnapshot("before-test.vsf") → Save state +2. [Make changes, test things] +3. loadSnapshot("before-test.vsf") → Restore to known state +``` + +## Response Format + +All responses include: +- **Structured data** with `value` and `hex` representations +- **`_meta` block** with connection state +- **`hint` field** with contextual next steps + +Example `getRegisters` response: +```json +{ + "a": { "value": 65, "hex": "$41" }, + "x": { "value": 0, "hex": "$00" }, + "y": { "value": 0, "hex": "$00" }, + "sp": { "value": 243, "hex": "$f3", "stackTop": "$01f3" }, + "pc": { "value": 2049, "hex": "$0801" }, + "flags": { + "negative": false, + "overflow": false, + "zero": false, + "carry": false, + "string": "nv-bdizc" + }, + "hint": "CPU state looks normal", + "_meta": { + "connected": true, + "running": false, + "host": "127.0.0.1", + "port": 6502 + } +} +``` + +## Architecture Overview + +``` +┌─────────────────────────────────────────────────────────┐ +│ MCP Client (Agent) │ +└─────────────────────────────────────────────────────────┘ + │ + │ MCP Protocol (stdio) + ▼ +┌─────────────────────────────────────────────────────────┐ +│ src/index.ts │ +│ (MCP Server) │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ Tool Handlers (24 tools) │ │ +│ │ • Connection: connect, disconnect, status │ │ +│ │ • Memory: readMemory, writeMemory │ │ +│ │ • CPU: getRegisters, step, continue, reset │ │ +│ │ • Breakpoints: set, delete, list, toggle │ │ +│ │ • Watchpoints: set, list │ │ +│ │ • Semantic: readScreen, readVicState, etc. │ │ +│ │ • Visual: screenshot, renderScreen │ │ +│ │ • State: saveSnapshot, loadSnapshot, loadPrg │ │ +│ └─────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────┘ + │ + │ Uses + ▼ +┌─────────────────────────────────────────────────────────┐ +│ src/protocol/client.ts │ +│ (ViceClient) │ +│ • TCP socket connection to VICE │ +│ • Binary protocol encoding/decoding │ +│ • Request/response correlation │ +│ • Checkpoint (breakpoint/watchpoint) tracking │ +└─────────────────────────────────────────────────────────┘ + │ + │ TCP Socket + ▼ +┌─────────────────────────────────────────────────────────┐ +│ VICE Binary Monitor │ +│ (Port 6502) │ +└─────────────────────────────────────────────────────────┘ +``` + +### Key Files + +| File | Purpose | +|------|---------| +| `src/index.ts` | MCP server, tool definitions, semantic layer | +| `src/protocol/client.ts` | VICE binary monitor client | +| `src/protocol/types.ts` | Protocol constants and types | +| `src/utils/c64.ts` | C64 utilities (PETSCII, colors, VIC banks) | +| `src/utils/disasm.ts` | 6502 disassembler with all addressing modes | + +### Design Principles + +1. **Semantic over raw**: Return interpreted data, not just bytes +2. **Hints everywhere**: Every response suggests next actions +3. **Cross-references**: Tools reference related tools +4. **Fail informatively**: Errors explain what went wrong and how to fix it +5. **Agent-first**: Designed for autonomous operation, not human CLI use + +## Protocol Reference + +vice-mcp implements the [VICE Binary Monitor Protocol](https://vice-emu.sourceforge.io/vice_13.html). Key commands used: + +| Code | Command | Purpose | +|------|---------|---------| +| 0x01 | MemoryGet | Read memory | +| 0x02 | MemorySet | Write memory | +| 0x12 | CheckpointSet | Create breakpoint/watchpoint | +| 0x13 | CheckpointDelete | Remove checkpoint | +| 0x15 | CheckpointToggle | Enable/disable checkpoint | +| 0x31 | RegistersGet | Read CPU registers | +| 0x41 | Dump | Save snapshot | +| 0x42 | Undump | Load snapshot | +| 0x81 | Continue | Resume execution | +| 0x82 | Step | Single-step | +| 0x84 | DisplayGet | Capture screen | +| 0x91 | PaletteGet | Get color palette | +| 0xdd | AutoStart | Load and run program | + +## License + +MIT