ppsspp_read_range
Read a contiguous range of bytes from PSP memory and return as a space-separated hex dump. Fetches multiple bytes in a single call, reducing round trips.
Instructions
PURPOSE: Read a contiguous range of bytes from PSP memory and return as a hex dump. USAGE: Use whenever you need more than ~4 bytes — one round-trip vs N typed reads. PPSSPP returns the data base64-encoded over the wire; this tool decodes and formats as space-separated hex bytes. No hard size limit from the WebSocket but stay reasonable (≤16 KiB per call) for response sizes. BEHAVIOR: No side effects — pure read. Reads size consecutive bytes starting at address. Returns an error if any byte in the range is outside the valid PSP memory map. RETURNS: 'ADDR_HEX [N bytes]:' header + space-separated 2-digit uppercase hex bytes.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | PSP physical address. PSP memory layout: user RAM starts at 0x08800000 (or 0x08000000 — varies by firmware allocation), kernel RAM at 0x08000000-0x087FFFFF, VRAM at 0x04000000-0x041FFFFF, scratchpad at 0x00010000-0x00013FFF, hardware regs at 0xBC000000+. Most game state lives in user RAM. Note PPSSPP may also accept 0x88xxxxxx kernel-mode mirrors of the same physical memory. | |
| size | Yes | Number of bytes to read (1-65536). Larger reads work but produce big responses. |
Implementation Reference
- src/tools.ts:110-126 (registration)Tool registration in TOOLS array — defines name, description, inputSchema (address + size params). Registered with the MCP server via ListToolsRequestSchema handler.
{ name: "ppsspp_read_range", description: "PURPOSE: Read a contiguous range of bytes from PSP memory and return as a hex dump. " + "USAGE: Use whenever you need more than ~4 bytes — one round-trip vs N typed reads. PPSSPP returns the data base64-encoded over the wire; this tool decodes and formats as space-separated hex bytes. No hard size limit from the WebSocket but stay reasonable (≤16 KiB per call) for response sizes. " + "BEHAVIOR: No side effects — pure read. Reads `size` consecutive bytes starting at `address`. Returns an error if any byte in the range is outside the valid PSP memory map. " + "RETURNS: 'ADDR_HEX [N bytes]:' header + space-separated 2-digit uppercase hex bytes.", inputSchema: { type: "object", required: ["address", "size"], properties: { address: { type: "integer", minimum: 0, description: ADDRESS_PARAM_DESC }, size: { type: "integer", minimum: 1, maximum: 65536, description: "Number of bytes to read (1-65536). Larger reads work but produce big responses." }, }, additionalProperties: false, }, }, - src/tools.ts:117-125 (schema)Input schema — requires address (integer >=0) and size (integer 1-65536). No additional properties allowed.
inputSchema: { type: "object", required: ["address", "size"], properties: { address: { type: "integer", minimum: 0, description: ADDRESS_PARAM_DESC }, size: { type: "integer", minimum: 1, maximum: 65536, description: "Number of bytes to read (1-65536). Larger reads work but produce big responses." }, }, additionalProperties: false, }, - src/tools.ts:446-451 (handler)Handler implementation — calls PPSSPP's memory.read via WebSocket with address and size, decodes base64 response, formats as space-separated uppercase hex bytes, returns with header showing address and byte count.
case "ppsspp_read_range": { const r = await pp.call<{ base64: string }>("memory.read", { address: a(), size: p.size }); const bytes = Buffer.from(r.base64 ?? "", "base64"); const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0").toUpperCase()).join(" "); return ok(`${addrHex(a())} [${bytes.length} bytes]:\n${hex}`); }