# First contact with the real VT1200 Date: 2026-10-18. Terminal at **100.103.100.103** (static IP, no BOOTP), reached from host `100.103.255.254` on `enp197s0f3u1`. **Read-only throughout this note — no `poke`, no `jump`.** ## Results | check | result | |---|---| | TCP 771 | **open** | | opcode 7 | challenge (flag `0x7F`) sent, computed reply accepted, `Done\n\0` | | `peek 0x3F200000` (8 B) | `e9 7a e2 f5 aa aa 55 55` — **matches `vt1200_v22.bin`** | | `peek 0xAECE0` (1 B) | `bd` — message classes 0,1,2 admitted (emulator: `05`) | | `peek 0x1E8BA0` (4 B) | `0x018BF1B0` bits = **3,251,638 bytes** free in the heap | | screenshot over `peek` | `dwt/evidence/real-unit-canvas.png` | The screenshot shows the live Terminal Manager V2.2: Ethernet `08-00-2B-16-4B-5A`, IP `100.103.100.103`, LAT `LAT_08002B164B5A`, and five `Debug connection from IP host 100.103.255.254` lines in Messages — one per connection made here. That is the read primitive working on real hardware. ## Two differences from the emulator, worth knowing 1. **The real unit challenges opcode 7.** The emulator only challenges opcodes ≥ 2. A plain liveness check therefore exercises the challenge too, and its success is additional evidence that `dwt/challenge.py` matches the shipped image. 2. **Message filter is `0xBD`, not `0x05`.** Levels 0, 1 and 2 are admitted on the real unit; the emulator only admitted 0 and 3. ## Geometry The raw VRAM canvas is **1024×1024**, captured correctly. The visible screen is 1280×1024, with the canvas at x=192; `dwt/screenshot.py --screen` uses the emulator's 1280×901/offset-192×36 defaults and will misplace the bottom on the real unit. The raw canvas is the authoritative artifact; for a faithful screen image use `--screen-width 1280 --screen-height 1024 --offset-x 192 --offset-y 0` once the vertical origin is measured. ## Next The remaining unproven step on this unit is the write path: `poke`/`jump` and then the COFF loader + `create_process`. The loader already refuses a target outside a free-list block (status 8), so a first attempt with `marker.coff` will tell us whether the linked ranges are free before anything runs. ## Display geometry and background (measured) * Framebuffer **1024×1024, 128 bytes/row**, LSB-first. A 160-byte pitch shears; 128 bytes is coherent. The 160-byte figure is the **total raster** (1280/8), not the memory pitch (`RENDER_REPORT.md`). * Visible raster **1280×1024** (monitor OSD: 77.2 kHz / 73 Hz; Samsung SyncMaster 770 native 1280×1024). The 1024-wide canvas is displayed 5:4, so `dwt/screenshot.py --stretch 1280x1024` matches the screen. `--screen`'s emulator 1280×901 geometry pads/crops and looks line-doubled. * The `101010` background is **real data**, not a decode error. It is a 50% stipple: rows alternate `55` (`01010101`) and `ff`. The root background has a setting; setting it to **100% white** changed the root to solid `ff` (verified by a fresh grab). The Terminal Manager window kept its own stipple, so its window background is a **separate setting** (or was taken at creation). * The bottom message box `Ethernet Port Error - 24` is present in VRAM; it is a real terminal error, not a capture artifact. ### The TM stipple survives the root-background change A fresh grab after the root was set to 100% white confirms: root `0xff`, TM body still alternating `0x55`/`0xff` rows. So the TM pattern is not the desktop background setting and the manager has no option for it. The likely explanation is the **display fetch**, not the data: if the video mode shows only one set of rows (line doubling / interlace), the `0xff` rows are what reaches the glass and the `0x55` rows are never shown — which is why the TM looks white while the raw framebuffer looks striped. That also explains why the capture looked "line doubled": it is showing both row sets. The emulator forces the **VR150** monitor position (`IP4-IP6` high, `0x70`). The real unit's rear switch selects the mode; if it is at another position the firmware may use a different fetch/pattern. Test: set the switch to position 1 (VR150), power-cycle, grab again. ### Line-interleaved framebuffer — the "line doubled" answer The real framebuffer is **line-interleaved**: even rows carry the image, odd rows carry a `0x55` mask in window areas (and `0xff` in the root). The display **doubles the even field**, so the odd rows are never shown. A linear `peek` reads both fields, which is why the first captures looked striped and "line doubled". Evidence: in the Messages area every even row is `0xff`/text and every odd row is a uniform `0x55`; the root is `0xff` on both. After the owner set the background to 100% white and rebooted, the root is `0xff` everywhere and the TM's odd rows are still `0x55` — yet the screen is solid white. That proves the odd rows are a non-displayed mask. Correct capture: ```sh python3 dwt/screenshot.py --host 100.103.100.103 \ --field even --stretch 1280x1024 --out screen.png ``` `dwt/evidence/real-unit-white2.png` is that capture and matches the glass. This is a **display-fetch difference, not a CPU-emulation difference**. MAME's driver models a linear 1bpp framebuffer, so the emulator never shows the interleave; the real TMS34010 display controller is programmed for the doubled even field. ### Correction: the framebuffer is 1024x2048, not line-doubled The earlier "the display doubles the even field" reading was wrong. A **256 KiB** read (2048 rows x 128 bytes) shows the 1024 image lines sitting on **even rows at 1:1**, with the odd rows carrying the mask. The earlier 128 KiB read held only the **top 512 image lines**; doubling them stretched the top half and cut the bottom — which is exactly the "missing left/bottom" and "line doubled" appearance. Correct 1:1 capture: ```sh python3 dwt/screenshot.py --host 100.103.100.103 --real --out screen.png ``` `--real` means `--rows 0:2048 --field even` and outputs **1024x1024 with no resampling**. `dwt/evidence/real-unit-1to1.png` is that capture: Icon Box, Terminal Manager, Memory bar, and the `Ethernet Port Error - 24` box at the bottom — the whole screen. `--stretch 1280x1024` is only the monitor's 5:4 scaling of the 1024-wide framebuffer; it is **not** 1:1 and the nearest-neighbour version produces the uneven-pixel artefacts. Use it only for an approximate visual match, not as evidence. ### Final geometry: 1280x1024, 256-byte row stride The real unit is **1280x1024** with a **256-byte row stride**. Each row's first **160 bytes (1280 px)** are the image; the remaining **96 bytes** are a `0x55` mask. The earlier "1024x2048, even rows" reading was an artifact of treating that 96-byte gap as an alternate row. This is why the 1024-wide reads lost the right quarter: the Icon Box really is 1280 px wide and its resize buttons are at the far right, outside a 1024-px crop. The mask bytes are what looked like "line doubling". Correct 1:1 capture: ```sh python3 dwt/screenshot.py --host 100.103.100.103 --real --out screen.png ``` `--real` = width 1280, stride 256, 1024 rows, no resampling. `dwt/evidence/real-unit-1280-1to1.png` is the full 1280x1024 screen, including the Icon Box resize buttons and the `Ethernet Port Error - 24` box. The emulator geometry is unchanged: 1024x1024 with a 128-byte stride. ### Background references Both backgrounds are captured at the correct geometry: `dwt/evidence/real-unit-1280-1to1.png` (100% white root) and `dwt/evidence/real-unit-1280-50pct.png` (50% `1010` root, the owner's preference). Only the root's image bytes change; the 256-byte stride and the 1280x1024 size are identical. ### X11 app on the real unit (2026-10-18) The host-side loader ran end to end against the terminal: ```sh python3 dwt/loader/hostload.py --host 100.103.100.103 \ --coff dwt/loader/build/xhello.coff --real ``` ``` jump(malloc) -> 0x007e7bf0 COFF 774 B poked (0 differing) loader 1220 B @ 0x01880000 (0 differing) loader A8 = 0; entry 0x01840000; pcb 0x003f6510 xhello stage=6 strlen=4 ``` Evidence: `dwt/evidence/real-unit-xhello.png` — a 400x200 WM-framed black window over the Terminal Manager, on the real screen. **Caveat:** the loader and app are linked at fixed addresses (`0x01880000`, `0x01840000`). Re-running while that app is live overwrites the running code. Power-cycle (or choose new addresses) before loading again. ### MOP console on the real unit `dwt/mop_console.py --iface enp197s0f3u1 --mac 08:00:2b:16:4b:5a` works with no password. `SHOW` returned: ``` Firmware Revision V2.2 Option Memory Present (SIMM 1/2/3 installed) Image Option Not Present Display Type Monochrome Monitor Type VR319 ``` **Monitor Type VR319** is the answer to the geometry question: the unit is in the VR319 (19", 100 dpi) mode, not the emulator's forced VR150. That is why the real framebuffer is 1280x1024 with the 256-byte stride. `TEST 9 9 8` (Ethernet port test, LANCE loopback bit 3) was refused: ``` ?ILLEGAL COMMAND - DWT IN USE ``` The console refuses diagnostics while the DWT has active work — our injected xhello window is the blocker. The service guide requires no open windows before remote tests: power-cycle (or close all session windows) and retry. ### Diagnostic results are not observable through rdebug `dwt/mailbox_watch.py` polled the mailbox pointer (`0x27C190`) and the level-1 dispatcher slot (`0x16F0`) across a power cycle. The rdebug service was only connectable **after** the OS was up, at which point: ``` mailbox=0x00000000 slot=0x8ac00000 (OS data) ``` During the boot it was unusable (timeouts / AssertionError). So the level-1 result is consumed before rdebug exists; the mailbox is a dialog/debug structure, not the boot handoff. The only durable record is the **screen**: the boot alert, and the Diagnostics dialog's on-screen results. ### Menu-driven Ethernet Address ROM test: PASS After a clean power cycle, selecting **Ethernet Address ROM Test** in the Diagnostics dialog completed, the dialog closed, and the Terminal Manager's bottom notification reads: ``` All Diagnostics Passed ``` Evidence: `dwt/evidence/real-unit-romtest-result.png`. This is the ROM checksum test (service-guide error **23** would be the failure), and it **passes** on the real unit, consistent with MAME. The boot-level `Ethernet Port Error - 24` is the separate AUI/transceiver termination test, not the ROM. The first attempt hung the Terminal Manager; this one completed. The hang is not deterministic. The mailbox watcher's reconnect storm during boot is one possible co-factor (it spawns a debug process per accepted connection), but the diagnostic reset is the other; a single success does not settle which.