From 6eb64c15c6c3e1ab330a2dd62abcfe3bb660e1e6 Mon Sep 17 00:00:00 2001 From: Adrian Siekierka Date: Sat, 14 May 2022 21:38:53 +0200 Subject: [PATCH] uxnds 0.3.5 --- Makefile | 4 +- arm9/source/emulator.c | 91 +++++++---------- arm9/source/file.c | 217 +++++++++++++++++++++++++++++++++++++++++ arm9/source/file.h | 17 ++++ arm9/source/ppu.c | 4 +- arm9/source/uxn.c | 84 ++++++++-------- 6 files changed, 316 insertions(+), 101 deletions(-) create mode 100644 arm9/source/file.c create mode 100644 arm9/source/file.h diff --git a/Makefile b/Makefile index 92bc35a..95ae55a 100644 --- a/Makefile +++ b/Makefile @@ -13,9 +13,9 @@ export TOPDIR := $(CURDIR) NITRO_FILES := # These set the information text in the nds file -GAME_TITLE := uxnds v0.3.4 +GAME_TITLE := uxnds v0.3.5 GAME_SUBTITLE1 := tiny virtual machine -GAME_SUBTITLE2 := 04/02/2022 +GAME_SUBTITLE2 := 14/05/2022 include $(DEVKITARM)/ds_rules diff --git a/arm9/source/emulator.c b/arm9/source/emulator.c index a22d56a..6c96af8 100644 --- a/arm9/source/emulator.c +++ b/arm9/source/emulator.c @@ -6,6 +6,7 @@ #include "../../include/uxn.h" #include "../../include/apu.h" #include "../../include/fifo.h" +#include "file.h" #include "ppu.h" /* @@ -27,6 +28,7 @@ static u32 apu_samples[(UXNDS_AUDIO_BUFFER_SIZE * 4) >> 1]; static Device *devscreen, *devctrl, *devmouse, *devaudio0; Uint8 dispswap = 0, debug = 0; +char load_filename[129]; static PrintConsole *mainConsole; #ifdef DEBUG @@ -121,19 +123,28 @@ screen_talk(Device *d, Uint8 b0, Uint8 w) if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 1); /* auto x+1 */ if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 1); /* auto y+1 */ } else if(b0 == 0xf) { + Uint8 twobpp = d->dat[0xf] >> 7; Uint16 x = peek16(d->dat, 0x8); Uint16 y = peek16(d->dat, 0xa); Uint32 *layer = d->dat[0xf] >> 6 & 0x1 ? ppu.fg : ppu.bg; - Uint8 *addr = &d->mem[peek16(d->dat, 0xc)]; - if(d->dat[0xf] & 0x80) { - ppu_2bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); - if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 16); /* auto addr+16 */ - } else { - ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); - if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 8); /* auto addr+8 */ + Uint16 addr = peek16(d->dat, 0xc); + Uint8 n = d->dat[0x6] >> 4; + Uint8 dx = (d->dat[0x6] & 0x01) << 3; + Uint8 dy = (d->dat[0x6] & 0x02) << 2; + Uint16 len = (n + 1) << (3 + twobpp); + if(addr > (0x10000 - len)) return 1; + for (Uint8 i = 0; i <= n; i++) { + if (twobpp) { + ppu_2bpp(&ppu, layer, x + dy * i, y + dx * i, &d->mem[addr], d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); + addr += (d->dat[0x6] & 0x04) << 2; + } else { + ppu_1bpp(&ppu, layer, x + dy * i, y + dx * i, &d->mem[addr], d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); + addr += (d->dat[0x6] & 0x04) << 1; + } } - if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 8); /* auto x+8 */ - if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 8); /* auto y+8 */ + poke16(d->dat, 0x8, x + dx); /* auto x+dx */ + poke16(d->dat, 0xa, y + dy); /* auto y+dy */ + poke16(d->dat, 0xc, addr); /* auto addr */ } } return 1; @@ -155,48 +166,11 @@ get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int f return snprintf(p, len, "???? %s\n", basename); } -static Uint16 -file_read_dir(char *dest, Uint16 len, DIR *dir, const char *filename) -{ - static char pathname[512]; - char *p = dest; - struct dirent *de; - while(de = readdir(dir)) { - Uint16 n; - if(de->d_name[0] == '.' && de->d_name[1] == '\0') - continue; - snprintf(pathname, sizeof(pathname), "%s/%s", filename, de->d_name); - n = get_entry(p, len, pathname, de->d_name, 1); - if(!n) break; - p += n; - len -= n; - } - return p - dest; -} - - int file_talk(Device *d, Uint8 b0, Uint8 w) { - Uint8 read = b0 == 0xd; - if(w && (read || b0 == 0xf)) { - char *name = (char *)&d->mem[peek16(d->dat, 0x8)]; - Uint16 result = 0, length = peek16(d->dat, 0xa); - Uint16 offset = peek16(d->dat, 0x4); - Uint16 addr = peek16(d->dat, b0 - 1); - FILE *f; DIR *dir; - if (dir = opendir(name)) { - result = file_read_dir(&d->mem[addr], length, dir, name); - closedir(dir); - } else if(f = fopen(name, read ? "r" : (offset ? "a" : "w"))) { - dprintf("%s %04x %s %s: ", read ? "Loading" : "Saving", addr, read ? "from" : "to", name); - if(fseek(f, offset, SEEK_SET) != -1) - result = read ? fread(&d->mem[addr], 1, length, f) : fwrite(&d->mem[addr], 1, length, f); - dprintf("%04x bytes\n", result); - fclose(f); - } - poke16(d->dat, 0x2, result); - } + if (w) file_deo(d, b0); + else file_dei(d, b0); return 1; } @@ -359,7 +333,7 @@ profiler_ticks(Uint32 tticks, int pos, const char *name) } #endif -void +int prompt_reset(Uxn *u) { consoleClear(); @@ -373,7 +347,7 @@ prompt_reset(Uxn *u) break; } else if (allHeld & KEY_B) { consoleClear(); - return; + return 0; } } @@ -381,13 +355,14 @@ prompt_reset(Uxn *u) if(!resetuxn(u)) return error("Resetting", "Failed"); - if(!loaduxn(u, "boot.rom")) + if(!loaduxn(u, load_filename)) return error("Load", "Failed"); if(!initppu(&ppu)) return error("PPU", "Init failure"); evaluxn(u, 0x0100); consoleClear(); + return 0; } int @@ -470,8 +445,12 @@ main(int argc, char **argv) if (!fatInitDefault()) return error("FAT init", "Failed"); chdir("/uxn"); - if(!loaduxn(&u, "boot.rom")) - return error("Load", "Failed"); + if(!loaduxn(&u, "boot.rom")) { + if(!loaduxn(&u, "launcher.rom")) { + dprintf("Halted: Missing input rom.\n"); + return error("Load", "Failed"); + } + } if(!init()) return error("Init", "Failed"); @@ -494,9 +473,9 @@ main(int argc, char **argv) portuxn(&u, 0x7, "---", nil_talk); devctrl = portuxn(&u, 0x8, "controller", nil_talk); devmouse = portuxn(&u, 0x9, "mouse", nil_talk); - portuxn(&u, 0xa, "file", file_talk); - portuxn(&u, 0xb, "datetime", datetime_talk); - portuxn(&u, 0xc, "---", nil_talk); + portuxn(&u, 0xa, "file0", file_talk); + portuxn(&u, 0xb, "file1", file_talk); + portuxn(&u, 0xc, "datetime", datetime_talk); portuxn(&u, 0xd, "---", nil_talk); portuxn(&u, 0xe, "---", nil_talk); portuxn(&u, 0xf, "---", nil_talk); diff --git a/arm9/source/file.c b/arm9/source/file.c new file mode 100644 index 0000000..8f2f32d --- /dev/null +++ b/arm9/source/file.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include + +#include "../../include/uxn.h" +#include "file.h" + +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +typedef struct { + FILE *f; + DIR *dir; + char current_filename[4096]; + struct dirent *de; + enum { IDLE, + FILE_READ, + FILE_WRITE, + DIR_READ } state; +} UxnFile; + +static UxnFile uxn_file[POLYFILEY]; + +static void +reset(UxnFile *c) +{ + if(c->f != NULL) { + fclose(c->f); + c->f = NULL; + } + if(c->dir != NULL) { + closedir(c->dir); + c->dir = NULL; + } + c->de = NULL; + c->state = IDLE; +} + +static Uint16 +get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int fail_nonzero) +{ + struct stat st; + if(len < strlen(basename) + 7) + return 0; + if(stat(pathname, &st)) + return fail_nonzero ? sprintf(p, "!!!! %s\n", basename) : 0; + else if(S_ISDIR(st.st_mode)) + return sprintf(p, "---- %s\n", basename); + else if(st.st_size < 0x10000) + return sprintf(p, "%04x %s\n", (unsigned int)st.st_size, basename); + else + return sprintf(p, "???? %s\n", basename); +} + +static Uint16 +file_read_dir(UxnFile *c, char *dest, Uint16 len) +{ + static char pathname[512]; + char *p = dest; + if(c->de == NULL) c->de = readdir(c->dir); + for(; c->de != NULL; c->de = readdir(c->dir)) { + Uint16 n; + if(c->de->d_name[0] == '.' && c->de->d_name[1] == '\0') + continue; + if(strlen(c->current_filename) + 1 + strlen(c->de->d_name) < sizeof(pathname)) + sprintf(pathname, "%s/%s", c->current_filename, c->de->d_name); + else + pathname[0] = '\0'; + n = get_entry(p, len, pathname, c->de->d_name, 1); + if(!n) break; + p += n; + len -= n; + } + return p - dest; +} + +static Uint16 +file_init(UxnFile *c, char *filename, size_t max_len) +{ + char *p = c->current_filename; + size_t len = sizeof(c->current_filename); + reset(c); + if(len > max_len) len = max_len; + while(len) { + if((*p++ = *filename++) == '\0') + return 0; + len--; + } + c->current_filename[0] = '\0'; + return 0; +} + +static Uint16 +file_read(UxnFile *c, void *dest, Uint16 len) +{ + if(c->state != FILE_READ && c->state != DIR_READ) { + reset(c); + if((c->dir = opendir(c->current_filename)) != NULL) + c->state = DIR_READ; + else if((c->f = fopen(c->current_filename, "rb")) != NULL) + c->state = FILE_READ; + } + if(c->state == FILE_READ) + return fread(dest, 1, len, c->f); + if(c->state == DIR_READ) + return file_read_dir(c, dest, len); + return 0; +} + +static Uint16 +file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags) +{ + Uint16 ret = 0; + if(c->state != FILE_WRITE) { + reset(c); + if((c->f = fopen(c->current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL) + c->state = FILE_WRITE; + } + if(c->state == FILE_WRITE) { + if((ret = fwrite(src, 1, len, c->f)) > 0 && fflush(c->f) != 0) + ret = 0; + } + return ret; +} + +static Uint16 +file_stat(UxnFile *c, void *dest, Uint16 len) +{ + char *basename = strrchr(c->current_filename, '/'); + if(basename != NULL) + basename++; + else + basename = c->current_filename; + return get_entry(dest, len, c->current_filename, basename, 0); +} + +static Uint16 +file_delete(UxnFile *c) +{ + return unlink(c->current_filename); +} + +static UxnFile * +file_instance(Device *d) +{ + return &uxn_file[d - &d->u->dev[DEV_FILE0]]; +} + +/* IO */ + +void +file_deo(Device *d, Uint8 port) +{ + UxnFile *c = file_instance(d); + Uint16 addr, len, res; + switch(port) { + case 0x5: + DEVPEEK16(addr, 0x4); + DEVPEEK16(len, 0xa); + if(len > 0x10000 - addr) + len = 0x10000 - addr; + res = file_stat(c, &d->mem[addr], len); + DEVPOKE16(0x2, res); + break; + case 0x6: + res = file_delete(c); + DEVPOKE16(0x2, res); + break; + case 0x9: + DEVPEEK16(addr, 0x8); + res = file_init(c, (char *)&d->mem[addr], 0x10000 - addr); + DEVPOKE16(0x2, res); + break; + case 0xd: + DEVPEEK16(addr, 0xc); + DEVPEEK16(len, 0xa); + if(len > 0x10000 - addr) + len = 0x10000 - addr; + res = file_read(c, &d->mem[addr], len); + DEVPOKE16(0x2, res); + break; + case 0xf: + DEVPEEK16(addr, 0xe); + DEVPEEK16(len, 0xa); + if(len > 0x10000 - addr) + len = 0x10000 - addr; + res = file_write(c, &d->mem[addr], len, d->dat[0x7]); + DEVPOKE16(0x2, res); + break; + } +} + +Uint8 +file_dei(Device *d, Uint8 port) +{ + UxnFile *c = file_instance(d); + Uint16 res; + switch(port) { + case 0xc: + case 0xd: + res = file_read(c, &d->dat[port], 1); + DEVPOKE16(0x2, res); + break; + } + return d->dat[port]; +} diff --git a/arm9/source/file.h b/arm9/source/file.h new file mode 100644 index 0000000..9fc5b44 --- /dev/null +++ b/arm9/source/file.h @@ -0,0 +1,17 @@ +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +#define POLYFILEY 2 +#define DEV_FILE0 0xa + +void file_deo(Device *d, Uint8 port); +Uint8 file_dei(Device *d, Uint8 port); diff --git a/arm9/source/ppu.c b/arm9/source/ppu.c index 405fc0e..db7a845 100644 --- a/arm9/source/ppu.c +++ b/arm9/source/ppu.c @@ -15,7 +15,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -static Uint8 font[][8] = { +/* static Uint8 font[][8] = { {0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c}, {0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, {0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe}, @@ -31,7 +31,7 @@ static Uint8 font[][8] = { {0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c}, {0x00, 0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc}, {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, - {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; + {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; */ DTCM_DATA static Uint8 blending[5][16] = { diff --git a/arm9/source/uxn.c b/arm9/source/uxn.c index bb980be..57e8a38 100644 --- a/arm9/source/uxn.c +++ b/arm9/source/uxn.c @@ -92,7 +92,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr -= 1; } break; - case 0x03: /* DUP */ + case 0x06: /* DUP */ { Uint8 a = u->wst.dat[u->wst.ptr - 1]; u->wst.dat[u->wst.ptr] = a; @@ -109,7 +109,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 1; } break; - case 0x04: /* NIP */ + case 0x03: /* NIP */ { Uint8 a = u->wst.dat[u->wst.ptr - 1]; u->wst.dat[u->wst.ptr - 2]; @@ -123,7 +123,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr -= 1; } break; - case 0x05: /* SWP */ + case 0x04: /* SWP */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; u->wst.dat[u->wst.ptr - 2] = a; @@ -136,7 +136,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0x06: /* OVR */ + case 0x07: /* OVR */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; u->wst.dat[u->wst.ptr] = b; @@ -153,7 +153,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 1; } break; - case 0x07: /* ROT */ + case 0x05: /* OVR */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3]; u->wst.dat[u->wst.ptr - 3] = b; @@ -542,7 +542,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr -= 2; } break; - case 0x23: /* DUP2 */ + case 0x26: /* DUP2 */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; u->wst.dat[u->wst.ptr] = b; @@ -560,7 +560,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 2; } break; - case 0x24: /* NIP2 */ + case 0x23: /* NIP2 */ { Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); @@ -575,7 +575,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr -= 2; } break; - case 0x25: /* SWP2 */ + case 0x24: /* SWP2 */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; u->wst.dat[u->wst.ptr - 4] = b; @@ -590,7 +590,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0x26: /* OVR2 */ + case 0x27: /* OVR2 */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; u->wst.dat[u->wst.ptr] = d; @@ -608,7 +608,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 2; } break; - case 0x27: /* ROT2 */ + case 0x25: /* OVR2 */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4], e = u->wst.dat[u->wst.ptr - 5], f = u->wst.dat[u->wst.ptr - 6]; u->wst.dat[u->wst.ptr - 6] = d; @@ -1025,7 +1025,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr -= 1; } break; - case 0x43: /* DUPr */ + case 0x46: /* DUPr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1]; u->rst.dat[u->rst.ptr] = a; @@ -1042,7 +1042,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 1; } break; - case 0x44: /* NIPr */ + case 0x43: /* NIPr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1]; u->rst.dat[u->rst.ptr - 2]; @@ -1056,7 +1056,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr -= 1; } break; - case 0x45: /* SWPr */ + case 0x44: /* SWPr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; u->rst.dat[u->rst.ptr - 2] = a; @@ -1069,7 +1069,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0x46: /* OVRr */ + case 0x47: /* OVRr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; u->rst.dat[u->rst.ptr] = b; @@ -1086,7 +1086,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 1; } break; - case 0x47: /* ROTr */ + case 0x45: /* OVRr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3]; u->rst.dat[u->rst.ptr - 3] = b; @@ -1475,7 +1475,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr -= 2; } break; - case 0x63: /* DUP2r */ + case 0x66: /* DUP2r */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; u->rst.dat[u->rst.ptr] = b; @@ -1493,7 +1493,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 2; } break; - case 0x64: /* NIP2r */ + case 0x63: /* NIP2r */ { Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); @@ -1508,7 +1508,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr -= 2; } break; - case 0x65: /* SWP2r */ + case 0x64: /* SWP2r */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; u->rst.dat[u->rst.ptr - 4] = b; @@ -1523,7 +1523,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0x66: /* OVR2r */ + case 0x67: /* OVR2r */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; u->rst.dat[u->rst.ptr] = d; @@ -1541,7 +1541,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 2; } break; - case 0x67: /* ROT2r */ + case 0x65: /* OVR2r */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4], e = u->rst.dat[u->rst.ptr - 5], f = u->rst.dat[u->rst.ptr - 6]; u->rst.dat[u->rst.ptr - 6] = d; @@ -1949,7 +1949,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0x83: /* DUPk */ + case 0x86: /* DUPk */ { Uint8 a = u->wst.dat[u->wst.ptr - 1]; u->wst.dat[u->wst.ptr] = a; @@ -1967,7 +1967,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 2; } break; - case 0x84: /* NIPk */ + case 0x83: /* NIPk */ { Uint8 a = u->wst.dat[u->wst.ptr - 1]; u->wst.dat[u->wst.ptr - 2]; @@ -1985,7 +1985,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 1; } break; - case 0x85: /* SWPk */ + case 0x84: /* SWPk */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; u->wst.dat[u->wst.ptr] = a; @@ -2003,7 +2003,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 2; } break; - case 0x86: /* OVRk */ + case 0x87: /* OVRk */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; u->wst.dat[u->wst.ptr] = b; @@ -2022,7 +2022,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 3; } break; - case 0x87: /* ROTk */ + case 0x85: /* OVRk */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3]; u->wst.dat[u->wst.ptr] = b; @@ -2461,7 +2461,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0xa3: /* DUP2k */ + case 0xa6: /* DUP2k */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; u->wst.dat[u->wst.ptr] = b; @@ -2481,7 +2481,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 4; } break; - case 0xa4: /* NIP2k */ + case 0xa3: /* NIP2k */ { Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)); (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8)); @@ -2500,7 +2500,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 2; } break; - case 0xa5: /* SWP2k */ + case 0xa4: /* SWP2k */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; u->wst.dat[u->wst.ptr] = b; @@ -2520,7 +2520,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 4; } break; - case 0xa6: /* OVR2k */ + case 0xa7: /* OVR2k */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4]; u->wst.dat[u->wst.ptr] = d; @@ -2542,7 +2542,7 @@ evaluxn(Uxn *u, Uint16 vec) u->wst.ptr += 6; } break; - case 0xa7: /* ROT2k */ + case 0xa5: /* OVR2k */ { Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4], e = u->wst.dat[u->wst.ptr - 5], f = u->wst.dat[u->wst.ptr - 6]; u->wst.dat[u->wst.ptr] = d; @@ -2996,7 +2996,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0xc3: /* DUPkr */ + case 0xc6: /* DUPkr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1]; u->rst.dat[u->rst.ptr] = a; @@ -3014,7 +3014,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 2; } break; - case 0xc4: /* NIPkr */ + case 0xc3: /* NIPkr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1]; u->rst.dat[u->rst.ptr - 2]; @@ -3032,7 +3032,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 1; } break; - case 0xc5: /* SWPkr */ + case 0xc4: /* SWPkr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; u->rst.dat[u->rst.ptr] = a; @@ -3050,7 +3050,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 2; } break; - case 0xc6: /* OVRkr */ + case 0xc7: /* OVRkr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; u->rst.dat[u->rst.ptr] = b; @@ -3069,7 +3069,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 3; } break; - case 0xc7: /* ROTkr */ + case 0xc5: /* OVRkr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3]; u->rst.dat[u->rst.ptr] = b; @@ -3508,7 +3508,7 @@ evaluxn(Uxn *u, Uint16 vec) #endif } break; - case 0xe3: /* DUP2kr */ + case 0xe6: /* DUP2kr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; u->rst.dat[u->rst.ptr] = b; @@ -3528,7 +3528,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 4; } break; - case 0xe4: /* NIP2kr */ + case 0xe3: /* NIP2kr */ { Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)); (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8)); @@ -3547,7 +3547,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 2; } break; - case 0xe5: /* SWP2kr */ + case 0xe4: /* SWP2kr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; u->rst.dat[u->rst.ptr] = b; @@ -3567,7 +3567,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 4; } break; - case 0xe6: /* OVR2kr */ + case 0xe7: /* OVR2kr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4]; u->rst.dat[u->rst.ptr] = d; @@ -3589,7 +3589,7 @@ evaluxn(Uxn *u, Uint16 vec) u->rst.ptr += 6; } break; - case 0xe7: /* ROT2kr */ + case 0xe5: /* OVR2kr */ { Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4], e = u->rst.dat[u->rst.ptr - 5], f = u->rst.dat[u->rst.ptr - 6]; u->rst.dat[u->rst.ptr] = d; @@ -4061,16 +4061,18 @@ bootuxn(Uxn *u) return resetuxn(u); } +extern char *load_filename; + int loaduxn(Uxn *u, char *filepath) { FILE *f; if(!(f = fopen(filepath, "rb"))) { - dprintf("Halted: Missing input rom.\n"); return 0; } fread(u->ram.dat + PAGE_PROGRAM, sizeof(u->ram.dat) - PAGE_PROGRAM, 1, f); dprintf("Uxn loaded[%s].\n", filepath); + strcpy(load_filename, filepath); return 1; }