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())