Author SHA1 Message Date
CydandClaude Fable 5 359e1c0a40 vRIO auto-opens COM11 at startup when present
The usual port (device end of the COM1 pair) is selected and opened
automatically at launch. Missing or busy just logs to the wire log --
no modal at startup -- and leaves the manual picker in charge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 08:25:28 -05:00
CydandClaude Fable 5 c6e0522408 PlasmaNew: replica goes USB-CDC (Win x64 hosts), park pending dump
The cockpit PCs are now Win x64, so the replica needs no real RS-232 — a
native-USB MCU presenting as a USB CDC virtual COM port is transparent to
the host (opens COMx, can't tell it isn't a UART). Records the consequences
(baud cosmetic, timing instant, pin the COM number, LEDs need their own
power) and marks the hardware/protocol thread parked until the U3 EPROM
firmware dump (or Babcock programming manual) is in hand.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 21:10:34 -05:00
CydandClaude Fable 5 9a1c8478bf Add PlasmaNew: plasma display reverse-engineering reference
Historical reference for recreating the cockpit plasma display in hardware.
The original Babcock plasma panels are failing; the end goal is a drop-in
replica — a modern microcontroller driving a 128x32 LED array that reads the
same RS-232 serial bus and speaks the same command protocol as the original
PD01D221. vPLASMA (the C# app) is the executable spec and test oracle for
that firmware.

Contents:
- PD01D221.pdf — Babcock datasheet (doc 9200-0109 Rev A)
- Board photos: controller overview, Cherry silkscreen, EPROM/SRAM, JP1
- README.md — full investigation: hardware ID (stock Babcock PD01D221,
  Cherry PCB 4317-C), chip inventory, recovered ESC command protocol, the
  JP1 config-jumper map (MODA/MODB hardwired to expanded mode), and the
  firmware-dump plan.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 20:50:35 -05:00
7 changed files with 245 additions and 3 deletions
Binary file not shown.
+206
View File
@@ -0,0 +1,206 @@
# PlasmaNew — reverse-engineering the real cockpit plasma display
Working notes and reference material for the cockpit plasma display.
**End goal: a hardware replica.** The original Babcock plasma panels are
starting to fail and are effectively irreplaceable. The plan is to drive a
modern **128 × 32 LED array** with a **modern microcontroller** that reads
the same RS-232 serial bus and speaks the same command protocol as the
original PD01D221 — a drop-in replacement, functionally identical from the
host's side, with none of the plasma physics or high voltage.
[vPLASMA](../src/VPlasma.App/) (the C# app in this repo) is the software
counterpart and serves the replica directly: it is an **executable
specification** of the display's behavior and a **test oracle**. Every
command semantic pinned down in `VPlasmaDevice` ports straight to the
replica's firmware, and the same differential-test rig (real panel vs.
vPLASMA) validates the replica. vPLASMA today is built from *observed
traffic* (the game's driver + a factory test tool); grounding it in the
*actual hardware* — protocol, fonts, and timing — feeds both the emulator
and the replacement firmware.
## What the display is
A **commercial off-the-shelf Babcock Display Products Division PD01D221**
"128 × 32 dot-matrix, gas-plasma display with controller and DC-DC
converter," with an RS-232C serial interface and a dedicated microprocessor
for refresh and the user interface. Built by **Cherry** (PCB assembly
**4317-C**, Made in Taiwan, © 1994). See [`PD01D221.pdf`](PD01D221.pdf)
(Babcock doc 9200-0109 Rev A).
Product family (the suffix letter = how much is on the board):
| Model | Contents |
|-------|----------|
| PD01**B**22B | 128×32 panel + driver electronics only (host refreshes it) |
| PD01**F**221 | + on-board DC-DC converter |
| PD01**D**221 | **+ controller: RS-232C, dedicated microprocessor** ← this unit |
**VWE used it stock — no custom fonts or bitmaps were installed.** So the
display's behavior is entirely the standard Babcock PD-series firmware, and
the `ESC P` "graphics" the game drew were rendered at runtime by the game,
not preloaded. Nothing on the display is VWE-specific.
## Board inventory
Chip IDs read from the photos below.
| Ref | Part | Role |
|-----|------|------|
| U1 | **Motorola MC68HC11D0** (44-pin QFP, mask 1C17F, wk 28/94) | ROMless HC11 MCU — the controller. Runs from external bus in expanded mode. |
| U3 | **TI TMS27PC512** (PLCC-32, 150 ns, Singapore) | **64 KB OTP EPROM = the firmware** (stock Babcock code + fonts). Standard 27C512. |
| U2 | QFP ~100-pin, label **"35GWP004 REV A 3994"** | Custom Cherry display/scan **ASIC** (wk 39/94). Drives the HV stage. *Not* the firmware. |
| U4 | **Mosel MS62256L-10** | 32 KB SRAM — frame buffer / scratch. |
| U7 | **Supertex HV7708** | 32-channel high-voltage plasma driver (more HV off-frame). |
| U5 | **Maxim MAX202CWE** | RS-232 transceiver — the serial interface. |
| — | **MAX707** | Reset / watchdog supervisor. |
| Y1 | **7.3728 MHz** crystal | E-clock = 1.8432 MHz; gives exact standard baud rates. |
Memory picture: ROMless HC11 + external 64 KB EPROM (code + fonts) + 32 KB
SRAM + custom scan ASIC + HV drivers. A 64 KB program EPROM for a 128×32
panel implies far more feature set than the game ever used.
## Reference photos
| File | Shows |
|------|-------|
| [`mpul-2026-07-07-152834.jpeg`](mpul-2026-07-07-152834.jpeg) | Controller overview: MC68HC11D0 (U1), the "35GWP004" ASIC (U2), HV7708 (U7), MAX202, MAX707. |
| [`silkscreenl-2026-07-07-152841.jpeg`](silkscreenl-2026-07-07-152841.jpeg) | Cherry silkscreen: PCB **4317-C**, © 1994, "Made in Taiwan". |
| [`unknown-2026-07-07-153818.jpeg`](unknown-2026-07-07-153818.jpeg) | The **TMS27PC512 EPROM** (U3, initially unidentified), Mosel SRAM (U4), HC11. |
| [`jumpers-2026-07-07-163733.jpeg`](jumpers-2026-07-07-163733.jpeg) | The **JP1** config header next to the HC11. |
## Datasheet-confirmed facts (`PD01D221.pdf`, doc 9200-0109 Rev A)
- Serial format **8N1**, baud **jumper-selectable 4800 / 9600 / 19.2K /
38.4K** (the game uses 9600).
- "Choice of standard fonts and styles" (= `ESC K` / `ESC H`); "program
custom characters" (a custom-char download command — **exists but VWE
didn't use it**); "graphic input commands / overlays" (= `ESC P`).
- Serial is **bidirectional**. Connector **J1**: pin 2 TxD (display→host),
pin 3 RxD (host→display), pin 4 CTS, pin 8 DTR ("display ready"), pin 5
GND. The game drove it write-only (flow control disabled, TxD ignored),
so vPLASMA's listen-only model is faithful.
- Also carries an 8-bit **parallel** port (J2), unused by the game.
- **The datasheet does *not* contain the `ESC` command table.** That's a
separate Babcock programming/user manual, which is **not available online**
(checked general web, datasheetarchive, bitsavers, archive.org, resellers;
only this datasheet was ever digitized). Sources for it: ask Babcock
directly (La Mirada CA, (714) 994-6500, babcockinc.com), or reconstruct it
from the dump + the sources we already have.
## Command protocol recovered so far
From the game driver (`TeslaRel410\CODE\RP\MUNGA_L4\L4PLASMA.CPP`) and the
factory test tool (`…\VWETEST\VGLTEST\PLASMA.EXE`). Full grammar lives in
[`../src/VPlasma.Core/Protocol/PlasmaProtocol.cs`](../src/VPlasma.Core/Protocol/PlasmaProtocol.cs).
| Bytes | Meaning |
|-------|---------|
| `ESC @` | Clear screen, reset text state |
| `ESC L` | Home cursor |
| `ESC G n` | Cursor mode (00/FF hidden, 01 steady, 03 flashing) |
| `ESC K n` | Font select (07; FF = default) |
| `ESC H n` | Text attributes (intensity / underline / reverse / flash) |
| `ESC P s y x w h data…` | Graphics write: MSB = leftmost pixel |
| BS / HT / LF / VT / CR | Cursor motion |
The Babcock manual (or a firmware dump) would fill in exact operand
encodings, tab stops, the `ESC P` "screen" byte, and any commands the game
never used.
## JP1 configuration header
Traced pin-by-pin (see the jumper photo). **JP1 is firmware-read
configuration, not CPU mode select** — each shunt ties a GP port pin the
firmware polls at boot. Shunt to GND = logic 0.
| JP1 pos | HC11 pin | Function |
|---------|----------|----------|
| 1 | pin 24 / PA0 | Baud select bit 0 |
| 2 | pin 22 / PA2 | Baud select bit 1 |
| 3 | pin 21 / PA3 | Option (unknown) |
| 4 | pin 15 / PD5 | Option (unknown) |
| 5 | pin 14 / PD4 | Option (unknown) |
| 6 | pin 13 / PD3 | Option (unknown) |
| 7 | J2 SEL → +5 V | Parallel interface select |
Positions 12 = the datasheet's baud "JUMPER 1 / JUMPER 2." Positions 36
are four unknown firmware option bits — candidates for a hidden factory
self-test / diagnostic mode.
HC11 pin map cross-checked while tracing: PD0PD5 = pins 1015, PA0PA7 =
pins 2417 (descending).
**MODA/MODB are hardwired high (expanded mode) through a diode to +5 V — not
jumper-selectable.** So bootstrap mode cannot be entered by moving a jumper;
it needs a mode-pin override. (Exact diode circuit still to be characterized.)
## Firmware-dump plan
Goal: get the 64 KB EPROM image, disassemble the HC11 code to recover the
full command table + font bitmaps + timing, then differential-test vPLASMA
against the real panel on identical byte streams. The recovered spec feeds
**both** vPLASMA and the replacement firmware.
1. **Free, no-solder — hunt for a diagnostic mode.** Capture J1 TxD while
power-cycling normally (may emit a banner/version), then step the four
unknown config jumpers (PA3, PD5, PD4, PD3) through combinations watching
TxD for a factory self-test or ROM dump.
2. **Serial bootstrap (conditional).** Bootstrap needs MODA = MODB = 0 at the
reset edge; they're pulled to +5 V via a diode. If that circuit has a
series resistor (or a diode-OR node), pull both low during a reset pulse
and run the standard **Motorola AN1060** dump loader out J1 — no cutting.
If hard-tied, a single trace cut/lift is needed. *Blocked on the diode
details.*
3. **Reliable fallback — read the EPROM directly.** PLCC-32 test clip on U3
with the HC11 held in reset, or hot-air U3 off and read it in a 27C512
adapter. Guaranteed image.
Safety: the panel runs on a few hundred volts from the on-board DC-DC. Keep
all work in the logic corner (HC11 / EPROM / MAX202); never probe the HV
section or the panel connector while powered.
## Open items
- Characterize the MODA/MODB diode circuit → decide if serial bootstrap is a
tack-a-wire job or needs a trace cut.
- Capture J1 TxD across config-jumper combinations (path 1).
- Obtain the Babcock PD01D programming manual, **or** dump the U3 EPROM.
- Once we have the command table + fonts: fold into `VPlasmaDevice`, replace
the public-domain 5×7 stand-in with the real Babcock glyphs, and
differential-test against the hardware.
- **Prototype the replica.** A modern MCU (RP2040 / ESP32 / Teensy) reads the
command stream into the same command parser and drives a 128×32 LED matrix
from the same frame buffer — the per-pixel lit / half-intensity / flash
flags in `VPlasmaDevice` map directly onto PWM brightness + blink. An amber
matrix best mimics the neon-orange plasma; for a true cockpit swap, match
the original active area (~12.75" × 3.15", ~0.1" pitch = 128×32).
## Replica interface — USB, not RS-232
The cockpit PCs are now **Win x64**, so the replica likely needs **no real
serial port**: a native-USB MCU presenting as a **USB CDC virtual COM port**
is transparent — the host opens `COMx` and can't tell it isn't a UART. This
deletes the RS-232 transceiver and connector from the BOM. Consequences:
- **Baud is cosmetic** over USB CDC (the 9600/… setting is accepted as a
no-op; the two baud-select jumpers need no hardware equivalent).
- **Timing becomes instant** rather than ~1 ms/byte — harmless for a display,
and vPLASMA can still throttle to mimic the original for differential tests.
- **Pin the COM number** the host expects (original was COM2) in Device
Manager so it drops in with no host-side config change.
- **DTR/RTS still cross** the CDC link if any host logic ever needs them (the
game didn't use flow control).
- **Power gotcha:** USB alone can't drive the LED array at full brightness —
use USB for data + a **separate DC feed** for the LEDs (or USB-C PD).
Transparency assumes the host reaches the display as a Windows `COMx`
endpoint — e.g. DOSBox-X `serial2=directserial realport:COMx`, which a USB
CDC port satisfies perfectly. Confirm the current drive path.
## Status
**Parked pending a firmware dump.** The software emulator (vPLASMA) is built
and released; this hardware/protocol thread is blocked on getting the U3
EPROM image (or the Babcock programming manual). Resume at the dump plan
above once a dump is in hand.
Binary file not shown.

After

Width:  |  Height:  |  Size: 675 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 KiB

+39 -3
View File
@@ -8,12 +8,21 @@ namespace VRio.App;
/// <summary>
/// vRIO main window: the interactive cockpit panel on the left (the same
/// functional map RIOJoy's profile editor shows) and a control strip on the
/// right — COM port, device settings, and a live wire log. Open the COM port,
/// point RIOJoy at the other end of the null-modem pair, and every click here
/// arrives at RIOJoy exactly as if the physical cockpit sent it.
/// right — COM port, device settings, and a live wire log. At startup the
/// usual port (<see cref="PreferredPort"/>) is opened automatically when it's
/// available; otherwise open a COM port by hand. Point RIOJoy at the other
/// end of the null-modem pair, and every click here arrives at RIOJoy exactly
/// as if the physical cockpit sent it.
/// </summary>
internal sealed class MainForm : Form
{
/// <summary>
/// vRIO's usual port: the device end of the COM1⇄COM11 com0com pair.
/// Auto-opened at startup when present and free; the picker still allows
/// any other port.
/// </summary>
private const string PreferredPort = "COM11";
private readonly VRioDevice _device = new();
private readonly VRioSerialService _service;
private readonly PanelCanvas _canvas = new();
@@ -248,6 +257,7 @@ internal sealed class MainForm : Form
UpdateStatus();
PrependLog("vRIO ready. Open a COM port, then point RIOJoy at the other end of the pair.");
LoadBindings();
AutoOpenPreferredPort();
}
private Panel BuildControlStrip()
@@ -307,6 +317,32 @@ internal sealed class MainForm : Form
_portBox.SelectedIndex = idx >= 0 ? idx : 0;
}
/// <summary>
/// Startup convenience: if <see cref="PreferredPort"/> exists, select it
/// and try to open it. Failures (port missing, or busy because another
/// vRIO/app holds it) just log — no modal box at launch — and leave the
/// manual picker in charge.
/// </summary>
private void AutoOpenPreferredPort()
{
int idx = _portBox.Items.IndexOf(PreferredPort);
if (idx < 0)
{
PrependLog($"{PreferredPort} not present — pick a port and open it manually.");
return;
}
_portBox.SelectedIndex = idx;
try
{
_service.Open(PreferredPort);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidOperationException or ArgumentException)
{
PrependLog($"{PreferredPort} is present but could not be opened ({ex.Message.TrimEnd('.')}) — open it manually once it frees up.");
}
}
private void ToggleOpen()
{
if (_service.IsOpen)