ROM import tables
One file per ROM revision. Addresses are bit addresses and are not assumed stable across firmware revisions; v2.2 is the first target.
vt1200-v22.syms is the per-ROM entry table. Every entry is validated by
scripts/m4/validate-syms.sh against the v2.2 image (md5
b46a3e442ccb86134d2356bd70d22fd2): it must be in the ROM bit range
3F200000h..3FFFFFFFh, 16-bit aligned, and disassemble to a plausible function
prologue (MMTM/MOVE/SETF/CMP/ADDI). scripts/tests/m4/symbols.sh
runs the gate and also pins the XMapWindow/XRaiseWindow correction.
The table is consumed through scripts/m2/gen-rom-imports.sh, which emits an
ABI-preserving jauc <address>h stub for every
<name> <bit-address> line. The 30-entry v2.2 table is the M4 table: the
four M3 connection/window entries plus the drawing, event, XImage, XG,
blitter and image-client entries. scripts/m2/gen-rom-imports.sh emits every
entry; each client links only the stubs it calls.
Do not assume an address here is validated just because it is listed. Each
entry below names its evidence. Nothing is guessed: XCreateImage,
XPutImage, XGetImage, XDestroyImage, the two error-handler setters,
XCreatePixmap, XSetInputFocus and blit_copy were extracted from the ROM
disassembly before being added.
XLoadFont and XCopyArea are not in the pinned termtris xlib.h
(that header has 15 entries). They are inherited from the M4 plan
(task-5-brief.md) and are ROM-validated here by their request builders:
the XLoadFont body at 0x3FD4AE80 builds movi 0x2d (OpenFont opcode 45)
and the XCopyArea body at 0x3FD3E220 builds movi 0x3e (CopyArea
opcode 62); both write the opcode with movb to the request buffer. The same
addresses/opcodes are listed in the vendored DWT GUI_APPS.md table.
scripts/m4/validate-syms.sh now checks both builders. Do not cite the
termtris header for them.
XMapWindow correction
The M3 table used 0x3FD645B0 under the name XMapWindow. That address is
XRaiseWindow: its body builds X11 request opcode 12
(ConfigureWindow) with value-mask 0x40 (CWStackMode) and value 0
(Above). The true XMapWindow is 0x3FD64F60, whose body builds request
opcode 8 (MapWindow). The termtris VT1200 xlib.h already used
0x3FD64F60.
scripts/m3/validate-syms.sh and scripts/m3/dis-roundtrip.sh now expect
0x3FD64F60, and scripts/tests/m4/symbols.sh fails if a table maps
XMapWindow to 0x3FD645B0 (reported as XRaiseWindow/wrong). A client that
wants map-and-raise calls XMapWindow and then XRaiseWindow.
The vendored DWT reverse-engineering notes (vendor/vt1200/dwt/notes/GUI_APPS.md,
vendor/vt1200/dwt/notes/CROSS.md, vendor/vt1200/dwt/gui/xhello.asm) still
label 0x3FD645B0 as XMapWindow. Those are historical notes and were
deliberately left untouched: the address is XRaiseWindow, and the corrected
table here is authoritative. scripts/m4/validate-syms.sh and
scripts/tests/m4/symbols.sh pin the correction.
v2.2 entries validated
The table below has 30 entries: 12 connection/window/event, 1 blitter
helper, 8 drawing/GC, 6 XImage/error-handler and 3 C runtime entries.
scripts/m4/validate-syms.sh walks all 30 and prints the count.
Connection, windows, events
| entry | bit address | evidence |
|---|---|---|
XOpenDisplay |
0x3F9C2570 |
termtris xlib.h; xhello.asm calls it; MAME child connects |
XCreateSimpleWindow |
0x3FD41B90 |
termtris xlib.h; nine-argument create, window id nonzero |
XCreatePixmap |
0x3FD416E0 |
CreatePixmap request opcode 0x35; five arguments (display, drawable, width, height, depth); M4 image client's aligned 1-bit pixmap |
XMapWindow |
0x3FD64F60 |
request opcode 8 (MapWindow); termtris xlib.h |
XRaiseWindow |
0x3FD645B0 |
request opcode 12 (ConfigureWindow), CWStackMode=Above |
XSync |
0x3FD9F6B0 |
termtris xlib.h; called after mapping |
XFlush |
0x3F9B1030 |
termtris xlib.h |
XPending |
0x3FD67620 |
termtris xlib.h |
XNextEvent |
0x3F9C1CF0 |
termtris xlib.h; event loop proof |
XSelectInput |
0x3FD97D50 |
termtris xlib.h (ChangeWindowAttributes) |
XGetInputFocus |
0x3FD55210 |
termtris xlib.h |
XSetInputFocus |
0x3FD536B0 |
SetInputFocus request opcode 0x2a; the ROM body reads 0xffe0/0xffc0/0xffa0 and supplies CurrentTime; sibling of XGetInputFocus opcode 0x2b |
Blitter copy helper
| entry | bit address | evidence |
|---|---|---|
blit_copy |
0x3FB44400 |
_XPutImage's copy entry (0x3F9CBFE0 calls 0x3FB44400); TMS34010 blitter memcpy with the ROM order (source, destination, byte count) and a normal MMTM prologue. The M4 image client primes it once per draw with a 4-byte self-copy because a loader-created process starts with a zeroed blitter window/pitch context. Validated by scripts/m4/validate-syms.sh and the _blit_copy JAUC/CALLA checks in dis-roundtrip.sh. |
Drawing and GC
| entry | bit address | evidence |
|---|---|---|
XCreateGC |
0x3F997000 |
termtris xlib.h; request opcode 55 |
XSetForeground |
0x3FD99A60 |
termtris xlib.h; caches in GC |
XFillRectangle |
0x3F99E8F0 |
termtris xlib.h; request opcode 70 |
XDrawString |
0x3FDA0000 |
termtris xlib.h; request opcode 74 (PolyText8) |
XLoadFont |
0x3FD4AE80 |
ROM body builds movi 0x2d (OpenFont opcode 45) and movb to the request buffer; dwt/notes/GUI_APPS.md table; not in the termtris xlib.h; checked by validate-syms.sh |
XCopyArea |
0x3FD3E220 |
ROM body builds movi 0x3e (CopyArea opcode 62) and movb to the request buffer; dwt/notes/GUI_APPS.md table; not in the termtris xlib.h; checked by validate-syms.sh; the M4 image client copies its aligned pixmap with it |
XLookupString |
0x3F9A9C30 |
termtris xlib.h; key translation |
sleep |
0x3FB33A20 |
termtris xlib.h; called directly |
XImage and error handlers (ROM-validated)
| entry | bit address | evidence |
|---|---|---|
XCreateImage |
0x3F9A0490 |
installed as XImage.f.create_image by the ROM initializer at 0x3F9A6AA0; calloc(1, 0x58) = sizeof(XImage) == 88 and field initialization; called by XGetImage with ten arguments at 0x3FD56190 |
XPutImage |
0x3F9CEC70 |
prologue MMTM sp, a5,a7,a9,a10,a11,a13; body builds request opcode 0x48 at 0x3F9CEE00; references XPutImage: bits_per_pixel conversion unimplemented. at 0x3F9D0E80 |
XGetImage |
0x3FD556B0 |
prologue MMTM sp, a7,a9,a10,a11,a13; body builds request opcode 0x49 at 0x3FD55830; error path references XGetImage: Can't get requested memory at 0x3FD567A0 |
XDestroyImage |
0x3F9A0D80 |
ROM private _XDestroyImage, installed as XImage.f.destroy_image by the same initializer; real Xlib defines XDestroyImage as a macro over this pointer. The stub name is _XDestroyImage |
XSetErrorHandler |
0x3FD45700 |
stores the handler in the per-process XG block at +0x60; default 0x3F9BD9F0 (_XDefaultError); session manager, WM, and VTE call it with an error-event handler |
XSetIOErrorHandler |
0x3FD458F0 |
stores the handler in the XG block at +0x40; default 0x3F9BCD40 (_XDefaultIOError); same callers pass an I/O-error handler |
The error-handler setters operate on the per-process XG block, the same block
that scripts/m4/xgfix.c installs before XOpenDisplay. Ghidra byte
addresses are reproduced as ROM bit addresses (bit = byte << 3); the
reconstructed ROM image starts at bit 0x3F200000.
C runtime
| entry | bit address | evidence |
|---|---|---|
strlen |
0x3FB458D0 |
xhello.asm ABI check (strlen("0::0") == 4) |
malloc |
0x3F701230 |
ROM allocator; called by XCreateImage/XGetImage |
free |
0x3F702440 |
ROM free; called by XDestroyImage |
M3/M4 regression checks
scripts/m3/validate-syms.sh independently checks the four M3 entries
(XOpenDisplay, XCreateSimpleWindow, XMapWindow, XSync) and now expects
XMapWindow 0x3FD64F60. scripts/tests/m3/run.sh runs it before every MAME
run, so the compiled client cannot pass with a stale stub. The M3 and M4
validators are separate scripts (the M3 one is a four-entry regression; the M4
one walks the whole 30-entry table), but they use the same
range/alignment/prologue rules and the same corrected address. The M4 table
also carries XCreatePixmap, XSetInputFocus, blit_copy, XImage,
XGetImage/XDestroyImage and both error-handler setters; symbols.sh
rejects the historical XMapWindow 0x3FD645B0 mapping and an unaligned
XPutImage.
The build resolves these as absolute symbols (or ABI-preserving stubs). Do not bake them into the compiler: keep them in a per-ROM linker script.