vPLASMA (standalone): manual COM12 open, and decode jumpers 3/4/5
- Remove the COM12 auto-open and its retry timer; the serial link is now
opened manually via an "Open/Close COM12" button in the config panel.
The named-pipe transport still serves automatically. Baud straps reopen
only if already open.
- Decode the three previously-unknown JP1 config jumpers from the firmware
(boot config routine at $9190) and relabel them:
* Jumper 3 (PA3): sets flag $B7.2, driving hardware output PA5 to a
fixed level (a board config line).
* Jumper 4 (PD5): display orientation — installed = horizontal 128x32,
removed = vertical 32x128 (the demo's "HORIZONTAL OR VERTICAL").
* Jumper 5 (PD4): power-on display/pixel test pattern ($B888).
PlasmaNew/README.md's JP1 table now carries the full firmware-backed decode.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+14
-12
@@ -114,19 +114,21 @@ 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 |
|
||||
All decoded from the firmware's boot config routine at `$9190` (installed =
|
||||
grounded = logic 0):
|
||||
|
||||
Positions 1–2 = the datasheet's baud "JUMPER 1 / JUMPER 2." Positions 3–6
|
||||
are four unknown firmware option bits — candidates for a hidden factory
|
||||
self-test / diagnostic mode.
|
||||
| JP1 pos | HC11 pin | Function | Firmware |
|
||||
|---------|----------|----------|----------|
|
||||
| 1 | pin 24 / PA0 | Baud select bit 0 | `$9193` → SCI baud reg `$2B` |
|
||||
| 2 | pin 22 / PA2 | Baud select bit 1 | `$9197` → SCI baud reg `$2B` |
|
||||
| 3 | pin 21 / PA3 | HW config line | `$91CA` sets flag `$B7.2`, which drives output PA5 to a fixed level (board control line; exact effect board-dependent) |
|
||||
| 4 | pin 15 / PD5 | Display orientation | `$90AE`: installed = horizontal 128×32, removed = vertical 32×128 (`$B3.0`; the demo's "HORIZONTAL OR VERTICAL ORIENTATION") |
|
||||
| 5 | pin 14 / PD4 | Display/pixel test | `$91C3` installed → `$B888` writes a walking-bit test pattern (dead-dot check) |
|
||||
| 6 | pin 13 / PD3 | Demonstration program | `$91DB` installed → `$BB60` runs the built-in demo |
|
||||
| 7 | J2 SEL → +5 V | Parallel interface select | (board interface mux) |
|
||||
|
||||
Baud straps 1+2 pick SCI baud register (`$2B`) values `$13`/`$11`/`$12`/`$10`
|
||||
= 4800 / 9600 / 19.2K / 38.4K (more zeros grounded ⇒ slower).
|
||||
|
||||
HC11 pin map cross-checked while tracing: PD0–PD5 = pins 10–15, PA0–PA7 =
|
||||
pins 24–17 (descending).
|
||||
|
||||
+56
-47
@@ -4,16 +4,15 @@ namespace VPlasma.App;
|
||||
|
||||
/// <summary>
|
||||
/// vPLASMA main window: the plasma glass on the left, a config panel on the
|
||||
/// right. The device end is hardwired to <see cref="PortName"/> (the plasma
|
||||
/// side of the second com0com pair) and opened automatically — a retry timer
|
||||
/// keeps trying while the port is missing or busy, and reopens it if it dies.
|
||||
/// The DOSBox-X fork's named-pipe transport (<c>\\.\pipe\vplasma</c>) is
|
||||
/// served permanently alongside it.
|
||||
/// right. The serial device end is <see cref="PortName"/> (the plasma side of
|
||||
/// the second com0com pair); it is <b>opened manually</b> from the panel — no
|
||||
/// auto-open. The DOSBox-X fork's named-pipe transport
|
||||
/// (<c>\\.\pipe\vplasma</c>) is served permanently regardless.
|
||||
///
|
||||
/// <para>The right panel mirrors the real PD01D221's <b>JP1 configuration
|
||||
/// jumpers</b> (recovered in <c>PlasmaNew/FIRMWARE.md</c>): the two baud
|
||||
/// straps drive the open baud, jumper 6 runs the built-in demo (exactly what
|
||||
/// the firmware does when that jumper is installed), and the rest are the
|
||||
/// straps drive the open baud, jumper 6 runs the built-in demo (as the
|
||||
/// firmware does when that jumper is installed), and the rest are the
|
||||
/// hardware's config bits. Plus display controls, live counters, and a wire
|
||||
/// log. Double-click the glass to cycle the self-test pages; right-click to
|
||||
/// reset to the power-on state.</para>
|
||||
@@ -28,15 +27,15 @@ internal sealed class MainForm : Form
|
||||
private readonly VPlasmaPipeService _pipeService;
|
||||
private readonly PlasmaCanvas _canvas = new();
|
||||
|
||||
private readonly System.Windows.Forms.Timer _reconnectTimer = new() { Interval = 3000 };
|
||||
private readonly System.Windows.Forms.Timer _uiTimer = new() { Interval = 500 };
|
||||
private readonly System.Windows.Forms.Timer _demoTimer = new() { Interval = 3000 };
|
||||
private int _selfTestPage;
|
||||
|
||||
// ---- config panel controls -------------------------------------------
|
||||
private readonly Button _openClose = new() { Text = "Open COM12", Width = 100, Height = 24 };
|
||||
private readonly Label _linkStatus = new()
|
||||
{
|
||||
Location = new Point(12, 12),
|
||||
Location = new Point(12, 42),
|
||||
AutoSize = true,
|
||||
MaximumSize = new Size(286, 0),
|
||||
ForeColor = Color.Gray,
|
||||
@@ -46,9 +45,9 @@ internal sealed class MainForm : Form
|
||||
// the CPU). Text/tooltips carry each strap's real function and HC11 pin.
|
||||
private readonly CheckBox _jp1 = Jumper("1 — Baud select A (PA0)");
|
||||
private readonly CheckBox _jp2 = Jumper("2 — Baud select B (PA2)");
|
||||
private readonly CheckBox _jp3 = Jumper("3 — Config bit (PA3)");
|
||||
private readonly CheckBox _jp4 = Jumper("4 — Config bit (PD5)");
|
||||
private readonly CheckBox _jp5 = Jumper("5 — Config bit (PD4)");
|
||||
private readonly CheckBox _jp3 = Jumper("3 — HW config line (PA3)");
|
||||
private readonly CheckBox _jp4 = Jumper("4 — Orientation H/V (PD5)");
|
||||
private readonly CheckBox _jp5 = Jumper("5 — Display test (PD4)");
|
||||
private readonly CheckBox _jp6 = Jumper("6 — Demo program (PD3)");
|
||||
private readonly CheckBox _jp7 = Jumper("7 — Parallel select (J2 SEL)");
|
||||
private readonly Label _baudLabel = new() { AutoSize = true, ForeColor = Color.DimGray };
|
||||
@@ -82,8 +81,8 @@ internal sealed class MainForm : Form
|
||||
{
|
||||
Text = $"vPLASMA v{Application.ProductVersion} — Virtual plasma display";
|
||||
Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
|
||||
ClientSize = new Size(_canvas.Width + 316, Math.Max(_canvas.Height + 8, 520));
|
||||
MinimumSize = new Size(_canvas.Width + 332, 420);
|
||||
ClientSize = new Size(_canvas.Width + 316, Math.Max(_canvas.Height + 8, 560));
|
||||
MinimumSize = new Size(_canvas.Width + 332, 480);
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
|
||||
_service = new VPlasmaSerialService(_device);
|
||||
@@ -104,6 +103,7 @@ internal sealed class MainForm : Form
|
||||
_pipeService.Logged += line => RunOnUi(() => PrependLog(line));
|
||||
_pipeService.ClientChanged += _ => RunOnUi(UpdateStatus);
|
||||
|
||||
_openClose.Click += (_, _) => ToggleConnection();
|
||||
_canvas.DoubleClick += (_, _) => RunSelfTest();
|
||||
_canvas.MouseClick += (_, e) => { if (e.Button == MouseButtons.Right) ResetDisplay(); };
|
||||
|
||||
@@ -111,7 +111,8 @@ internal sealed class MainForm : Form
|
||||
_clear.Click += (_, _) => ResetDisplay();
|
||||
_clearLog.Click += (_, _) => _logBox.Clear();
|
||||
|
||||
// Baud straps → reopen at the selected rate. Jumper 6 → demo loop.
|
||||
// Baud straps → reopen at the selected rate (only if already open).
|
||||
// Jumper 6 → demo loop.
|
||||
_jp1.CheckedChanged += (_, _) => ApplyBaud();
|
||||
_jp2.CheckedChanged += (_, _) => ApplyBaud();
|
||||
_jp6.CheckedChanged += (_, _) => ApplyDemo();
|
||||
@@ -120,14 +121,11 @@ internal sealed class MainForm : Form
|
||||
// Default straps: jumper 2 installed only = 9600 (the game's setting).
|
||||
_jp2.Checked = true;
|
||||
|
||||
_reconnectTimer.Tick += (_, _) => EnsureOpen();
|
||||
_reconnectTimer.Start();
|
||||
_uiTimer.Tick += (_, _) => UpdateCounters();
|
||||
_uiTimer.Start();
|
||||
|
||||
FormClosed += (_, _) =>
|
||||
{
|
||||
_reconnectTimer.Dispose();
|
||||
_uiTimer.Dispose();
|
||||
_demoTimer.Dispose();
|
||||
_service.Dispose();
|
||||
@@ -138,17 +136,18 @@ internal sealed class MainForm : Form
|
||||
_service.Baud = SelectedBaud();
|
||||
UpdateStatus();
|
||||
UpdateCounters();
|
||||
EnsureOpen();
|
||||
_pipeService.Start();
|
||||
PrependLog("vPLASMA ready. Serving COM12 + \\\\.\\pipe\\vplasma. Toggle jumper 6 for the built-in demo.");
|
||||
_pipeService.Start(); // the pipe transport still serves automatically
|
||||
PrependLog("vPLASMA ready. Serving \\\\.\\pipe\\vplasma. Click “Open COM12” for the serial link; jumper 6 for the demo.");
|
||||
}
|
||||
|
||||
private Panel BuildConfigPanel()
|
||||
{
|
||||
var panel = new Panel { Dock = DockStyle.Right, Width = 300, BackColor = SystemColors.Control };
|
||||
_openClose.Location = new Point(12, 12);
|
||||
panel.Controls.Add(_openClose);
|
||||
panel.Controls.Add(_linkStatus);
|
||||
|
||||
var jumpers = new GroupBox { Text = "JP1 configuration jumpers", Location = new Point(12, 44), Size = new Size(276, 176) };
|
||||
var jumpers = new GroupBox { Text = "JP1 configuration jumpers", Location = new Point(12, 70), Size = new Size(276, 176) };
|
||||
CheckBox[] jp = { _jp1, _jp2, _jp3, _jp4, _jp5, _jp6, _jp7 };
|
||||
for (int i = 0; i < jp.Length; i++)
|
||||
{
|
||||
@@ -159,27 +158,28 @@ internal sealed class MainForm : Form
|
||||
jumpers.Controls.Add(_baudLabel);
|
||||
panel.Controls.Add(jumpers);
|
||||
|
||||
_tips.SetToolTip(_openClose, "Open or close the COM12 serial link. Not opened automatically.");
|
||||
_tips.SetToolTip(_jp1, "Baud select, low bit. With jumper 2: 4800/9600/19.2K/38.4K.");
|
||||
_tips.SetToolTip(_jp2, "Baud select, high bit. Installed alone = 9600 (the game's rate).");
|
||||
_tips.SetToolTip(_jp3, "Firmware config bit on PA3 (function not yet decoded).");
|
||||
_tips.SetToolTip(_jp4, "Firmware config bit on PD5 (function not yet decoded).");
|
||||
_tips.SetToolTip(_jp5, "Firmware config bit on PD4 (function not yet decoded).");
|
||||
_tips.SetToolTip(_jp3, "Sets flag B7.2, driving the PA5 hardware line to a fixed level (a board config line; exact effect board-dependent).");
|
||||
_tips.SetToolTip(_jp4, "Display orientation: installed = horizontal 128×32, removed = vertical (rotated 32×128).");
|
||||
_tips.SetToolTip(_jp5, "Installed at power-on runs the panel pixel test pattern (a walking-bit dead-dot check).");
|
||||
_tips.SetToolTip(_jp6, "Install to run the built-in demonstration program (as the firmware does).");
|
||||
_tips.SetToolTip(_jp7, "Selects the parallel interface on the real board; no effect here (serial only).");
|
||||
|
||||
var display = new GroupBox { Text = "Display", Location = new Point(12, 230), Size = new Size(276, 62) };
|
||||
var display = new GroupBox { Text = "Display", Location = new Point(12, 256), Size = new Size(276, 62) };
|
||||
_selfTest.Location = new Point(12, 22);
|
||||
_clear.Location = new Point(146, 22);
|
||||
display.Controls.Add(_selfTest);
|
||||
display.Controls.Add(_clear);
|
||||
panel.Controls.Add(display);
|
||||
|
||||
_counters.Location = new Point(12, 302);
|
||||
_counters.Location = new Point(12, 328);
|
||||
panel.Controls.Add(_counters);
|
||||
|
||||
var logLabel = new Label { Text = "Wire log:", Location = new Point(12, 384), AutoSize = true };
|
||||
var logLabel = new Label { Text = "Wire log:", Location = new Point(12, 410), AutoSize = true };
|
||||
panel.Controls.Add(logLabel);
|
||||
_logBox.SetBounds(12, 402, 276, 0);
|
||||
_logBox.SetBounds(12, 428, 276, 0);
|
||||
panel.Controls.Add(_logBox);
|
||||
panel.Controls.Add(_clearLog);
|
||||
|
||||
@@ -192,6 +192,26 @@ internal sealed class MainForm : Form
|
||||
return panel;
|
||||
}
|
||||
|
||||
// ---- connection --------------------------------------------------------
|
||||
|
||||
private void ToggleConnection()
|
||||
{
|
||||
if (_service.IsOpen)
|
||||
{
|
||||
_service.Close();
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
_service.Open(PortName);
|
||||
}
|
||||
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidOperationException or ArgumentException)
|
||||
{
|
||||
PrependLog($"Open failed: {ex.Message}");
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// ---- jumper behaviour --------------------------------------------------
|
||||
|
||||
/// <summary>Baud from the two straps (installed = logic 0), per the datasheet.</summary>
|
||||
@@ -207,10 +227,12 @@ internal sealed class MainForm : Form
|
||||
{
|
||||
int baud = SelectedBaud();
|
||||
_service.Baud = baud;
|
||||
PrependLog($"Baud straps → {baud} 8N1 (reopening)");
|
||||
if (_service.IsOpen)
|
||||
_service.Close(); // the reconnect timer reopens at the new baud
|
||||
EnsureOpen();
|
||||
{
|
||||
PrependLog($"Baud straps → {baud} 8N1 (reopening)");
|
||||
_service.Close();
|
||||
ToggleConnection();
|
||||
}
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
@@ -252,28 +274,15 @@ internal sealed class MainForm : Form
|
||||
PrependLog("Display reset to power-on state");
|
||||
}
|
||||
|
||||
private void EnsureOpen()
|
||||
{
|
||||
if (_service.IsOpen)
|
||||
return;
|
||||
try
|
||||
{
|
||||
_service.Open(PortName);
|
||||
}
|
||||
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidOperationException or ArgumentException)
|
||||
{
|
||||
UpdateStatus(); // stays closed; the timer tries again
|
||||
}
|
||||
}
|
||||
|
||||
// ---- status / counters / log ------------------------------------------
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
_openClose.Text = _service.IsOpen ? "Close COM12" : "Open COM12";
|
||||
_baudLabel.Text = $"{SelectedBaud()} baud";
|
||||
string line = _service.IsOpen
|
||||
? $"Listening on {PortName} @ {_service.Baud} 8N1."
|
||||
: $"{PortName} unavailable — retrying.";
|
||||
: $"{PortName} closed.";
|
||||
if (_pipeService.IsClientConnected)
|
||||
line += " Pipe host connected.";
|
||||
_linkStatus.Text = line;
|
||||
|
||||
Reference in New Issue
Block a user