Files
arti d8d54bb990 feat(xie): a client-chosen XIE image is displayed on the VT1200
The XIE path now runs end to end: XieCreateImage -> XieCreatePhoto ->
XiePutTile -> XieExport(photomap -> depth-1 pixmap) -> XCopyArea(pixmap ->
window), and the client's tile appears on screen at the client's own window
position, pixel-exact.

TWO FAULTS BEHIND THE LONG DEAD END

1. Device model (harness/mame/vt1200.cpp, opt-in VT1200_ACCEL=1).  The
   accelerator's output port 0x5600200 returns the pixel stream the firmware
   pushed into the FIFO -- the firmware then stores it into the drawable itself
   (file 0x125528: MOVE *B6,*B1 ; ADDK 0x10,B1).  The FIFO read pointer was
   never reset between transfers, so consecutive exports read stale words and
   the same fill produced 759 then 516 set pixels.  Reset m_fifo_in/out on the
   data-register write; the export is now deterministic.

2. Measurement, not the device.
   - dwt/screenshot.py without --real reads 1024x1024 at a 128-byte row stride,
     but the VR319 default programs 1280x1024 at a 2048-bit (256-byte) pitch.
     That is the "shifted" picture; --real is the correct read.
   - The earlier "0 differing bytes over 128 KiB" VRAM comparison stepped peek
     by 1024 *bit* addresses, so it scanned rows 0..63 only -- never the window
     at rows 200..263.  Over the real raster the white/black diff is 576 bytes
     spanning exactly those rows.
   - New instrument: decclient does a server-side XGetImage readback of the
     pixmap and window and counts set pixels.  That separated "the server never
     drew it" from "the framebuffer view is wrong".

EVIDENCE (reproduced twice, the second time from a fresh machine)

  no export vs 0xFF : 4096 / 4096 pixels differ
  no export vs 0x00 :    0 / 4096   (the window background is black)
  0xFF      vs 0x00 : 4096 / 4096
  0xAA      vs 0x0F : 2048 / 4096   (the two stripe phases)

Tile byte 0xAA reproduces as 1-pixel vertical stripes, 0x0F as 4-pixel, with
no shear -- so the placement is right and the pixels are the client's.

Contents: xie/ holds DEC XIE 2.3 headers, 84 man pages and complete
client+server source; a libXie.a and decclient built from DEC's own code; the
XIE probes; and evidence/ with every measurement, including explicit
retractions of the earlier wrong readings (VRAM_IDENTICAL_FOR_BOTH_FILLS and
friends).  xie/evidence/XIE_IMAGE_DISPLAYED.md is the report; frames are in
xie/evidence/png/.

The accelerator model stays opt-in: it answers the status poll and relays the
pixel stream, but performs no compositing, so it is a stand-in and the verified
default configuration is unchanged (a no-env run still parks in the level-0
diagnostics menu at PC=3FDCE400).
2026-11-01 23:22:25 +02:00

71 lines
3.1 KiB
Plaintext

XIE 2.3 dispatch tables, dumped straight out of the ROM image.
Ghidra session afdab6e16b8240f294d45a5309f7caa3, program vt1200_v22.bin
(raw binary, base rom:00000000 == file offset 0, md5 b46a3e442ccb86134d2356bd70d22fd2)
Encodings
ghidra_byte = (mame_bit - 0x3F200000) / 8
mame_bit = 0x3F200000 + ghidra_byte * 8
Three 46-entry CARD32 arrays (bit addresses) live back to back, each preceded
by its own {CARD16, CARD32} install record:
0x18D8E8 -> RAM 0xD3F90 proc table (used by XieProc)
0x18D9A6 -> RAM 0xD4550 swapped proc table (used by XieSProc)
0x18DA64 -> RAM 0xD4B10 REPLY-swap table (used inside the five query
handlers; only slots 1,3,6,10,24 are non-stub)
NOTE: the "swapped" columns printed below are the 0x18DA64 array, i.e. the
reply-swap table, not the swapped-proc table. See GHIDRA_XIE_HANDLERS.md.
0x18D8E2: CARD16 0x005C CARD32 0x000D3F90 <- proc table
0x18D9A0: CARD16 0x005C CARD32 0x000D4550 <- swapped proc table
0x18DA5E: CARD16 0x005C CARD32 0x000D4B10 <- reply-swap table
idx main(bit) main_off swapped(bit) swap_off
0 3F5261E0 064C3C 3F5261E0 064C3C
1 3F545260 068A4C 3F5491E0 06923C
2 3F546D30 068DA6 3F5261E0 064C3C
3 3F3FEBC0 03FD78 3F549620 0692C4
4 3F3FF030 03FE06 3F5261E0 064C3C
5 3F546EE0 068DDC 3F5261E0 064C3C
6 3F547630 068EC6 3F549980 069330
7 3F534330 066866 3F5261E0 064C3C
8 3F534720 0668E4 3F5261E0 064C3C
9 3F534C70 06698E 3F5261E0 064C3C
10 3F535B20 066B64 3F549CA0 069394
11 3F533DB0 0667B6 3F5261E0 064C3C
12 3F5339C0 066738 3F5261E0 064C3C
13 3F535470 066A8E 3F5261E0 064C3C
14 3F5361A0 066C34 3F5261E0 064C3C
15 3F5529B0 06A536 3F5261E0 064C3C
16 3F5261E0 064C3C 3F5261E0 064C3C
17 3F5261E0 064C3C 3F5261E0 064C3C
18 3F552D20 06A5A4 3F5261E0 064C3C
19 3F553B70 06A76E 3F5261E0 064C3C
20 3F5552A0 06AA54 3F5261E0 064C3C
21 3F516A00 062D40 3F5261E0 064C3C
22 3F5187A0 0630F4 3F5261E0 064C3C
23 3F5261E0 064C3C 3F5261E0 064C3C
24 3F518AF0 06315E 3F54AFC0 0695F8
25 3F5261E0 064C3C 3F5261E0 064C3C
26 3F5261E0 064C3C 3F5261E0 064C3C
27 3F5261E0 064C3C 3F5261E0 064C3C
28 3F5261E0 064C3C 3F5261E0 064C3C
29 3F5261E0 064C3C 3F5261E0 064C3C
30 3F5261E0 064C3C 3F5261E0 064C3C
31 3F5261E0 064C3C 3F5261E0 064C3C
32 3F5261E0 064C3C 3F5261E0 064C3C
33 3F526640 064CC8 3F5261E0 064C3C
34 3F5261E0 064C3C 3F5261E0 064C3C
35 3F5261E0 064C3C 3F5261E0 064C3C
36 3F5261E0 064C3C 3F5261E0 064C3C
37 3F5261E0 064C3C 3F5261E0 064C3C
38 3F5261E0 064C3C 3F5261E0 064C3C
39 3F5261E0 064C3C 3F5261E0 064C3C
40 3F529310 065262 3F5261E0 064C3C
41 3F5261E0 064C3C 3F5261E0 064C3C
42 3F5261E0 064C3C 3F5261E0 064C3C
43 3F52B000 065600 3F5261E0 064C3C
44 3F52E550 065CAA 3F5261E0 064C3C
45 3F5261E0 064C3C 3F5261E0 064C3C
0x64C3C is the shared "not implemented" stub (returns/sends BadRequest).
Only 9 slots have a distinct swapped handler: 1, 3, 6, 10, 24.