dolphin_read16
Read an unsigned 16-bit big-endian value from PowerPC memory at a specified absolute address. Use for 16-bit fields like HP, score, or coordinates in GameCube and Wii titles.
Instructions
PURPOSE: Read an unsigned 16-bit big-endian value from PowerPC memory at the given absolute address. USAGE: For 16-bit fields — HP, score, coordinates on many GC/Wii titles. For single bytes use dolphin_read8; for 32/64-bit use dolphin_read32/read64. Value is interpreted big-endian (PowerPC native); the byte at address is the high byte. BEHAVIOR: No side effects — pure read. Address MUST be 2-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 2 consecutive bytes starting here and interprets them as a big-endian value. MUST be 2-byte aligned (address % 2 === 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 & ~1, 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:510-510 (handler)Handler for dolphin_read16 — calls the bridge's memory.read_u16 RPC with the parsed address argument, formats the result as 'ADDR_HEX: DEC (0xHEX)' and returns it as text content.
case "dolphin_read16": return ok(`${addrHex(a())}: ${fmtHex(await dol.call<number>("memory.read_u16", [a()]))}`); - src/tools.ts:104-120 (schema)Schema for dolphin_read16 — defines the tool's name, description (covering purpose, usage, behavior, returns), and input schema requiring an integer 'address' that must be 2-byte aligned.
{ name: "dolphin_read16", description: "PURPOSE: Read an unsigned 16-bit big-endian value from PowerPC memory at the given absolute address. " + "USAGE: For 16-bit fields — HP, score, coordinates on many GC/Wii titles. For single bytes use dolphin_read8; for 32/64-bit use dolphin_read32/read64. Value is interpreted big-endian (PowerPC native); the byte at `address` is the high byte. " + "BEHAVIOR: No side effects — pure read. Address MUST be 2-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(2) }, }, additionalProperties: false, }, }, - src/tools.ts:488-489 (registration)Registration function called from index.ts. Registers ListToolsRequestSchema (returns the TOOLS array) and CallToolRequestSchema (dispatches by name via switch-case, including 'dolphin_read16').
export function registerTools(server: Server, dol: DolphinClient): void { server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS })); - src/tools.ts:476-486 (helper)Helper functions used by the dolphin_read16 handler: addrHex formats address as 8-digit uppercase hex, fmtHex formats a number as 'DEC (0xHEX)', ok wraps text into MCP text content response.
function ok(text: string) { return { content: [{ type: "text" as const, text }] }; } function fmtHex(n: number | bigint): string { return `${n} (0x${n.toString(16).toUpperCase()})`; } function addrHex(n: number): string { return `0x${n.toString(16).toUpperCase().padStart(8, "0")}`; }