step
Execute single instructions in the VICE C64 emulator to debug 6502 assembly code, control execution flow, and analyze CPU state changes for program understanding.
Instructions
Execute one or more instructions, then stop.
Single-stepping is essential for understanding code flow and debugging.
Options:
count: Number of instructions to execute (default: 1)
stepOver: If true, treat JSR as single instruction (don't step into subroutines)
After stepping, use getRegisters to see the new CPU state.
Related tools: getRegisters, continue, setBreakpoint, status
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of instructions to step (default: 1) | |
| stepOver | No | Step over JSR calls instead of into them (default: false) |
Implementation Reference
- src/index.ts:461-517 (registration)Registers the MCP tool named 'step' using server.registerTool, including schema and handler function.server.registerTool( "step", { description: `Execute one or more instructions, then stop. Single-stepping is essential for understanding code flow and debugging. Options: - count: Number of instructions to execute (default: 1) - stepOver: If true, treat JSR as single instruction (don't step into subroutines) After stepping, use getRegisters to see the new CPU state. Related tools: getRegisters, continue, setBreakpoint, status`, inputSchema: z.object({ count: z.number().min(1).optional().describe("Number of instructions to step (default: 1)"), stepOver: z.boolean().optional().describe("Step over JSR calls instead of into them (default: false)"), }), }, async (args) => { try { await client.step(args.count || 1, args.stepOver || false); // Get registers after step const regResponse = await client.getRegisters(); const count = regResponse.body.readUInt16LE(0); let offset = 2; let pc = 0; for (let i = 0; i < count && offset < regResponse.body.length; i++) { const id = regResponse.body[offset]; const size = regResponse.body[offset + 1]; offset += 2; if (id === 3 && size === 2) { // PC pc = regResponse.body.readUInt16LE(offset); } offset += size; } return formatResponse({ stepped: true, count: args.count || 1, stepOver: args.stepOver || false, pc: { value: pc, hex: `$${pc.toString(16).padStart(4, "0")}`, }, message: `Stepped ${args.count || 1} instruction(s)`, hint: "Use getRegisters() for full CPU state, or readMemory at PC for next instruction", }); } catch (error) { return formatError(error as ViceError); } } );
- src/index.ts:475-479 (schema)Zod input schema for the 'step' tool, defining optional count and stepOver parameters.inputSchema: z.object({ count: z.number().min(1).optional().describe("Number of instructions to step (default: 1)"), stepOver: z.boolean().optional().describe("Step over JSR calls instead of into them (default: false)"), }), },
- src/index.ts:480-516 (handler)Handler function for the 'step' tool that calls client.step(), fetches updated registers, and formats the response with execution state.async (args) => { try { await client.step(args.count || 1, args.stepOver || false); // Get registers after step const regResponse = await client.getRegisters(); const count = regResponse.body.readUInt16LE(0); let offset = 2; let pc = 0; for (let i = 0; i < count && offset < regResponse.body.length; i++) { const id = regResponse.body[offset]; const size = regResponse.body[offset + 1]; offset += 2; if (id === 3 && size === 2) { // PC pc = regResponse.body.readUInt16LE(offset); } offset += size; } return formatResponse({ stepped: true, count: args.count || 1, stepOver: args.stepOver || false, pc: { value: pc, hex: `$${pc.toString(16).padStart(4, "0")}`, }, message: `Stepped ${args.count || 1} instruction(s)`, hint: "Use getRegisters() for full CPU state, or readMemory at PC for next instruction", }); } catch (error) { return formatError(error as ViceError); } } );
- src/protocol/client.ts:479-486 (helper)ViceClient.step method that sends the Step command to VICE binary monitor protocol with stepOver and count parameters.async step(count = 1, stepOver = false): Promise<ViceResponse> { const body = Buffer.alloc(3); body[0] = stepOver ? 1 : 0; body.writeUInt16LE(count, 1); const response = await this.sendCommand(Command.Step, body); this.state.running = false; return response; }