The real display's power-on test (JP1 jumper 5, firmware $B888) runs through several drawing sequences — a solid fill, a border+grid, more — each held briefly, to expose dead dots and addressing faults; it isn't just full on/off. Both vPLASMA and the replica firmware now cycle 5 representative patterns: solid, border+grid, horizontal stripes, vertical stripes, checkerboard. - VPlasmaDevice.ShowTestPattern(int) + TestPatternCount; the app cycles them on a 1.2s timer while jumper 5 is installed. - PlasmaDisplay::showTestPattern(int) + TEST_PATTERN_COUNT (shared logic); the Matrix Portal sketch's DOWN button toggles the cycling test. (The firmware's exact byte patterns live in the display's native scan-buffer layout, which we haven't mapped, so these stand in for that sequence rather than reproducing it byte-for-byte.) Verified: 29 C# tests pass; the C++ patterns render distinctly on the host. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
94 lines
4.3 KiB
Markdown
94 lines
4.3 KiB
Markdown
# Plasma display replica — Adafruit Matrix Portal S3 + HUB75
|
||
|
||
A hardware replacement for the failing Babcock **PD01D221** cockpit plasma
|
||
display ([../README.md](../README.md), [../FIRMWARE.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 0–63 = panel A, 64–127 = 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
|
||
|
||
`PlasmaDisplay` is a line-for-line port of `VPlasmaDevice`; keep the two in
|
||
sync (same commands, fonts, orientation/`plot` mapping). To validate the
|
||
replica, run the **differential test**: send identical byte streams to the
|
||
hardware and to vPLASMA and compare the glass. The real panel still works, so
|
||
it can be the third reference.
|
||
|
||
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 A`–`F`).
|