diff --git a/oquonie.rom b/oquonie.rom new file mode 100644 index 0000000..411c572 Binary files /dev/null and b/oquonie.rom differ diff --git a/src/devices/datetime.c b/src/devices/datetime.c index e7a9f86..41b0f7d 100644 --- a/src/devices/datetime.c +++ b/src/devices/datetime.c @@ -4,7 +4,7 @@ #include "datetime.h" /* -Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick +Copyright (c) 2021-2023 Devine Lu Linvega, 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 diff --git a/src/devices/file.c b/src/devices/file.c index 18a518a..c5f3fbc 100644 --- a/src/devices/file.c +++ b/src/devices/file.c @@ -8,6 +8,11 @@ #include #include +#ifdef _WIN32 +#include +#define realpath(s, dummy) lrealpath(s) +#endif + #ifndef PATH_MAX #define PATH_MAX 4096 #endif @@ -16,7 +21,7 @@ #include "file.h" /* -Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick +Copyright (c) 2021-2023 Devine Lu Linvega, 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 @@ -84,14 +89,17 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len) continue; if(strcmp(c->de->d_name, "..") == 0) { /* hide "sandbox/.." */ - char cwd[PATH_MAX] = {'\0'}, t[PATH_MAX] = {'\0'}; + char cwd[PATH_MAX] = {'\0'}, *t; /* Note there's [currently] no way of chdir()ing from uxn, so $PWD * is always the sandbox top level. */ getcwd(cwd, sizeof(cwd)); /* We already checked that c->current_filename exists so don't need a wrapper. */ - realpath(c->current_filename, t); - if(strcmp(cwd, t) == 0) + t = realpath(c->current_filename, NULL); + if(strcmp(cwd, t) == 0) { + free(t); continue; + } + free(t); } if(strlen(c->current_filename) + 1 + strlen(c->de->d_name) < sizeof(pathname)) sprintf(pathname, "%s/%s", c->current_filename, c->de->d_name); @@ -108,7 +116,7 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len) static char * retry_realpath(const char *file_name) { - char r[PATH_MAX] = {'\0'}, p[PATH_MAX] = {'\0'}, *x; + char *r, p[PATH_MAX] = {'\0'}, *x; if(file_name == NULL) { errno = EINVAL; return NULL; @@ -123,7 +131,7 @@ retry_realpath(const char *file_name) strcat(p, "/"); /* TODO: use a macro instead of '/' for the path delimiter */ } strcat(p, file_name); - while(realpath(p, r) == NULL) { + while((r = realpath(p, NULL)) == NULL) { if(errno != ENOENT) return NULL; x = strrchr(p, '/'); /* TODO: path delimiter macro */ @@ -132,7 +140,7 @@ retry_realpath(const char *file_name) else return NULL; } - return strdup(r); + return r; } static void @@ -168,7 +176,7 @@ file_init(UxnFile *c, char *filename, size_t max_len, int override_sandbox) } static Uint16 -file_read(UxnFile *c, void *dest, Uint16 len) +file_read(UxnFile *c, void *dest, int len) { if(c->outside_sandbox) return 0; if(c->state != FILE_READ && c->state != DIR_READ) { @@ -278,15 +286,3 @@ file_dei(Uint8 id, Uint8 *d, Uint8 port) } return d[port]; } - -/* Boot */ - -int -load_rom(Uxn *u, char *filename) -{ - int ret; - file_init(uxn_file, filename, strlen(filename) + 1, 1); - ret = file_read(uxn_file, &u->ram[PAGE_PROGRAM], 0x10000 - PAGE_PROGRAM); - reset(uxn_file); - return ret; -} diff --git a/src/devices/file.h b/src/devices/file.h index 5edb9f5..2a6fa13 100644 --- a/src/devices/file.h +++ b/src/devices/file.h @@ -14,4 +14,3 @@ WITH REGARD TO THIS SOFTWARE. void file_deo(Uint8 id, Uint8 *ram, Uint8 *d, Uint8 port); Uint8 file_dei(Uint8 id, Uint8 *d, Uint8 port); -int load_rom(Uxn *u, char *filename); diff --git a/src/devices/system.c b/src/devices/system.c index 5339c41..214a1c7 100644 --- a/src/devices/system.c +++ b/src/devices/system.c @@ -39,6 +39,55 @@ system_inspect(Uxn *u) system_print(u->rst, "rst"); } +/* RAM */ + +void +system_cmd(Uint8 *ram, Uint16 addr) +{ + Uint16 a = addr, i = 0; + Uint8 o = ram[a++]; + if(o == 1) { + Uint16 length = (ram[a++] << 8) + ram[a++]; + Uint16 src_page = ((ram[a++] << 8) + ram[a++]) % 16, src_addr = (ram[a++] << 8) + ram[a++]; + Uint16 dst_page = ((ram[a++] << 8) + ram[a++]) % 16, dst_addr = (ram[a++] << 8) + ram[a]; + for(i = 0; i < length; i++) + ram[dst_page * 0x10000 + dst_addr + i] = ram[src_page * 0x10000 + src_addr + i]; + } +} + +int +system_load(Uxn *u, char *filename) +{ + int l, i = 0; + FILE *f = fopen(filename, "rb"); + if(!f) + return 0; + l = fread(&u->ram[PAGE_PROGRAM], 1, 0x10000 - PAGE_PROGRAM, f); + while(l && ++i < RAM_PAGES) + l = fread(u->ram + 0x10000 * i, 1, 0x10000, f); + fclose(f); + return 1; +} + +/* IO */ + +void +system_deo(Uxn *u, Uint8 *d, Uint8 port) +{ + Uint16 a; + switch(port) { + case 0x3: + PEKDEV(a, 0x2); + system_cmd(u->ram, a); + break; + case 0xe: + if(u->wst->ptr || u->rst->ptr) system_inspect(u); + break; + } +} + +/* Error */ + int uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr) { @@ -57,44 +106,3 @@ uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr) } return 0; } - -/* MMU */ - -Uint8 * -mmu_init(Mmu *m, Uint16 pages) -{ - m->length = pages; - m->pages = (Uint8 *)calloc(0x10000 * pages, sizeof(Uint8)); - return m->pages; -} - -void -mmu_eval(Uint8 *ram, Uint16 addr) -{ - Uint16 a = addr, i = 0; - Uint8 o = ram[a++]; - if(o == 1) { - Uint16 length = (ram[a++] << 8) + ram[a++]; - Uint16 src_page = ((ram[a++] << 8) + ram[a++]) % 16, src_addr = (ram[a++] << 8) + ram[a++]; - Uint16 dst_page = ((ram[a++] << 8) + ram[a++]) % 16, dst_addr = (ram[a++] << 8) + ram[a]; - for(i = 0; i < length; i++) - ram[dst_page * 0x10000 + dst_addr + i] = ram[src_page * 0x10000 + src_addr + i]; - } -} - -/* IO */ - -void -system_deo(Uxn *u, Uint8 *d, Uint8 port) -{ - Uint16 a; - switch(port) { - case 0x3: - PEKDEV(a, 0x2); - mmu_eval(u->ram, a); - break; - case 0xe: - if(u->wst->ptr || u->rst->ptr) system_inspect(u); - break; - } -} diff --git a/src/devices/system.h b/src/devices/system.h index 6be1005..87923e0 100644 --- a/src/devices/system.h +++ b/src/devices/system.h @@ -9,11 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -void system_inspect(Uxn *u); +#define RAM_PAGES 0x10 + +int system_load(Uxn *u, char *filename); void system_deo(Uxn *u, Uint8 *d, Uint8 port); - -typedef struct { - Uint8 length, *pages; -} Mmu; - -Uint8 *mmu_init(Mmu *m, Uint16 pages); +void system_inspect(Uxn *u); diff --git a/src/uxn11.c b/src/uxn11.c index 01dafa1..6b247b3 100644 --- a/src/uxn11.c +++ b/src/uxn11.c @@ -108,7 +108,7 @@ emu_draw(void) static int emu_start(Uxn *u, char *rom) { - if(!load_rom(u, rom)) + if(!system_load(u, rom)) return 0; if(!uxn_screen.width || !uxn_screen.height) screen_resize(&uxn_screen, WIDTH, HEIGHT); @@ -225,7 +225,6 @@ int main(int argc, char **argv) { Uxn u; - Mmu m; int i; char expirations[8]; struct pollfd fds[2]; @@ -233,7 +232,7 @@ main(int argc, char **argv) if(argc < 2) return emu_error("Usage", "uxn11 game.rom args"); rom_path = argv[1]; - if(!uxn_boot(&u, mmu_init(&m, 16), emu_dei, emu_deo)) + if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), emu_dei, emu_deo)) return emu_error("Boot", "Failed"); /* start sequence */ if(!emu_start(&u, rom_path)) diff --git a/src/uxncli.c b/src/uxncli.c index 94d7935..4d4b249 100644 --- a/src/uxncli.c +++ b/src/uxncli.c @@ -37,8 +37,8 @@ console_input(Uxn *u, char c) static void console_deo(Uint8 *d, Uint8 port) { - FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr - : 0; + FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr : + 0; if(fd) { fputc(d[port], fd); fflush(fd); @@ -78,12 +78,11 @@ main(int argc, char **argv) { Uxn u; int i; - Mmu mmu; if(argc < 2) return emu_error("Usage", "uxncli game.rom args"); - if(!uxn_boot(&u, mmu_init(&mmu, 16), emu_dei, emu_deo)) + if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), emu_dei, emu_deo)) return emu_error("Boot", "Failed"); - if(!load_rom(&u, argv[1])) + if(!system_load(&u, argv[1])) return emu_error("Load", "Failed"); if(!uxn_eval(&u, PAGE_PROGRAM)) return emu_error("Init", "Failed");