Skip to main content
Glama
simen

VICE C64 Emulator MCP Server

by simen

setBreakpoint

Set an execution breakpoint at a memory address to debug Commodore 64 programs. When the program counter reaches the address, execution stops for code analysis and debugging.

Instructions

Set an execution breakpoint at a memory address.

When the PC reaches this address, execution stops. Use to:

  • Debug code at specific points

  • Catch when routines are called

  • Analyze code flow

Returns a breakpoint ID for later management.

Related tools: deleteBreakpoint, listBreakpoints, continue, step

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYesAddress to break at (0x0000-0xFFFF)
enabledNoWhether breakpoint is active (default: true)
temporaryNoAuto-delete after hit (default: false)

Implementation Reference

  • src/index.ts:562-604 (registration)
    MCP tool registration for 'setBreakpoint', including schema and handler function
    server.registerTool(
      "setBreakpoint",
      {
        description: `Set an execution breakpoint at a memory address.
    
    When the PC reaches this address, execution stops. Use to:
    - Debug code at specific points
    - Catch when routines are called
    - Analyze code flow
    
    Returns a breakpoint ID for later management.
    
    Related tools: deleteBreakpoint, listBreakpoints, continue, step`,
        inputSchema: z.object({
          address: z.number().min(0).max(0xffff).describe("Address to break at (0x0000-0xFFFF)"),
          enabled: z.boolean().optional().describe("Whether breakpoint is active (default: true)"),
          temporary: z.boolean().optional().describe("Auto-delete after hit (default: false)"),
        }),
      },
      async (args) => {
        try {
          const id = await client.setBreakpoint(args.address, {
            enabled: args.enabled ?? true,
            temporary: args.temporary ?? false,
          });
    
          return formatResponse({
            success: true,
            breakpointId: id,
            address: {
              value: args.address,
              hex: `$${args.address.toString(16).padStart(4, "0")}`,
            },
            enabled: args.enabled ?? true,
            temporary: args.temporary ?? false,
            message: `Breakpoint ${id} set at $${args.address.toString(16).padStart(4, "0")}`,
            hint: "Use continue() to run until breakpoint is hit",
          });
        } catch (error) {
          return formatError(error as ViceError);
        }
      }
    );
  • Handler function for the 'setBreakpoint' MCP tool that validates input, calls ViceClient.setBreakpoint, formats success/error response with metadata
    async (args) => {
      try {
        const id = await client.setBreakpoint(args.address, {
          enabled: args.enabled ?? true,
          temporary: args.temporary ?? false,
        });
    
        return formatResponse({
          success: true,
          breakpointId: id,
          address: {
            value: args.address,
            hex: `$${args.address.toString(16).padStart(4, "0")}`,
          },
          enabled: args.enabled ?? true,
          temporary: args.temporary ?? false,
          message: `Breakpoint ${id} set at $${args.address.toString(16).padStart(4, "0")}`,
          hint: "Use continue() to run until breakpoint is hit",
        });
      } catch (error) {
        return formatError(error as ViceError);
      }
    }
  • Zod input schema defining parameters for setBreakpoint: address (required 0-65535), optional enabled/temporary booleans
    inputSchema: z.object({
      address: z.number().min(0).max(0xffff).describe("Address to break at (0x0000-0xFFFF)"),
      enabled: z.boolean().optional().describe("Whether breakpoint is active (default: true)"),
      temporary: z.boolean().optional().describe("Auto-delete after hit (default: false)"),
    }),
  • ViceClient.setBreakpoint method: validates address, builds VICE binary monitor protocol packet for CheckpointSet (execution breakpoint), sends command, parses ID, tracks locally
    async setBreakpoint(
      address: number,
      options: {
        enabled?: boolean;
        stop?: boolean;
        temporary?: boolean;
      } = {}
    ): Promise<number> {
      const { enabled = true, stop = true, temporary = false } = options;
    
      if (address < 0 || address > 0xffff) {
        throw this.makeError(
          "INVALID_ADDRESS",
          `Address 0x${address.toString(16)} is outside C64 memory range`,
          "C64 addresses are 16-bit (0x0000-0xFFFF)"
        );
      }
    
      // Build request: start(2) + end(2) + stop(1) + enabled(1) + op(1) + temp(1)
      const body = Buffer.alloc(8);
      body.writeUInt16LE(address, 0);
      body.writeUInt16LE(address, 2);
      body[4] = stop ? 1 : 0;
      body[5] = enabled ? 1 : 0;
      body[6] = CheckpointOp.Exec;
      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: address,
        endAddress: address,
        enabled,
        temporary,
        type: "exec",
      });
    
      return id;
    }

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