aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-08-27 19:47:34 +0200
committerBad Diode <bd@badd10de.dev>2023-08-27 19:47:34 +0200
commit9fc5ff0b00e1ca72c75721d3bdc4ff2287b48fc2 (patch)
treedfb87fde586d011f4a46d23e590c6423c80b8317
parent4305d585d87c6bbc197b0fe2d9f144d6d0b772e2 (diff)
downloaduxngba-9fc5ff0b00e1ca72c75721d3bdc4ff2287b48fc2.tar.gz
uxngba-9fc5ff0b00e1ca72c75721d3bdc4ff2287b48fc2.zip
Testing barebones uxn_eval implementation in ASM
-rw-r--r--src/main.c806
-rw-r--r--src/uxn-core.s567
2 files changed, 1005 insertions, 368 deletions
diff --git a/src/main.c b/src/main.c
index a2a43d4..21c8e0e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -15,7 +15,7 @@
15#include "common.h" 15#include "common.h"
16#include "filesystem.c" 16#include "filesystem.c"
17 17
18#include "uxn.c" 18#include "uxn.h"
19#include "ppu.c" 19#include "ppu.c"
20#include "apu.c" 20#include "apu.c"
21#include "file.c" 21#include "file.c"
@@ -37,6 +37,7 @@
37#define CONTROL_METHODS CONTROL_CONTROLLER,CONTROL_MOUSE,CONTROL_KEYBOARD 37#define CONTROL_METHODS CONTROL_CONTROLLER,CONTROL_MOUSE,CONTROL_KEYBOARD
38#endif 38#endif
39 39
40#define PROF_ENABLE 0
40#ifndef PROF_ENABLE 41#ifndef PROF_ENABLE
41#define PROF_ENABLE 0 42#define PROF_ENABLE 0
42#endif 43#endif
@@ -214,130 +215,130 @@ typedef struct Mouse {
214} Mouse; 215} Mouse;
215 216
216EWRAM_BSS 217EWRAM_BSS
217static u8 umem[0x10300]; 218u8 uxn_ram[0x10300];
218 219
219static Uxn u; 220// static Uxn u;
220 221
221static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; 222static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2};
222 223
223int 224// int
224uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) { 225// uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) {
225 (void)u; 226// (void)u;
226 txt_printf("HALTED\n"); 227// txt_printf("HALTED\n");
227 txt_printf("I: %lu\n", instr); 228// txt_printf("I: %lu\n", instr);
228 txt_printf("E: %lu\n", err); 229// txt_printf("E: %lu\n", err);
229 txt_printf("A: %lu\n", addr); 230// txt_printf("A: %lu\n", addr);
230 while (true); 231// while (true);
231} 232// }
232 233
233IWRAM_CODE 234IWRAM_CODE
234u8 235u8
235screen_dei(u8 *d, u8 port) { 236screen_dei(u8 *d, u8 port) {
236 switch(port) { 237 // switch(port) {
237 case 0x2: return (SCREEN_WIDTH >> 8); 238 // case 0x2: return (SCREEN_WIDTH >> 8);
238 case 0x3: return (SCREEN_WIDTH); 239 // case 0x3: return (SCREEN_WIDTH);
239 case 0x4: return (SCREEN_HEIGHT >> 8); 240 // case 0x4: return (SCREEN_HEIGHT >> 8);
240 case 0x5: return (SCREEN_HEIGHT); 241 // case 0x5: return (SCREEN_HEIGHT);
241 default: return d[port]; 242 // default: return d[port];
242 } 243 // }
243} 244}
244 245
245IWRAM_CODE 246IWRAM_CODE
246void 247void
247screen_deo(u8 *ram, u8 *d, u8 port) { 248screen_deo(u8 *ram, u8 *d, u8 port) {
248 switch(port) { 249 // switch(port) {
249 case 0xe: { 250 // case 0xe: {
250 u8 ctrl = d[0xe]; 251 // u8 ctrl = d[0xe];
251 u8 color = ctrl & 0x3; 252 // u8 color = ctrl & 0x3;
252 u16 x0 = PEEK2(d + 0x8); 253 // u16 x0 = PEEK2(d + 0x8);
253 u16 y0 = PEEK2(d + 0xa); 254 // u16 y0 = PEEK2(d + 0xa);
254 u8 *layer = (ctrl & 0x40) ? FG_BACK : BG_BACK; 255 // u8 *layer = (ctrl & 0x40) ? FG_BACK : BG_BACK;
255 if(ctrl & 0x80) { 256 // if(ctrl & 0x80) {
256 u16 x1 = SCREEN_WIDTH - 1; 257 // u16 x1 = SCREEN_WIDTH - 1;
257 u16 y1 = SCREEN_HEIGHT - 1; 258 // u16 y1 = SCREEN_HEIGHT - 1;
258 if(ctrl & 0x10) x1 = x0, x0 = 0; 259 // if(ctrl & 0x10) x1 = x0, x0 = 0;
259 if(ctrl & 0x20) y1 = y0, y0 = 0; 260 // if(ctrl & 0x20) y1 = y0, y0 = 0;
260 PROF(screen_fill(layer, x0, y0, x1, y1, color), ppu_fill_cycles); 261 // PROF(screen_fill(layer, x0, y0, x1, y1, color), ppu_fill_cycles);
261 } else { 262 // } else {
262 PROF(ppu_pixel(layer, x0, y0, color), ppu_pixel_cycles); 263 // PROF(ppu_pixel(layer, x0, y0, color), ppu_pixel_cycles);
263 if(d[0x6] & 0x1) POKE2(d + 0x8, x0 + 1); /* auto x+1 */ 264 // if(d[0x6] & 0x1) POKE2(d + 0x8, x0 + 1); /* auto x+1 */
264 if(d[0x6] & 0x2) POKE2(d + 0xa, y0 + 1); /* auto y+1 */ 265 // if(d[0x6] & 0x2) POKE2(d + 0xa, y0 + 1); /* auto y+1 */
265 } 266 // }
266 break; 267 // break;
267 } 268 // }
268 case 0xf: { 269 // case 0xf: {
269 u16 x, y, dx, dy, addr; 270 // u16 x, y, dx, dy, addr;
270 u8 n, twobpp = !!(d[0xf] & 0x80); 271 // u8 n, twobpp = !!(d[0xf] & 0x80);
271 x = PEEK2(d + 0x8); 272 // x = PEEK2(d + 0x8);
272 y = PEEK2(d + 0xa); 273 // y = PEEK2(d + 0xa);
273 addr = PEEK2(d + 0xc); 274 // addr = PEEK2(d + 0xc);
274 n = d[0x6] >> 4; 275 // n = d[0x6] >> 4;
275 dx = (d[0x6] & 0x01) << 3; 276 // dx = (d[0x6] & 0x01) << 3;
276 dy = (d[0x6] & 0x02) << 2; 277 // dy = (d[0x6] & 0x02) << 2;
277 if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) { 278 // if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) {
278 return; 279 // return;
279 } 280 // }
280 u8 *layer = (d[0xf] & 0x40) ? FG_BACK : BG_BACK; 281 // u8 *layer = (d[0xf] & 0x40) ? FG_BACK : BG_BACK;
281 u8 color = d[0xf] & 0xf; 282 // u8 color = d[0xf] & 0xf;
282 u8 flipx = d[0xf] & 0x10; 283 // u8 flipx = d[0xf] & 0x10;
283 u8 flipy = d[0xf] & 0x20; 284 // u8 flipy = d[0xf] & 0x20;
284 for(size_t i = 0; i <= n; i++) { 285 // for(size_t i = 0; i <= n; i++) {
285 u8 *sprite = &ram[addr]; 286 // u8 *sprite = &ram[addr];
286 if (twobpp) { 287 // if (twobpp) {
287 PROF(ppu_2bpp(layer, 288 // PROF(ppu_2bpp(layer,
288 x + dy * i, 289 // x + dy * i,
289 y + dx * i, 290 // y + dx * i,
290 sprite, 291 // sprite,
291 color, 292 // color,
292 flipx, flipy), ppu_chr_cycles); 293 // flipx, flipy), ppu_chr_cycles);
293 } else { 294 // } else {
294 PROF(ppu_1bpp(layer, 295 // PROF(ppu_1bpp(layer,
295 x + dy * i, 296 // x + dy * i,
296 y + dx * i, 297 // y + dx * i,
297 sprite, 298 // sprite,
298 color, 299 // color,
299 flipx, flipy), ppu_icn_cycles); 300 // flipx, flipy), ppu_icn_cycles);
300 } 301 // }
301 addr += (d[0x6] & 0x04) << (1 + twobpp); 302 // addr += (d[0x6] & 0x04) << (1 + twobpp);
302 } 303 // }
303 POKE2(d + 0xc, addr); /* auto addr+length */ 304 // POKE2(d + 0xc, addr); /* auto addr+length */
304 POKE2(d + 0x8, x + dx); /* auto x+8 */ 305 // POKE2(d + 0x8, x + dx); /* auto x+8 */
305 POKE2(d + 0xa, y + dy); /* auto y+8 */ 306 // POKE2(d + 0xa, y + dy); /* auto y+8 */
306 break; 307 // break;
307 } 308 // }
308 } 309 // }
309} 310}
310 311
311u8 312u8
312audio_dei(int instance, u8 *d, u8 port) { 313audio_dei(int instance, u8 *d, u8 port) {
313 AudioChannel *c = &channels[instance]; 314 // AudioChannel *c = &channels[instance];
314 switch(port) { 315 // switch(port) {
315 // case 0x4: return apu_get_vu(instance); 316 // // case 0x4: return apu_get_vu(instance);
316 case 0x2: { 317 // case 0x2: {
317 POKE2(d + 0x2, c->pos); 318 // POKE2(d + 0x2, c->pos);
318 c->pos <<= 12; // fixed point. 319 // c->pos <<= 12; // fixed point.
319 break; 320 // break;
320 } 321 // }
321 } 322 // }
322 return d[port]; 323 return d[port];
323} 324}
324 325
325void 326void
326audio_deo(int instance, u8 *d, u8 port, Uxn *u) { 327audio_deo(int instance, u8 *d, u8 port, Uxn *u) {
327 AudioChannel *c = &channels[instance]; 328 // AudioChannel *c = &channels[instance];
328 if (port == 0xf) { 329 // if (port == 0xf) {
329 u16 length = 0; 330 // u16 length = 0;
330 u16 adsr = 0; 331 // u16 adsr = 0;
331 u16 addr = 0; 332 // u16 addr = 0;
332 u8 pitch = d[0xf] & 0x7f; 333 // u8 pitch = d[0xf] & 0x7f;
333 adsr = PEEK2(d + 0x8); 334 // adsr = PEEK2(d + 0x8);
334 length = PEEK2(d + 0xa); 335 // length = PEEK2(d + 0xa);
335 addr = PEEK2(d + 0xc); 336 // addr = PEEK2(d + 0xc);
336 u8 *data = &u->ram[addr]; 337 // u8 *data = &u->ram[addr];
337 u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3; 338 // u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3;
338 bool loop = !(d[0xf] & 0x80); 339 // bool loop = !(d[0xf] & 0x80);
339 update_channel(c, data, length, pitch, adsr, vol, loop); 340 // update_channel(c, data, length, pitch, adsr, vol, loop);
340 } 341 // }
341} 342}
342 343
343u8 344u8
@@ -361,75 +362,75 @@ datetime_dei(u8 *d, u8 port) {
361 362
362u8 363u8
363file_dei(u8 id, u8 *d, u8 port) { 364file_dei(u8 id, u8 *d, u8 port) {
364 UxnFile *c = &uxn_file[id]; 365 // UxnFile *c = &uxn_file[id];
365 u16 res; 366 // u16 res;
366 switch(port) { 367 // switch(port) {
367 case 0xc: 368 // case 0xc:
368 case 0xd: { 369 // case 0xd: {
369 res = file_read(c, &d[port], 1); 370 // res = file_read(c, &d[port], 1);
370 POKE2(d + 0x2, res); 371 // POKE2(d + 0x2, res);
371 break; 372 // break;
372 } 373 // }
373 } 374 // }
374 return d[port]; 375 return d[port];
375} 376}
376 377
377void 378void
378file_deo(u8 id, u8 *ram, u8 *d, u8 port) { 379file_deo(u8 id, u8 *ram, u8 *d, u8 port) {
379 u16 a, b, res; 380 // u16 a, b, res;
380 UxnFile *f = &uxn_file[id]; 381 // UxnFile *f = &uxn_file[id];
381 switch(port) { 382 // switch(port) {
382 case 0x5: { 383 // case 0x5: {
383 a = PEEK2(d + 0x4); 384 // a = PEEK2(d + 0x4);
384 b = PEEK2(d + 0xa); 385 // b = PEEK2(d + 0xa);
385 if(b > 0x10000 - a) { 386 // if(b > 0x10000 - a) {
386 b = 0x10000 - a; 387 // b = 0x10000 - a;
387 } 388 // }
388 res = file_stat(f, &ram[a], b); 389 // res = file_stat(f, &ram[a], b);
389 POKE2(d + 0x2, res); 390 // POKE2(d + 0x2, res);
390 } break; 391 // } break;
391 case 0x6: { 392 // case 0x6: {
392 // TODO: no file deletion for now 393 // // TODO: no file deletion for now
393 // res = file_delete(); 394 // // res = file_delete();
394 // POKE2(d + 0x2, res); 395 // // POKE2(d + 0x2, res);
395 } break; 396 // } break;
396 case 0x9: { 397 // case 0x9: {
397 a = PEEK2(d + 0x8); 398 // a = PEEK2(d + 0x8);
398 res = file_init(f, &ram[a]); 399 // res = file_init(f, &ram[a]);
399 POKE2(d + 0x2, res); 400 // POKE2(d + 0x2, res);
400 } break; 401 // } break;
401 case 0xd: { 402 // case 0xd: {
402 a = PEEK2(d + 0xc); 403 // a = PEEK2(d + 0xc);
403 b = PEEK2(d + 0xa); 404 // b = PEEK2(d + 0xa);
404 if(b > 0x10000 - a) { 405 // if(b > 0x10000 - a) {
405 b = 0x10000 - a; 406 // b = 0x10000 - a;
406 } 407 // }
407 res = file_read(f, &ram[a], b); 408 // res = file_read(f, &ram[a], b);
408 POKE2(d + 0x2, res); 409 // POKE2(d + 0x2, res);
409 } break; 410 // } break;
410 case 0xf: { 411 // case 0xf: {
411 a = PEEK2(d + 0xe); 412 // a = PEEK2(d + 0xe);
412 b = PEEK2(d + 0xa); 413 // b = PEEK2(d + 0xa);
413 if(b > 0x10000 - a) { 414 // if(b > 0x10000 - a) {
414 b = 0x10000 - a; 415 // b = 0x10000 - a;
415 } 416 // }
416 res = file_write(f, &ram[a], b, d[0x7]); 417 // res = file_write(f, &ram[a], b, d[0x7]);
417 POKE2(d + 0x2, res); 418 // POKE2(d + 0x2, res);
418 } break; 419 // } break;
419 } 420 // }
420} 421}
421 422
422void 423void
423console_deo(u8 *d, u8 port) { 424console_deo(u8 *d, u8 port) {
424 switch(port) { 425 // switch(port) {
425 case 0x8: 426 // case 0x8:
426 txt_putc(d[port]); 427 // txt_putc(d[port]);
427 return; 428 // return;
428 case 0x9: 429 // case 0x9:
429 txt_printf("ERROR: %c"); 430 // txt_printf("ERROR: %c");
430 txt_putc(d[port]); 431 // txt_putc(d[port]);
431 return; 432 // return;
432 } 433 // }
433} 434}
434 435
435#define RAM_PAGES 0x10 436#define RAM_PAGES 0x10
@@ -464,11 +465,11 @@ system_cmd(u8 *ram, u16 addr) {
464 465
465void 466void
466system_deo(Uxn *u, u8 *d, u8 port) { 467system_deo(Uxn *u, u8 *d, u8 port) {
467 switch(port) { 468 // switch(port) {
468 case 0x3: { 469 // case 0x3: {
469 system_cmd(u->ram, PEEK2(d + 2)); 470 // system_cmd(u->ram, PEEK2(d + 2));
470 } break; 471 // } break;
471 } 472 // }
472} 473}
473 474
474u8 475u8
@@ -509,201 +510,221 @@ uxn_deo(Uxn *u, u8 addr) {
509} 510}
510 511
511void 512void
512init_uxn(Uxn *u) { 513init_uxn() {
513 // Initialize uxn. 514 // Initialize uxn.
514 u32 fill = 0; 515 u32 fill = 0;
515 dma_fill(umem, fill, 0x10300, 3); 516 dma_fill(uxn_ram, fill, 0x10300, 3);
516 uxn_boot(u, umem, uxn_dei, uxn_deo); 517 // uxn_boot(u, uxn_ram, uxn_dei, uxn_deo);
517 518
518 // Copy rom to VM. 519 // Copy rom to VM.
519 memcpy(u->ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); 520 u8 uxn_rom[] = {
521 // Hello world (h)
522 // 0x80, 0x68, 0x80, 0x18, 0x17,
523 //
524 // ADD test
525 0x80, 0x04, 0x80, 0x03, 0x80, 0x02, 0x80, 0x01, 0x18
526 };
527 memcpy(uxn_ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom));
520} 528}
521 529
522IWRAM_CODE 530IWRAM_CODE
523void 531void
524handle_input(Uxn *u) { 532handle_input(Uxn *u) {
525 poll_keys(); 533 // poll_keys();
526 if (key_tap(KEY_SELECT)) { 534 // if (key_tap(KEY_SELECT)) {
527 // Reset control variables on method switch. 535 // // Reset control variables on method switch.
528 switch (ctrl_methods[ctrl_idx]) { 536 // switch (ctrl_methods[ctrl_idx]) {
529 case CONTROL_CONTROLLER: { 537 // case CONTROL_CONTROLLER: {
530 u8 *d = &u->dev[0x80]; 538 // u8 *d = &u->dev[0x80];
531 d[2] = 0; 539 // d[2] = 0;
532 uxn_eval(u, PEEK2(d)); 540 // uxn_eval(u, PEEK2(d));
533 d[3] = 0; 541 // d[3] = 0;
534 } break; 542 // } break;
535 case CONTROL_MOUSE: { 543 // case CONTROL_MOUSE: {
536 u8 *d = &u->dev[0x90]; 544 // u8 *d = &u->dev[0x90];
537 d[6] = 0; 545 // d[6] = 0;
538 d[7] = 0; 546 // d[7] = 0;
539 POKE2(d + 0x2, -10); 547 // POKE2(d + 0x2, -10);
540 POKE2(d + 0x4, -10); 548 // POKE2(d + 0x4, -10);
541 uxn_eval(u, PEEK2(d)); 549 // uxn_eval(u, PEEK2(d));
542 } break; 550 // } break;
543 case CONTROL_KEYBOARD: { 551 // case CONTROL_KEYBOARD: {
544 toggle_keyboard(); 552 // toggle_keyboard();
545 } break; 553 // } break;
546 } 554 // }
547 555
548 // Update ctrl_idx. 556 // // Update ctrl_idx.
549 ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1; 557 // ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1;
550 558
551 // Initialize controller variables here. 559 // // Initialize controller variables here.
552 if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { 560 // if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
553 toggle_keyboard(); 561 // toggle_keyboard();
554 } 562 // }
555 } 563 // }
556 564
557 if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) { 565 // if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) {
558 u8 *d = &u->dev[0x80]; 566 // u8 *d = &u->dev[0x80];
559 // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just 567 // // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just
560 // swap some things if needed. 568 // // swap some things if needed.
561 u8 *flag = &d[2]; 569 // u8 *flag = &d[2];
562 if (key_tap(KEY_A)) { 570 // if (key_tap(KEY_A)) {
563 *flag |= 0x01; 571 // *flag |= 0x01;
564 } else { 572 // } else {
565 *flag &= ~0x01; 573 // *flag &= ~0x01;
566 } 574 // }
567 if (key_tap(KEY_B)) { 575 // if (key_tap(KEY_B)) {
568 *flag |= 0x02; 576 // *flag |= 0x02;
569 } else { 577 // } else {
570 *flag &= ~0x02; 578 // *flag &= ~0x02;
571 } 579 // }
572 if (key_tap(KEY_L)) { 580 // if (key_tap(KEY_L)) {
573 *flag |= 0x04; 581 // *flag |= 0x04;
574 } else { 582 // } else {
575 *flag &= ~0x04; 583 // *flag &= ~0x04;
576 } 584 // }
577 if (key_tap(KEY_R)) { 585 // if (key_tap(KEY_R)) {
578 *flag |= 0x08; 586 // *flag |= 0x08;
579 } else { 587 // } else {
580 *flag &= ~0x08; 588 // *flag &= ~0x08;
581 } 589 // }
582 if (key_tap(KEY_UP)) { 590 // if (key_tap(KEY_UP)) {
583 *flag |= 0x10; 591 // *flag |= 0x10;
584 } else { 592 // } else {
585 *flag &= ~0x10; 593 // *flag &= ~0x10;
586 } 594 // }
587 if (key_tap(KEY_DOWN)) { 595 // if (key_tap(KEY_DOWN)) {
588 *flag |= 0x20; 596 // *flag |= 0x20;
589 } else { 597 // } else {
590 *flag &= ~0x20; 598 // *flag &= ~0x20;
591 } 599 // }
592 if (key_tap(KEY_LEFT)) { 600 // if (key_tap(KEY_LEFT)) {
593 *flag |= 0x40; 601 // *flag |= 0x40;
594 } else { 602 // } else {
595 *flag &= ~0x40; 603 // *flag &= ~0x40;
596 } 604 // }
597 if (key_tap(KEY_RIGHT)) { 605 // if (key_tap(KEY_RIGHT)) {
598 *flag |= 0x80; 606 // *flag |= 0x80;
599 } else { 607 // } else {
600 *flag &= ~0x80; 608 // *flag &= ~0x80;
601 } 609 // }
602 610
603 if (key_prev != key_curr) { 611 // if (key_prev != key_curr) {
604 uxn_eval(u, PEEK2(d)); 612 // uxn_eval(u, PEEK2(d));
605 } 613 // }
606 d[3] = 0; 614 // d[3] = 0;
607 } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) { 615 // } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) {
608 u8 *d = &u->dev[0x90]; 616 // u8 *d = &u->dev[0x90];
609 // Detect "mouse key press". 617 // // Detect "mouse key press".
610 u8 flag = d[6]; 618 // u8 flag = d[6];
611 bool event = false; 619 // bool event = false;
612 if (key_tap(KEY_B)) { 620 // if (key_tap(KEY_B)) {
613 event = true; 621 // event = true;
614 flag |= 0x01; 622 // flag |= 0x01;
615 } else if (key_released(KEY_B)) { 623 // } else if (key_released(KEY_B)) {
616 event = true; 624 // event = true;
617 flag &= ~0x01; 625 // flag &= ~0x01;
618 } 626 // }
619 if (key_tap(KEY_A)) { 627 // if (key_tap(KEY_A)) {
620 event = true; 628 // event = true;
621 flag |= 0x10; 629 // flag |= 0x10;
622 } else if (key_released(KEY_A)) { 630 // } else if (key_released(KEY_A)) {
623 event = true; 631 // event = true;
624 flag &= ~0x10; 632 // flag &= ~0x10;
625 } 633 // }
634
635 // // Handle chording.
636 // d[6] = flag;
637 // if(flag == 0x10 && (d[6] & 0x01)) {
638 // d[7] = 0x01;
639 // }
640 // if(flag == 0x01 && (d[6] & 0x10)) {
641 // d[7] = 0x10;
642 // }
643
644 // // Detect mouse movement.
645 // if (key_pressed(KEY_UP)) {
646 // event = true;
647 // mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
648 // } else if (key_pressed(KEY_DOWN)) {
649 // event = true;
650 // mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
651 // }
652 // if (key_pressed(KEY_LEFT)) {
653 // event = true;
654 // mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
655 // } else if (key_pressed(KEY_RIGHT)) {
656 // event = true;
657 // mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
658 // }
659
660 // // Eval mouse.
661 // POKE2(d + 0x2, mouse.x);
662 // POKE2(d + 0x4, mouse.y);
663 // if (event) {
664 // uxn_eval(u, PEEK2(d));
665 // }
666 // } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
667 // u8 *d = &u->dev[0x80];
668 // if (key_tap(KEY_LEFT)) {
669 // update_cursor(cursor_position - 1);
670 // } else if (key_tap(KEY_RIGHT)) {
671 // update_cursor(cursor_position + 1);
672 // }
673 // if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) {
674 // update_cursor(cursor_position - KEYBOARD_ROW_SIZE);
675 // } else if (key_tap(KEY_DOWN)
676 // && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) {
677 // update_cursor(cursor_position + KEYBOARD_ROW_SIZE);
678 // }
679 // if (key_tap(KEY_B)) {
680 // u8 symbol = keyboard[cursor_position].symbol;
681 // switch (symbol) {
682 // case 0x7f: {
683 // // Backspace.
684 // d[3] = 0x08;
685 // } break;
686 // case 0x14: {
687 // // New line.
688 // d[3] = 0x0d;
689 // } break;
690 // case 0x18: {
691 // // Arrow up.
692 // d[2] = 0x10;
693 // } break;
694 // case 0x19: {
695 // // Arrow down.
696 // d[2] = 0x20;
697 // } break;
698 // case 0x1b: {
699 // // Arrow left.
700 // d[2] = 0x40;
701 // } break;
702 // case 0x1a: {
703 // // Arrow right.
704 // d[2] = 0x80;
705 // } break;
706 // default: {
707 // d[3] = symbol;
708 // } break;
709 // }
710 // uxn_eval(u, PEEK2(d));
711 // d[3] = 0;
712 // }
713 // }
714}
626 715
627 // Handle chording. 716#define STACK_SIZE 16
628 d[6] = flag; 717u8 stack[STACK_SIZE] = {0};
629 if(flag == 0x10 && (d[6] & 0x01)) { 718extern void uxn_init_asm(void);
630 d[7] = 0x01; 719extern void uxn_eval_asm(u16 pc);
631 }
632 if(flag == 0x01 && (d[6] & 0x10)) {
633 d[7] = 0x10;
634 }
635 720
636 // Detect mouse movement. 721// TODO: This should be on the IWRAM for maximum speed, as these are operations
637 if (key_pressed(KEY_UP)) { 722// we will use very often.
638 event = true; 723extern u8 wst[256];
639 mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8); 724extern u8 rst[256];
640 } else if (key_pressed(KEY_DOWN)) { 725extern u8 io_ports[256];
641 event = true; 726extern uintptr_t wst_ptr;
642 mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8); 727extern uintptr_t rst_ptr;
643 }
644 if (key_pressed(KEY_LEFT)) {
645 event = true;
646 mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
647 } else if (key_pressed(KEY_RIGHT)) {
648 event = true;
649 mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
650 }
651
652 // Eval mouse.
653 POKE2(d + 0x2, mouse.x);
654 POKE2(d + 0x4, mouse.y);
655 if (event) {
656 uxn_eval(u, PEEK2(d));
657 }
658 } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
659 u8 *d = &u->dev[0x80];
660 if (key_tap(KEY_LEFT)) {
661 update_cursor(cursor_position - 1);
662 } else if (key_tap(KEY_RIGHT)) {
663 update_cursor(cursor_position + 1);
664 }
665 if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) {
666 update_cursor(cursor_position - KEYBOARD_ROW_SIZE);
667 } else if (key_tap(KEY_DOWN)
668 && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) {
669 update_cursor(cursor_position + KEYBOARD_ROW_SIZE);
670 }
671 if (key_tap(KEY_B)) {
672 u8 symbol = keyboard[cursor_position].symbol;
673 switch (symbol) {
674 case 0x7f: {
675 // Backspace.
676 d[3] = 0x08;
677 } break;
678 case 0x14: {
679 // New line.
680 d[3] = 0x0d;
681 } break;
682 case 0x18: {
683 // Arrow up.
684 d[2] = 0x10;
685 } break;
686 case 0x19: {
687 // Arrow down.
688 d[2] = 0x20;
689 } break;
690 case 0x1b: {
691 // Arrow left.
692 d[2] = 0x40;
693 } break;
694 case 0x1a: {
695 // Arrow right.
696 d[2] = 0x80;
697 } break;
698 default: {
699 d[3] = symbol;
700 } break;
701 }
702 uxn_eval(u, PEEK2(d));
703 d[3] = 0;
704 }
705 }
706}
707 728
708int 729int
709main(void) { 730main(void) {
@@ -721,38 +742,87 @@ main(void) {
721 video_init(); 742 video_init();
722 743
723 // Initialize text engine. 744 // Initialize text engine.
724#ifdef TEXT_ENABLE 745// #ifdef TEXT_ENABLE
725 txt_init(1, TEXT_LAYER); 746 txt_init(1, TEXT_LAYER);
726 txt_position(0,0); 747 txt_position(0,0);
727#endif 748// #endif
728 749
729 // Initialize UXN. 750 // Initialize UXN.
730 init_uxn(&u); 751 init_uxn();
731 752
732 // Enable sound. 753 // Enable sound.
733 init_sound(); 754 init_sound();
734 755
735 // Main loop. 756 // Main loop.
736 uxn_eval(&u, PAGE_PROGRAM); 757 // uxn_eval(&u, PAGE_PROGRAM);
737 u8 frame_counter = 0; 758 u8 frame_counter = 0;
738 // NOTE: A VBLANK is 83776 cycles, anything other than that will make it so 759 // NOTE: A VBLANK is 83776 cycles, anything other than that will make it so
739 // we fail to render at 60FPS. 760 // we fail to render at 60FPS.
761
762 // TODO: Initialize memory.
763 // Initialize stack.
764 for (size_t i = 0; i < 256; i++) {
765 wst[i] = 0;
766 rst[i] = 0;
767 io_ports[i] = 0;
768 }
769 uxn_init_asm();
770
771 txt_printf("ROM\n\n");
772 for (size_t i = 0; i < 8; i++) {
773 txt_printf("%02x ", uxn_ram[i + PAGE_PROGRAM]);
774 }
775 txt_printf("\n\n");
776
777 txt_printf("STACK (BEFORE)\n");
778 txt_printf("PTR: %d\n", wst_ptr - (uintptr_t)wst);
779 for (size_t i = 0; i < STACK_SIZE; i++) {
780 if (i % 4 == 0) {
781 txt_printf("\n");
782 }
783 txt_printf("%02x ", wst[i]);
784 }
785 txt_printf("\n\n");
786
787 uxn_eval_asm(PAGE_PROGRAM);
788 txt_printf("STACK (AFTER)\n");
789 txt_printf("PTR: %d\n", wst_ptr - (uintptr_t)wst);
790 for (size_t i = 0; i < STACK_SIZE; i++) {
791 if (i % 4 == 0) {
792 txt_printf("\n");
793 }
794 txt_printf("%02x ", wst[i]);
795 }
796
797 uintptr_t stack_base = wst;
798 uintptr_t stack_size = wst_ptr - stack_base;
740 while(true) { 799 while(true) {
800 txt_position(0,0);
801 // bios_vblank_wait();
802 // FRAME_START();
803 // // PROF(handle_input(&u), input_cycles);
804 // // PROF(uxn_eval(&u, PEEK2(&u.dev[0x20])), eval_cycles);
805 // // PROF(sound_mix(), mix_cycles);
806 // // // TODO: allow configuration to do VSYNC at 15 or 30 fps to avoid too
807 // // // much memory copying on demanding uxn roms.
808 // // PROF_SHOW();
809 // // PROF(flipbuf(), flip_cycles);
810 // // frame_counter++;
811 // // if (frame_counter == 60) {
812 // // seconds++;
813 // // frame_counter = 0;
814 // // }
815 // FRAME_END();
741 bios_vblank_wait(); 816 bios_vblank_wait();
742 FRAME_START(); 817 FRAME_START();
743 PROF(handle_input(&u), input_cycles); 818 flipbuf();
744 PROF(uxn_eval(&u, PEEK2(&u.dev[0x20])), eval_cycles); 819 // screen_fill(0);
745 PROF(sound_mix(), mix_cycles); 820 // txt_printf("WST: 0x%08x\n", wst);
746 // TODO: allow configuration to do VSYNC at 15 or 30 fps to avoid too 821 // txt_printf("PTR: 0x%08x\n", wst_ptr);
747 // much memory copying on demanding uxn roms.
748 PROF_SHOW();
749 PROF(flipbuf(), flip_cycles);
750 frame_counter++;
751 if (frame_counter == 60) {
752 seconds++;
753 frame_counter = 0;
754 }
755 FRAME_END(); 822 FRAME_END();
823 PROF_SHOW();
824 // txt_render();
825 // txt_clear();
756 } 826 }
757 827
758 return 0; 828 return 0;
diff --git a/src/uxn-core.s b/src/uxn-core.s
new file mode 100644
index 0000000..2e7a165
--- /dev/null
+++ b/src/uxn-core.s
@@ -0,0 +1,567 @@
1.file "uxn-core.s"
2.section .iwram, "ax", %progbits
3.extern uxn_ram
4.align
5
6@
7@ Core variables
8@
9
10.global wst
11wst: .space 256
12.global wst_ptr
13wst_ptr: .word wst
14
15.global rst
16rst: .space 256
17.global rst_ptr
18rst_ptr: .word rst
19
20.global io_ports
21io_ports: .space 256
22
23@
24@ r0 is our custom stack pointer
25@ r1 is the value we want to insert/extract
26@
27@ When the stack grows downwards:
28@ push {r1} == str r1, [sp, #-4]!
29@ pop {r1} == ldr r1, [sp], #4
30@
31@ In our case the stack grow upwards:
32@
33@ 8bit:
34@ push {r1} == strb r1, [sp], #1
35@ pop {r1} == ldrb r1, [sp, #-1]!
36@
37@ 32bit:
38@ push {r1} == str r1, [sp], #4
39@ pop {r1} == ldr r1, [sp, #-4]!
40@
41
42.global uxn_init_asm
43uxn_init_asm:
44 @ DEBUG: Initialize the stack for testing purposes.
45 ldr r0, wst_ptr
46 mov r1, #4
47 strb r1, [r0], #1
48 sub r1, r1, #1
49 strb r1, [r0], #1
50 sub r1, r1, #1
51 strb r1, [r0], #1
52 sub r1, r1, #1
53 strb r1, [r0], #1
54 adr r1, wst_ptr
55 str r0, [r1]
56 bx lr
57
58@ UXN evaluation function.
59@
60@ r0: PC pointer (argument is offset from RAM).
61@ r1: Stack pointer (wst/rst).
62@ r2: Ram ptr.
63@ r3-r7: Scratch registers.
64.global uxn_eval_asm
65uxn_eval_asm:
66 @ Initialization.
67 push {r4-r7}
68 ldr r1, wst_ptr
69 ldr r2, =uxn_ram
70 add r0, r0, r2
71
72uxn_decode:
73 ldrb r3, [r0], #1 @ current OP value / table index
74
75 @ TODO: Setup wst/rst? or fill operations accordingly?
76 @ str r3, [r1], #1 @ Push to stack: Debugging
77
78 @ Decode OP based on table lookup.
79 adr r4, op_table @ decoding table
80 ldr r4, [r4, r3, lsl #2] @ op_table[idx * 4]
81 bx r4 @ op_table[idx * 4]()
82
83uxn_ret:
84 @ Update stack pointer and return.
85 adr r0, wst_ptr
86 str r1, [r0]
87 pop {r4-r7}
88 bx lr
89
90@
91@ OP implementations.
92@
93
94brk:
95 b uxn_ret
96
97jci:
98 b uxn_ret
99
100jmi:
101 b uxn_ret
102
103jsi:
104 b uxn_ret
105
106litr:
107 ldrb r3, [r0], #1
108 strb r3, [r1], #1
109 b uxn_decode
110
111lit2r:
112 b uxn_ret
113
114inc:
115 b uxn_ret
116
117inc2:
118 b uxn_ret
119
120pop:
121 b uxn_ret
122
123pop2:
124 b uxn_ret
125
126nip:
127 b uxn_ret
128
129nip2:
130 b uxn_ret
131
132swp:
133 b uxn_ret
134
135swp2:
136 b uxn_ret
137
138rot:
139 b uxn_ret
140
141rot2:
142 b uxn_ret
143
144dup:
145 b uxn_ret
146
147dup2:
148 b uxn_ret
149
150ovr:
151 b uxn_ret
152
153ovr2:
154 b uxn_ret
155
156equ:
157 b uxn_ret
158
159equ2:
160 b uxn_ret
161
162neq:
163 b uxn_ret
164
165neq2:
166 b uxn_ret
167
168gth:
169 b uxn_ret
170
171gth2:
172 b uxn_ret
173
174lth:
175 b uxn_ret
176
177lth2:
178 b uxn_ret
179
180jmp:
181 b uxn_ret
182
183jmp2:
184 b uxn_ret
185
186jcn:
187 b uxn_ret
188
189jcn2:
190 b uxn_ret
191
192jsr:
193 b uxn_ret
194
195jsr2:
196 b uxn_ret
197
198sth:
199 b uxn_ret
200
201sth2:
202 b uxn_ret
203
204ldz:
205 b uxn_ret
206
207ldz2:
208 b uxn_ret
209
210stz:
211 b uxn_ret
212
213stz2:
214 b uxn_ret
215
216ldr:
217 b uxn_ret
218
219ldr2:
220 b uxn_ret
221
222str:
223 b uxn_ret
224
225str2:
226 b uxn_ret
227
228lda:
229 b uxn_ret
230
231lda2:
232 b uxn_ret
233
234sta:
235 b uxn_ret
236
237sta2:
238 b uxn_ret
239
240dei:
241 b uxn_ret
242
243dei2:
244 b uxn_ret
245
246deo:
247 b uxn_ret
248
249deo2:
250 b uxn_ret
251
252add:
253 ldr r3, [r1, #-1]!
254 ldr r4, [r1, #-1]!
255 add r3, r3, r4
256 strb r3, [r1], #1
257 b uxn_ret @ NOTE: This should return to the next loop iteration.
258
259add2:
260 b uxn_ret
261
262sub:
263 @ ldr r2, [r0, #-1]!
264 @ ldr r1, [r0, #-1]!
265 @ sub r1, r1, r2
266 @ strb r1, [r0], #1
267 b uxn_ret @ NOTE: This should return to the next loop iteration.
268
269sub2:
270 b uxn_ret
271
272mul:
273 b uxn_ret
274
275mul2:
276 b uxn_ret
277
278div:
279 b uxn_ret
280
281div2:
282 b uxn_ret
283
284and:
285 b uxn_ret
286
287and2:
288 b uxn_ret
289
290ora:
291 b uxn_ret
292
293ora2:
294 b uxn_ret
295
296eor:
297 b uxn_ret
298
299eor2:
300 b uxn_ret
301
302sft:
303 b uxn_ret
304
305sft2:
306 b uxn_ret
307
308@ OP table
309op_table:
310 .word brk @ 0x00
311 .word inc @ 0x01
312 .word pop @ 0x02
313 .word nip @ 0x03
314 .word swp @ 0x04
315 .word rot @ 0x05
316 .word dup @ 0x06
317 .word ovr @ 0x07
318 .word equ @ 0x08
319 .word neq @ 0x09
320 .word gth @ 0x0a
321 .word lth @ 0x0b
322 .word jmp @ 0x0c
323 .word jcn @ 0x0d
324 .word jsr @ 0x0e
325 .word sth @ 0x0f
326 .word ldz @ 0x00
327 .word stz @ 0x11
328 .word ldr @ 0x12
329 .word str @ 0x13
330 .word lda @ 0x14
331 .word sta @ 0x15
332 .word dei @ 0x16
333 .word deo @ 0x17
334 .word add @ 0x18
335 .word sub @ 0x19
336 .word mul @ 0x1a
337 .word div @ 0x1b
338 .word and @ 0x1c
339 .word ora @ 0x1d
340 .word eor @ 0x1e
341 .word sft @ 0x1f
342 .word brk @ 0x20
343 .word inc2 @ 0x21
344 .word pop2 @ 0x22
345 .word nip2 @ 0x23
346 .word swp2 @ 0x24
347 .word rot2 @ 0x25
348 .word dup2 @ 0x26
349 .word ovr2 @ 0x27
350 .word equ2 @ 0x28
351 .word neq2 @ 0x29
352 .word gth2 @ 0x2a
353 .word lth2 @ 0x2b
354 .word jmp2 @ 0x2c
355 .word jcn2 @ 0x2d
356 .word jsr2 @ 0x2e
357 .word sth2 @ 0x2f
358 .word ldz2 @ 0x30
359 .word stz2 @ 0x31
360 .word ldr2 @ 0x32
361 .word str2 @ 0x33
362 .word lda2 @ 0x34
363 .word sta2 @ 0x35
364 .word dei2 @ 0x36
365 .word deo2 @ 0x37
366 .word add2 @ 0x38
367 .word sub2 @ 0x39
368 .word mul2 @ 0x3a
369 .word div2 @ 0x3b
370 .word and2 @ 0x3c
371 .word ora2 @ 0x3d
372 .word eor2 @ 0x3e
373 .word sft2 @ 0x3f
374@ TODO: Can we mask this instead of having empty space?
375 .word brk @ 0x40
376 .word brk @ 0x41
377 .word brk @ 0x42
378 .word brk @ 0x43
379 .word brk @ 0x44
380 .word brk @ 0x45
381 .word brk @ 0x46
382 .word brk @ 0x47
383 .word brk @ 0x48
384 .word brk @ 0x49
385 .word brk @ 0x4a
386 .word brk @ 0x4b
387 .word brk @ 0x4c
388 .word brk @ 0x4d
389 .word brk @ 0x4e
390 .word brk @ 0x4f
391 .word brk @ 0x50
392 .word brk @ 0x51
393 .word brk @ 0x52
394 .word brk @ 0x53
395 .word brk @ 0x54
396 .word brk @ 0x55
397 .word brk @ 0x56
398 .word brk @ 0x57
399 .word brk @ 0x58
400 .word brk @ 0x59
401 .word brk @ 0x5a
402 .word brk @ 0x5b
403 .word brk @ 0x5c
404 .word brk @ 0x5d
405 .word brk @ 0x5e
406 .word brk @ 0x5f
407 .word brk @ 0x60
408 .word brk @ 0x61
409 .word brk @ 0x62
410 .word brk @ 0x63
411 .word brk @ 0x64
412 .word brk @ 0x65
413 .word brk @ 0x66
414 .word brk @ 0x67
415 .word brk @ 0x68
416 .word brk @ 0x69
417 .word brk @ 0x6a
418 .word brk @ 0x6b
419 .word brk @ 0x6c
420 .word brk @ 0x6d
421 .word brk @ 0x6e
422 .word brk @ 0x6f
423 .word brk @ 0x70
424 .word brk @ 0x71
425 .word brk @ 0x72
426 .word brk @ 0x73
427 .word brk @ 0x74
428 .word brk @ 0x75
429 .word brk @ 0x76
430 .word brk @ 0x77
431 .word brk @ 0x78
432 .word brk @ 0x79
433 .word brk @ 0x7a
434 .word brk @ 0x7b
435 .word brk @ 0x7c
436 .word brk @ 0x7d
437 .word brk @ 0x7e
438 .word brk @ 0x7f
439 .word litr @ 0x80
440 .word brk @ 0x81
441 .word brk @ 0x82
442 .word brk @ 0x83
443 .word brk @ 0x84
444 .word brk @ 0x85
445 .word brk @ 0x86
446 .word brk @ 0x87
447 .word brk @ 0x88
448 .word brk @ 0x89
449 .word brk @ 0x8a
450 .word brk @ 0x8b
451 .word brk @ 0x8c
452 .word brk @ 0x8d
453 .word brk @ 0x8e
454 .word brk @ 0x8f
455 .word brk @ 0x90
456 .word brk @ 0x91
457 .word brk @ 0x92
458 .word brk @ 0x93
459 .word brk @ 0x94
460 .word brk @ 0x95
461 .word brk @ 0x96
462 .word brk @ 0x97
463 .word brk @ 0x98
464 .word brk @ 0x99
465 .word brk @ 0x9a
466 .word brk @ 0x9b
467 .word brk @ 0x9c
468 .word brk @ 0x9d
469 .word brk @ 0x9e
470 .word brk @ 0x9f
471 .word brk @ 0xa0
472 .word brk @ 0xa1
473 .word brk @ 0xa2
474 .word brk @ 0xa3
475 .word brk @ 0xa4
476 .word brk @ 0xa5
477 .word brk @ 0xa6
478 .word brk @ 0xa7
479 .word brk @ 0xa8
480 .word brk @ 0xa9
481 .word brk @ 0xaa
482 .word brk @ 0xab
483 .word brk @ 0xac
484 .word brk @ 0xad
485 .word brk @ 0xae
486 .word brk @ 0xaf
487 .word brk @ 0xb0
488 .word brk @ 0xb1
489 .word brk @ 0xb2
490 .word brk @ 0xb3
491 .word brk @ 0xb4
492 .word brk @ 0xb5
493 .word brk @ 0xb6
494 .word brk @ 0xb7
495 .word brk @ 0xb8
496 .word brk @ 0xb9
497 .word brk @ 0xba
498 .word brk @ 0xbb
499 .word brk @ 0xbc
500 .word brk @ 0xbd
501 .word brk @ 0xbe
502 .word brk @ 0xbf
503 .word brk @ 0xc0
504 .word brk @ 0xc1
505 .word brk @ 0xc2
506 .word brk @ 0xc3
507 .word brk @ 0xc4
508 .word brk @ 0xc5
509 .word brk @ 0xc6
510 .word brk @ 0xc7
511 .word brk @ 0xc8
512 .word brk @ 0xc9
513 .word brk @ 0xca
514 .word brk @ 0xcb
515 .word brk @ 0xcc
516 .word brk @ 0xcd
517 .word brk @ 0xce
518 .word brk @ 0xcf
519 .word brk @ 0xd0
520 .word brk @ 0xd1
521 .word brk @ 0xd2
522 .word brk @ 0xd3
523 .word brk @ 0xd4
524 .word brk @ 0xd5
525 .word brk @ 0xd6
526 .word brk @ 0xd7
527 .word brk @ 0xd8
528 .word brk @ 0xd9
529 .word brk @ 0xda
530 .word brk @ 0xdb
531 .word brk @ 0xdc
532 .word brk @ 0xdd
533 .word brk @ 0xde
534 .word brk @ 0xdf
535 .word brk @ 0xe0
536 .word brk @ 0xe1
537 .word brk @ 0xe2
538 .word brk @ 0xe3
539 .word brk @ 0xe4
540 .word brk @ 0xe5
541 .word brk @ 0xe6
542 .word brk @ 0xe7
543 .word brk @ 0xe8
544 .word brk @ 0xe9
545 .word brk @ 0xea
546 .word brk @ 0xeb
547 .word brk @ 0xec
548 .word brk @ 0xed
549 .word brk @ 0xee
550 .word brk @ 0xef
551 .word brk @ 0xf0
552 .word brk @ 0xf1
553 .word brk @ 0xf2
554 .word brk @ 0xf3
555 .word brk @ 0xf4
556 .word brk @ 0xf5
557 .word brk @ 0xf6
558 .word brk @ 0xf7
559 .word brk @ 0xf8
560@ TODO: Can we mask this instead of having empty space?
561 .word lit2r @ 0xf9
562 .word litr @ 0xfa
563 .word lit2r @ 0xfb
564 .word litr @ 0xfc
565 .word jsi @ 0xfd
566 .word jmi @ 0xfe
567 .word jci @ 0xff