GB Operator-style cart dumper/player for a homebrewed DSi. the DSi is the dock: agent homebrew reads the cart directly over wifi, desktop cli drives it.
agent/— NDS homebrew (C, libnds 2.x/calico/dswifi 2.x). streams cart rom+save over TCP :5000cli/— bun + TypeScript terminal app. identifies cart, streams to local cache, launches emulator
- build agent:
cd agent && make(needs devkitPronds-dev) - copy
agent/dsi-operator.ndsto DSi SD card - launch it via Unlaunch or TWiLight Menu++ (DSi mode)
- it connects to your saved wifi (WPA2 via advanced slots 4-6 works) and shows its IP
- insert a DS cart
cd cli && bun install
bun run src/index.ts config set host <dsi-ip>
bun run src/index.ts scan # what's in the slot?
bun run src/index.ts dump # stream rom+save to ~/.dsi-operator/games/<GAMECODE>/
bun run src/index.ts list
bun run src/index.ts play # GB Operator flowplay with a cart inserted: dumps if not cached, seeds desmume's battery save
from the cart save, launches, and writes the save back to the cart + verifies
when you quit the emulator with Cmd+Q. closing its window does not quit DeSmuME
on macOS. as if you played on the console.
first dump of a cart streams the whole rom (~30-60s for 32MB). after that it's
cached — scan shows cache: hit and play skips the transfer.
TCP :5000, little-endian. request: u8[4] cmd | u32le arg0 | u32le arg1.
response: u8[4] "OK "/"ERR " | u32le len | payload.
PING— livenessINFO— 512-byte nds header + rom/save sizes + cart-present flagRROM off len— raw rom bytes, len <= 0x8000RSAV off len— raw save bytes, len <= 0x8000WSAV off len+ payload — write save bytes (offset 0 erases flash chips first)
desmume integration: saves are seeded/read as .dsv (raw + 122-byte footer)
in the newest ~/Library/Application Support/DeSmuME/*/Battery dir, named
<GAMECODE>.dsv to match the cached rom filename.
cd cli && bun test— protocol codec + mock-agent roundtrip testsbun run src/index.ts mock— local mock agent, no hardware needed
- auxspi saves (pokemon hg/ss infrared carts)
- nand-save carts (warioware diy etc.)
- udp discovery, compression
- gui