A create_process child has no per-process Xlib context (XG). This makes
windows and drawing work while events silently fail, so the docs now state the
addresses, the block, and the ordering rule; dwt/loader/xg.c provides the
install helper and was built and run.
The mechanism, from the ROM
0x3F708700 is the current-process helper — it is nothing but move @0x1b3900,a8,1; rets:
So proc = *(u32 *)0x001B3900, pp = *(u32 *)(proc + 0x100), XG = *(u32 *)pp,
free list at XG + 0xCC0 bits. In a fresh child XG is 0, so the whole XG
structure is read from low RAM.
Docs
dwt/notes/GUI_APPS.md: new §10.5 (renumbering the old §10.5–10.7 to
§10.6–10.8), plus a step 0 in §4's minimum sequence and a pointer in the
process table.
dwt/loader/README.md: new section before Build, and xg.c in the file table.
Both say: zeroed ≥1 KiB block (static vt_u32 vt_xg[256] in termtris), store
its address into *(u32 *)pp, and do it before XOpenDisplay. The symptom
is stated as measured: windows and drawing work, XNextEvent returns zeroed
records and never a real event.
Helper, built and run
dwt/loader/xg.c implements int vt_install_xg(void); it returns 0 if *(0x001B3900) or *(proc+0x100) is not a plausible RAM pointer, otherwise
zeroes a 1 KiB block, stores it, and returns 1.
Demonstrated with the unmodified termtris smoke client, linked against the
loader-tree helper:
The display opens and the window is created/mapped, but the event loop only sees
zeroed records. Full transcript: dwt/loader/evidence/xg_helper_run.log.
Limits
The ordering rule (before XOpenDisplay) is the order the working client
uses; I did not test installing after XOpenDisplay.
1 KiB is the tested block size, not a proven minimum.
The measured failure is zero-valued events; the exact low-RAM words that
become the queue are whatever the previous boot left and are not
characterised.
ROM unchanged: md5 b46a3e442ccb86134d2356bd70d22fd2 vt1200_v22.bin before
and after the runs.
Closes #2
A `create_process` child has no per-process Xlib context (`XG`). This makes
windows and drawing work while events silently fail, so the docs now state the
addresses, the block, and the ordering rule; `dwt/loader/xg.c` provides the
install helper and was built and run.
## The mechanism, from the ROM
`0x3F708700` is the current-process helper — it is nothing but
`move @0x1b3900,a8,1; rets`:
```
$ tools/smart34010/dis34 -l -o -b 3F708700 \
-s $(( (0x3F708700-0x3F200000)/8 )) vt1200_v22.bin
3f708700: move @0x1b3900, a8, 1
3f708730: rets
```
`XNextEvent` is `0x3F9C1CF0`; its dequeue path loads `XG` twice and manages the
free list at `XG+0xCC0` bits (= byte `+0x198`):
```
$ tools/smart34010/dis34 -l -o -b 3F9C23C0 \
-s $(( (0x3F9C23C0-0x3F200000)/8 )) vt1200_v22.bin
3f9c23c0: calla 0x3f708700
3f9c23f0: move *a8(0x100), a7, 1
3f9c2410: move *a7, a7, 1
3f9c2420: move *a7(0xcc0), *a11(0x0), 1
...
3f9c24b0: move a11, *a7(0xcc0), 1
```
The enqueue helper `0x3F9B89A0` (called from `XNextEvent` at `0x3F9C2180`) does
the same three loads and takes a node from the same free list:
```
$ tools/smart34010/dis34 -l -o -b 3F9B89A0 \
-s $(( (0x3F9B89A0-0x3F200000)/8 )) vt1200_v22.bin
3f9b8a80: calla 0x3f708700
3f9b8ab0: move *a8(0x100), a7, 1
3f9b8ad0: move *a7, a7, 1
3f9b8ae0: move *a7(0xcc0), a11, 1
...
3f9b8b70: move *a11(0x0), *a7(0xcc0), 1
```
So `proc = *(u32 *)0x001B3900`, `pp = *(u32 *)(proc + 0x100)`, `XG = *(u32 *)pp`,
free list at `XG + 0xCC0` bits. In a fresh child `XG` is 0, so the whole XG
structure is read from low RAM.
## Docs
- `dwt/notes/GUI_APPS.md`: new §10.5 (renumbering the old §10.5–10.7 to
§10.6–10.8), plus a step 0 in §4's minimum sequence and a pointer in the
process table.
- `dwt/loader/README.md`: new section before Build, and `xg.c` in the file table.
Both say: zeroed ≥1 KiB block (`static vt_u32 vt_xg[256]` in termtris), store
its address into `*(u32 *)pp`, and do it **before `XOpenDisplay`**. The symptom
is stated as measured: windows and drawing work, `XNextEvent` returns zeroed
records and never a real event.
## Helper, built and run
`dwt/loader/xg.c` implements `int vt_install_xg(void)`; it returns 0 if
`*(0x001B3900)` or `*(proc+0x100)` is not a plausible RAM pointer, otherwise
zeroes a 1 KiB block, stores it, and returns 1.
Demonstrated with the **unmodified** termtris smoke client, linked against the
loader-tree helper:
```
$ apps/termtris/build.sh apps/termtris/tests/smoke.c dwt/loader/xg.c
...
.bss 0 01a00000 0000a700
01a08700 00002000 XG.obj (.bss)
$ HOME=/tmp/opencode/vt1200-task2/home VT1200_SKIP_LEVEL1=1 \
SMOKE_MARK=0x01a08000 LOADER_AT=2500 LOADER_END=3400 \
LOADER_BIN=$PWD/dwt/loader/build/loader.bin \
LOADER_COFF=$PWD/apps/termtris/build/smoke.coff \
LOADER_OUT=/tmp/opencode/vt1200-task2 \
/home/arti/code/k-space/mame0289/vt1200 vt1200 \
-rompath harness/mame/roms -video none -sound none -nothrottle \
-skip_gameinfo -cfg_directory /tmp/opencode/vt1200-task2/cfg \
-nvram_directory /tmp/opencode/vt1200-task2/nvram \
-debug -debugger none -autoboot_script apps/termtris/tests/smoke.lua \
-autoboot_delay 0
LOADER: result status=0 (OK) ... pcb=003FEE50 nscns=4 len=1349
SMOKE: magic=534D4F4B dpy=00942290 win=00400001 n=9 type=2 keycode=194 lookup_n=1 ch=61 ks=0061 keymark=4B455950
```
`type=2` is `KeyPress`, `keycode=194` is the LK401 `A`, and `keymark=4B455950`
is the client's own "KEYP" marker.
Control: the same client with a stub `vt_install_xg()` that installs nothing:
```
SMOKE: magic=534D4F4B dpy=00942290 win=00400001 n=10 type=0 keycode=0 lookup_n=0 ch=00 ks=0000 keymark=00000000
```
The display opens and the window is created/mapped, but the event loop only sees
zeroed records. Full transcript: `dwt/loader/evidence/xg_helper_run.log`.
## Limits
- The ordering rule (before `XOpenDisplay`) is the order the working client
uses; I did not test installing after `XOpenDisplay`.
- 1 KiB is the tested block size, not a proven minimum.
- The measured failure is zero-valued events; the exact low-RAM words that
become the queue are whatever the previous boot left and are not
characterised.
- ROM unchanged: `md5 b46a3e442ccb86134d2356bd70d22fd2 vt1200_v22.bin` before
and after the runs.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #2
A
create_processchild has no per-process Xlib context (XG). This makeswindows and drawing work while events silently fail, so the docs now state the
addresses, the block, and the ordering rule;
dwt/loader/xg.cprovides theinstall helper and was built and run.
The mechanism, from the ROM
0x3F708700is the current-process helper — it is nothing butmove @0x1b3900,a8,1; rets:XNextEventis0x3F9C1CF0; its dequeue path loadsXGtwice and manages thefree list at
XG+0xCC0bits (= byte+0x198):The enqueue helper
0x3F9B89A0(called fromXNextEventat0x3F9C2180) doesthe same three loads and takes a node from the same free list:
So
proc = *(u32 *)0x001B3900,pp = *(u32 *)(proc + 0x100),XG = *(u32 *)pp,free list at
XG + 0xCC0bits. In a fresh childXGis 0, so the whole XGstructure is read from low RAM.
Docs
dwt/notes/GUI_APPS.md: new §10.5 (renumbering the old §10.5–10.7 to§10.6–10.8), plus a step 0 in §4's minimum sequence and a pointer in the
process table.
dwt/loader/README.md: new section before Build, andxg.cin the file table.Both say: zeroed ≥1 KiB block (
static vt_u32 vt_xg[256]in termtris), storeits address into
*(u32 *)pp, and do it beforeXOpenDisplay. The symptomis stated as measured: windows and drawing work,
XNextEventreturns zeroedrecords and never a real event.
Helper, built and run
dwt/loader/xg.cimplementsint vt_install_xg(void); it returns 0 if*(0x001B3900)or*(proc+0x100)is not a plausible RAM pointer, otherwisezeroes a 1 KiB block, stores it, and returns 1.
Demonstrated with the unmodified termtris smoke client, linked against the
loader-tree helper:
type=2isKeyPress,keycode=194is the LK401A, andkeymark=4B455950is the client's own "KEYP" marker.
Control: the same client with a stub
vt_install_xg()that installs nothing:The display opens and the window is created/mapped, but the event loop only sees
zeroed records. Full transcript:
dwt/loader/evidence/xg_helper_run.log.Limits
XOpenDisplay) is the order the working clientuses; I did not test installing after
XOpenDisplay.become the queue are whatever the previous boot left and are not
characterised.
md5 b46a3e442ccb86134d2356bd70d22fd2 vt1200_v22.binbeforeand after the runs.
310a9a3ea5toa43eba776ba43eba776bto3f6eb56749