commit 593f9ad

Devine Lu Linvega  ·  2025-05-13 00:04:57 +0000 UTC
parent 96132ae
Inlined deos
1 files changed,  +167, -211
+167, -211
  1@@ -206,45 +206,28 @@ system_dei(Uint8 addr)
  2 }
  3 
  4 static void
  5-system_deo(Uint8 port)
  6-{
  7-	switch(port) {
  8-	case 0x3: {
  9-		Uint16 value;
 10-		Uint16 addr = PEEK2(uxn.dev + 2);
 11-		Uint8 *aptr = uxn.ram + addr;
 12-		Uint16 length = PEEK2(aptr + 1);
 13-		if(uxn.ram[addr] == 0x0) {
 14-			Uint32 a = PEEK2(aptr + 3) * 0x10000 + PEEK2(aptr + 5);
 15-			Uint32 b = a + length;
 16-			value = uxn.ram[addr + 7];
 17-			for(; a < b; uxn.ram[a++] = value);
 18-		} else if(uxn.ram[addr] == 0x1) {
 19-			Uint32 a = PEEK2(aptr + 3) * 0x10000 + PEEK2(aptr + 5);
 20-			Uint32 b = a + length;
 21-			Uint32 c = PEEK2(aptr + 7) * 0x10000 + PEEK2(aptr + 9);
 22-			for(; a < b; uxn.ram[c++] = uxn.ram[a++]);
 23-		} else if(uxn.ram[addr] == 0x2) {
 24-			Uint32 a = PEEK2(aptr + 3) * 0x10000 + PEEK2(aptr + 5);
 25-			Uint32 b = a + length;
 26-			Uint32 c = PEEK2(aptr + 7) * 0x10000 + PEEK2(aptr + 9);
 27-			Uint32 d = c + length;
 28-			for(; b >= a; uxn.ram[--d] = uxn.ram[--b]);
 29-		} else
 30-			fprintf(stderr, "Unknown command: %s\n", &uxn.ram[addr]);
 31-		break;
 32-	}
 33-	case 0x4:
 34-		uxn.wst.ptr = uxn.dev[4];
 35-		break;
 36-	case 0x5:
 37-		uxn.rst.ptr = uxn.dev[5];
 38-		break;
 39-	case 0xe:
 40-		system_print("WST", &uxn.wst);
 41-		system_print("RST", &uxn.rst);
 42-		break;
 43-	}
 44+system_expansion(Uint16 addr)
 45+{
 46+	Uint8 *aptr = uxn.ram + addr;
 47+	Uint16 value, length = PEEK2(aptr + 1);
 48+	if(uxn.ram[addr] == 0x0) {
 49+		Uint32 a = PEEK2(aptr + 3) * 0x10000 + PEEK2(aptr + 5);
 50+		Uint32 b = a + length;
 51+		value = uxn.ram[addr + 7];
 52+		for(; a < b; uxn.ram[a++] = value);
 53+	} else if(uxn.ram[addr] == 0x1) {
 54+		Uint32 a = PEEK2(aptr + 3) * 0x10000 + PEEK2(aptr + 5);
 55+		Uint32 b = a + length;
 56+		Uint32 c = PEEK2(aptr + 7) * 0x10000 + PEEK2(aptr + 9);
 57+		for(; a < b; uxn.ram[c++] = uxn.ram[a++]);
 58+	} else if(uxn.ram[addr] == 0x2) {
 59+		Uint32 a = PEEK2(aptr + 3) * 0x10000 + PEEK2(aptr + 5);
 60+		Uint32 b = a + length;
 61+		Uint32 c = PEEK2(aptr + 7) * 0x10000 + PEEK2(aptr + 9);
 62+		Uint32 d = c + length;
 63+		for(; b >= a; uxn.ram[--d] = uxn.ram[--b]);
 64+	} else
 65+		fprintf(stderr, "Unknown command: %s\n", &uxn.ram[addr]);
 66 }
 67 
 68 /*
 69@@ -295,7 +278,6 @@ static pid_t child_pid;
 70 #define CMD_EXIT 0x16 /* if dead, exit code of process */
 71 #define CMD_ADDR 0x1c /* address to read command args from */
 72 #define CMD_MODE 0x1e /* mode to execute, 0x00 to 0x07 */
 73-#define CMD_EXEC 0x1f /* write to execute programs, etc */
 74 
 75 /* call after we're sure the process has exited */
 76 
 77@@ -420,7 +402,7 @@ kill_child(void)
 78 }
 79 
 80 static void
 81-start_fork(void)
 82+console_start_fork(void)
 83 {
 84 	fflush(stderr);
 85 	kill_child();
 86@@ -453,18 +435,6 @@ console_dei(Uint8 addr)
 87 	return uxn.dev[addr];
 88 }
 89 
 90-static void
 91-console_deo(Uint8 addr)
 92-{
 93-	FILE *fd;
 94-	switch(addr) {
 95-	case 0x11: console_vector = PEEK2(&uxn.dev[0x10]); return;
 96-	case 0x18: fd = stdout, fputc(uxn.dev[0x18], fd), fflush(fd); break;
 97-	case 0x19: fd = stderr, fputc(uxn.dev[0x19], fd), fflush(fd); break;
 98-	case CMD_EXEC: start_fork(); break;
 99-	}
100-}
101-
102 /*
103 @|Screen ------------------------------------------------------------ */
104 
105@@ -565,6 +535,101 @@ screen_redraw(void)
106 
107 static int rX, rY, rA, rMX, rMY, rMA, rML, rDX, rDY;
108 
109+static void
110+screen_draw_pixel(void)
111+{
112+	int ctrl = uxn.dev[0x2e];
113+	int color = ctrl & 0x3;
114+	int len = MAR2(uxn_screen.width);
115+	Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
116+	/* fill mode */
117+	if(ctrl & 0x80) {
118+		int x1, y1, x2, y2, ax, bx, ay, by, hor, ver;
119+		if(ctrl & 0x10)
120+			x1 = 0, x2 = rX;
121+		else
122+			x1 = rX, x2 = uxn_screen.width;
123+		if(ctrl & 0x20)
124+			y1 = 0, y2 = rY;
125+		else
126+			y1 = rY, y2 = uxn_screen.height;
127+		screen_change(x1, y1, x2, y2);
128+		x1 = MAR(x1), y1 = MAR(y1);
129+		hor = MAR(x2) - x1, ver = MAR(y2) - y1;
130+		for(ay = y1 * len, by = ay + ver * len; ay < by; ay += len)
131+			for(ax = ay + x1, bx = ax + hor; ax < bx; ax++)
132+				layer[ax] = color;
133+	}
134+	/* pixel mode */
135+	else {
136+		if(rX >= 0 && rY >= 0 && rX < len && rY < uxn_screen.height)
137+			layer[MAR(rX) + MAR(rY) * len] = color;
138+		screen_change(rX, rY, rX + 1, rY + 1);
139+		if(rMX) rX++;
140+		if(rMY) rY++;
141+	}
142+}
143+
144+static void
145+screen_draw_sprite(void)
146+{
147+	int ctrl = uxn.dev[0x2f];
148+	int blend = ctrl & 0xf, opaque = blend % 5;
149+	int fx = ctrl & 0x10 ? -1 : 1, fy = ctrl & 0x20 ? -1 : 1;
150+	int qfx = fx > 0 ? 7 : 0, qfy = fy < 0 ? 7 : 0;
151+	int dxy = fy * rDX, dyx = fx * rDY;
152+	int wmar = MAR(uxn_screen.width), wmar2 = MAR2(uxn_screen.width);
153+	int hmar2 = MAR2(uxn_screen.height);
154+	int i, x1, x2, y1, y2, ax, ay, qx, qy, x = rX, y = rY;
155+	Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
156+	if(ctrl & 0x80) {
157+		int addr_incr = rMA << 2;
158+		for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) {
159+			Uint16 xmar = MAR(x), ymar = MAR(y);
160+			Uint16 xmar2 = MAR2(x), ymar2 = MAR2(y);
161+			if(xmar < wmar && ymar2 < hmar2) {
162+				Uint8 *sprite = &uxn.ram[rA];
163+				int by = ymar2 * wmar2;
164+				for(ay = ymar * wmar2, qy = qfy; ay < by; ay += wmar2, qy += fy) {
165+					int ch1 = sprite[qy], ch2 = sprite[qy + 8] << 1, bx = xmar2 + ay;
166+					for(ax = xmar + ay, qx = qfx; ax < bx; ax++, qx -= fx) {
167+						int color = ((ch1 >> qx) & 1) | ((ch2 >> qx) & 2);
168+						if(opaque || color) layer[ax] = blending[color][blend];
169+					}
170+				}
171+			}
172+		}
173+	} else {
174+		int addr_incr = rMA << 1;
175+		for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) {
176+			Uint16 xmar = MAR(x), ymar = MAR(y);
177+			Uint16 xmar2 = MAR2(x), ymar2 = MAR2(y);
178+			if(xmar < wmar && ymar2 < hmar2) {
179+				Uint8 *sprite = &uxn.ram[rA];
180+				int by = ymar2 * wmar2;
181+				for(ay = ymar * wmar2, qy = qfy; ay < by; ay += wmar2, qy += fy) {
182+					int ch1 = sprite[qy], bx = xmar2 + ay;
183+					for(ax = xmar + ay, qx = qfx; ax < bx; ax++, qx -= fx) {
184+						int color = (ch1 >> qx) & 1;
185+						if(opaque || color) layer[ax] = blending[color][blend];
186+					}
187+				}
188+			}
189+		}
190+	}
191+	if(fx < 0)
192+		x1 = x, x2 = rX;
193+	else
194+		x1 = rX, x2 = x;
195+	if(fy < 0)
196+		y1 = y, y2 = rY;
197+	else
198+		y1 = rY, y2 = y;
199+	screen_change(x1 - 8, y1 - 8, x2 + 8, y2 + 8);
200+	if(rMX) rX += rDX * fx;
201+	if(rMY) rY += rDY * fy;
202+}
203+
204 static Uint8
205 screen_dei(Uint8 addr)
206 {
207@@ -583,114 +648,6 @@ screen_dei(Uint8 addr)
208 	}
209 }
210 
211-static void
212-screen_deo(Uint8 addr)
213-{
214-	switch(addr) {
215-	case 0x21: screen_vector = PEEK2(&uxn.dev[0x20]); return;
216-	case 0x23: screen_apply(PEEK2(&uxn.dev[0x22]), uxn_screen.height); return;
217-	case 0x25: screen_apply(uxn_screen.width, PEEK2(&uxn.dev[0x24])); return;
218-	case 0x26: 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; return;
219-	case 0x28:
220-	case 0x29: rX = (uxn.dev[0x28] << 8) | uxn.dev[0x29], rX = twos(rX); return;
221-	case 0x2a:
222-	case 0x2b: rY = (uxn.dev[0x2a] << 8) | uxn.dev[0x2b], rY = twos(rY); return;
223-	case 0x2c:
224-	case 0x2d: rA = (uxn.dev[0x2c] << 8) | uxn.dev[0x2d]; return;
225-	case 0x2e: {
226-		int ctrl = uxn.dev[0x2e];
227-		int color = ctrl & 0x3;
228-		int len = MAR2(uxn_screen.width);
229-		Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
230-		/* fill mode */
231-		if(ctrl & 0x80) {
232-			int x1, y1, x2, y2, ax, bx, ay, by, hor, ver;
233-			if(ctrl & 0x10)
234-				x1 = 0, x2 = rX;
235-			else
236-				x1 = rX, x2 = uxn_screen.width;
237-			if(ctrl & 0x20)
238-				y1 = 0, y2 = rY;
239-			else
240-				y1 = rY, y2 = uxn_screen.height;
241-			screen_change(x1, y1, x2, y2);
242-			x1 = MAR(x1), y1 = MAR(y1);
243-			hor = MAR(x2) - x1, ver = MAR(y2) - y1;
244-			for(ay = y1 * len, by = ay + ver * len; ay < by; ay += len)
245-				for(ax = ay + x1, bx = ax + hor; ax < bx; ax++)
246-					layer[ax] = color;
247-		}
248-		/* pixel mode */
249-		else {
250-			if(rX >= 0 && rY >= 0 && rX < len && rY < uxn_screen.height)
251-				layer[MAR(rX) + MAR(rY) * len] = color;
252-			screen_change(rX, rY, rX + 1, rY + 1);
253-			if(rMX) rX++;
254-			if(rMY) rY++;
255-		}
256-		return;
257-	}
258-	case 0x2f: {
259-		int ctrl = uxn.dev[0x2f];
260-		int blend = ctrl & 0xf, opaque = blend % 5;
261-		int fx = ctrl & 0x10 ? -1 : 1, fy = ctrl & 0x20 ? -1 : 1;
262-		int qfx = fx > 0 ? 7 : 0, qfy = fy < 0 ? 7 : 0;
263-		int dxy = fy * rDX, dyx = fx * rDY;
264-		int wmar = MAR(uxn_screen.width), wmar2 = MAR2(uxn_screen.width);
265-		int hmar2 = MAR2(uxn_screen.height);
266-		int i, x1, x2, y1, y2, ax, ay, qx, qy, x = rX, y = rY;
267-		Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
268-		if(ctrl & 0x80) {
269-			int addr_incr = rMA << 2;
270-			for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) {
271-				Uint16 xmar = MAR(x), ymar = MAR(y);
272-				Uint16 xmar2 = MAR2(x), ymar2 = MAR2(y);
273-				if(xmar < wmar && ymar2 < hmar2) {
274-					Uint8 *sprite = &uxn.ram[rA];
275-					int by = ymar2 * wmar2;
276-					for(ay = ymar * wmar2, qy = qfy; ay < by; ay += wmar2, qy += fy) {
277-						int ch1 = sprite[qy], ch2 = sprite[qy + 8] << 1, bx = xmar2 + ay;
278-						for(ax = xmar + ay, qx = qfx; ax < bx; ax++, qx -= fx) {
279-							int color = ((ch1 >> qx) & 1) | ((ch2 >> qx) & 2);
280-							if(opaque || color) layer[ax] = blending[color][blend];
281-						}
282-					}
283-				}
284-			}
285-		} else {
286-			int addr_incr = rMA << 1;
287-			for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) {
288-				Uint16 xmar = MAR(x), ymar = MAR(y);
289-				Uint16 xmar2 = MAR2(x), ymar2 = MAR2(y);
290-				if(xmar < wmar && ymar2 < hmar2) {
291-					Uint8 *sprite = &uxn.ram[rA];
292-					int by = ymar2 * wmar2;
293-					for(ay = ymar * wmar2, qy = qfy; ay < by; ay += wmar2, qy += fy) {
294-						int ch1 = sprite[qy], bx = xmar2 + ay;
295-						for(ax = xmar + ay, qx = qfx; ax < bx; ax++, qx -= fx) {
296-							int color = (ch1 >> qx) & 1;
297-							if(opaque || color) layer[ax] = blending[color][blend];
298-						}
299-					}
300-				}
301-			}
302-		}
303-		if(fx < 0)
304-			x1 = x, x2 = rX;
305-		else
306-			x1 = rX, x2 = x;
307-		if(fy < 0)
308-			y1 = y, y2 = rY;
309-		else
310-			y1 = rY, y2 = y;
311-		screen_change(x1 - 8, y1 - 8, x2 + 8, y2 + 8);
312-		if(rMX) rX += rDX * fx;
313-		if(rMY) rY += rDY * fy;
314-		return;
315-	}
316-	}
317-}
318-
319 /*
320 @|Controller -------------------------------------------------------- */
321 
322@@ -724,14 +681,6 @@ controller_key(Uint8 key)
323 	}
324 }
325 
326-static void
327-controller_deo(Uint8 addr)
328-{
329-	switch(addr) {
330-	case 0x81: controller_vector = PEEK2(&uxn.dev[0x80]); break;
331-	}
332-}
333-
334 /*
335 @|Mouse ------------------------------------------------------------- */
336 
337@@ -769,14 +718,6 @@ mouse_scroll(Uint16 x, Uint16 y)
338 	uxn.dev[0x9c] = 0, uxn.dev[0x9d] = 0;
339 }
340 
341-static void
342-mouse_deo(Uint8 addr)
343-{
344-	switch(addr) {
345-	case 0x91: mouse_vector = PEEK2(&uxn.dev[0x90]); break;
346-	}
347-}
348-
349 /*
350 @|File -------------------------------------------------------------- */
351 
352@@ -1012,27 +953,6 @@ file_success(int port, int value)
353 
354 static int rL1, rL2;
355 
356-static void
357-file_deo(Uint8 port)
358-{
359-	switch(port) {
360-	/* File 1 */
361-	case 0xab: rL1 = PEEK2(&uxn.dev[0xaa]); break;
362-	case 0xa5: file_success(0xa2, file_stat(0, PEEK2(&uxn.dev[0xa4]), rL1)); break;
363-	case 0xa6: file_success(0xa2, file_delete(0)); break;
364-	case 0xa9: file_success(0xa2, file_init(0, PEEK2(&uxn.dev[0xa8]))); break;
365-	case 0xad: file_success(0xa2, file_read(0, PEEK2(&uxn.dev[0xac]), rL1)); break;
366-	case 0xaf: file_success(0xa2, file_write(0, PEEK2(&uxn.dev[0xae]), rL1, uxn.dev[0xa7])); break;
367-	/* File 2 */
368-	case 0xbb: rL2 = PEEK2(&uxn.dev[0xba]); break;
369-	case 0xb5: file_success(0xb2, file_stat(1, PEEK2(&uxn.dev[0xb4]), rL2)); break;
370-	case 0xb6: file_success(0xb2, file_delete(1)); break;
371-	case 0xb9: file_success(0xb2, file_init(1, PEEK2(&uxn.dev[0xb8]))); break;
372-	case 0xbd: file_success(0xb2, file_read(1, PEEK2(&uxn.dev[0xbc]), rL2)); break;
373-	case 0xbf: file_success(0xb2, file_write(1, PEEK2(&uxn.dev[0xbe]), rL2, uxn.dev[0xb7])); break;
374-	}
375-}
376-
377 /*
378 @|Datetime ---------------------------------------------------------- */
379 
380@@ -1082,18 +1002,54 @@ void
381 emu_deo(Uint8 addr, Uint8 value)
382 {
383 	uxn.dev[addr] = value;
384-	switch(addr & 0xf0) {
385-	case 0x00:
386-		system_deo(addr);
387-		if(addr > 0x7 && addr < 0xe)
388-			screen_palette();
389-		break;
390-	case 0x10: console_deo(addr); break;
391-	case 0x20: screen_deo(addr); break;
392-	case 0x80: controller_deo(addr); break;
393-	case 0x90: mouse_deo(addr); break;
394-	case 0xa0: file_deo(addr); break;
395-	case 0xb0: file_deo(addr); break;
396+	switch(addr) {
397+	/* System */
398+	case 0x03: system_expansion(PEEK2(uxn.dev + 2)); return;
399+	case 0x04: uxn.wst.ptr = uxn.dev[4]; return;
400+	case 0x05: uxn.rst.ptr = uxn.dev[5]; return;
401+	case 0x08:
402+	case 0x09:
403+	case 0x0a:
404+	case 0x0b:
405+	case 0x0c:
406+	case 0x0d: screen_palette(); return;
407+	case 0x0e: system_print("WST", &uxn.wst), system_print("RST", &uxn.rst); return;
408+	/* Console */
409+	case 0x11: console_vector = PEEK2(&uxn.dev[0x10]); return;
410+	case 0x18: fputc(uxn.dev[0x18], stdout), fflush(stdout); return;
411+	case 0x19: fputc(uxn.dev[0x19], stderr), fflush(stderr); return;
412+	case 0x1f: console_start_fork(); return;
413+	/* Screen */
414+	case 0x21: screen_vector = PEEK2(&uxn.dev[0x20]); return;
415+	case 0x23: screen_apply(PEEK2(&uxn.dev[0x22]), uxn_screen.height); return;
416+	case 0x25: screen_apply(uxn_screen.width, PEEK2(&uxn.dev[0x24])); return;
417+	case 0x26: 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; return;
418+	case 0x28:
419+	case 0x29: rX = (uxn.dev[0x28] << 8) | uxn.dev[0x29], rX = twos(rX); return;
420+	case 0x2a:
421+	case 0x2b: rY = (uxn.dev[0x2a] << 8) | uxn.dev[0x2b], rY = twos(rY); return;
422+	case 0x2c:
423+	case 0x2d: rA = (uxn.dev[0x2c] << 8) | uxn.dev[0x2d]; return;
424+	case 0x2e: screen_draw_pixel(); return;
425+	case 0x2f: screen_draw_sprite(); return;
426+	/* Controller */
427+	case 0x81: controller_vector = PEEK2(&uxn.dev[0x80]); return;
428+	/* Mouse */
429+	case 0x91: mouse_vector = PEEK2(&uxn.dev[0x90]); return;
430+	/* File 1 */
431+	case 0xab: rL1 = PEEK2(&uxn.dev[0xaa]); return;
432+	case 0xa5: file_success(0xa2, file_stat(0, PEEK2(&uxn.dev[0xa4]), rL1)); return;
433+	case 0xa6: file_success(0xa2, file_delete(0)); return;
434+	case 0xa9: file_success(0xa2, file_init(0, PEEK2(&uxn.dev[0xa8]))); return;
435+	case 0xad: file_success(0xa2, file_read(0, PEEK2(&uxn.dev[0xac]), rL1)); return;
436+	case 0xaf: file_success(0xa2, file_write(0, PEEK2(&uxn.dev[0xae]), rL1, uxn.dev[0xa7])); return;
437+	/* File 2 */
438+	case 0xbb: rL2 = PEEK2(&uxn.dev[0xba]); return;
439+	case 0xb5: file_success(0xb2, file_stat(1, PEEK2(&uxn.dev[0xb4]), rL2)); return;
440+	case 0xb6: file_success(0xb2, file_delete(1)); return;
441+	case 0xb9: file_success(0xb2, file_init(1, PEEK2(&uxn.dev[0xb8]))); return;
442+	case 0xbd: file_success(0xb2, file_read(1, PEEK2(&uxn.dev[0xbc]), rL2)); return;
443+	case 0xbf: file_success(0xb2, file_write(1, PEEK2(&uxn.dev[0xbe]), rL2, uxn.dev[0xb7])); return;
444 	}
445 }
446 
447@@ -1302,7 +1258,7 @@ main(int argc, char **argv)
448 {
449 	int i = 1;
450 	if(argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v')
451-		return !fprintf(stdout, "Uxn11 - Varvara Emulator, 3 May 2025.\n");
452+		return !fprintf(stdout, "Uxn11 - Varvara Emulator, 12 May 2025.\n");
453 	else if(argc == 1)
454 		return !fprintf(stdout, "usage: %s [-v] file.rom [args..]\n", argv[0]);
455 	else if(!display_init())