getRegisters
Retrieve the current CPU register state to debug Commodore 64 programs, including accumulator, index registers, stack pointer, program counter, and status flags.
Instructions
Get current 6502/6510 CPU register state.
Returns all CPU registers with interpreted flags.
Registers:
A: Accumulator (arithmetic operations)
X, Y: Index registers (addressing, loops)
SP: Stack pointer ($100-$1FF range)
PC: Program counter (current instruction address)
Flags: N(egative), V(overflow), B(reak), D(ecimal), I(nterrupt), Z(ero), C(arry)
Use this to:
Check CPU state at breakpoints
Understand program flow
Debug crashes (check PC, SP)
Related tools: setRegister, step, continue, status
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/index.ts:328-435 (registration)MCP tool registration for 'getRegisters'. Includes tool description and inline handler function that fetches registers via ViceClient, parses response, decodes flags, and returns formatted JSON with hex values and hints.server.registerTool( "getRegisters", { description: `Get current 6502/6510 CPU register state. Returns all CPU registers with interpreted flags. Registers: - A: Accumulator (arithmetic operations) - X, Y: Index registers (addressing, loops) - SP: Stack pointer ($100-$1FF range) - PC: Program counter (current instruction address) - Flags: N(egative), V(overflow), B(reak), D(ecimal), I(nterrupt), Z(ero), C(arry) Use this to: - Check CPU state at breakpoints - Understand program flow - Debug crashes (check PC, SP) Related tools: setRegister, step, continue, status`, }, async () => { try { const response = await client.getRegisters(); // Parse register response // Format: count(2) + [id(1) + size(1) + value(size)]... const count = response.body.readUInt16LE(0); const registers: Record<string, number> = {}; let offset = 2; const regNames: Record<number, string> = { 0: "A", 1: "X", 2: "Y", 3: "PC", 4: "SP", 5: "FL", // Flags }; for (let i = 0; i < count && offset < response.body.length; i++) { const id = response.body[offset]; const size = response.body[offset + 1]; offset += 2; let value = 0; if (size === 1) { value = response.body[offset]; } else if (size === 2) { value = response.body.readUInt16LE(offset); } offset += size; const name = regNames[id] || `R${id}`; registers[name] = value; } // Parse flags const flags = registers.FL || 0; const flagsDecoded = { negative: !!(flags & 0x80), overflow: !!(flags & 0x40), break: !!(flags & 0x10), decimal: !!(flags & 0x08), interrupt: !!(flags & 0x04), 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({ a: { value: registers.A, hex: `$${(registers.A || 0).toString(16).padStart(2, "0")}` }, x: { value: registers.X, hex: `$${(registers.X || 0).toString(16).padStart(2, "0")}` }, y: { value: registers.Y, hex: `$${(registers.Y || 0).toString(16).padStart(2, "0")}` }, sp: { value: registers.SP, hex: `$${(registers.SP || 0).toString(16).padStart(2, "0")}`, stackTop: `$01${(registers.SP || 0).toString(16).padStart(2, "0")}`, }, pc: { value: registers.PC, hex: `$${(registers.PC || 0).toString(16).padStart(4, "0")}`, }, flags: flagsDecoded, hint: registers.SP !== undefined && registers.SP < 0x10 ? "Warning: Stack pointer very low - possible stack overflow" : registers.SP !== undefined && registers.SP > 0xf0 ? "Warning: Stack nearly empty - possible stack underflow" : "CPU state looks normal", }); } catch (error) { return formatError(error as ViceError); } } );
- src/index.ts:349-433 (handler)Executes the getRegisters tool: calls ViceClient.getRegisters(), parses the binary response into named registers (A,X,Y,PC,SP,FL), decodes flag bits into NV-BDIZC string and booleans, formats with hex representations and stack overflow warnings, returns via formatResponse.async () => { try { const response = await client.getRegisters(); // Parse register response // Format: count(2) + [id(1) + size(1) + value(size)]... const count = response.body.readUInt16LE(0); const registers: Record<string, number> = {}; let offset = 2; const regNames: Record<number, string> = { 0: "A", 1: "X", 2: "Y", 3: "PC", 4: "SP", 5: "FL", // Flags }; for (let i = 0; i < count && offset < response.body.length; i++) { const id = response.body[offset]; const size = response.body[offset + 1]; offset += 2; let value = 0; if (size === 1) { value = response.body[offset]; } else if (size === 2) { value = response.body.readUInt16LE(offset); } offset += size; const name = regNames[id] || `R${id}`; registers[name] = value; } // Parse flags const flags = registers.FL || 0; const flagsDecoded = { negative: !!(flags & 0x80), overflow: !!(flags & 0x40), break: !!(flags & 0x10), decimal: !!(flags & 0x08), interrupt: !!(flags & 0x04), 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({ a: { value: registers.A, hex: `$${(registers.A || 0).toString(16).padStart(2, "0")}` }, x: { value: registers.X, hex: `$${(registers.X || 0).toString(16).padStart(2, "0")}` }, y: { value: registers.Y, hex: `$${(registers.Y || 0).toString(16).padStart(2, "0")}` }, sp: { value: registers.SP, hex: `$${(registers.SP || 0).toString(16).padStart(2, "0")}`, stackTop: `$01${(registers.SP || 0).toString(16).padStart(2, "0")}`, }, pc: { value: registers.PC, hex: `$${(registers.PC || 0).toString(16).padStart(4, "0")}`, }, flags: flagsDecoded, hint: registers.SP !== undefined && registers.SP < 0x10 ? "Warning: Stack pointer very low - possible stack overflow" : registers.SP !== undefined && registers.SP > 0xf0 ? "Warning: Stack nearly empty - possible stack underflow" : "CPU state looks normal", }); } catch (error) { return formatError(error as ViceError); } }
- src/protocol/client.ts:439-444 (helper)ViceClient method that sends RegistersGet command to VICE binary monitor protocol, constructs 1-byte memspace body, expects RegisterInfo response type.async getRegisters(memspace: MemorySpace = MemorySpace.MainCPU): Promise<ViceResponse> { const body = Buffer.alloc(1); body[0] = memspace; // VICE sends RegisterInfo (0x62) as async event with ReqID=0xff return this.sendCommand(Command.RegistersGet, body, ResponseType.RegisterInfo); }