aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-12 16:46:23 +0200
committerBad Diode <bd@badd10de.dev>2023-04-12 16:47:30 +0200
commitdde6b57621c75ed8db728e84bc4f632d501f835f (patch)
treeb10d7b571ff89f03f11faeb7cce90593f702c2b1
parent3bcfebcaeddd73a1981bdd82bc4ce41e180e98a9 (diff)
downloaduxn64-main.tar.gz
uxn64-main.zip
Updated the uxn core to latest versionHEADmain
-rw-r--r--src/main.c254
m---------src/uxn0
2 files changed, 140 insertions, 114 deletions
diff --git a/src/main.c b/src/main.c
index 84dc684..52813c5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -52,12 +52,10 @@ static OSMesgQueue audio_msg_queue;
52 52
53#define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) 53#define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X))
54 54
55static u8 uxn_ram[0x10000]; 55static u8 uxn_ram[0x80000];
56static Uxn u; 56static Uxn u;
57static Device *devscreen; 57u16 deo_mask[] = {0xff08, 0x0300, 0xc028, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xa260, 0xa260, 0x0000, 0x0000, 0x0000, 0x0000};
58static Device *devctrl; 58u16 dei_mask[] = {0x0000, 0x0000, 0x003c, 0x0014, 0x0014, 0x0014, 0x0014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07ff, 0x0000, 0x0000, 0x0000};
59static Device *devmouse;
60static Device *devaudio;
61 59
62#define MOUSE_DELTA 1 60#define MOUSE_DELTA 1
63typedef struct Mouse { 61typedef struct Mouse {
@@ -71,9 +69,10 @@ static Mouse mouse = {0};
71static size_t seconds = 0; 69static size_t seconds = 0;
72 70
73int 71int
74uxn_halt(Uxn *u, u8 error, u16 addr) { 72uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) {
75 (void)u; 73 (void)u;
76 (void)error; 74 (void)instr;
75 (void)err;
77 (void)addr; 76 (void)addr;
78 for (;;) {} 77 for (;;) {}
79} 78}
@@ -83,39 +82,44 @@ uxn_interrupt(void) {
83 return 1; 82 return 1;
84} 83}
85 84
86static u8
87nil_dei(Device *d, u8 port) {
88 return d->dat[port];
89}
90
91u8 85u8
92datetime_dei(Device *d, u8 port) { 86datetime_dei(Uxn *u, u8 addr) {
93 (void)port; 87 (void)u;
94 size_t minutes = seconds / 60; 88 (void)addr;
95 size_t hours = minutes / 60; 89 // size_t minutes = seconds / 60;
96 DEVPOKE16(0x0, 0); 90 // size_t hours = minutes / 60;
97 d->dat[0x2] = 0; 91 // POKE2(d + 0x0, 0);
98 d->dat[0x3] = 0; 92 // d[0x2] = 0;
99 d->dat[0x4] = hours; 93 // d[0x3] = 0;
100 d->dat[0x5] = minutes; 94 // d[0x4] = hours;
101 d->dat[0x6] = seconds % 60; 95 // d[0x5] = minutes;
102 d->dat[0x7] = 0; 96 // d[0x6] = seconds % 60;
103 DEVPOKE16(0x08, 0); 97 // d[0x7] = 0;
104 d->dat[0xa] = 0; 98 // // POKE2(d + 0x08, 0);
105} 99 // d[0xa] = 0;
106 100 // switch(addr) {
107static void 101 // case 0xc0: return 0;
108nil_deo(Device *d, u8 port) { 102 // case 0xc1: return 0;
109 (void)d; 103 // case 0xc2: return 0;
110 (void)port; 104 // case 0xc3: return 0;
105 // case 0xc4: return hours;
106 // case 0xc5: return minutes;
107 // case 0xc6: return seconds % 60;
108 // case 0xc7: return 0;
109 // case 0xc8: return 0;
110 // case 0xc9: return 0;
111 // case 0xca: return 0;
112 // default: return u->dev[addr];
113 // }
114 // return 0;
111} 115}
112 116
113static void 117static void
114screen_palette(Device *d) { 118screen_palette(u8 *d) {
115 for(size_t i = 0; i < 4; ++i) { 119 for(size_t i = 0; i < 4; ++i) {
116 u8 r = ((d->dat[0x8 + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; 120 u8 r = ((*(d + i / 2) >> (!(i % 2) << 2)) & 0x0f) * 0x11;
117 u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; 121 u8 g = ((*(d + 2 + i / 2) >> (!(i % 2) << 2)) & 0x0f) * 0x11;
118 u8 b = ((d->dat[0xc + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; 122 u8 b = ((*(d + 4 + i / 2) >> (!(i % 2) << 2)) & 0x0f) * 0x11;
119 123
120 palette[i] = GPACK_RGBA5551(r, g, b, 1); 124 palette[i] = GPACK_RGBA5551(r, g, b, 1);
121 } 125 }
@@ -128,107 +132,110 @@ screen_palette(Device *d) {
128 redraw_screen(); 132 redraw_screen();
129} 133}
130 134
131u8 135#define RAM_PAGES 0x10
132system_dei(Device *d, u8 port) { 136
133 switch(port) { 137static void
134 case 0x2: return d->u->wst.ptr; 138system_cmd(Uint8 *ram, Uint16 addr) {
135 case 0x3: return d->u->rst.ptr; 139 if(ram[addr] == 0x01) {
136 default: return d->dat[port]; 140 Uint16 i, length = PEEK2(ram + addr + 1);
141 Uint16 a_page = PEEK2(ram + addr + 1 + 2), a_addr = PEEK2(ram + addr + 1 + 4);
142 Uint16 b_page = PEEK2(ram + addr + 1 + 6), b_addr = PEEK2(ram + addr + 1 + 8);
143 int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000;
144 for(i = 0; i < length; i++)
145 ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)];
137 } 146 }
138} 147}
139 148
140void 149void
141system_deo(Device *d, u8 port) { 150system_deo(Uxn *u, u8 *d, u8 port) {
142 switch(port) { 151 switch(port) {
143 case 0x2: d->u->wst.ptr = d->dat[port]; break; 152 case 0x3:
144 case 0x3: d->u->rst.ptr = d->dat[port]; break; 153 system_cmd(u->ram, PEEK2(d + 2));
145 case 0xe: break; 154 break;
146 default: { 155 // case 0xe:
147 if(port > 0x7 && port < 0xe) { 156 // system_inspect(u);
148 screen_palette(d); 157 // break;
149 }
150 } break;
151 } 158 }
152} 159}
153 160
154static void 161static void
155console_deo(Device *d, u8 port) { 162console_deo(u8 *d, u8 port) {
156 (void)d; 163 (void)d;
157 (void)port; 164 (void)port;
158} 165}
159 166
160u8 167u8
161screen_dei(Device *d, u8 port) { 168screen_dei(u8 *d, u8 port) {
162 switch(port) { 169 switch(port) {
163 case 0x2: return screen_width >> 8; 170 case 0x2: return screen_width >> 8;
164 case 0x3: return screen_width; 171 case 0x3: return screen_width;
165 case 0x4: return screen_height >> 8; 172 case 0x4: return screen_height >> 8;
166 case 0x5: return screen_height; 173 case 0x5: return screen_height;
167 default: return d->dat[port]; 174 default: return d[port];
168 } 175 }
169} 176}
170 177
171void 178void
172screen_deo(Device *d, u8 port) { 179screen_deo(u8 *ram, u8 *d, u8 port) {
173 switch(port) { 180 switch(port) {
174 case 0xe: { 181 case 0xe: {
175 u16 x, y; 182 u16 x, y;
176 u8 layer = d->dat[0xe] & 0x40; 183 u8 layer = d[0xe] & 0x40;
177 DEVPEEK16(x, 0x8); 184 x = PEEK2(d + 0x8);
178 DEVPEEK16(y, 0xa); 185 y = PEEK2(d + 0xa);
179 ppu_pixel(layer ? pixels_fg : pixels_bg, x, y, d->dat[0xe] & 0x3); 186 ppu_pixel(layer ? pixels_fg : pixels_bg, x, y, d[0xe] & 0x3);
180 if(d->dat[0x6] & 0x01) DEVPOKE16(0x8, x + 1); /* auto x+1 */ 187 if(d[0x6] & 0x01) POKE2(d + 0x8, x + 1); /* auto x+1 */
181 if(d->dat[0x6] & 0x02) DEVPOKE16(0xa, y + 1); /* auto y+1 */ 188 if(d[0x6] & 0x02) POKE2(d + 0xa, y + 1); /* auto y+1 */
182 } break; 189 break;
190 }
183 case 0xf: { 191 case 0xf: {
184 u16 x, y, dx, dy, addr; 192 u16 x, y, dx, dy, addr;
185 u8 twobpp = !!(d->dat[0xf] & 0x80); 193 u8 n, twobpp = !!(d[0xf] & 0x80);
186 DEVPEEK16(x, 0x8); 194 x = PEEK2(d + 0x8);
187 DEVPEEK16(y, 0xa); 195 y = PEEK2(d + 0xa);
188 DEVPEEK16(addr, 0xc); 196 addr = PEEK2(d + 0xc);
189 u8 n = d->dat[0x6] >> 4; 197 n = d[0x6] >> 4;
190 dx = (d->dat[0x6] & 0x01) << 3; 198 dx = (d[0x6] & 0x01) << 3;
191 dy = (d->dat[0x6] & 0x02) << 2; 199 dy = (d[0x6] & 0x02) << 2;
192 if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) { 200 if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) {
193 return; 201 return;
194 } 202 }
195 u8 *layer = (d->dat[0xf] & 0x40) ? pixels_fg : pixels_bg; 203 u8 *layer = (d[0xf] & 0x40) ? pixels_fg : pixels_bg;
196 u8 color = d->dat[0xf] & 0xf; 204 u8 color = d[0xf] & 0xf;
197 u8 flipx = d->dat[0xf] & 0x10; 205 u8 flipx = d[0xf] & 0x10;
198 u8 flipy = d->dat[0xf] & 0x20; 206 u8 flipy = d[0xf] & 0x20;
199 for(size_t i = 0; i <= n; i++) { 207 for(size_t i = 0; i <= n; i++) {
200 u8 *sprite = &d->u->ram[addr]; 208 u8 *sprite = &ram[addr];
201 if (twobpp) { 209 if (twobpp) {
202 ppu_2bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy); 210 ppu_2bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy);
203 } else { 211 } else {
204 ppu_1bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy); 212 ppu_1bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy);
205 } 213 }
206 addr += (d->dat[0x6] & 0x04) << (1 + twobpp); 214 addr += (d[0x6] & 0x04) << (1 + twobpp);
207 } 215 }
208 DEVPOKE16(0xc, addr); /* auto addr+length */ 216 POKE2(d + 0xc, addr); /* auto addr+length */
209 DEVPOKE16(0x8, x + dx); /* auto x+8 */ 217 POKE2(d + 0x8, x + dx); /* auto x+8 */
210 DEVPOKE16(0xa, y + dy); /* auto y+8 */ 218 POKE2(d + 0xa, y + dy); /* auto y+8 */
211 } break; 219 break;
220 }
212 } 221 }
213 reqdraw = 1; 222 reqdraw = 1;
214} 223}
215 224
216static u8 225static u8
217audio_dei(Device *d, u8 port) { 226audio_dei(int instance, u8 *d, u8 port) {
218 int instance = d - devaudio;
219 switch(port) { 227 switch(port) {
220 case 0x4: return audio_get_vu(instance); 228 case 0x4: return audio_get_vu(instance);
221 case 0x2: DEVPOKE16(0x2, audio_get_position(instance)); /* fall through */ 229 case 0x2: POKE2(d + 0x2, audio_get_position(instance)); /* fall through */
222 default: return d->dat[port]; 230 default: return d[port];
223 } 231 }
224} 232}
225 233
226static void 234static void
227audio_deo(Device *d, u8 port) { 235audio_deo(int instance, u8 *d, u8 port, Uxn *u) {
228 int instance = d - devaudio;
229 if(port == 0xf) { 236 if(port == 0xf) {
230 // TODO: stop the audio before audio_start 237 // TODO: stop the audio before audio_start
231 audio_start(instance, d); 238 audio_start(instance, d, u);
232 pause_audio = 0; 239 pause_audio = 0;
233 } 240 }
234} 241}
@@ -263,8 +270,9 @@ handle_input(int i) {
263 bool update_mouse = false; 270 bool update_mouse = false;
264 271
265 // Check for controller changes. 272 // Check for controller changes.
273 u8 *devctrl = &u.dev[0x80];
266 if (prev_pad.button != current_pad.button) { 274 if (prev_pad.button != current_pad.button) {
267 u8 *uxn_ctrl = &devctrl->dat[2]; 275 u8 *uxn_ctrl = &devctrl[2];
268 if (current_pad.button & U_JPAD || current_pad.button & U_CBUTTONS) { 276 if (current_pad.button & U_JPAD || current_pad.button & U_CBUTTONS) {
269 *uxn_ctrl |= 0x10; 277 *uxn_ctrl |= 0x10;
270 update_ctrl = true; 278 update_ctrl = true;
@@ -340,28 +348,28 @@ handle_input(int i) {
340 } 348 }
341 349
342 // Check for "mouse" x/y changes. 350 // Check for "mouse" x/y changes.
351 u8 *devmouse = &u.dev[0x90];
343 if (current_pad.stick_x != 0 || current_pad.stick_y != 0) { 352 if (current_pad.stick_x != 0 || current_pad.stick_y != 0) {
344 Device *d = devmouse;
345 mouse.x = CLAMP(mouse.x + prev_pad.stick_x / 8, 0, (s32)screen_width); 353 mouse.x = CLAMP(mouse.x + prev_pad.stick_x / 8, 0, (s32)screen_width);
346 mouse.y = CLAMP(mouse.y - prev_pad.stick_y / 8, 0, (s32)screen_height); 354 mouse.y = CLAMP(mouse.y - prev_pad.stick_y / 8, 0, (s32)screen_height);
347 DEVPOKE16(0x2, mouse.x); 355 POKE2(devmouse + 0x2, mouse.x);
348 DEVPOKE16(0x4, mouse.y); 356 POKE2(devmouse + 0x4, mouse.y);
349 update_mouse = true; 357 update_mouse = true;
350 } 358 }
351 359
352 if (update_ctrl) { 360 if (update_ctrl) {
353 uxn_eval(&u, GETVECTOR(devctrl)); 361 uxn_eval(&u, PEEK2(devctrl));
354 devctrl->dat[3] = 0; 362 devctrl[3] = 0;
355 } 363 }
356 if (update_mouse) { 364 if (update_mouse) {
357 devmouse->dat[6] = mouse.buttons; 365 devmouse[6] = mouse.buttons;
358 if(mouse.buttons == 0x10 && (devmouse->dat[6] & 0x01)) { 366 if(mouse.buttons == 0x10 && (devmouse[6] & 0x01)) {
359 devmouse->dat[7] = 0x01; 367 devmouse[7] = 0x01;
360 } 368 }
361 if(mouse.buttons == 0x01 && (devmouse->dat[6] & 0x10)) { 369 if(mouse.buttons == 0x01 && (devmouse[6] & 0x10)) {
362 devmouse->dat[7] = 0x10; 370 devmouse[7] = 0x10;
363 } 371 }
364 uxn_eval(&u, GETVECTOR(devmouse)); 372 uxn_eval(&u, PEEK2(devmouse));
365 } 373 }
366} 374}
367 375
@@ -385,6 +393,40 @@ poll_input() {
385 } 393 }
386} 394}
387 395
396u8
397uxn_dei(Uxn *u, u8 addr) {
398 u8 p = addr & 0x0f, d = addr & 0xf0;
399 switch(d) {
400 case 0x20: return screen_dei(&u->dev[d], p);
401 case 0x30: return audio_dei(0, &u->dev[d], p);
402 case 0x40: return audio_dei(1, &u->dev[d], p);
403 case 0x50: return audio_dei(2, &u->dev[d], p);
404 case 0x60: return audio_dei(3, &u->dev[d], p);
405 case 0xc0: return datetime_dei(u, p);
406 }
407 return u->dev[addr];
408}
409
410void
411uxn_deo(Uxn *u, u8 addr) {
412 u8 p = addr & 0x0f, d = addr & 0xf0;
413 switch(d) {
414 case 0x00:
415 system_deo(u, &u->dev[d], p);
416 if(p > 0x7 && p < 0xe)
417 screen_palette(&u->dev[0x8]);
418 break;
419 case 0x10: console_deo(&u->dev[d], p); break;
420 case 0x20: screen_deo(u->ram, &u->dev[d], p); break;
421 case 0x30: audio_deo(0, &u->dev[d], p, u); break;
422 case 0x40: audio_deo(1, &u->dev[d], p, u); break;
423 case 0x50: audio_deo(2, &u->dev[d], p, u); break;
424 case 0x60: audio_deo(3, &u->dev[d], p, u); break;
425 // case 0xa0: file_deo_2(0, u->ram, &u->dev[d], p); break;
426 // case 0xb0: file_deo_2(1, u->ram, &u->dev[d], p); break;
427 }
428}
429
388void 430void
389init_uxn(Uxn *u) { 431init_uxn(Uxn *u) {
390 // Setup UXN memory. 432 // Setup UXN memory.
@@ -401,22 +443,6 @@ init_uxn(Uxn *u) {
401 } 443 }
402 444
403 // Prepare devices. 445 // Prepare devices.
404 /* system */ uxn_port(u, 0x0, system_dei, system_deo);
405 /* console */ uxn_port(u, 0x1, nil_dei, console_deo);
406 /* screen */ devscreen = uxn_port(u, 0x2, screen_dei, screen_deo);
407 /* audio0 */ devaudio = uxn_port(u, 0x3, audio_dei, audio_deo);
408 /* audio1 */ uxn_port(u, 0x4, audio_dei, audio_deo);
409 /* audio2 */ uxn_port(u, 0x5, audio_dei, audio_deo);
410 /* audio3 */ uxn_port(u, 0x6, audio_dei, audio_deo);
411 /* unused */ uxn_port(u, 0x7, nil_dei, nil_deo);
412 /* control */ devctrl = uxn_port(u, 0x8, nil_dei, nil_deo);
413 /* mouse */ devmouse = uxn_port(u, 0x9, nil_dei, nil_deo);
414 /* file0 */ uxn_port(u, 0xa, nil_dei, nil_deo);
415 /* file1 */ uxn_port(u, 0xb, nil_dei, nil_deo);
416 /* datetime */ uxn_port(u, 0xc, datetime_dei, nil_deo);
417 /* unused */ uxn_port(u, 0xd, nil_dei, nil_deo);
418 /* unused */ uxn_port(u, 0xe, nil_dei, nil_deo);
419 /* unused */ uxn_port(u, 0xf, nil_dei, nil_deo);
420 uxn_eval(u, PAGE_PROGRAM); 446 uxn_eval(u, PAGE_PROGRAM);
421} 447}
422 448
@@ -454,7 +480,7 @@ main_proc(void *arg) {
454 u8 frame_counter = 0; 480 u8 frame_counter = 0;
455 while (true) { 481 while (true) {
456 poll_input(); 482 poll_input();
457 uxn_eval(&u, GETVECTOR(devscreen)); 483 uxn_eval(&u, PEEK2(&u.dev[0x20]));
458 blit_framebuffer(); 484 blit_framebuffer();
459 swap_buffers(); 485 swap_buffers();
460 osYieldThread(); 486 osYieldThread();
diff --git a/src/uxn b/src/uxn
Subproject 5496712ae1b231ea31be68151d2cfd10e933969 Subproject 344c5c99040206b0f06d0a34a77569956c62231