vPLASMA: make jumpers 4 (orientation) and 5 (display test) functional

Both now do what the firmware does, at the device level so the shared
PlasmaCanvas (and vRIO's embedded glass) are untouched:

- Jumper 4 → display orientation. VPlasmaDevice gains a PlasmaOrientation
  property; in Vertical the logical space is 32x128 and every dot is rotated
  onto the physical 128x32 glass via a new Plot() helper that all drawing
  (text, cursor, ESC P graphics, ESC Q/R bounds) now goes through. Jumper 4
  installed = horizontal (the normal cockpit setup, default), removed =
  vertical. Changing it re-inits the panel, like the boot strap read.
- Jumper 5 → ShowTestPattern(): lights every dot (the power-on dead-dot
  check the firmware runs at $B888). Removing the jumper clears it.

The config panel wires both up and shows the live orientation in the
counters. 27 unit tests pass (3 new: vertical rotation mapping, orientation
re-init, test pattern), including the unchanged horizontal path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-16 18:26:51 -05:00
co-authored by Claude Opus 4.8
parent d8ab0ffe49
commit 95b701ae0a
4 changed files with 193 additions and 53 deletions
+31 -4
View File
@@ -111,15 +111,19 @@ internal sealed class MainForm : Form
_clear.Click += (_, _) => ResetDisplay();
_clearLog.Click += (_, _) => _logBox.Clear();
// Baud straps → reopen at the selected rate (only if already open).
// Jumper 6 → demo loop.
// Functional straps: baud (1+2), orientation (4), display test (5),
// demo (6). Jumpers 3 and 7 are tracked toggles (board-level effects).
_jp1.CheckedChanged += (_, _) => ApplyBaud();
_jp2.CheckedChanged += (_, _) => ApplyBaud();
_jp4.CheckedChanged += (_, _) => ApplyOrientation();
_jp5.CheckedChanged += (_, _) => ApplyTestPattern();
_jp6.CheckedChanged += (_, _) => ApplyDemo();
_demoTimer.Tick += (_, _) => StepDemo();
// Default straps: jumper 2 installed only = 9600 (the game's setting).
// Default straps: jumper 2 installed = 9600 (the game's rate); jumper 4
// installed = horizontal orientation (both the normal cockpit setup).
_jp2.Checked = true;
_jp4.Checked = true;
_uiTimer.Tick += (_, _) => UpdateCounters();
_uiTimer.Start();
@@ -236,6 +240,28 @@ internal sealed class MainForm : Form
UpdateStatus();
}
private void ApplyOrientation()
{
// Jumper 4 installed (checked) = horizontal 128×32; removed = vertical.
_device.Orientation = _jp4.Checked ? PlasmaOrientation.Horizontal : PlasmaOrientation.Vertical;
PrependLog($"Jumper 4 → {(_jp4.Checked ? "horizontal 128×32" : "vertical 32×128")} orientation");
}
private void ApplyTestPattern()
{
// Jumper 5 installed runs the power-on panel test (all dots lit).
if (_jp5.Checked)
{
_device.ShowTestPattern();
PrependLog("Jumper 5 installed — panel test pattern (all dots lit)");
}
else
{
_device.Reset();
PrependLog("Jumper 5 removed — test pattern cleared");
}
}
private void ApplyDemo()
{
if (_jp6.Checked)
@@ -297,7 +323,8 @@ internal sealed class MainForm : Form
$"Chars drawn: {_device.TextCharsDrawn}\n" +
$"Font: {_device.Font} ({_device.FontWidth}×{_device.FontHeight})\n" +
$"Cursor: X {_device.CursorX}, Y {_device.CursorY} ({_device.CursorMode})\n" +
$"Attributes: {(_device.Attributes == PlasmaAttributes.None ? "default" : _device.Attributes.ToString())}";
$"Attributes: {(_device.Attributes == PlasmaAttributes.None ? "default" : _device.Attributes.ToString())}\n" +
$"Orientation: {_device.Orientation} ({_device.LogicalWidth}×{_device.LogicalHeight})";
}
private void PrependLog(string line)