commit bcfa57d

Devine Lu Linvega  ·  2026-02-08 09:29:26 +0000 UTC
parent 01c7537
Re-created the uxn struct
1 files changed,  +114, -111
+114, -111
  1@@ -27,13 +27,16 @@ typedef unsigned char Uint8;
  2 typedef unsigned short Uint16;
  3 typedef void (*deo_handler)(void);
  4 typedef Uint8 (*dei_handler)(void);
  5+typedef struct {
  6+	Uint8 *ram, dev[0x100], stk[2][0x100], ptr[2];
  7+} Uxn;
  8 
  9+static Uxn uxn;
 10 static Display *emu_dpy;
 11 static Window emu_win;
 12 static XImage *emu_img;
 13 static int emu_x11;
 14 static int emu_timer;
 15-static Uint8 *ram, dev[0x100], ptr[2], stk[2][0x100];
 16 static unsigned int uxn_eval(Uint16 pc);
 17 
 18 /* clang-format off */
 19@@ -60,10 +63,10 @@ static void
 20 system_print(char *name, int r)
 21 {
 22 	Uint8 i;
 23-	fprintf(stderr, "%s%c", name, ptr[r] - 8 ? ' ' : '|');
 24-	for(i = ptr[r] - 8; i != ptr[r]; i++)
 25-		fprintf(stderr, "%02x%c", stk[r][i], i == 0xff ? '|' : ' ');
 26-	fprintf(stderr, "<%02x\n", ptr[r]);
 27+	fprintf(stderr, "%s%c", name, uxn.ptr[r] - 8 ? ' ' : '|');
 28+	for(i = uxn.ptr[r] - 8; i != uxn.ptr[r]; i++)
 29+		fprintf(stderr, "%02x%c", uxn.stk[r][i], i == 0xff ? '|' : ' ');
 30+	fprintf(stderr, "<%02x\n", uxn.ptr[r]);
 31 }
 32 
 33 static unsigned int
 34@@ -71,9 +74,9 @@ system_load(const char *rom_path)
 35 {
 36 	FILE *f = fopen(rom_path, "rb");
 37 	if(f) {
 38-		unsigned int i = 0, l = fread(ram + 0x100, 0x10000 - 0x100, 1, f);
 39+		unsigned int i = 0, l = fread(uxn.ram + 0x100, 0x10000 - 0x100, 1, f);
 40 		while(l && ++i < BANKS)
 41-			l = fread(ram + i * 0x10000, 0x10000, 1, f);
 42+			l = fread(uxn.ram + i * 0x10000, 0x10000, 1, f);
 43 		fclose(f);
 44 	}
 45 	return !!f;
 46@@ -82,52 +85,52 @@ system_load(const char *rom_path)
 47 static unsigned int
 48 system_boot(char *rom_path, const unsigned int has_args)
 49 {
 50-	ram = (Uint8 *)calloc(BANKS_CAP, sizeof(Uint8));
 51+	uxn.ram = (Uint8 *)calloc(BANKS_CAP, sizeof(Uint8));
 52 	system_boot_path = rom_path;
 53-	dev[0x17] = has_args;
 54-	return ram && system_load(rom_path);
 55+	uxn.dev[0x17] = has_args;
 56+	return uxn.ram && system_load(rom_path);
 57 }
 58 
 59 static unsigned int
 60 system_reboot(const unsigned int soft)
 61 {
 62-	memset(dev, 0, 0x100);
 63-	memset(stk[0], 0, 0x100);
 64-	memset(stk[1], 0, 0x100);
 65+	memset(uxn.dev, 0, 0x100);
 66+	memset(uxn.stk[0], 0, 0x100);
 67+	memset(uxn.stk[1], 0, 0x100);
 68 	if(soft)
 69-		memset(ram + 0x100, 0, 0xff00);
 70+		memset(uxn.ram + 0x100, 0, 0xff00);
 71 	else
 72-		memset(ram, 0, 0x10000);
 73-	ptr[0] = ptr[1] = 0;
 74+		memset(uxn.ram, 0, 0x10000);
 75+	uxn.ptr[0] = uxn.ptr[1] = 0;
 76 	return system_load(system_boot_path);
 77 }
 78 
 79 static void
 80 system_deo_expansion(void)
 81 {
 82-	const Uint16 exp = peek2(dev + 2);
 83-	Uint8 *aptr = ram + exp;
 84+	const Uint16 exp = peek2(uxn.dev + 2);
 85+	Uint8 *aptr = uxn.ram + exp;
 86 	Uint16 length = peek2(aptr + 1);
 87 	unsigned int bank = peek2(aptr + 3) * 0x10000;
 88 	unsigned int addr = peek2(aptr + 5);
 89-	if(ram[exp] == 0x0) {
 90+	if(uxn.ram[exp] == 0x0) {
 91 		if(bank < BANKS_CAP)
 92-			memset(ram + bank + addr, ram[exp + 7], length);
 93-	} else if(ram[exp] == 1 || ram[exp] == 2) {
 94+			memset(uxn.ram + bank + addr, uxn.ram[exp + 7], length);
 95+	} else if(uxn.ram[exp] == 1 || uxn.ram[exp] == 2) {
 96 		unsigned int dst_bank = peek2(aptr + 7) * 0x10000;
 97 		unsigned int dst_addr = peek2(aptr + 9);
 98 		if(bank < BANKS_CAP && dst_bank < BANKS_CAP)
 99-			memmove(ram + dst_bank + dst_addr, ram + bank + addr, length);
100+			memmove(uxn.ram + dst_bank + dst_addr, uxn.ram + bank + addr, length);
101 	} else
102-		fprintf(stderr, "Unknown command: %s\n", &ram[exp]);
103+		fprintf(stderr, "Unknown command: %s\n", &uxn.ram[exp]);
104 }
105 
106 /* clang-format off */
107 
108-static Uint8 system_dei_wst(void) { return ptr[0]; }
109-static Uint8 system_dei_rst(void) { return ptr[1]; }
110-static void system_deo_wst(void) { ptr[0] = dev[4]; }
111-static void system_deo_rst(void) { ptr[1] = dev[5]; }
112+static Uint8 system_dei_wst(void) { return uxn.ptr[0]; }
113+static Uint8 system_dei_rst(void) { return uxn.ptr[1]; }
114+static void system_deo_wst(void) { uxn.ptr[0] = uxn.dev[4]; }
115+static void system_deo_rst(void) { uxn.ptr[1] = uxn.dev[5]; }
116 static void system_deo_print(void) { system_print("WST", 0), system_print("RST", 1); }
117 
118 /* clang-format on */
119@@ -146,7 +149,7 @@ static unsigned int
120 console_input(int c, unsigned int type)
121 {
122 	if(c == EOF) c = 0, type = CONSOLE_END;
123-	dev[0x12] = c, dev[0x17] = type;
124+	uxn.dev[0x12] = c, uxn.dev[0x17] = type;
125 	if(console_vector) uxn_eval(console_vector);
126 	return type != CONSOLE_END;
127 }
128@@ -214,16 +217,16 @@ start_fork_pipe(void)
129 {
130 	pid_t pid;
131 	pid_t parent_pid = getpid();
132-	int addr = peek2(&dev[CMD_ADDR]);
133+	int addr = peek2(&uxn.dev[CMD_ADDR]);
134 	fflush(stdout);
135 	if(child_mode & 0x08) {
136-		dev[CMD_EXIT] = dev[CMD_LIVE] = 0x00;
137+		uxn.dev[CMD_EXIT] = uxn.dev[CMD_LIVE] = 0x00;
138 		return;
139 	}
140 	if(child_mode & 0x01) {
141 		/* parent writes to child's stdin */
142 		if(pipe(to_child_fd) == -1) {
143-			dev[CMD_EXIT] = dev[CMD_LIVE] = 0xff;
144+			uxn.dev[CMD_EXIT] = uxn.dev[CMD_LIVE] = 0xff;
145 			fprintf(stderr, "Pipe error to child.\n");
146 			return;
147 		}
148@@ -231,16 +234,16 @@ start_fork_pipe(void)
149 	if(child_mode & (0x04 | 0x02)) {
150 		/* parent reads from child's stdout and/or stderr */
151 		if(pipe(from_child_fd) == -1) {
152-			dev[CMD_EXIT] = dev[CMD_LIVE] = 0xff;
153+			uxn.dev[CMD_EXIT] = uxn.dev[CMD_LIVE] = 0xff;
154 			fprintf(stderr, "Pipe error from child.\n");
155 			return;
156 		}
157 	}
158 
159-	fork_args[2] = (char *)&ram[addr];
160+	fork_args[2] = (char *)&uxn.ram[addr];
161 	pid = fork();
162 	if(pid < 0) { /* failure */
163-		dev[CMD_EXIT] = dev[CMD_LIVE] = 0xff;
164+		uxn.dev[CMD_EXIT] = uxn.dev[CMD_LIVE] = 0xff;
165 		fprintf(stderr, "Fork failure.\n");
166 	} else if(pid == 0) { /* child */
167 
168@@ -267,8 +270,8 @@ start_fork_pipe(void)
169 		exit(1);
170 	} else { /*parent*/
171 		child_pid = pid;
172-		dev[CMD_LIVE] = 0x01;
173-		dev[CMD_EXIT] = 0x00;
174+		uxn.dev[CMD_LIVE] = 0x01;
175+		uxn.dev[CMD_EXIT] = 0x00;
176 		if(child_mode & 0x01) {
177 			saved_out = dup(1);
178 			dup2(to_child_fd[1], 1);
179@@ -288,12 +291,12 @@ check_child(void)
180 	int wstatus;
181 	if(child_pid) {
182 		if(waitpid(child_pid, &wstatus, WNOHANG)) {
183-			dev[CMD_LIVE] = 0xff;
184-			dev[CMD_EXIT] = WEXITSTATUS(wstatus);
185+			uxn.dev[CMD_LIVE] = 0xff;
186+			uxn.dev[CMD_EXIT] = WEXITSTATUS(wstatus);
187 			clean_after_child();
188 		} else {
189-			dev[CMD_LIVE] = 0x01;
190-			dev[CMD_EXIT] = 0x00;
191+			uxn.dev[CMD_LIVE] = 0x01;
192+			uxn.dev[CMD_EXIT] = 0x00;
193 		}
194 	}
195 }
196@@ -305,8 +308,8 @@ kill_child(void)
197 	if(child_pid) {
198 		kill(child_pid, 9);
199 		if(waitpid(child_pid, &wstatus, WNOHANG)) {
200-			dev[CMD_LIVE] = 0xff;
201-			dev[CMD_EXIT] = WEXITSTATUS(wstatus);
202+			uxn.dev[CMD_LIVE] = 0xff;
203+			uxn.dev[CMD_EXIT] = WEXITSTATUS(wstatus);
204 			clean_after_child();
205 		}
206 	}
207@@ -317,7 +320,7 @@ console_deo_fork(void)
208 {
209 	fflush(stderr);
210 	kill_child();
211-	child_mode = dev[CMD_MODE];
212+	child_mode = uxn.dev[CMD_MODE];
213 	start_fork_pipe();
214 }
215 
216@@ -329,13 +332,13 @@ console_close(void)
217 
218 /* clang-format off */
219 
220-static Uint8 console_dei_childlive(void) { check_child(); return dev[CMD_LIVE]; }
221-static Uint8 console_dei_childexit(void) { check_child(); return dev[CMD_EXIT]; }
222-static void console_deo_vector(void) { console_vector = peek2(&dev[0x10]); }
223-static void console_deo_stdout(void) { fputc(dev[0x18], stdout), fflush(stdout); }
224-static void console_deo_stderr(void) { fputc(dev[0x19], stderr), fflush(stderr); }
225-static void console_deo_hb(void) { fprintf(stderr, "%02x", dev[0x1a]); }
226-static void console_deo_lb(void) { fprintf(stderr, "%02x", dev[0x1b]); }
227+static Uint8 console_dei_childlive(void) { check_child(); return uxn.dev[CMD_LIVE]; }
228+static Uint8 console_dei_childexit(void) { check_child(); return uxn.dev[CMD_EXIT]; }
229+static void console_deo_vector(void) { console_vector = peek2(&uxn.dev[0x10]); }
230+static void console_deo_stdout(void) { fputc(uxn.dev[0x18], stdout), fflush(stdout); }
231+static void console_deo_stderr(void) { fputc(uxn.dev[0x19], stderr), fflush(stderr); }
232+static void console_deo_hb(void) { fprintf(stderr, "%02x", uxn.dev[0x1a]); }
233+static void console_deo_lb(void) { fprintf(stderr, "%02x", uxn.dev[0x1b]); }
234 
235 /* clang-format on */
236 
237@@ -384,9 +387,9 @@ system_deo_colorize(void)
238 	unsigned int i, shift, colors[4];
239 	for(i = 0, shift = 4; i < 4; ++i, shift ^= 4) {
240 		Uint8
241-			r = dev[0x8 + i / 2] >> shift & 0xf,
242-			g = dev[0xa + i / 2] >> shift & 0xf,
243-			b = dev[0xc + i / 2] >> shift & 0xf;
244+			r = uxn.dev[0x8 + i / 2] >> shift & 0xf,
245+			g = uxn.dev[0xa + i / 2] >> shift & 0xf,
246+			b = uxn.dev[0xc + i / 2] >> shift & 0xf;
247 		colors[i] = 0x0f000000 | r << 16 | g << 8 | b;
248 		colors[i] |= colors[i] << 4;
249 	}
250@@ -401,9 +404,9 @@ screen_resize(int width, int height)
251 	if(width != screen_width || height != screen_height) {
252 		int length;
253 		screen_width = width, screen_wmar2 = width + 0x10;
254-		dev[0x22] = screen_width >> 8, dev[0x23] = screen_width;
255+		uxn.dev[0x22] = screen_width >> 8, uxn.dev[0x23] = screen_width;
256 		screen_height = height, screen_hmar2 = height + 0x10;
257-		dev[0x24] = screen_height >> 8, dev[0x25] = screen_height;
258+		uxn.dev[0x24] = screen_height >> 8, uxn.dev[0x25] = screen_height;
259 		length = screen_wmar2 * screen_hmar2;
260 		screen_layers = realloc(screen_layers, length);
261 		memset(screen_layers, 0, length);
262@@ -479,7 +482,7 @@ screen_update(void)
263 static void
264 screen_deo_pixel(void)
265 {
266-	const int ctrl = dev[0x2e];
267+	const int ctrl = uxn.dev[0x2e];
268 	const int hi = ctrl & 0x40;
269 	const Uint8 mask = hi ? 0x3 : 0xc;
270 	const Uint8 color = hi ? ((ctrl & 0x3) << 2) : (ctrl & 0x3);
271@@ -518,7 +521,7 @@ static void
272 screen_deo_sprite(void)
273 {
274 	int i, j, x = rX, y = rY;
275-	const int ctrl = dev[0x2f];
276+	const int ctrl = uxn.dev[0x2f];
277 	const int flipx = ctrl & 0x10, flipy = ctrl & 0x20;
278 	const int dx = flipx ? -rDY : rDY, dy = flipy ? -rDX : rDX;
279 	const int row_start = flipx ? 0 : 7, row_delta = flipx ? 1 : -1;
280@@ -534,7 +537,7 @@ screen_deo_sprite(void)
281 		const Uint16 x0 = x + 8, y0 = y + 8;
282 		if(x0 + 8 >= stride || y0 + 8 >= screen_hmar2) continue;
283 		Uint8 *dst = screen_layers + y0 * stride + x0;
284-		const Uint8 *col = &ram[rA + col_start];
285+		const Uint8 *col = &uxn.ram[rA + col_start];
286 		for(j = 0; j < 8; j++, dst += stride, col += col_delta) {
287 			Uint8 *d = dst;
288 			const int ch1 = *col, ch2 = is_2bpp ? col[8] : 0;
289@@ -563,13 +566,13 @@ static Uint8 screen_dei_ryhb(void) { return rY >> 8; }
290 static Uint8 screen_dei_rylb(void) { return rY; }
291 static Uint8 screen_dei_rahb(void) { return rA >> 8; }
292 static Uint8 screen_dei_ralb(void) { return rA; }
293-static void screen_deo_vector(void) { screen_vector = peek2(&dev[0x20]); }
294-static void screen_deo_width(void) { screen_resize(peek2(&dev[0x22]) & 0xfff, screen_height & 0xfff); }
295-static void screen_deo_height(void) { screen_resize(screen_width & 0xfff, peek2(&dev[0x24]) & 0xfff); }
296-static void screen_deo_auto(void) { rMX = dev[0x26] & 0x1, rMY = dev[0x26] & 0x2, rMA = dev[0x26] & 0x4, rML = dev[0x26] >> 4, rDX = rMX << 3, rDY = rMY << 2; }
297-static void screen_deo_x(void) { rX = (dev[0x28] << 8) | dev[0x29], rX = TWOS(rX); }
298-static void screen_deo_y(void) { rY = (dev[0x2a] << 8) | dev[0x2b], rY = TWOS(rY); }
299-static void screen_deo_addr(void) { rA = (dev[0x2c] << 8) | dev[0x2d]; }
300+static void screen_deo_vector(void) { screen_vector = peek2(&uxn.dev[0x20]); }
301+static void screen_deo_width(void) { screen_resize(peek2(&uxn.dev[0x22]) & 0xfff, screen_height & 0xfff); }
302+static void screen_deo_height(void) { screen_resize(screen_width & 0xfff, peek2(&uxn.dev[0x24]) & 0xfff); }
303+static void screen_deo_auto(void) { rMX = uxn.dev[0x26] & 0x1, rMY = uxn.dev[0x26] & 0x2, rMA = uxn.dev[0x26] & 0x4, rML = uxn.dev[0x26] >> 4, rDX = rMX << 3, rDY = rMY << 2; }
304+static void screen_deo_x(void) { rX = (uxn.dev[0x28] << 8) | uxn.dev[0x29], rX = TWOS(rX); }
305+static void screen_deo_y(void) { rY = (uxn.dev[0x2a] << 8) | uxn.dev[0x2b], rY = TWOS(rY); }
306+static void screen_deo_addr(void) { rA = (uxn.dev[0x2c] << 8) | uxn.dev[0x2d]; }
307 
308 /* clang-format on */
309 
310@@ -582,7 +585,7 @@ static void
311 controller_down(Uint8 mask)
312 {
313 	if(mask) {
314-		dev[0x82] |= mask;
315+		uxn.dev[0x82] |= mask;
316 		if(controller_vector) uxn_eval(controller_vector);
317 	}
318 }
319@@ -591,7 +594,7 @@ static void
320 controller_up(Uint8 mask)
321 {
322 	if(mask) {
323-		dev[0x82] &= (~mask);
324+		uxn.dev[0x82] &= (~mask);
325 		if(controller_vector) uxn_eval(controller_vector);
326 	}
327 }
328@@ -600,16 +603,16 @@ static void
329 controller_key(Uint8 key)
330 {
331 	if(key) {
332-		dev[0x83] = key;
333+		uxn.dev[0x83] = key;
334 		if(controller_vector) uxn_eval(controller_vector);
335-		dev[0x83] = 0;
336+		uxn.dev[0x83] = 0;
337 	}
338 }
339 
340 void
341 controller_deo_vector(void)
342 {
343-	controller_vector = peek2(&dev[0x80]);
344+	controller_vector = peek2(&uxn.dev[0x80]);
345 }
346 
347 /*
348@@ -620,39 +623,39 @@ static unsigned int mouse_vector;
349 static void
350 mouse_down(Uint8 mask)
351 {
352-	dev[0x96] |= mask;
353+	uxn.dev[0x96] |= mask;
354 	if(mouse_vector) uxn_eval(mouse_vector);
355 }
356 
357 static void
358 mouse_up(Uint8 mask)
359 {
360-	dev[0x96] &= (~mask);
361+	uxn.dev[0x96] &= (~mask);
362 	if(mouse_vector) uxn_eval(mouse_vector);
363 }
364 
365 static void
366 mouse_pos(Uint16 x, Uint16 y)
367 {
368-	dev[0x92] = x >> 8, dev[0x93] = x;
369-	dev[0x94] = y >> 8, dev[0x95] = y;
370+	uxn.dev[0x92] = x >> 8, uxn.dev[0x93] = x;
371+	uxn.dev[0x94] = y >> 8, uxn.dev[0x95] = y;
372 	if(mouse_vector) uxn_eval(mouse_vector);
373 }
374 
375 static void
376 mouse_scroll(Uint16 x, Uint16 y)
377 {
378-	dev[0x9a] = x >> 8, dev[0x9b] = x;
379-	dev[0x9c] = -y >> 8, dev[0x9d] = -y;
380+	uxn.dev[0x9a] = x >> 8, uxn.dev[0x9b] = x;
381+	uxn.dev[0x9c] = -y >> 8, uxn.dev[0x9d] = -y;
382 	if(mouse_vector) uxn_eval(mouse_vector);
383-	dev[0x9a] = 0, dev[0x9b] = 0;
384-	dev[0x9c] = 0, dev[0x9d] = 0;
385+	uxn.dev[0x9a] = 0, uxn.dev[0x9b] = 0;
386+	uxn.dev[0x9c] = 0, uxn.dev[0x9d] = 0;
387 }
388 
389 void
390 mouse_deo_vector(void)
391 {
392-	mouse_vector = peek2(&dev[0x90]);
393+	mouse_vector = peek2(&uxn.dev[0x90]);
394 }
395 
396 /*
397@@ -801,7 +804,7 @@ static unsigned int
398 file_init(unsigned int id, Uint16 addr)
399 {
400 	file_reset(id);
401-	ufs[id].filepath = (char *)&ram[addr];
402+	ufs[id].filepath = (char *)&uxn.ram[addr];
403 	return 0;
404 }
405 
406@@ -814,7 +817,7 @@ file_not_ready(unsigned int id)
407 static unsigned int
408 file_read(unsigned int id, Uint16 addr, unsigned int len)
409 {
410-	void *dest = &ram[addr];
411+	void *dest = &uxn.ram[addr];
412 	struct stat st;
413 	unsigned int n;
414 	if(file_not_ready(id))
415@@ -860,7 +863,7 @@ file_write(unsigned int id, Uint16 addr, unsigned int len, Uint8 flags)
416 			ufs[id].state = FILE_WRITE;
417 	}
418 	if(ufs[id].state == FILE_WRITE)
419-		if((ret = fwrite(&ram[addr], 1, len, ufs[id].f)) > 0 && fflush(ufs[id].f) != 0)
420+		if((ret = fwrite(&uxn.ram[addr], 1, len, ufs[id].f)) > 0 && fflush(ufs[id].f) != 0)
421 			ret = 0;
422 	if(ufs[id].state == DIR_WRITE)
423 		ret = is_dir_real(ufs[id].filepath);
424@@ -878,7 +881,7 @@ file_stat(unsigned int id, Uint16 addr, unsigned int len)
425 		len = 0x10000 - addr;
426 	err = stat(ufs[id].filepath, &st);
427 	dir = S_ISDIR(st.st_mode);
428-	return put_stat(&ram[addr], len, st.st_size, err, dir, 0);
429+	return put_stat(&uxn.ram[addr], len, st.st_size, err, dir, 0);
430 }
431 
432 static unsigned int
433@@ -891,18 +894,18 @@ file_delete(unsigned int id)
434 
435 /* clang-format off */
436 
437-static void filea_deo_vector(void) { rL1 = peek2(&dev[0xaa]); }
438-static void filea_deo_stat(void) { poke2(&dev[0xa2], file_stat(0, peek2(&dev[0xa4]), rL1)); }
439-static void filea_deo_delete(void) { poke2(&dev[0xa2], file_delete(0)); }
440-static void filea_deo_name(void) { poke2(&dev[0xa2], file_init(0, peek2(&dev[0xa8]))); }
441-static void filea_deo_read(void) { poke2(&dev[0xa2], file_read(0, peek2(&dev[0xac]), rL1)); }
442-static void filea_deo_write(void) { poke2(&dev[0xa2], file_write(0, peek2(&dev[0xae]), rL1, dev[0xa7])); }
443-static void fileb_deo_vector(void) { rL2 = peek2(&dev[0xba]); }
444-static void fileb_deo_stat(void) { poke2(&dev[0xb2], file_stat(1, peek2(&dev[0xb4]), rL2)); }
445-static void fileb_deo_delete(void) { poke2(&dev[0xb2], file_delete(1)); }
446-static void fileb_deo_name(void) { poke2(&dev[0xb2], file_init(1, peek2(&dev[0xb8]))); }
447-static void fileb_deo_read(void) { poke2(&dev[0xb2], file_read(1, peek2(&dev[0xbc]), rL2)); }
448-static void fileb_deo_write(void) { poke2(&dev[0xb2], file_write(1, peek2(&dev[0xbe]), rL2, dev[0xb7])); }
449+static void filea_deo_vector(void) { rL1 = peek2(&uxn.dev[0xaa]); }
450+static void filea_deo_stat(void) { poke2(&uxn.dev[0xa2], file_stat(0, peek2(&uxn.dev[0xa4]), rL1)); }
451+static void filea_deo_delete(void) { poke2(&uxn.dev[0xa2], file_delete(0)); }
452+static void filea_deo_name(void) { poke2(&uxn.dev[0xa2], file_init(0, peek2(&uxn.dev[0xa8]))); }
453+static void filea_deo_read(void) { poke2(&uxn.dev[0xa2], file_read(0, peek2(&uxn.dev[0xac]), rL1)); }
454+static void filea_deo_write(void) { poke2(&uxn.dev[0xa2], file_write(0, peek2(&uxn.dev[0xae]), rL1, uxn.dev[0xa7])); }
455+static void fileb_deo_vector(void) { rL2 = peek2(&uxn.dev[0xba]); }
456+static void fileb_deo_stat(void) { poke2(&uxn.dev[0xb2], file_stat(1, peek2(&uxn.dev[0xb4]), rL2)); }
457+static void fileb_deo_delete(void) { poke2(&uxn.dev[0xb2], file_delete(1)); }
458+static void fileb_deo_name(void) { poke2(&uxn.dev[0xb2], file_init(1, peek2(&uxn.dev[0xb8]))); }
459+static void fileb_deo_read(void) { poke2(&uxn.dev[0xb2], file_read(1, peek2(&uxn.dev[0xbc]), rL2)); }
460+static void fileb_deo_write(void) { poke2(&uxn.dev[0xb2], file_write(1, peek2(&uxn.dev[0xbe]), rL2, uxn.dev[0xb7])); }
461 
462 /* clang-format on */
463 
464@@ -1014,14 +1017,14 @@ static inline Uint8
465 emu_dei(const Uint8 port)
466 {
467 	dei_handler h = dei_handlers[port];
468-	return h ? h() : dev[port];
469+	return h ? h() : uxn.dev[port];
470 }
471 
472 static inline void
473 emu_deo(const Uint8 port, const Uint8 value)
474 {
475 	deo_handler h = deo_handlers[port];
476-	dev[port] = value;
477+	uxn.dev[port] = value;
478 	if(h) h();
479 }
480 
481@@ -1034,32 +1037,32 @@ emu_deo(const Uint8 port, const Uint8 value)
482 	case 0xa0|opc:case 0xe0|opc:{const int d=1,k=*p;A *p=k;B} break;}
483 #define DEC s[--(*p)]
484 #define INC s[(*p)++]
485-#define FLIP s = stk[!r], p = &ptr[!r];
486-#define JUMP(x) b = ram[pc] << 8, b |= ram[pc + 1], pc += x + 2;
487+#define FLIP s = uxn.stk[!r], p = &uxn.ptr[!r];
488+#define JUMP(x) b = uxn.ram[pc] << 8, b |= uxn.ram[pc + 1], pc += x + 2;
489 #define DROP(o,m) o = DEC; if(m) o |= DEC << 8;
490 #define TAKE(o) if(d) o[1] = DEC; o[0] = DEC;
491 #define PUSH(i,m) { if(m) c = (i), INC = c >> 8, INC = c; else INC = i; }
492 #define GIVE(i) INC = i[0]; if(d) INC = i[1];
493 #define DEVO(o,r) emu_deo(o, r[0]); if(d) emu_deo(o + 1, r[1]);
494 #define DEVI(i,r) r[0] = emu_dei(i); if(d) r[1] = emu_dei(i + 1);
495-#define POKE(o,r,m) ram[o] = r[0]; if(d) ram[(o + 1) & m] = r[1];
496-#define PEEK(i,r,m) r[0] = ram[i]; if(d) r[1] = ram[(i + 1) & m];
497+#define POKE(o,r,m) uxn.ram[o] = r[0]; if(d) uxn.ram[(o + 1) & m] = r[1];
498+#define PEEK(i,r,m) r[0] = uxn.ram[i]; if(d) r[1] = uxn.ram[(i + 1) & m];
499 
500 static unsigned
501 uxn_eval(Uint16 pc)
502 {
503 	Uint16 a, b, c, x[2], y[2], z[2];
504 	for(;;) {
505-	Uint8 op = ram[pc++], r = (op >> 6) & 1, *s = stk[r], *p = &ptr[r];
506+	Uint8 op = uxn.ram[pc++], r = (op >> 6) & 1, *s = uxn.stk[r], *p = &uxn.ptr[r];
507 	switch(op) {
508 	/* BRK */ case 0x00:return 1;
509 	/* JCI */ case 0x20:if(DEC) JUMP(b) else pc += 2; break;
510 	/* JMI */ case 0x40:JUMP(b) break;
511 	/* JSI */ case 0x60:JUMP(0) PUSH(pc,1) pc += b; break;
512-	/* LI2 */ case 0xa0:INC = ram[pc++]; /* Fall-through */
513-	/* LIT */ case 0x80:INC = ram[pc++]; break;
514-	/* L2r */ case 0xe0:INC = ram[pc++]; /* Fall-through */
515-	/* LIr */ case 0xc0:INC = ram[pc++]; break;
516+	/* LI2 */ case 0xa0:INC = uxn.ram[pc++]; /* Fall-through */
517+	/* LIT */ case 0x80:INC = uxn.ram[pc++]; break;
518+	/* L2r */ case 0xe0:INC = uxn.ram[pc++]; /* Fall-through */
519+	/* LIr */ case 0xc0:INC = uxn.ram[pc++]; break;
520 	/* INC */ OPC(0x01,DROP(a,d),PUSH(a + 1,d))
521 	/* POP */ OPC(0x02,*p -= 1 + d;,{})
522 	/* NIP */ OPC(0x03,TAKE(x) *p -= 1 + d;,GIVE(x))
523@@ -1193,7 +1196,7 @@ emu_event(void)
524 		screen_reqdraw = 1;
525 		break;
526 	case ClientMessage:
527-		dev[0x0f] = 0x80;
528+		uxn.dev[0x0f] = 0x80;
529 		break;
530 	case KeyPress: {
531 		KeySym sym;
532@@ -1267,7 +1270,7 @@ emu_run(void)
533 	fds[0].fd = emu_x11, fds[0].events = POLLIN;
534 	fds[1].fd = emu_timer, fds[1].events = POLLIN;
535 	fds[2].fd = STDIN_FILENO, fds[2].events = POLLIN | POLLHUP;
536-	while(!dev[0x0f]) {
537+	while(!uxn.dev[0x0f]) {
538 		/* only poll stdin while it's still active */
539 		if(poll(fds, stdin_active ? 3 : 2, -1) <= 0)
540 			continue;
541@@ -1304,7 +1307,7 @@ main(int argc, char **argv)
542 {
543 	int i = 1;
544 	if(argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v')
545-		return !fprintf(stdout, "%s - Varvara Emulator, 22 Jan 2026.\n", argv[0]);
546+		return !fprintf(stdout, "%s - Varvara Emulator, 8 Feb 2026.\n", argv[0]);
547 	else if(argc == 1)
548 		return !fprintf(stdout, "usage: %s [-v] file.rom [args..]\n", argv[0]);
549 	else if(!system_boot(argv[i++], argc > 2))
550@@ -1318,10 +1321,10 @@ main(int argc, char **argv)
551 			console_input('\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA);
552 		}
553 	}
554-	if(!dev[0x0f]) {
555+	if(!uxn.dev[0x0f]) {
556 		if(!emu_init())
557 			return !fprintf(stdout, "Could not initialize %s.\n", argv[0]);
558 		emu_run();
559 	}
560-	return dev[0x0f] & 0x7f;
561+	return uxn.dev[0x0f] & 0x7f;
562 }