Commit Graph
59 Commits
Author SHA1 Message Date
SDD a1e3ebfaff reference: the level-0 10-byte puzzle -- count-only, no loopback, no 10-byte device message 2026-10-16 14:16:37 +03:00
SDD d017953d52 docs: plan the LANCE Ethernet model + network font delivery
Evidence for the RAP/RDP window pair (0x5900000/0x5800000), INT1 as the LANCE
interrupt, and the separate MAC address ROM at 0x6800000; MAME am79c90 drop-in
assessment with the kn01/ncd68k templates; the TFTP/LAT font delivery path
(no X font server on 7100); acceptance, risks and sequencing.
2026-10-16 14:16:05 +03:00
SDD 47dac6b283 docs: DUART2 modelled; Terminal Manager reached; the bare run's old level-1 pass was a latch artefact (honest failure now) 2026-10-16 14:00:23 +03:00
SDD 1ca4817745 harness: model DUART2 by default (drop the VT1200_DUART2 gate)
The real VT1200 board has a DUART2 (SCN2681) at 0x0620000 for the keyboard
(ch A) and mouse (ch B) with INT2 wired.  Map it unconditionally instead of
opting in via VT1200_DUART2; the OS's DUART interrupt dispatcher needs a real
read-only ISR distinct from the write-only IMR.

Verified with frame dumps: with ONLY VT1200_SKIP_LEVEL1=1 the Terminal Manager
V2.2 dialog now appears (frame 3000; VRAM md5 73c3c9a1..., identical to the old
skip+DUART2 run).

This does NOT keep the faithful no-env path: level 0's I/O data path test
(L3FDCE470) transmits 0xE1 to DUART2-A and drains the receiver until it has read
10 bytes (SRA RxRDY).  The board write-back latch used to alias CSRA/RHRA and
faked that (baseline first divergence: R 06200001 pc=3FDCE670 = 0x0099 vs the
real chip's 0x000C), so the firmware dropped into the interactive diagnostics
menu.  No faithful device we have (LK401 sends at most 4 bytes) supplies the 10
bytes; an external TX->RX loopback does not change the transmit count.  See
OS_BRINGUP_REPORT.md section 8 (DONE_WITH_CONCERNS).

The OS keyboard/mouse driver does initialise: skip-phase OS code programs
DUART2 (MR1A=0x13, CSRA=0x99, IMR=0x33, ...) and sends FD to the keyboard plus
the documented LED/click/bell/auto-repeat commands, and 'T' to the mouse.
2026-10-16 13:59:09 +03:00
SDD 6ce84b86f2 run.sh: skip mode also models DUART2 -- required for the OS (phantom ISR read at 0x06200005); reaches the Terminal Manager 2026-10-16 13:40:21 +03:00
SDD c06cf7096b harness: skip run is STUCK at the X11 weave -- wall is unmodelled DUART2 (phantom ISR read at 0x06200005); add multi-timestamp dumps + console string resolver
The skip gate reaches the root weave and stops: video RAM and the rendered
frame are byte-identical at frames 3000/10000/30000/45000/60000 (42 s -> 14
min), and all 4 MiB of main RAM is identical at every sample except one byte
that oscillates.  The PC histogram is tight: entered at frame ~611, dominated
by 0x3FB30390/0x3FB30110.

Wall: DUART2 (0x0620000, keyboard/mouse) is unmodelled, so the read-only ISR
at 0x06200005 is served by the board write-back latch and returns the value
the OS wrote to the write-only IMR (0x0033).  The OS's DUART dispatcher
(0x3FB43800) masks 0x66 -> 0x22, so it services a phantom interrupt that can
never clear, spinning in the channel handler 0x3FB42410 and queue routine
0x3FB300F0.  Forcing only 0x06200005 to 0 reproduces the full DUART2-mapped
run byte-for-byte; with VT1200_DUART2=1 the Terminal Manager dialog box from
the reference video appears at frame 3000 and the machine runs on.

Defaults unchanged: no-env still reaches HOST PORT - 15, skip still reaches
the weave.  New opt-in knobs VT1200_DUMP_{FRAME,RAM_FRAMES,VRAM_FRAMES} and
resolve_console.py; progress.lua untouched.
2026-10-16 13:39:37 +03:00
SDD 855f3e85e9 docs: the OS DOES paint -- skip run boots to a running X11 server (root weave confirmed in a frame dump); correct the claim I wrote 2026-10-16 13:26:27 +03:00
SDD b99b7de62e harness: add run.sh launcher (faithful/skip/pie/headless modes, verified end to end) 2026-10-16 13:21:51 +03:00
SDD c3faa7729d docs: correct stale README - DUARTs/VRAM are modelled, fix memory_access template args, add gate list and new baseline 2026-10-16 13:19:25 +03:00
SDD 5abf4f33be harness: promote the working VT1200 config to the default; retire settled env gates
A bare 'vt1200 vt1200' now boots exactly as the old six-variable incantation
(VRAM, handshake busy=2, DUART1, monitor switch) did, so the no-env run is no
longer a silently-broken machine.

Promoted (5): VT1200_VRAM, VT1200_BOARD_MODEL, VT1200_BOARD_BUSY_TICKS,
VT1200_DUART, VT1200_DUART_SEL (folded to DUART1-only; DUART2 is the new
opt-in VT1200_DUART2).

Deleted (15): VT1200_CAL/_VID4M/_W8, VT1200_BOARD_RAM/_DEFAULT/_BUSY_W2/
_BUSY_W3/_DMA_TICKS/_SWITCH, VT1200_DUART_LB1/LB2, VT1200_LOWLOG,
VT1200_VRAMLOG, VT1200_STRUCTLOG, VT1200_DUART1_INT2.
VT1200_BOARD_SWITCH is superseded: 0x0640000D is the DUART1 IP register, and
the DUART mapping wins the last-wins slice, so the board model switch was
never consulted (verified: identical output with and without it).

Renamed: VT1200_DUART_IP3 -> VT1200_SKIP_LEVEL1, which now also selects the
OS-phase DUART1 IRQ routing (INT2) instead of POST's INT1, removing the
standalone VT1200_DUART1_INT2 knob. The skip gate itself stays opt-in.

Evidence (equivalence): frame-160/200/600 md5, progress.lua at 200/1500
frames, and the cap.lua console transcript from the no-env run are
byte-identical to the incantation run. Re-baseline: no-env 200-frame hottest
PC 3FDCE400 samples 199 (1 PC) -> samples 53 (78 PCs). ROM md5 unchanged
b46a3e442ccb86134d2356bd70d22fd2. Header comment block updated; see
harness/mame/GATE_CLEANUP_REPORT.md.
2026-10-16 13:18:14 +03:00
SDD 9d912ae084 harness: l1patch.lua -- runtime level-1 host-port patch + test-map probe
Runtime region-writes (on-disk ROM untouched) applied after the level-0 ROM
checksum:
  three known failing checks: 3FA73980 CA04->C004, 3FA76060 CB04->C004,
    3FA760F0 CB04->C004 (skip the c6/c0/c1 flag stores)
  VT1200_L1PATCH_EXTRA adds the second-round checks 3FA761F0 / 3FA763A0
    (the retry loop reaches c3/c2 once c0/c1 stop short-circuiting)
  VT1200_L1PATCH_VERDICT optionally forces L3FA6E4B0's return (3FA71B60
    4D28 move a9,a8 -> 5708 clr a8)

With the five branch patches the HOST PORT test's caller returns 0 and no
'HOST PORT - 15' is printed, but level 1 does not complete: the CPU stays in
the DUART ISR chain (INT1 0x0F60 -> 3FA92F40 -> L3FA78D90 -> 3FA78xxx-3FA7Bxxx)
for >19000 frames with no error.  l1p_pie_frame1500.png is a frame dump of the
self-test circle/pie -- the renderer draws curves, fills and blits correctly.
2026-10-16 13:09:45 +03:00
SDD 55cf122edd docs: correct the stale 256 KiB RAM claim in BRINGUP_LOG
The '256 KiB / driver only models 256 KiB of main RAM' note was from an early
dump and is wrong.  The driver maps 0x00000000-0x01ffffff, which on this
bit-addressed space is 0x2000000 units = 0x400000 bytes = 4 MiB, confirmed
empirically (mainram share size == 4194304).  Keep the correction with the
original so the stale figure cannot mislead again.
2026-10-16 13:09:37 +03:00
SDD db535c2adc harness: explicit monochrome palette (pen 0 black, pen 1 white)
vt1200.cpp declared PALETTE(config, m_palette).set_entries(256) with no init
delegate, so render_active_line()'s pens 0/1 rendered in whatever MAME's
default palette held -- reported as red on screen.  Use
palette_device::MONOCHROME (emupal.cpp: palette_init_monochrome) with two
entries, so the colour is ours and deterministic.

Verified via a real MAME screenshot (screen:snapshot(), which renders through
the palette -- dump_frame()'s PPM is straight from bitmap pens and cannot show
colour): pal_mono_frame600.png is exactly black (0,0,0) + white (255,255,255).
palverify.lua takes the screenshot; the frame is the level-1 error screen.
2026-10-16 13:02:50 +03:00
SDD ac60ad2f89 docs: plan to retire the settled VT1200_* env gates (promote working config to default, delete finished experiments) 2026-10-16 13:02:20 +03:00
SDD 6cbb362bb9 harness: VT1200_DUART1_INT2 -- route DUART1's IRQ to INT2 (A/B knob)
The OS's DUART1 driver services the 0x6400000 window from the INT2 stub
(0x0F30 -> 0x3FA93070); with the default INT1 wiring the DUART1 TxRDY IRQ is
handed to the INT1 stub's 0x5800000 board-DMA handler (0x3F7151F0 ->
0x3F9D5B40), which never reads the DUART ISR, so INTPEND's INT1 bit stays
latched and the CPU re-enters the handler ~387x per frame.

Empirical A/B (level-1-skipped boot via VT1200_DUART_IP3):
  default (INT1): INT1 stub entered 387x in one frame; screen frozen.
  VT1200_DUART1_INT2=1: zero interrupt entries in a one-frame trace;
    the OS reads DUART1 ISR (reg5) at pc=3FB43900 right after the IRQ.
INTENB reads 0x0606 (INT1|INT2|HI|DI), so the routing (not the enable mask)
is what identifies the line.  Opt-in; default unchanged.

osprobe.lua: also print INTENB and DUART1 MR1A/CSRA in the globals dump.
2026-10-16 13:01:40 +03:00
SDD c19c603d77 harness: VT1200_DUART_IP3 -- drive DUART1 IP3 high to take the OS cold-start gate
Add an opt-in knob (VT1200_DUART_IP3=1) that asserts DUART1 input-port bit 3.
The POST gate at bit 0x3F2042D0 tests IP3 (@0x64000D0 bit 3) and, when it is
high and the 0x6200000 status handshake did not return 0x55, branches to the
OS cold-start 0x3F5788C0 (jauc), skipping the whole level-1 batch: the sole
caller of the level-1 runner 0x3FDF72D0 is 0x3F204400, inside the skipped
region.  Verified from the raw opcodes against MAME's tms34010 opcode table
(BTST_K sets Z=NOT bit; jane=JNE absolute-long) and empirically.

Default behaviour is unchanged (no env -> the gate is not taken).  The real
terminal reads IP3 low, so this is a modelled board input, not a faithful POST
path; results from a level-1-skipped harness are not evidence about the real
hardware's POST, but are evidence about the OS/graphics route.

osprobe.lua: gate/OS/Park probe (breakpoints on 0x3F2043B0 / 0x3F204400 /
0x3F5788C0, per-frame PC histogram, optional instruction trace and RAM-global
dump).
2026-10-16 12:55:36 +03:00
SDD c69d2c295f reference: level-1 host-port test — can it be skipped? (analysis, no skip)
Answers the five sub-questions from the service guide, the linear dis34 dump,
the existing reports, and one empirical capture:

* level 1 runs unconditionally at power-up; the boot calls the level-1 runner
  at bit 0x3F204400 (calla L3FDF72D0). The only conditional at the call site is
  the DUART1 IP3 hardware input bit (firmware @0x64000D0 bit 3), not a stored
  value.
* the host-port test has no 'not installed' sense; only SIMMs (@0x5000000) and
  the Image Option (@0x62000D0 bit 5) have presence checks.
* no persistent test-selection record: the power-up test set is a hard-coded
  ROM immediate (0x10FEFD80) written into a RAM descriptor; the interactive
  menu and NCP P3 only modify a run. NVRAM is read only by the user-settings
  code, never on the level-1 path.
* a level-1 failure wedges the boot in the board-LED code loop (0x3F208060,
  jruc itself); transcript = LEVEL1/2 TESTING, HOST PORT - 15, TYPE 'GO' TO
  CONTINUE, then the LED loop.
* the one in-ROM bypass (0x3F2043B0 -> OS cold-start 0x3F5788C0) is a
  board-input gate (IP3 high + no 0x55 signature); it skips all of level 1,
  not just the host port, and is not a firmware setting.

Verdict: no persistent/configurable skip; harness must pass level 1 or assert
DUART1 IP3 (0x0640000D bit 3) to take the OS branch.

Evidence + scratch: reference/l1probe/.
2026-10-16 12:42:35 +03:00
SDD 571850e564 harness: render the TMS34010 active scanlines from video RAM
MAME's TMS34010 renderer does not read VRAM: tms340x0_ind16 calls the
driver's scanline callback for the active region and paints only the
blanking regions.  Our callback drew nothing, so the active area was
never painted and every frame dump was all-black.

Add render_active_line(), called from scanline(): it reads the
framebuffer out of the video-RAM share at bit 0x04000000 with a measured
1024-bit (0x40-word, 128-byte) row pitch and LSB-first bit order within
each 16-bit word.  The pitch comes from the firmware's own character
blitter (PIXBLT at pc=3FDF9A00 advances its destination by 0x40 words per
glyph row); at the 160-byte pitch MAME derived from HEBLNK/HSBLNK/HTOTAL
the text is sheared and unreadable.

Validated: frame 160 shows the level-1 CP437 character table legibly,
frame 600 the level-1 error screen.  VT1200_DPYLOG added as an opt-in
per-scanline display-params dump.

Regression (no VT1200_* env): PC=3FDCE400 samples=199 -- holds.

See harness/mame/RENDER_REPORT.md.
2026-10-16 12:42:33 +03:00
SDD bcbd7924af docs: last authorised timing change tested (idle-path transmit start) -- real deviation, not the cause; reverted
Mechanism quantified first, per byte over the 5-byte burst: start latency 2605, 15442,
20652, 20650, 20652 cycles -- i.e. 1 bit for the idle byte 0 only, then constant because
later characters are pinned by the previous character's end.  It does NOT accumulate.

Implemented the authorised contained change (write_TX idle path begins the start bit
immediately; new start_now parameter in emu/diserial.{h,cpp}; buffered path and receive
side untouched; SCN2681 16x-clock citations recorded).  Result: byte 0's latency 2605 -> 5
cycles, nothing else moved, and the outcome was identical -- same three failing checks,
same returns (L3FA71BC0=0x00900040, L3FA753D0=3, L3FA6E4B0=6), same console line.

DECISION: reverted.  The deviation is real but the change does not move the symptom and is
only a partial fidelity fix (a faithful model would clock the transmitter at 16x).  Keeping
a change that buys nothing adds noise.  MAME tree is back to edit 2 (overrun latch) only
plus the edit-1 refutation note; emu/diserial.{h,cpp} unmodified.

DUART_REPORT.md now carries the full handover: established / ruled out / remaining
discrepancy / open deviations.  Acceptance still fails; regression holds.
2026-10-16 12:26:01 +03:00
SDD 88d006730a docs: identify the writers of +0x3c0/+0x3d0 (the DUART ISR) and what L3FA71BC0 checks
Direct writer evidence (VT1200_STRUCTLOG): test +0x3c0 = ISR struct[idx4].0x3b0 and
+0x3d0 = the ISR index5 SRA snapshot (TxRDYA path, 3FA79690/3FA7A390); test
struct[i].0x60 = the ISR's received-status field (RxRDYA path 3FA79690).  So both
sub-tests' failures are the ISR's SRA snapshots and nothing else.

L3FA71BC0 (18 flag sites probed, exactly one fires): c6, cmp 3FA73970 btst5 on
struct[i].0x60, set when bit5 = SRA PARITY ERROR is set.  Observed 0x0001 (clean) in most
combinations and 0x0021 (RxRDY|parity error) in 3 -> its remaining failure is a parity
error in the received status, not a timing one.  c5 (framing error) does not fire.

L3FA753D0's failure is the index4/index5 snapshots lacking FFULL/OVR (receive-count lag).
One mechanism can produce both (a receive-side sub-bit mis-sampling/offset) but the parity
error should be checked directly before attributing.

Owner's L3FA753D0 reading verified with two corrections: their PCs are the loads (the
compares are 3FA76050/E0, 3FA761E0, 3FA76390); and the flag encoding is bit N = flag
+cN (proof: the +c6 store logs as val=0040 at the word a13(0xc0)), with the caveat that
the 32-bit return also spans a13+0xd0.
2026-10-16 12:23:14 +03:00
SDD d7725faa1e docs: enumerate the three remaining failing checks; record the transmit-start citation
Enumeration (measurement only): of the 18 flag-set sites in L3FA71BC0 and 4 in L3FA753D0,
exactly three fire -- L3FA71BC0 c6 (cmp 3FA73970 btst5 on struct[index].0x60; actual
0x0001/0x0009, bit5 clear) and L3FA753D0 c1/c0 (cmp 3FA760E0 btst1 / 3FA76050 btst4 on
the index4/index5 SRA snapshots; actual 0x05/0x07, FFULL and OVR clear).  All other
checks pass; cE is a summary flag, not a check.

Task 2 citation (for independent reading): SCN2681 p.7 "Data is transferred from the
holding register to transmit shift register when it is idle..." and p.22 "TxRDY sets at
the end of the 'start bit' time.  It is during the start bit that the data in the transmit
holding register is transferred...".  Neither states a bit-count latency; MAME measurably
inserts ~1 bit (RX sync = THRA write + 2605 cycles, bit = 2604).  Candidate deviation,
not written.

Full picture (established / ruled out / remaining discrepancy / open deviations) recorded
in DUART_REPORT.md.  Acceptance still fails; regression holds.
2026-10-16 12:21:16 +03:00
SDD 03e6a88b22 docs: establish causally what raises HOST PORT - 15; resolve the sub-test polarity; rule out the loopback-clock deviation as the cause
Call site (not a register snapshot): 3FA84FB0 calla L3FA6E4B0; 3FA84FE0 stores a8;
3FA85000 move a8,a8 / 3FA85010 jreq; the nonzero path ends at 3FA85360-3FA853A0 with
a11 = 0x400 returned.  Live breakpoint confirms code=0x400 enters the HOST PORT handler
3FDE9D70.  So the quantity to zero is L3FA6E4B0's return value (all five descriptor
fields zero).

Polarity resolved: L3FA71BC0/L3FA753D0 return their 32-bit flag word, which is 0 iff all
their checks pass, so L3FA6E4B0's bits are failure bits.  My earlier "L3FA753D0 returns
0x408 while its checks pass" was a misread -- the same 32-bit word also carries the
setf-4/setf-2 fields at a13(0xc4/c8/ca/cc).  The checks are therefore the right quantity.

Loopback-clock deviation (SCN2681 p.12 item 2): real but NOT the cause.  CSRA=0x88 gives
TX==RX==2400 baud, so the clock source changes only the sampling phase, not the bit count
or the completion time; and the received bytes are already correct, so MAME samples the
TX bit centres.  Not changed (would be banking a green).  Measured residual: a ~1-bit
write->receive offset (completion at W+1.07 char vs a 1.00-char write interval), sourced
from the ~1 bit between a THRA write and the first transmitted bit; forcing it to zero
corrupted the sampling phase, so the half-bit TX offset is load-bearing.

Model vs datasheet items 3/4/5: matches (loopback fills the FIFO with the receiver
disabled, which is what CRA=5 then CRA=0xA relies on).  Regression holds.
2026-10-16 12:18:30 +03:00
SDD 70e2486d57 mc68681: revert the TxRDY edit (REFUTED by the fitted part's datasheet); keep the overrun edit
Independent verification (reference/mc68681-datasheet-verification.md) read the SCN2681
spec: p.22 "Transmitter Disable Note" -- "TxRDY sets at the end of the 'start bit' time.
It is during the start bit that the data in the transmit holding register is transferred
to the transmit shift register."  That is exactly upstream's tra_callback() assertion, so
upstream was faithful and our edit contradicted the datasheet.  Reverted; the revert note
records the refutation and says not to re-apply.  Commit 9902722165fc's "fix two DUART
timing deviations" is therefore half false -- only the overrun edit stands.

Reverting it does NOT relocate the failure: cfg2 (edit1 off, edit2 on) gives
L3FA71BC0=0x00900040, L3FA753D0=3, L3FA767E0=0, L3FA6E4B0=6, console unchanged.

"ISR one byte ahead" explained: TxRDY re-asserts at the end of the start bit (faithful),
so the ISR writes the next byte ~1 bit into the current character, while MAME clocks the
loopback receiver from the independent receive clock -- the datasheet (p.12, local
loopback item 2) says "The transmit clock is used for the receiver".  Edit 1 was masking
that deviation.  Next fix identified but not written (needs the quoted sentence read
independently first, per process).

Step-5 leads: crystal 3.6864 MHz is the datasheet nominal but the board crystal is still
unconfirmed; CSRA=0x88 gives TX==RX==2400 baud (the rx arg is unused in calc_baud);
MR1A=0x10 -> 5-bit frame matches the 0x1F mask; COUNTER_READY cleared (firmware's own
Start-Counter read, not in IMR, not handled); INT1/INT2 immaterial (L3FA78D90 ignores the
mask arg; OPCR/OPR cleared, so the single INTRN is the path).

Regression holds.
2026-10-16 12:15:47 +03:00
SDD 72a96862c7 docs: causality audit -- the host-port failure is pre-existing, not caused by the two MAME edits
Four-config A/B (IRQ wiring kept in all four; both mc68681 edits reverted in cfg 4):
the console line and L3FA6E4B0's return are identical (HOST PORT - 15 / 6) in cfg 1-4.
Verdict: PRE-EXISTING.  Neither timing edit causes or relocates the failure.

Methodology correction: hp_ret.lua's labels were on the wrong rets addresses.  The real
returns are L3FA6E4B0 -> 6, L3FA71BC0 -> 0x00900040, L3FA753D0 -> 0x00000408,
L3FA767E0 -> 0.  hp_ret2.lua fixes the addresses.

What 6 is: not a device code.  L3FA6E4B0 reduces five descriptor fields (struct+0x60/
0x80/0xa0/0xc0/0xe0, written from the four sub-test calls) to a 5-bit value; 6 = 0b00110
= "L3FA71BC0 nonzero, L3FA753D0 nonzero".  The caller turns any nonzero into 0x400,
which the dispatcher maps to HOST PORT - 15.  Flagged: L3FA753D0 returns 0x408 while all
its own checks pass, so "nonzero" != "failed its checks"; polarity unresolved.

Leads: COUNTER_READY is set by the firmware's own Start-Counter-Command read (reg 0x0E),
is not in IMR, and is not handled by the ISR -- not the cause.  The DUART clock
(3.6864 MHz) could not be confirmed from the service guide.

Variant MAME files kept in harness/mame/mame_edits/.  Regression holds.
2026-10-16 12:13:39 +03:00
SDD 031d30da67 reference: DUART datasheet verification of the two mc68681 edits (claim 1 refuted)
Download the SCN2681 (Philips 1995), SCC2681, SCN68681 and MC68HC681 UM
datasheets into reference/duart-datasheet/ with pdftotext extractions, and
audit each claimed justification against them:

  Claim 1 (TxRDY asserted in tra_complete, not tra_callback): REFUTED.
    The quoted p.7 sentence is real, but SCN2681 p.22 says explicitly
    'TxRDY sets at the end of the start bit time' -- which is exactly the
    removed upstream behaviour.  Upstream was right.

  Claim 2 (overrun latched on the start bit, not completion): CONFIRMED.
    'the overrun error status bit (SR[4]) will be set upon receipt of the
    start bit of the new (overrunning) character' (p.8, also SRA[4] p.14).
    Caveats: p.8 also says errors are 'strobed ... at the received
    character boundary' (internal tension); and a valid start bit is
    validated ~half a bit after the falling edge, not at it.

  Claim 3 (3-deep FIFO, 4th held, overrun on 5th; MAME faithful): CONFIRMED.
    'capacity of three characters' + 4th held in the shift register (p.8);
    MAME's SIZE+1 guard overruns exactly on the 5th.

Also snapshot the worker's uncommitted MAME diff and upstream 0.289 code.
2026-10-16 12:13:07 +03:00
SDD 9902722165 harness: wire DUART IRQ to the TMS34010 (host-port test transmit); fix two DUART timing deviations
Root cause of the missing THRA write (HOST PORT test): the level-1 host-port
test's transmit is ISR-driven, and the DUART interrupt was never wired to the
CPU.  The firmware installs RAM trampolines in the fixed vector table (INT1
vector 0xffffffc0 -> stub at bit 0x0f60 = JA 0x3FA92F40, which calls the DUART
ISR L3FA78D90 with (2, 0x270860, 0x6400000)).  Counters: INTENB reaches 0x0006
(INT1|INT2) at the test, so interrupts are enabled.

vt1200.cpp: wire m_duart1/m_duart2 irq_cb() to CPU external interrupt 1/2
(duart1_irq_w/duart2_irq_w), gated on VT1200_DUART.  Result: THRA writes go
from 0 to 20 per run; the test's SRA-overrun and RHRA-pattern checks now pass.

MAME tree (mc68681.cpp/.h), two datasheet-backed corrections with revert notes:
 1. TxRDY was asserted mid-character ("not until the end of start bit time");
    the datasheet asserts it at the THR->TSR transfer.  Corrected.
 2. The overrun error was latched when the overrunning character *completed*
    (rx_fifo_push); the datasheet latches it "upon receipt of the start bit of
    the new (overrunning) character".  Corrected via duart_channel::rx_w().
    This clears every check in the RXCHECK sub-test (flags 1 -> 0).

Acceptance is NOT met: cap.lua still prints 'LEVEL1/2 ERROR -> HOST PORT - 15'.
The next failure is the preceding L3FA71BC0 (DUART baud/timer) sub-test
returning 6; its flag-set sites were breakpointed and never fired.  Regression
holds (no VT1200_* env -> PC=3FDCE400 samples=199).  Details, numbers and the
datasheet audit: harness/mame/DUART_REPORT.md sections FINAL FINDINGS / UPDATE.
2026-10-16 12:07:27 +03:00
SDD 3fd1e13b2e docs: keyboard/mouse protocol spec — LK401 (LK201 protocol) + VSXXX-AA mouse, sources, MAME lk201 device
Distils public docs into reference/keyboard-mouse/PROTOCOL.md for the level-1
Keyboard (27) / Mouse (26) device tests:
- keyboard: 4800 8N1 RS-423, self-test via FD -> 01 00 00 00 (errors 3D/3E)
- mouse: 4800 8O1 RS-232, self-test via 'T' -> 4-byte report (errors 3D/3E, >=0x20 fatal)
- separate ports: DUART2 A=keyboard, B=mouse (NOT daisy-chained)
MAME already has an LK201 device (src/mame/dec/lk201.cpp/.h) but no DEC mouse.
2026-10-16 11:38:52 +03:00
SDD 23e508f075 docs: level-1 test sequence, port tests vs device tests (keyboard/mouse device models needed for tests 26/27) 2026-10-16 11:31:56 +03:00
SDD b38da304c3 docs: correct DUART report - host port test is local loopback (service guide), wiring verified sound, missing THRA write is the real bug 2026-10-16 11:27:11 +03:00
SDD 2fd9286c1a harness: wire MAME SCN2681 at the DUART windows (host-port investigation)
Adds SCN2681 devices at 0x0640000 (DUART1 = host/printer) and 0x0620000
(DUART2 = keyboard/mouse), gated on VT1200_DUART, with the remap
verified as duart_register = handler_off (duart_byte = off*2, value in
the low byte of the firmware's 16-bit move).  Optional external TX->RX
loopback (VT1200_DUART_LB1/2) models the loopback connectors; the
monitor switch is driven on IP4-IP6.  New VT1200_DUARTLOG gives a full
non-deduplicated DUART access log.

Result: the level-1 HOST PORT test is reached and executed against the
real DUART, but still reports 'LEVEL1/2 ERROR -> HOST PORT - 15'.  The
test reads SRA/RHRA and requires a 5-byte external pattern
(0xAA,0xFF,0xAA,0x55) plus SRA overrun, yet the firmware never writes
the transmit register (0 writes to reg 3/B on either DUART in 1400
frames), so no internal or external loopback can supply it.  See
harness/mame/DUART_REPORT.md.

Regression holds: no VT1200_* env -> PC=3FDCE400 samples=199.
2026-10-16 11:22:56 +03:00
SDD 1c0a9b2b64 docs: Ghidra decompiler unreliable for this ROM (~85% of sampled functions flagged); SLEIGH instruction coverage incomplete 2026-10-16 11:08:46 +03:00
SDD 77c918f15c docs: next level-1 gate is HOST PORT (window 0x6400000); evidence and approach recorded 2026-10-16 11:01:39 +03:00
SDD 49378827e8 fix(tms34010): drop addr32 &0xFFFFF, fix ADDI imm; rebuild .sla, repair program, validate 31691 sites 2026-10-16 10:59:40 +03:00
SDD 5000b8bc07 harness: level-1 VIDEO MEMORY test passes (video RAM mapped + REFCNT advances); next gate is HOST PORT 2026-10-16 10:57:06 +03:00
SDD 5ef8712960 harness: identify the level-1 video-memory test that raises code 0x100 (VIDEO MEMORY-22)
The dispatch status is 0x100 (printed as '22' in the message). A driver-side
transparent low-RAM write log (VT1200_LOWLOG) shows the slot at bit 0x16F0 is
written by the store at 3FDF9090 from a13(0x10), which L3FA7C050 sets to the
literal 0x100 when the memory test L3F2018B0 returns non-zero. L3F2018B0 is the
level-1 video-memory test (base bit 0x04000000, count 0x20000). Its failing
checks: the 16-bit walking-bit read-back at 0x04000000 (baseline, unmapped) and,
with video RAM mapped, the REFCNT (0xC00001F0) 'must change' check.
2026-10-16 10:55:44 +03:00
SDD f46b4a44a4 docs: root-cause Ghidra TMS34010 CALLA bug to addr32 & 0xFFFFF (empty call graph) 2026-10-16 10:48:02 +03:00
SDD 3a1d10e9bb docs: consolidate level-1 investigation state; stack walk reaches the framework not the test 2026-10-16 10:40:24 +03:00
SDD 8a00cef556 docs: Ghidra CALLA targets do not resolve (empty call graph); smart34010 is authoritative for call targets 2026-10-16 10:38:16 +03:00
SDD 9a2363a68f docs: level-1 errors are status-code dispatched; withdraw the unsound failing-address claim 2026-10-16 10:36:27 +03:00
SDD cca49dc27d harness: VRAM transparent logging proxy; video RAM test is a walking-bit test and still fails 2026-10-16 10:33:00 +03:00
SDD 07997022ad docs: the video RAM test draws characters then verifies; mapping alone cannot satisfy it 2026-10-16 10:30:52 +03:00
SDD 52744cbd03 harness: correct video memory to bit 0x04000000; log the failing address; level 1 still fails 2026-10-16 10:27:32 +03:00
SDD f49f9984bb harness: close the instrument disagreement -- catch-all trustworthy, off = bit>>4
Closed cross-check (single run): the catch-all and VT1200_CAL proxies are
directly comparable (both base 0) and resolve identically; last-wins holds
for same- and mismatched-width overlaps. The apparent conflict was a units
error: a .rw(FUNC(offs_t)) handler receives (bitaddr-base)>>4 (tms34010
Width=1, AddrShift=3), so the catch-all logs bitaddr>>4. Its 0x400000..0x40D7FF
is bit 0x04000000..0x040D7FF0 (bytes 0x800000..0x81AFFE), outside the declared
4 MiB RAM -- genuinely unmapped. The old 0x00400000 proxy was 16x too low.
Catch-all reproduces the committed log byte-for-byte and does not perturb
coverage (56 / PC=3F208950 with and without). Regression holds: PC=3FDCE400
samples=199. Report: harness/mame/XCROSS_REPORT.md
2026-10-16 10:25:17 +03:00
SDD 99ca146fe3 docs: address units resolved from MAME source (map is in BITS; bytes = bit>>3) + two corrections 2026-10-16 10:18:01 +03:00
SDD 93fb92d807 docs: record the instrument disagreement precisely; block video work on a closed cross-check 2026-10-16 10:11:59 +03:00
SDD b2e0448001 harness: map-precedence calibration (last-wins proven) + layered address probes 2026-10-16 10:11:47 +03:00
SDD 7030f2068d harness: record headless-watchpoint void + the unresolved address-unit blocker, with a calibration plan 2026-10-16 10:07:38 +03:00
SDD ccd03b8879 harness: capture the firmware console; it reports LEVEL1/2 VIDEO MEMORY error 22 and restarts 2026-10-16 10:03:51 +03:00
SDD fe978dee18 harness: locate video memory at 0x00400000 via an unmapped-access catch-all 2026-10-16 09:45:28 +03:00
SDD 170d07f0a2 docs: plan-1 outcome, rulings, and triaged findings (durable record before workspace cleanup) 2026-10-16 02:15:51 +03:00