harness: the VSXXX-AB tablet is the default pointing device; VT1200_MOUSE=1 forces the faithful mouse back

The tablet was opt-in (VT1200_TABLET=1) with the mouse as the default.  Invert
it: the tablet is selected with no environment, and VT1200_MOUSE=1 (a
value-aware inverse switch, so VT1200_MOUSE=0 selects the tablet) restores the
VSXXX-AA mouse.

The real terminal almost certainly has a mouse, so this is a DELIBERATE
divergence from the target machine, documented in README.md alongside
VT1200_SKIP_LEVEL1 and VT1200_IO_PATH_STUB.  It is on by default because the OS
is only reachable through the skip gate and there the tablet's absolute reports
are what make the Terminal Manager usable.

Baselines re-measured, both unchanged:
  * no-env progress.lua at 200 frames: PC=3FDCE400 samples=198 (3 PCs) -> same.
    DUART2-B is never addressed in that window (the T/R exchange is OS-phase
    only), so the reply bytes A0 04 00 00 vs A0 02 00 00 and the 5- vs 3-byte
    framing do not reach the CPU.
  * VT1200_SKIP_LEVEL1=1 frame 3000: pixel-identical for tablet and
    VT1200_MOUSE=1 (magick AE=0); both reproduce the committed
    tablet_cursor_*.png frames exactly.

VT1200_TABLET is now a no-op; run.sh's tablet mode is reported to the owner for
rewording (its comments are his).
This commit is contained in:
SDD committed 2026-10-16 16:19:46 +03:00
1 parent 7f0b2ff27c
commit 6d8097360c
3 files changed
+149 -37

No files matched your search

+88 -15
View File
@@ -9,6 +9,44 @@ Everything in this directory is source-of-truth in this repo; the MAME source
tree is disposable and lives outside the project
(`/home/arti/code/k-space/mame0289`).
## Working conventions
Five rules. Each of them has already cost this project real time, which is why they
are written down rather than assumed.
1. **Never search from `/`.** A filesystem-wide `find /` or `grep -r` is slow, visible
to whoever is at the keyboard, and never necessary. Use `rg` with an **explicit
path** — this directory, or `/home/arti/code/k-space/mame0289/src` (within which
`src/devices/machine`, `src/devices/bus`, `src/osd/modules/netdev` cover most
questions). Never `/usr`, `/opt`, `/home` at large, `/proc` or `/sys`. Worth
knowing why this keeps happening: `scn2681.cpp` **does not exist** (the SCN2681
lives in `mc68681.*`), so a search for it walks the entire disk before giving up.
2. **Stage only your own paths.** `git add <path> [<path>…]` — never `git add -A`,
never `git commit -a`. Several workers share this repository at once, and a `-A`
sweeps someone else's in-flight files into your commit. That happened twice in one
day. If it happens, unstage and `git commit --amend`, and say so.
3. **One sample is not evidence.** "It never paints", "the driver only models 256 KiB
of RAM", and "it is stuck" were all *wrong*, and all three came from a single
observation. Before concluding, either **compare across time** (several frames,
several minutes, several runs) or **read the source**. A claim about behaviour
needs more than one look; a claim about the code needs the code.
4. **Changing MAME requires a quote and a second reader.** Plausible-sounding
sentences get assembled to justify a number that was really found by trial and
error — one such edit was reverted after an independent reader found the datasheet
said the opposite. So: quote the sentence or the source line, add a **revert note**,
and have someone else read the citation before it is believed.
5. **Do not fake it.** No responder that feeds the firmware the answer a test wants.
Where a real device is unknown, model what the documentation actually supports and
**report the gap**; where a stand-in is genuinely unavoidable, make it **opt-in and
name it for what it is** — see `VT1200_IO_PATH_STUB` and `VT1200_SKIP_LEVEL1`, both
of which are documented divergences, not quiet assumptions. And the **ROM stays
byte-identical** (`md5 b46a3e442ccb86134d2356bd70d22fd2`): patch at runtime if you
must, never the file.
```
harness/mame/
├── vt1200.cpp # the MAME driver (symlinked into the MAME tree)
@@ -70,8 +108,8 @@ to be a six-variable incantation; it is now the default, and a bare
own written value, so the OS services a phantom interrupt that can never clear.
* The **real input devices** on DUART2, driven by MAME's host input: a
**DEC LK401 keyboard** (channel A, 4800 8N1) and a pointing device on
channel B (4800 8O1) — either a **DEC VSXXX-AA mouse** (the default, relative)
or, with `VT1200_TABLET=1`, a **DEC VSXXX-AB tablet** (absolute). All are
channel B (4800 8O1) — a **DEC VSXXX-AB tablet** (**the default**, absolute)
or, with `VT1200_MOUSE=1`, a **DEC VSXXX-AA mouse** (relative). All are
modelled from `reference/keyboard-mouse/PROTOCOL.md` and wired to the SCN2681
at the bit level (`rx_a_w`/`rx_b_w` and `a_tx_cb`/`b_tx_cb`). They answer
`FD`/`T` because that is the protocol, not to satisfy a test. See
@@ -155,12 +193,14 @@ those commands, the OS reads `01 00 00 00` / `A0 02 00 00`, switches the mouse t
stream mode, and the X11 cursor moves with the mouse while keycodes reach the OS.
See `INPUT_REPORT.md` (the cursor evidence is the `input_cursor_*.png` frames).
With **`VT1200_TABLET=1`** the channel-B device is the **VSXXX-AB tablet**
instead: it identifies as device code `0100`, so the OS switches to 5-byte
absolute reports, and the emulated cursor follows the **host pointer's absolute
position** (driven through `IPT_LIGHTGUN_X/Y`, i.e. MAME needs
`-lightgun -lightgun_device mouse`). See `TABLET_REPORT.md` (evidence:
`tablet_cursor_*.png`). The mouse stays the default.
The channel-B device is **by default** the **VSXXX-AB tablet**: it identifies
as device code `0100`, so the OS switches to 5-byte absolute reports, and the
emulated cursor follows the **host pointer's absolute position** (driven through
`IPT_LIGHTGUN_X/Y`, i.e. MAME needs `-lightgun -lightgun_device mouse`). See
`TABLET_REPORT.md` (evidence: `tablet_cursor_*.png`). **`VT1200_MOUSE=1`** puts
the VSXXX-AA mouse back (device code `0010`, 3-byte relative reports). The mouse
is the *faithful* part — the real terminal almost certainly has a mouse — so the
tablet default is a **deliberate divergence** (below).
Not modelled: **LANCE Ethernet**. It does not block the X11 bring-up.
@@ -175,21 +215,41 @@ behaviour**, and is **not** evidence about the real terminal's POST.
The skip is deliberately **not** the default: the real machine runs level 1, so
the faithful configuration stays the default and the switch is how we diverge.
### Deliberate divergences from the target machine
Three harness behaviours are **not** what the real terminal does. They exist so
the emulator can be driven and inspected, and they are collected here so a
reader cannot mistake the harness for the machine:
| divergence | default | what it does | how to restore the real machine |
|---|---|---|---|
| **VSXXX-AB tablet** | **on** | puts the tablet, not the mouse, on DUART2-B; absolute reports let the host pointer drive the cursor positionally | `VT1200_MOUSE=1` |
| `VT1200_SKIP_LEVEL1` | off | drives DUART1 IP3 high, jumping past all 15 level-1 tests to the OS cold-start | leave it unset |
| `VT1200_IO_PATH_STUB` | off | feeds 10 bytes on DUART2-A after the level-0 `0xE1` write, so the count-only I/O data path test passes | leave it unset |
The tablet is the one that is **on by default** because the OS is only reachable
through the skip gate, and there the tablet's absolute pointer is what makes the
Terminal Manager usable. It is a **value-aware inverse switch**: the default
lives in the code, not in a wrapper script setting `VT1200_TABLET`, so
`VT1200_MOUSE=1` (or `VT1200_MOUSE=0` for the tablet) always flips it either way.
## Environment knobs (19; down from 33)
All opt-in, and all off by default — there is no longer a "working incantation" to
remember, because everything the firmware needs to run is now the default.
Almost all are opt-in and off by default — there is no longer a "working
incantation" to remember, because everything the firmware needs to run is now the
default. The one exception is that the **tablet is on by default**; `VT1200_MOUSE`
is the switch that restores the faithful mouse (see the divergences above).
Instrumentation: `VT1200_DUARTLOG`, `VT1200_BOARD_LOG`, `VT1200_BOARD_MAP`,
`VT1200_IRQLOG`, `VT1200_LOG_UNMAPPED`, `VT1200_DPYLOG` (+`_FRAMES`),
`VT1200_DUMP_FRAME` (+`_FRAMES`), `VT1200_DUMP_RAM` (+`_FRAMES`),
`VT1200_DUMP_VRAM` (+`_FRAMES`), `VT1200_DUMP_DIR`, `VT1200_NO_RENDER`,
`VT1200_INPUT_LOG` (per-byte keyboard/mouse/tablet TX/RX trace, with emulated
time). Behaviour switches: `VT1200_SKIP_LEVEL1`, `VT1200_TABLET` (put the
VSXXX-AB tablet on DUART2-B instead of the VSXXX-AA mouse — the tablet needs
MAME's `-lightgun -lightgun_device mouse` to follow the host pointer),
`VT1200_IO_PATH_STUB` (the level-0 test-fixture stand-in described above — not a
keyboard model, off by default).
time). Behaviour switches: `VT1200_SKIP_LEVEL1`, `VT1200_MOUSE` (put the
VSXXX-AA mouse (relative) back on DUART2-B; the VSXXX-AB tablet is the default —
either pointing device needs MAME's `-lightgun -lightgun_device mouse` to follow
the host pointer), `VT1200_IO_PATH_STUB` (the level-0 test-fixture stand-in
described above — not a keyboard model, off by default).
## Regression baseline
@@ -210,6 +270,19 @@ This has moved **twice**, both deliberately:
menu. That looks like a regression and is not one — it is the removal of a
false pass.
**The tablet-default change did NOT move this baseline** (198 → 198), and that is
expected, not an oversight. The tablet changes what DUART2-B carries on the wire
— its `T` self-test reply is `A0 04 00 00` versus the mouse's `A0 02 00 00`, and
it then frames 5-byte absolute reports instead of 3-byte relative ones — but at
200 frames a **no-env** run is still parked in the level-0 diagnostics menu and
has never addressed DUART2-B at all: the `T`/`R` exchange happens only in the OS
phase, which the no-env run does not reach. The only DUART2-B traffic in the
window is the device's unsolicited power-up self-test, which nothing clocks in.
The OS-phase render is unchanged too: with `VT1200_SKIP_LEVEL1=1` the frame-3000
dump is **pixel-identical** for the tablet and for `VT1200_MOUSE=1`
(`magick compare -metric AE` = 0), and both reproduce the committed
`tablet_cursor_*.png` frames exactly.
**The no-env value is unchanged by `VT1200_IO_PATH_STUB`** — stub off is the
default, so the `samples=198 (3 PCs)` line above still holds. The stub is a separate
observed configuration:
+9 -2
View File
@@ -8,8 +8,15 @@ puts the cursor in that corner.
Status: **works**. The OS accepts the tablet (it frames 5-byte absolute reports
instead of 3-byte relative ones), the cursor tracks the host pointer across the
whole screen, the mouse is still the default and still works, and every existing
regression baseline is unchanged.
whole screen, and every existing regression baseline is unchanged.
> **Update (same day).** The default was subsequently **inverted**: the tablet is
> now selected with **no environment**, and **`VT1200_MOUSE=1`** forces the
> VSXXX-AA mouse. It is recorded as a deliberate divergence in `README.md`. The
> text below still describes the original opt-in `VT1200_TABLET=1` wiring; read
> `VT1200_TABLET=1` as "the tablet path", which is now the default. Re-measured
> baselines: unchanged (`samples=198`, and the skip-gate frame-3000 dump is
> pixel-identical for mouse and tablet).
---
+52 -20
View File
@@ -32,17 +32,17 @@
the reset-vector page at logical bit 0xffffffe0 resolves to the last
four bytes of the image (file offset 0x1bfffc).
* MAME's SCN2681 at DUART2 (0x0620000 = keyboard (ch A) / mouse (ch B)),
wired to INT2. This is modelled unconditionally because the real
board has it and the OS's DUART interrupt dispatcher needs a real
chip. NOTE: with a real DUART2 and nothing attached to the keyboard
port, the *faithful* (no-env) boot now fails the level-0 I/O data path
test and drops into the interactive diagnostics menu; before DUART2
was modelled the board write-back latch accidentally faked that test
(see OS_BRINGUP_REPORT.md). VT1200_IO_PATH_STUB=1 adds an OPT-IN
stand-in for the unknown test fixture on that port (it is NOT a
keyboard model) so the count-only level-0 test can pass; the default
stays faithful and still fails.
* MAME's SCN2681 at DUART2 (0x0620000 = keyboard (ch A) / pointing
device (ch B)), wired to INT2. This is modelled unconditionally
because the real board has it and the OS's DUART interrupt dispatcher
needs a real chip. NOTE: with a real DUART2 and nothing attached to
the keyboard port, the *faithful* (no-env) boot now fails the level-0
I/O data path test and drops into the interactive diagnostics menu;
before DUART2 was modelled the board write-back latch accidentally
faked that test (see OS_BRINGUP_REPORT.md). VT1200_IO_PATH_STUB=1
adds an OPT-IN stand-in for the unknown test fixture on that port (it
is NOT a keyboard model) so the count-only level-0 test can pass; the
default stays faithful and still fails.
What is NOT modelled: LANCE Ethernet and the board system logic beyond the
register model. The firmware therefore still stops at the level-1 HOST
@@ -124,6 +124,23 @@
and the boot stops in the diagnostics
menu.
VT1200_MOUSE=1 force the VSXXX-AA mouse (the faithful part)
back onto DUART2 channel B. The DEFAULT is
the VSXXX-AB tablet, a DELIBERATE divergence
from the real terminal (which almost
certainly has a mouse attached): the tablet
reports the host pointer's ABSOLUTE position,
so the emulated cursor tracks the host
pointer instead of integrating relative
deltas. This is a VALUE-AWARE inverse
switch -- the default lives in code, not in
a wrapper script, so it can always be
flipped either way (VT1200_MOUSE=0, or
empty, leaves the tablet selected). Both
parts need MAME's `-lightgun -lightgun_device
mouse` for the host pointer to reach them,
and `-lightgun` does NOT grab the pointer.
Video: the driver paints the active scanlines itself, reading the
framebuffer out of video RAM (see render_active_line).
@@ -654,10 +671,10 @@ private:
// The real devices on DUART2. Keyboard on channel A, pointing device on
// channel B, as the board has them. Wired bit-by-bit to the SCN2681's
// serial lines. Channel B carries EITHER the VSXXX-AA mouse (the default)
// OR the VSXXX-AB tablet, selected at machine-configuration time by
// VT1200_TABLET=1; exactly one is instantiated, so the connector carries
// one real part.
// serial lines. Channel B carries the VSXXX-AB tablet BY DEFAULT, or the
// VSXXX-AA mouse with VT1200_MOUSE=1; exactly one is instantiated, so the
// connector carries one real part. (See the divergence note above and
// README.md.)
required_device<vt1200_lk401_device> m_lk401;
optional_device<vt1200_vsxxxaa_device> m_mouse;
optional_device<vt1200_vsxxxab_device> m_tablet;
@@ -882,7 +899,9 @@ void vt1200_state::machine_start()
logerror("vt1200: duart1=on (SCN2681 @0640000 host/printer), duart2=on (SCN2681 @0620000 kbd/mouse), skip_level1=%s\n",
getenv("VT1200_SKIP_LEVEL1") ? "on (IP3 high, IRQ->INT2)" : "off (IP3 low, IRQ->INT1)");
logerror("vt1200: io_path_stub=%s\n", m_iopath_stub ? "on (DUART2-A reply to 0xE1)" : "off (faithful)");
logerror("vt1200: DUART2 devices: LK401 keyboard (ch A) + VSXXX-AA mouse (ch B)\n");
logerror("vt1200: DUART2 devices: LK401 keyboard (ch A) + %s (ch B)%s\n",
m_tablet_selected ? "VSXXX-AB tablet (default)" : "VSXXX-AA mouse",
m_tablet_selected ? " [divergence: VT1200_MOUSE=1 forces the mouse]" : " [VT1200_MOUSE]");
}
void vt1200_state::machine_reset()
@@ -1498,10 +1517,23 @@ void vt1200_state::vt1200(machine_config &config)
// drives the device's receiver input (rx_w). No byte-level shortcut, so the
// framing and the 4800-baud timing are the DUART's own.
//
// VT1200_TABLET=1 puts the VSXXX-AB tablet on channel B instead of the
// VSXXX-AA mouse. The two are the same connector; the terminal tells them
// apart from the self-test ID, so only one is instantiated.
m_tablet_selected = (getenv("VT1200_TABLET") != nullptr);
// The VSXXX-AB tablet is the DEFAULT device on channel B. This is a
// DELIBERATE divergence from the target machine: the real terminal almost
// certainly has a VSXXX-AA mouse attached, but the tablet reports the host
// pointer's ABSOLUTE position, so the emulated cursor tracks the host
// pointer while interacting with the terminal (the mouse only integrates
// relative deltas). Exactly the same kind of divergence as
// VT1200_SKIP_LEVEL1 and VT1200_IO_PATH_STUB.
//
// VT1200_MOUSE=1 forces the VSXXX-AA mouse (the faithful device) back.
// This is a VALUE-AWARE inverse switch, not a presence check: the default
// is expressed in code, not by setting a variable in a wrapper script, so
// the choice stays the user's and can always be flipped either way.
// VT1200_MOUSE=0 (or empty) leaves the tablet selected. The two parts are
// the same connector; the terminal tells them apart from the self-test ID,
// so only one is instantiated.
const char *force_mouse = getenv("VT1200_MOUSE");
m_tablet_selected = !(force_mouse && *force_mouse && strcmp(force_mouse, "0") != 0);
VT1200_LK401(config, m_lk401, 0);
if (m_tablet_selected)
{