journal 2026-05-05

P72 AtomVM reaches chip-visible I/O

P71 proved AtomVM could run a real concurrent Erlang workload. P72 makes that workload touch the chip instead of staying sealed inside the VM.

The new platform NIF surface is intentionally tiny:

chip_io.erl calls those from Erlang, spawns a worker, writes three small RGB565 blocks into a scratch framebuffer window at 0x00f00000, and pulses the same MMIO_FRAME_READY bridge that P69 taught the Verilator harness to watch.

Captured UART:

AtomVM on P72 (chip-visible I/O NIF demo)
Starting AtomVM revision 0.8.0-dev+git.fd574b8
Found startup beam: chip_io.beam
P72 AtomVM chip I/O starting
chip mtime ms: 336
$ chip:uart_putc/1 says hello from Erlang
chip fb base: 15728640
frame worker pulses: 3
chip mtime delta ms: 243
P72 AtomVM chip I/O PASS
Return value: ok
AtomVM exited result=0

Harness:

[harness] frame 1 dumped (24576 bytes)
[harness] frame 2 dumped (24576 bytes)
[harness] frame 3 dumped (24576 bytes)
[harness] === run ended after 14883438 post-load cycles ===
[harness] halted=1, halt_code=0x00000001

Honest status: RTL simulation PASS. F/D architectural compliance was NOT RUN. LibreLane hardening was NOT RUN.

This is not the graphics rung yet. It is the bridge: Erlang can now reach platform NIFs, those NIFs can write chip memory/MMIO, and the host can observe the result. Next step is to turn the tiny marker into an actual AtomVM-rendered framebuffer demo.