P75 turns the P74 host-input bridge into a small real game. The host viewer is intentionally dumb: it sends key events and displays frames. Tetris runs in AtomVM Erlang on the simulated chip.
The path now looks like this:
pygame key event
-> captured/input.fifo
-> Verilator harness
-> host_input_valid/data
-> 16-entry RTL MMIO FIFO
-> chip:input/0
-> {input, Event}
-> Erlang Tetris process
-> chip:draw_tetris_frame/9 framebuffer rendering
The first P75 smoke exposed a useful bug. The RTL status register
changed from a single valid bit to a count field, but the C NIF was
still checking only bit 0. Six scripted events gave a FIFO count of
6, whose low bit is zero, so chip:input/0 reported no input. The
fix was to test whether the low five-bit count is nonzero.
Verification:
cd projects/75_atomvm_tetris/test
make all
make verilator-run-input-smoke
The passing smoke delivered six host events, rendered a Tetris frame,
consumed the scripted quit, and reported FIFO status 0.
The first live game was playable but slow enough to hit the 120M-cycle
budget after about 78 frames. The renderer was crossing from Erlang into
C repeatedly for every block rectangle. Moving the hot path into one
coarse chip:draw_tetris_frame/9 NIF made the same live path quit
cleanly at 71,030,364 post-load cycles after 138 rendered frames and 106
input events.
There was one hang-looking failure during that cleanup: the coarse
renderer was too strict about piece coordinates and could return
badarg during a transient off-board state. The final NIF clamps
framebuffer writes and treats malformed/off-board cells as empty, so the
render path does not crash the Erlang game process.
Honest status: RTL simulation only. F/D compliance was NOT RUN and LibreLane hardening was NOT RUN.