Skip to content
Phosphoneowiki
Contents

The decisions

Two choices explain the emulator’s shape. Here they are, with the options that were set aside.

ADR-01 — linking firmware/common/

Four options: rewrite the API in C (set aside: drift guaranteed); compile firmware/common/ as is with a host layer of our own (chosen); vendor a copy into the repository (set aside: duplication and drift); co-simulate the RP2040 (chosen in addition, as a second backend). The firmware path is a Makefile parameter (NEO_FIRMWARE) and its version is pinned in the screenshots’ manifest.

The problem: the linked firmware’s state is spread over hundreds of static variables, which we forbid ourselves to modify to make them serialisable. Options set aside: serialise variable by variable (impossible without touching the sources); gather the variables in a named section with #pragma clang section (ignored by WebAssembly, absent from GCC); copy the whole WebAssembly linear memory (carries libc, SDL, the heap, the stack: not restorable).

The solution chosen: two tiny objects (fwstate_begin.c and fwstate_end.c) linked just before and just after the firmware’s objects. Since the linker places .data and .bss in object order, all the firmware’s variables fit between the two boundaries: that range is copied, without touching its sources. Every build checks this on the link map. The image holds a header (version, revision), the 65C02, the host side field by field, and the firmware’s two blocks; it can only be read back with the same binary.

Sources in the repository : docs/adr/0001-liaison-firmware-common.md, docs/adr/0002-sauvegarde-etat-bornes-de-lien.md.