getRegisters
Retrieve the current CPU register state to monitor program execution, debug crashes, and understand program flow in Commodore 64 emulation.
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:361-446 (handler)MCP tool handler for 'getRegisters'. Fetches raw register data from ViceClient.getRegisters(), parses the response into named registers (A, X, Y, PC, SP, flags), decodes flag bits, formats hex values and provides stack overflow warnings.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:341-446 (registration)Registers the 'getRegisters' tool with the MCP server, providing a detailed description but no input schema (no parameters required)."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/protocol/client.ts:476-481 (helper)Low-level ViceClient helper method that sends the VICE binary monitor 'RegistersGet' command (memspace parameter defaults to MainCPU) and returns the raw ViceResponse containing register data.async getRegisters(memspace: MemorySpace = MemorySpace.MainCPU): Promise<ViceResponse> { const body = Buffer.alloc(1); body[0] = memspace; // VICE sends RegisterInfo (0x31) as async event with ReqID=0xff return this.sendCommand(Command.RegistersGet, body, ResponseType.RegisterInfo); }