diff --git a/src/index.ts b/src/index.ts index 86b9de6..93504ba 100644 --- a/src/index.ts +++ b/src/index.ts @@ -94,8 +94,8 @@ Related tools: connect, disconnect`, }), hint: state.connected ? state.running - ? "VICE is running. Use step() to pause execution." - : "VICE is paused. Use continue() to resume." + ? "VICE is running. Use setBreakpoint() + continue() to pause at a specific point, or step() to execute one instruction." + : "VICE is paused. Use continue() to resume or step() to execute one instruction." : "Not connected. Use connect() to establish connection to VICE.", }); } @@ -383,6 +383,17 @@ Related tools: setRegister, step, continue, status`, zero: !!(flags & 0x02), carry: !!(flags & 0x01), raw: flags, + // Compact string representation: NV-BDIZC (uppercase = set) + string: [ + flags & 0x80 ? "N" : "n", + flags & 0x40 ? "V" : "v", + "-", + flags & 0x10 ? "B" : "b", + flags & 0x08 ? "D" : "d", + flags & 0x04 ? "I" : "i", + flags & 0x02 ? "Z" : "z", + flags & 0x01 ? "C" : "c", + ].join(""), }; return formatResponse({ @@ -597,6 +608,45 @@ Related tools: setBreakpoint, listBreakpoints`, } ); +// Tool: listBreakpoints - List all breakpoints +server.registerTool( + "listBreakpoints", + { + description: `List all active breakpoints. + +Shows breakpoint IDs, addresses, and status for all breakpoints set in this session. + +Note: This tracks breakpoints set through this MCP session. Breakpoints set through VICE's built-in monitor may not appear. + +Related tools: setBreakpoint, deleteBreakpoint`, + }, + async () => { + const breakpoints = client.listBreakpoints(); + + if (breakpoints.length === 0) { + return formatResponse({ + count: 0, + breakpoints: [], + hint: "No breakpoints set. Use setBreakpoint() to add one.", + }); + } + + return formatResponse({ + count: breakpoints.length, + breakpoints: breakpoints.map((bp) => ({ + id: bp.id, + address: { + value: bp.address, + hex: `$${bp.address.toString(16).padStart(4, "0")}`, + }, + enabled: bp.enabled, + temporary: bp.temporary, + })), + hint: `${breakpoints.length} breakpoint(s) active. Use deleteBreakpoint(id) to remove.`, + }); + } +); + async function main() { const transport = new StdioServerTransport(); await server.connect(transport); diff --git a/src/protocol/client.ts b/src/protocol/client.ts index 9b0232a..8d5de39 100644 --- a/src/protocol/client.ts +++ b/src/protocol/client.ts @@ -18,6 +18,13 @@ export interface ViceError { suggestion?: string; } +export interface BreakpointInfo { + id: number; + address: number; + enabled: boolean; + temporary: boolean; +} + export class ViceClient { private socket: Socket | null = null; private requestId = 0; @@ -35,6 +42,8 @@ export class ViceClient { port: 0, running: true, }; + // Track breakpoints locally (VICE doesn't have a reliable list command in all versions) + private breakpoints = new Map(); // Event handlers for async events (breakpoints, etc.) public onStopped?: (response: ViceResponse) => void; @@ -415,13 +424,30 @@ export class ViceClient { body[7] = temporary ? 1 : 0; const response = await this.sendCommand(Command.CheckpointSet, body); - return response.body.readUInt32LE(0); + const id = response.body.readUInt32LE(0); + + // Track locally + this.breakpoints.set(id, { + id, + address, + enabled, + temporary, + }); + + return id; } async deleteBreakpoint(checkpointId: number): Promise { const body = Buffer.alloc(4); body.writeUInt32LE(checkpointId, 0); await this.sendCommand(Command.CheckpointDelete, body); + + // Remove from local tracking + this.breakpoints.delete(checkpointId); + } + + listBreakpoints(): BreakpointInfo[] { + return Array.from(this.breakpoints.values()); } }