writeMemory
Modify C64 memory by writing bytes to specific addresses for testing, patching code, or adjusting screen/color RAM in the VICE emulator.
Instructions
Write bytes to the C64's memory.
Directly modifies memory at the specified address. Changes take effect immediately.
Common uses:
Poke values for testing
Patch code at runtime
Modify screen/color RAM directly
Change VIC/SID registers
Be careful writing to ROM areas ($A000-$BFFF, $E000-$FFFF) - you may need to bank out ROM first.
Related tools: readMemory, fillMemory
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Start address (0x0000-0xFFFF) | |
| bytes | Yes | Array of bytes to write (0-255 each) |
Implementation Reference
- src/index.ts:280-326 (registration)MCP tool registration for 'writeMemory', including schema, description, and thin handler that delegates to ViceClient.writeMemoryserver.registerTool( "writeMemory", { description: `Write bytes to the C64's memory. Directly modifies memory at the specified address. Changes take effect immediately. Common uses: - Poke values for testing - Patch code at runtime - Modify screen/color RAM directly - Change VIC/SID registers Be careful writing to ROM areas ($A000-$BFFF, $E000-$FFFF) - you may need to bank out ROM first. Related tools: readMemory, fillMemory`, inputSchema: z.object({ address: z .number() .min(0) .max(0xffff) .describe("Start address (0x0000-0xFFFF)"), bytes: z .array(z.number().min(0).max(255)) .min(1) .describe("Array of bytes to write (0-255 each)"), }), }, async (args) => { try { await client.writeMemory(args.address, args.bytes); return formatResponse({ success: true, address: { value: args.address, hex: `$${args.address.toString(16).padStart(4, "0")}`, }, bytesWritten: args.bytes.length, message: `Wrote ${args.bytes.length} byte(s) to $${args.address.toString(16).padStart(4, "0")}`, }); } catch (error) { return formatError(error as ViceError); } } );
- src/protocol/client.ts:397-437 (handler)Core handler implementation in ViceClient that sends MemorySet command to VICE binary monitor protocol to write memoryasync writeMemory( address: number, data: Buffer | number[], memspace: MemorySpace = MemorySpace.MainCPU ): Promise<void> { const dataBuffer = Buffer.isBuffer(data) ? data : Buffer.from(data); 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)" ); } if (dataBuffer.length === 0) { throw this.makeError( "INVALID_DATA", "Cannot write empty data", "Provide at least one byte to write" ); } if (address + dataBuffer.length > 0x10000) { throw this.makeError( "INVALID_RANGE", `Write would extend past end of memory (0x${address.toString(16)} + ${dataBuffer.length} bytes)`, "Reduce data length or use a lower start address" ); } // Build request: side_effects(1) + start(2) + memspace(1) + length-1(1) + data(N) const body = Buffer.alloc(5 + dataBuffer.length); body[0] = 0; // No side effects body.writeUInt16LE(address, 1); body[3] = memspace; body[4] = dataBuffer.length - 1; dataBuffer.copy(body, 5); await this.sendCommand(Command.MemorySet, body); }
- src/index.ts:296-306 (schema)Zod input schema validation for the writeMemory tool parametersinputSchema: z.object({ address: z .number() .min(0) .max(0xffff) .describe("Start address (0x0000-0xFFFF)"), bytes: z .array(z.number().min(0).max(255)) .min(1) .describe("Array of bytes to write (0-255 each)"), }),