pine_read8
Read a single unsigned byte from PlayStation 2 emulated memory at a specified address, covering EE main RAM, hardware registers, VU memory, and more.
Instructions
Read a single unsigned byte (u8) from emulated memory.
PlayStation 2 main address space landmarks: 0x00000000 EE main RAM (32 MiB) — game code & data 0x10000000 Hardware registers (DMA, GIF, VIF, etc.) 0x11000000 VU0 / VU1 memory 0x12000000 GS privileged registers 0x1C000000 IOP RAM (2 MiB) 0x1F800000 IOP scratchpad 0x70000000 EE scratchpad (16 KiB) PINE memory operations target the EE address space.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Memory address |
Implementation Reference
- src/tools.ts:37-45 (schema)Definition and inputSchema for the pine_read8 tool: reads a single unsigned byte (u8) from emulated memory, with an 'address' integer parameter.
{ name: "pine_read8", description: `Read a single unsigned byte (u8) from emulated memory.\n\n${PS2_REGIONS}`, inputSchema: { type: "object", required: ["address"], properties: { address: { type: "integer", description: "Memory address" } }, }, }, - src/tools.ts:206-206 (handler)Handler for pine_read8 tool: calls pine.read8(addr()), formats the result as 'ADDR: VALUE (0xHEX)' via addrHex/fmtHex helpers.
case "pine_read8": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read8(addr()))}`); - src/pine.ts:215-219 (helper)PineClient.read8() method: sends a PINE Read8 opcode (0x00) with the address as a 4-byte LE argument, returns the response as a single unsigned byte.
async read8(addr: number): Promise<number> { const args = Buffer.alloc(4); args.writeUInt32LE(addr, 0); const r = await this.call(Op.Read8, args); return r.readUInt8(0); } - src/pine.ts:26-26 (helper)Opcode constant Read8 = 0x00, used by the PINE protocol client to request a single byte read.
Read8: 0x00, - src/tools.ts:171-250 (registration)registerTools() sets up the CallToolRequestSchema handler with a switch-case that dispatches tool names including 'pine_read8'.
export function registerTools(server: Server, pine: PineClient): void { server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS })); server.setRequestHandler(CallToolRequestSchema, async (req) => { const { name, arguments: args = {} } = req.params; const p = args as Record<string, unknown>; const addr = () => p.address as number; switch (name) { case "pine_ping": { const v = await pine.getVersion(); return ok(`OK — emulator: ${v}`); } case "pine_get_info": { const [title, id, uuid, gameVer, status] = await Promise.all([ pine.getTitle().catch(() => "(unavailable)"), pine.getId().catch(() => "(unavailable)"), pine.getUuid().catch(() => "(unavailable)"), pine.getGameVersion().catch(() => "(unavailable)"), pine.getStatus(), ]); return ok( `Title: ${title}\n` + `Serial: ${id}\n` + `Disc CRC: ${uuid}\n` + `Game version: ${gameVer}\n` + `Status: ${status}`, ); } case "pine_get_status": { return ok(`Status: ${await pine.getStatus()}`); } case "pine_read8": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read8(addr()))}`); case "pine_read16": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read16(addr()))}`); case "pine_read32": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read32(addr()))}`); case "pine_read64": return ok(`${addrHex(addr())}: ${fmtHex(await pine.read64(addr()))}`); case "pine_write8": { await pine.write8(addr(), p.value as number); return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`); } case "pine_write16": { await pine.write16(addr(), p.value as number); return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`); } case "pine_write32": { await pine.write32(addr(), p.value as number); return ok(`Wrote ${fmtHex(p.value as number)} → ${addrHex(addr())}`); } case "pine_write64": { const v = BigInt(p.value as string); await pine.write64(addr(), v); return ok(`Wrote ${fmtHex(v)} → ${addrHex(addr())}`); } case "pine_read_range": { const bytes = await pine.readRange(p.address as number, p.length as number); const hex = Array.from(bytes) .map((b) => b.toString(16).padStart(2, "0").toUpperCase()) .join(" "); return ok(`${addrHex(p.address as number)} [${bytes.length} bytes]:\n${hex}`); } case "pine_save_state": { await pine.saveState(p.slot as number); return ok(`Save state triggered for slot ${p.slot}`); } case "pine_load_state": { await pine.loadState(p.slot as number); return ok(`Load state triggered for slot ${p.slot}`); } default: throw new Error(`Unknown tool: ${name}`); } }); }