dolphin_read32
Reads a 32-bit big-endian value from PowerPC memory at a specified address. Use for pointers, timestamps, and counters in GameCube and Wii games.
Instructions
PURPOSE: Read an unsigned 32-bit big-endian value from PowerPC memory at the given absolute address. USAGE: The workhorse — most game state and pointers are 32-bit. Use for timestamps, large counters, RGBA colors, full pointers (PowerPC is a 32-bit ISA so pointers fit here). For 8/16/64-bit values use the corresponding sibling. BEHAVIOR: No side effects — pure read. Address MUST be 4-byte aligned. Returns an error on unmapped address, bridge disconnect, or FAIL.
GameCube + Wii main address space landmarks (PowerPC, big-endian): 0x80000000-0x817FFFFF MEM1 main RAM (24 MiB) — GameCube + Wii game code & data GameCube games stay entirely within MEM1. Wii games use MEM1 for code and frequently-accessed data. 0x80000020 OS_GLOBALS — game-info struct (disc ID, FST, etc.) 0x80000034 OS_ARENA_LO (start of free MEM1 heap) 0x80003100 OS_REPORT (developer-console mirror, varies by SDK) 0x90000000-0x93FFFFFF MEM2 (64 MiB) — Wii ONLY. Larger texture/asset data, IOS work areas. Reading MEM2 on a GameCube game returns garbage / FAIL. 0xCC000000-0xCC00FFFF Hollywood I/O (Wii) / Flipper I/O (GameCube) — DMA, GPU FIFO, AI, EXI registers. Reads are usually safe, writes can wedge the emulator. Avoid. 0xCD000000-0xCD007FFF Wii-only Hollywood registers.
Notes: • All multi-byte values are BIG-ENDIAN on the real hardware. Felk's memory.read_u*/write_u* helpers handle the byte swap for you — the value you see is the value the game sees as a u32. • Addresses are 32-bit; Felk truncates the high bits of any u64 address argument. • Pointers in MEM1 are often stored as 4-byte addresses with the high bit set (e.g. 0x81234567). Dereferencing them requires no masking — pass the raw value back into memory.read_*.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Absolute PowerPC virtual address (0x80000000-0x9FFFFFFF). Pass as a number; hex literals like 0x80001000 are fine. Reads 4 consecutive bytes starting here and interprets them as a big-endian value. MUST be 4-byte aligned (address % 4 === 0). PowerPC raises an alignment exception on misaligned access in hardware, but Dolphin's emulated bus is forgiving and silently returns the aligned-down word — i.e. you get the bytes from address & ~3, not what you asked for. For unaligned multi-byte reads use dolphin_read_range and assemble client-side. Useful ranges: 0x80000000-0x817FFFFF for MEM1 (GC + Wii), 0x90000000-0x93FFFFFF for MEM2 (Wii only). |
Implementation Reference
- src/tools.ts:121-137 (schema)Tool definition schema for dolphin_read32, specifying input requires a 4-byte-aligned integer `address` parameter.
{ name: "dolphin_read32", description: "PURPOSE: Read an unsigned 32-bit big-endian value from PowerPC memory at the given absolute address. " + "USAGE: The workhorse — most game state and pointers are 32-bit. Use for timestamps, large counters, RGBA colors, full pointers (PowerPC is a 32-bit ISA so pointers fit here). For 8/16/64-bit values use the corresponding sibling. " + "BEHAVIOR: No side effects — pure read. Address MUST be 4-byte aligned. Returns an error on unmapped address, bridge disconnect, or FAIL.\n\n" + GC_WII_MEMORY_MAP + "\n\n" + "RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.", inputSchema: { type: "object", required: ["address"], properties: { address: { type: "integer", minimum: 0, description: addrParamDesc(4) }, }, additionalProperties: false, }, }, - src/tools.ts:511-511 (handler)Handler for dolphin_read32: reads a 32-bit unsigned big-endian value from PowerPC memory via the bridge's memory.read_u32 call, formats address and value as hex.
case "dolphin_read32": return ok(`${addrHex(a())}: ${fmtHex(await dol.call<number>("memory.read_u32", [a()]))}`); - src/tools.ts:491-491 (registration)Registration of dolphin_read32 via CallToolRequestSchema handler dispatch (case switch at line 511).
server.setRequestHandler(CallToolRequestSchema, async (req) => { - src/tools.ts:488-489 (registration)Registration of all tools (including dolphin_read32) via ListToolsRequestSchema from the TOOLS array.
export function registerTools(server: Server, dol: DolphinClient): void { server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS })); - src/tools.ts:480-482 (helper)Helper functions fmtHex and addrHex used by dolphin_read32 handler for formatting output.
function fmtHex(n: number | bigint): string { return `${n} (0x${n.toString(16).toUpperCase()})`; }