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:uart_putc/1chip:mtime_ms/0chip:fb_base/0chip:write16/2chip:frame_ready/1
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.