; xhello.asm -- open a *new* X connection and create/map a window on the live ; DWT X server. ; ; Run as a first-class process created by xlaunch.asm (create_process), NOT in ; the rdebug dispatcher's context: a connect made from the rdebug process is ; accepted at the service layer but the server never reads the X11 setup, so ; XOpenDisplay returns an unusable Display. A fresh process works. ; ; Calling convention (the one the firmware itself uses; see the WM at ; 07F57044 and the TM at 07E5D2B4): ; ; MOVE A14,-*SP,1 ; reserve the slot the callee restores A14 from ; MOVI argN,A0 / MOVE A0,*A14+,1 ; last argument first, upward via A14 ; ... ; MOVI arg0,A0 / MOVE A0,*A14+,1 ; first argument last ; CALLA target ; ; Xlib clobbers the CPU's SETF field state, so the ABI's 32-bit field 1 is ; re-established after every call. The Display pointer and root/window ids are ; kept in a11/a10 (both callee-saved by every Xlib entry point): a RAM cell can ; be overwritten by the new process's stack, a register cannot. ; ; Xlib entry points (Ghidra address -> bit address): ; 7F384AE XOpenDisplay(name) -> 3F9C2570 ; 7FA8372 XCreateSimpleWindow(...) -> 3FD41B90 ; 7FAC8B6 XMapWindow(display,window) -> 3FD645B0 ; 7FB3ED6 XSync(display,discard) -> 3FD9F6B0 ; 7F68B1A strlen(s) -> 3FB458D0 (convention check) ; ; Markers (32-bit cells, bit addresses; diagnostic only): ; 01890100 display pointer ; 01890110 root window ; 01890120 window id ; 01890130 XSync return ; 01890140 stage counter ; 01890160 strlen("0::0") -- must be 4; if not, we stop before touching Xlib .text _start: setf 16, 0, 0 setf 32, 0, 1 mmtm sp, a0,a1,a2,a3,a4,a5,a6,a7 move sp, @01890420h, 1 ; entry SP move a14, @01890400h, 1 ; entry A14 movi 1, a0, L move a0, @01890140h, 1 ; stage = 1 ; ---- convention check: strlen("0::0") == 4 -------------------- move a14, -*sp, 1 movi 01892000h, a14, L movi 3FACE948h, a0, L ; ROM "0::0" move a0, *a14+, 1 ; arg0 calla 3FB458D0h ; strlen move @01890420h, sp, 1 move @01890400h, a14, 1 setf 16, 0, 0 ; Xlib leaves the field sizes changed; setf 32, 0, 1 ; re-establish the ABI's 32-bit field 1 move a8, @01890160h, 1 ; MARK strlen movi 4, a0, L cmp a0, a8 jrne done movi 2, a0, L move a0, @01890140h, 1 ; ---- display = XOpenDisplay("0::0") --------------------------- move a14, -*sp, 1 movi 01892000h, a14, L movi 3FACE948h, a0, L move a0, *a14+, 1 ; arg0 = name calla 3F9C2570h ; XOpenDisplay move @01890420h, sp, 1 move @01890400h, a14, 1 setf 16, 0, 0 setf 32, 0, 1 move a8, a11 ; keep the Display in a callee-saved reg move a11, @01890100h, 1 ; MARK display move a11, a11 jreq done movi 3, a0, L move a0, @01890140h, 1 ; ---- root = *(*(display+0x480)+0x40) -------------------------- move *a11(0480h), a10, 1 move *a10(040h), a10, 1 move a10, @01890110h, 1 ; MARK root ; ---- XCreateSimpleWindow(display,root,100,100,400,200,2,0,0) -- move a14, -*sp, 1 movi 01892000h, a14, L movi 0, a0, L move a0, *a14+, 1 ; background = 0 (black) move a0, *a14+, 1 ; border = 0 movi 2, a0, L move a0, *a14+, 1 ; border width movi 200, a0, L move a0, *a14+, 1 ; height movi 400, a0, L move a0, *a14+, 1 ; width movi 100, a0, L move a0, *a14+, 1 ; y move a0, *a14+, 1 ; x move a10, *a14+, 1 ; parent = root move a11, *a14+, 1 ; display calla 3FD41B90h ; XCreateSimpleWindow move @01890420h, sp, 1 move @01890400h, a14, 1 setf 16, 0, 0 setf 32, 0, 1 move a8, a10 ; window id (root no longer needed) move a10, @01890120h, 1 ; MARK window movi 4, a0, L move a0, @01890140h, 1 ; ---- XMapWindow(display, window) ------------------------------ move a14, -*sp, 1 movi 01892000h, a14, L move a10, *a14+, 1 ; window move a11, *a14+, 1 ; display calla 3FD645B0h ; XMapWindow move @01890420h, sp, 1 move @01890400h, a14, 1 setf 16, 0, 0 setf 32, 0, 1 movi 5, a0, L move a0, @01890140h, 1 ; ---- XSync(display, 0) ---------------------------------------- move a14, -*sp, 1 movi 01892000h, a14, L movi 0, a0, L move a0, *a14+, 1 ; discard = 0 move a11, *a14+, 1 ; display calla 3FD9F6B0h ; XSync move @01890420h, sp, 1 move @01890400h, a14, 1 setf 16, 0, 0 setf 32, 0, 1 move a8, @01890130h, 1 ; MARK sync movi 6, a0, L move a0, @01890140h, 1 done: mmfm sp, a0,a1,a2,a3,a4,a5,a6,a7 movi 0, a8, L rets .end