Skip to content

Memory

Read and write the emulator's address space. Client-side — the ROM lives on the client; calling these on the server has no game to address.

Addresses are u32. Out-of-range addresses trap at runtime. The set of valid ranges (RAM, registers, CHR-ROM, …) is console-specific.

Reading

munos
read_u8(addr: u32): u8
read_u16(addr: u32): u16
read_u32(addr: u32): u32
read_i8(addr: u32): i8
read_i16(addr: u32): i16
read_i32(addr: u32): i32

One builtin per width and signedness. Multi-byte reads use the console's native byte order, so you get the assembled value directly.

munos
const PLAYER_X: u32 = 0x0086
const SCORE:    u32 = 0x07DD

var x     = read_u8(PLAYER_X)    // u8
var score = read_u16(SCORE)      // u16, native byte order

Pick the width that matches how the game stores the value, and the sign that matches its meaning (a value that can go negative — a velocity — wants read_i8).

Writing

munos
write_u8(addr: u32, value: u8)
write_u16(addr: u32, value: u16)
write_u32(addr: u32, value: u32)
write_i8(addr: u32, value: i8)
write_i16(addr: u32, value: i16)
write_i32(addr: u32, value: i32)

Writing mutates the running game's state — the basis of randomizers, difficulty mods, and cheats.

munos
const LIVES: u32 = 0x075A
write_u8(LIVES, 99)

The value argument must match the builtin's width type; cast if needed (write_u8(addr, u8(n))).

Casting reads

Reads come back in their natural width (read_u8u8), but most arithmetic and most other builtins want i32. Casting at the read site is idiomatic:

munos
var x = i32(read_u8(PLAYER_X))   // ready for i32 math

See Types → Conversions.

Identifying the ROM

These builtins read the mapped CPU address space, not the cartridge file itself. To identify which game is loaded, use local_rom_hash().

Part of the MultiNostalgia project.