Files
VRIO/PlasmaNew/replica
CydandClaude Opus 4.8 78cd679b53 Add VPlasma.Wire: differential-test helper
A console tool for validating the hardware replica against vPLASMA and the
real panel by feeding all three identical byte streams.

- synth   — build a repeatable command stream (selftest/demo/banner/charset).
- render  — feed a stream through the vPLASMA engine and save the resulting
            128x32 frame as a PNG: the pixel-exact golden image.
- replay  — send a stream to any target port: the real panel (RS-232, self-
            pacing), the Matrix Portal replica (USB-CDC), or a virtual port
            (--paced).
- capture — log live traffic to a file, with --tee to forward it on to the
            real display so capture is non-intrusive.

Reuses VPlasma.Core (same parser/fonts as the emulator and the ported
firmware). The replica README documents the differential-test workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 20:42:00 -05:00
..

Plasma display replica — Adafruit Matrix Portal S3 + HUB75

A hardware replacement for the failing Babcock PD01D221 cockpit plasma display (../README.md, ../FIRMWARE.md). A modern microcontroller reads the same serial command stream the game sends and renders it to a modern LED matrix — a drop-in from the host's point of view, with none of the plasma physics or high voltage.

The firmware's command parser and fonts are ported verbatim from vRIO's vPLASMA emulator (src/VPlasma.Core), which is the reference oracle. Feed the replica and vPLASMA the same byte stream and they produce the same frame.

Bill of materials

Part Notes
Adafruit Matrix Portal S3 ESP32-S3 controller; plugs into the HUB75 header; native USB-C = the virtual COM port
2 × Adafruit 64×32 RGB LED Matrix (P-pitch to taste; 1/16 scan) chained → 128×32, the panel's native resolution
5 V power supply, ≥ 4 A the panels are the load; USB cannot power them
USB-C cable data (and logic power) from the host PC

An amber-leaning pitch and diffuser best mimic the neon-orange plasma; the firmware already renders in orange (255,96,0 full / 110,40,0 half).

Wiring

  1. Chain the panels: panel A OUT → panel B IN, left-to-right, so the pair reads as one 128-wide canvas (x 063 = panel A, 64127 = panel B). If the image comes out swapped, reverse the chain order.
  2. Mount the Matrix Portal S3 onto panel A's IN HUB75 header.
  3. Power: 5 V ≥ 4 A into the Matrix Portal's screw terminals; run the panels' power pigtails from the same 5 V. USB-C carries data (and powers the S3 logic) — do not rely on USB for panel current.

Build & flash

Arduino IDE (or arduino-cli):

  1. Boards Manager → install esp32 (Espressif). Select board "Adafruit Matrix Portal S3". Set USB CDC On Boot: Enabled (so Serial is the USB port the game opens).
  2. Library Manager → install Adafruit Protomatter (pulls in Adafruit GFX / BusIO).
  3. Open MatrixPortalPlasma/MatrixPortalPlasma.ino (keep PlasmaDisplay.*, plasma_fonts.h, demo_screens.h beside it) and Upload.

The HUB75 pin arrays at the top of the .ino are Adafruit's published Matrix Portal S3 values; if the panel garbles, verify them against your installed Protomatter version.

Using it with the game

The Matrix Portal enumerates as a USB CDC COM port. In Windows Device Manager you can pin it to the COM number the host expects. Point the game's plasma output at it — under the DOSBox-X fork:

serial2 = directserial realport:COMx

Baud is cosmetic over USB CDC (the 9600 line-coding is accepted as a no-op), so the display keeps up regardless. The link is one-way (the game writes, the display listens), exactly as the cockpit drove the real panel.

No-host testing (onboard buttons)

  • UP — toggle the built-in firmware demonstration (the real 10-screen PLASMADOT demo, demo_screens.h, extracted from the ROM).
  • DOWN — toggle the panel test: cycles diagnostic patterns (solid, border+grid, horizontal/vertical stripes, checkerboard) to expose dead dots and addressing faults — the multi-pattern sequence the real firmware runs.
  • Power-on briefly lights every dot (confirms both panels), then clears.

Files

File
MatrixPortalPlasma/MatrixPortalPlasma.ino sketch: Protomatter init, USB serial, render loop, buttons
MatrixPortalPlasma/PlasmaDisplay.h/.cpp the PD01D221 parser + 128×32 framebuffer — a C++ port of VPlasmaDevice
MatrixPortalPlasma/plasma_fonts.h the 8 real ROM fonts (PROGMEM), generated from tms27pc512.BIN
MatrixPortalPlasma/demo_screens.h the 10 firmware demo screens (PROGMEM)

Keeping it faithful — the differential test

PlasmaDisplay is a line-for-line port of VPlasmaDevice; keep the two in sync (same commands, fonts, orientation/plot mapping). Validate the replica by sending identical byte streams to the replica, to vPLASMA, and to the real panel, then comparing the glass.

The VPlasma.Wire tool (tools/VPlasma.Wire, dotnet run --project tools/VPlasma.Wire -- …) drives this:

# 1) Build a repeatable stream (or capture a real one — see below).
VPlasma.Wire synth  --kind demo    --out demo.bin

# 2) The vPLASMA golden image (pixel-exact reference PNG).
VPlasma.Wire render --in demo.bin  --out demo-golden.png --scale 8

# 3) Replay the SAME bytes to each target, and photograph the glass:
VPlasma.Wire replay --in demo.bin  --port COM3          # the real panel (RS-232)
VPlasma.Wire replay --in demo.bin  --port COM7          # the Matrix Portal (USB-CDC)

Compare the two photos against demo-golden.png. synth kinds: selftest, demo, banner, charset. render takes --orient v for vertical.

Capture a real session to build a test corpus non-intrusively — insert the tool in the path (point the game at COM12, tool tees on to the real display on COM3):

VPlasma.Wire capture --port COM12 --out session.bin --tee COM3

Then render/replay session.bin like any other stream.

Still deferred (as in vPLASMA, documented in ../FIRMWARE.md): the 10 double-buffered pages (ESC I/ESC i are consumed but single-page) and the vector-graphics primitives (ESC AF).