Skip to main content
Glama
simen
by simen

setWatchpoint

Set memory watchpoints to debug C64 programs by halting execution when specific addresses are read or written, helping identify unexpected memory access.

Instructions

Set a memory watchpoint to stop when memory is read or written.

Watchpoints are powerful for debugging:

  • "Why is this value changing?" → Use store watchpoint

  • "What's reading this address?" → Use load watchpoint

  • "Track all access to this region" → Use both

Range can be single address or address range (e.g., $D800-$DBFF for color RAM).

Related tools: deleteBreakpoint, listWatchpoints, continue

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
startAddressYesStart address of watched range (0x0000-0xFFFF)
endAddressNoEnd address of watched range (default: same as start for single address)
typeYesWatch type: 'load' (read), 'store' (write), or 'both'
enabledNoWhether watchpoint is active (default: true)
temporaryNoAuto-delete after hit (default: false)

Implementation Reference

  • Core handler implementation that sends the CheckpointSet command to VICE binary monitor to create a memory watchpoint (load/store checkpoint). Handles validation, protocol packet building, and local tracking.
    async setWatchpoint( startAddress: number, endAddress: number, type: "load" | "store" | "both", options: { enabled?: boolean; stop?: boolean; temporary?: boolean; } = {} ): Promise<number> { const { enabled = true, stop = true, temporary = false } = options; if (startAddress < 0 || startAddress > 0xffff) { throw this.makeError( "INVALID_ADDRESS", `Start address 0x${startAddress.toString(16)} is outside C64 memory range`, "C64 addresses are 16-bit (0x0000-0xFFFF)" ); } if (endAddress < 0 || endAddress > 0xffff) { throw this.makeError( "INVALID_ADDRESS", `End address 0x${endAddress.toString(16)} is outside C64 memory range`, "C64 addresses are 16-bit (0x0000-0xFFFF)" ); } if (startAddress > endAddress) { throw this.makeError( "INVALID_RANGE", `Start address (0x${startAddress.toString(16)}) is greater than end address (0x${endAddress.toString(16)})`, "Swap the addresses or check your range" ); } // Determine operation type let op: number; let checkpointType: CheckpointType; if (type === "load") { op = CheckpointOp.Load; checkpointType = "load"; } else if (type === "store") { op = CheckpointOp.Store; checkpointType = "store"; } else { op = CheckpointOp.Load | CheckpointOp.Store; checkpointType = "load"; // Will track as load for simplicity } // Build request: start(2) + end(2) + stop(1) + enabled(1) + op(1) + temp(1) const body = Buffer.alloc(8); body.writeUInt16LE(startAddress, 0); body.writeUInt16LE(endAddress, 2); body[4] = stop ? 1 : 0; body[5] = enabled ? 1 : 0; body[6] = op; body[7] = temporary ? 1 : 0; const response = await this.sendCommand(Command.CheckpointSet, body); const id = response.body.readUInt32LE(0); // Track locally this.checkpoints.set(id, { id, startAddress, endAddress, enabled, temporary, type: checkpointType, }); return id; }
  • src/index.ts:702-761 (registration)
    MCP server registration of the 'setWatchpoint' tool, including description, Zod input schema validation, and thin wrapper handler that delegates to ViceClient.setWatchpoint.
    server.registerTool( "setWatchpoint", { description: `Set a memory watchpoint to stop when memory is read or written. Watchpoints are powerful for debugging: - "Why is this value changing?" → Use store watchpoint - "What's reading this address?" → Use load watchpoint - "Track all access to this region" → Use both Range can be single address or address range (e.g., $D800-$DBFF for color RAM). Related tools: deleteBreakpoint, listWatchpoints, continue`, inputSchema: z.object({ startAddress: z.number().min(0).max(0xffff).describe("Start address of watched range (0x0000-0xFFFF)"), endAddress: z .number() .min(0) .max(0xffff) .optional() .describe("End address of watched range (default: same as start for single address)"), type: z.enum(["load", "store", "both"]).describe("Watch type: 'load' (read), 'store' (write), or 'both'"), enabled: z.boolean().optional().describe("Whether watchpoint is active (default: true)"), temporary: z.boolean().optional().describe("Auto-delete after hit (default: false)"), }), }, async (args) => { try { const endAddr = args.endAddress ?? args.startAddress; const id = await client.setWatchpoint(args.startAddress, endAddr, args.type, { enabled: args.enabled ?? true, temporary: args.temporary ?? false, }); const isSingleAddress = args.startAddress === endAddr; return formatResponse({ success: true, watchpointId: id, startAddress: { value: args.startAddress, hex: `$${args.startAddress.toString(16).padStart(4, "0")}`, }, endAddress: { value: endAddr, hex: `$${endAddr.toString(16).padStart(4, "0")}`, }, type: args.type, enabled: args.enabled ?? true, temporary: args.temporary ?? false, message: isSingleAddress ? `Watchpoint ${id} set at $${args.startAddress.toString(16).padStart(4, "0")} (${args.type})` : `Watchpoint ${id} set for $${args.startAddress.toString(16).padStart(4, "0")}-$${endAddr.toString(16).padStart(4, "0")} (${args.type})`, hint: "Use continue() to run until watchpoint is triggered", }); } catch (error) { return formatError(error as ViceError); } } );
  • Zod schema for input validation of the setWatchpoint tool parameters.
    inputSchema: z.object({ startAddress: z.number().min(0).max(0xffff).describe("Start address of watched range (0x0000-0xFFFF)"), endAddress: z .number() .min(0) .max(0xffff) .optional() .describe("End address of watched range (default: same as start for single address)"), type: z.enum(["load", "store", "both"]).describe("Watch type: 'load' (read), 'store' (write), or 'both'"), enabled: z.boolean().optional().describe("Whether watchpoint is active (default: true)"), temporary: z.boolean().optional().describe("Auto-delete after hit (default: false)"), }),
  • Type definitions for CheckpointInfo (used for watchpoints/breakpoints) and CheckpointType enum.
    export type CheckpointType = "exec" | "load" | "store"; export interface CheckpointInfo { id: number; startAddress: number; endAddress: number; enabled: boolean; temporary: boolean; type: CheckpointType; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/simen/vice-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server