diff --git a/src/devices/console.c b/src/devices/console.c index db0dd20..a699f2d 100644 --- a/src/devices/console.c +++ b/src/devices/console.c @@ -24,6 +24,16 @@ console_input(Uxn *u, char c, int type) return uxn_eval(u, PEEK2(d)); } +void +console_listen(Uxn *u, int i, int argc, char **argv) +{ + for(; i < argc; i++) { + char *p = argv[i]; + while(*p) console_input(u, *p++, CONSOLE_ARG); + console_input(u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA); + } +} + void console_deo(Uint8 *d, Uint8 port) { diff --git a/src/devices/console.h b/src/devices/console.h index aaaef23..eaa64f5 100644 --- a/src/devices/console.h +++ b/src/devices/console.h @@ -19,4 +19,5 @@ WITH REGARD TO THIS SOFTWARE. #define CONSOLE_END 0x4 int console_input(Uxn *u, char c, int type); +void console_listen(Uxn *u, int i, int argc, char **argv); void console_deo(Uint8 *d, Uint8 port); diff --git a/src/devices/screen.c b/src/devices/screen.c index f28bf82..01b2b68 100644 --- a/src/devices/screen.c +++ b/src/devices/screen.c @@ -38,7 +38,7 @@ screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2) if(y2 > uxn_screen.y2) uxn_screen.y2 = y2; } -static void +void screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color) { int x, y, width = uxn_screen.width, height = uxn_screen.height; diff --git a/src/devices/screen.h b/src/devices/screen.h index 320cc33..2989faf 100644 --- a/src/devices/screen.h +++ b/src/devices/screen.h @@ -22,10 +22,12 @@ typedef struct UxnScreen { extern UxnScreen uxn_screen; extern int emu_resize(int width, int height); +void screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color); void screen_palette(Uint8 *addr); void screen_resize(Uint16 width, Uint16 height); void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2); void screen_redraw(void); void screen_debugger(Uxn *u); + Uint8 screen_dei(Uxn *u, Uint8 addr); void screen_deo(Uint8 *ram, Uint8 *d, Uint8 port); diff --git a/src/devices/system.c b/src/devices/system.c index 5a44c5e..389ee0c 100644 --- a/src/devices/system.c +++ b/src/devices/system.c @@ -15,11 +15,27 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ +char *boot_rom; + static const char *errors[] = { "underflow", "overflow", "division by zero"}; +static 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], 0x10000 - PAGE_PROGRAM, 1, f); + while(l && ++i < RAM_PAGES) + l = fread(u->ram + 0x10000 * i, 0x10000, 1, f); + fclose(f); + return 1; +} + static void system_print(Stack *s, char *name) { @@ -32,19 +48,6 @@ system_print(Stack *s, char *name) fprintf(stderr, "\n"); } -static void -system_cmd(Uint8 *ram, Uint16 addr) -{ - if(ram[addr] == 0x1) { - Uint16 i, length = PEEK2(ram + addr + 1); - Uint16 a_page = PEEK2(ram + addr + 1 + 2), a_addr = PEEK2(ram + addr + 1 + 4); - Uint16 b_page = PEEK2(ram + addr + 1 + 6), b_addr = PEEK2(ram + addr + 1 + 8); - int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000; - for(i = 0; i < length; i++) - ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)]; - } -} - int system_error(char *msg, const char *err) { @@ -53,20 +56,6 @@ system_error(char *msg, const char *err) return 0; } -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], 0x10000 - PAGE_PROGRAM, 1, f); - while(l && ++i < RAM_PAGES) - l = fread(u->ram + 0x10000 * i, 0x10000, 1, f); - fclose(f); - return 1; -} - void system_inspect(Uxn *u) { @@ -94,6 +83,32 @@ system_version(char *name, char *date) return 0; } +void +system_reboot(Uxn *u, char *rom, int soft) +{ + int i; + for(i = 0x100 * soft; i < 0x10000; i++) + u->ram[i] = 0; + for(i = 0x0; i < 0x100; i++) + u->dev[i] = 0; + u->wst.ptr = 0; + u->rst.ptr = 0; + if(system_load(u, boot_rom)) + if(uxn_eval(u, PAGE_PROGRAM)) + boot_rom = rom; +} + +int +system_init(Uxn *u, Uint8 *ram, char *rom) +{ + u->ram = ram; + if(!system_load(u, rom)) + if(!system_load(u, "boot.rom")) + return system_error("Init", "Failed to load rom."); + boot_rom = rom; + return 1; +} + /* IO */ void @@ -101,13 +116,15 @@ system_deo(Uxn *u, Uint8 *d, Uint8 port) { switch(port) { case 0x3: - system_cmd(u->ram, PEEK2(d + 2)); - break; - case 0x5: - if(PEEK2(d + 4)) { - Uxn friend; - uxn_boot(&friend, u->ram); - uxn_eval(&friend, PEEK2(d + 4)); + Uint8 *ram = u->ram; + Uint16 addr = PEEK2(d + 2); + if(ram[addr] == 0x1) { + Uint16 i, length = PEEK2(ram + addr + 1); + Uint16 a_page = PEEK2(ram + addr + 1 + 2), a_addr = PEEK2(ram + addr + 1 + 4); + Uint16 b_page = PEEK2(ram + addr + 1 + 6), b_addr = PEEK2(ram + addr + 1 + 8); + int src = (a_page % RAM_PAGES) * 0x10000, dst = (b_page % RAM_PAGES) * 0x10000; + for(i = 0; i < length; i++) + ram[dst + (Uint16)(b_addr + i)] = ram[src + (Uint16)(a_addr + i)]; } break; case 0xe: diff --git a/src/devices/system.h b/src/devices/system.h index 0ec1e33..36c2cb3 100644 --- a/src/devices/system.h +++ b/src/devices/system.h @@ -15,9 +15,13 @@ WITH REGARD TO THIS SOFTWARE. #define RAM_PAGES 0x10 +extern char *boot_rom; + void system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo); -int system_version(char *emulator, char *date); -int system_load(Uxn *u, char *filename); +void system_reboot(Uxn *u, char *rom, int soft); void system_inspect(Uxn *u); +int system_version(char *emulator, char *date); int system_error(char *msg, const char *err); +int system_init(Uxn *u, Uint8 *ram, char *rom); + void system_deo(Uxn *u, Uint8 *d, Uint8 port); diff --git a/src/uxn.c b/src/uxn.c index 068cc78..d367181 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -117,14 +117,3 @@ uxn_eval(Uxn *u, Uint16 pc) } } } - -int -uxn_boot(Uxn *u, Uint8 *ram) -{ - Uint32 i; - char *cptr = (char *)u; - for(i = 0; i < sizeof(*u); i++) - cptr[i] = 0; - u->ram = ram; - return 1; -} diff --git a/src/uxn.h b/src/uxn.h index 8cab5f1..896bb53 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -46,5 +46,4 @@ extern Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10]; /* built-ins */ -int uxn_boot(Uxn *u, Uint8 *ram); int uxn_eval(Uxn *u, Uint16 pc); diff --git a/src/uxn11.c b/src/uxn11.c index f16c13a..3bae085 100644 --- a/src/uxn11.c +++ b/src/uxn11.c @@ -32,8 +32,6 @@ static Display *display; static Visual *visual; static Window window; -char *rom_path; - #define WIDTH (64 * 8) #define HEIGHT (40 * 8) #define PAD 2 @@ -86,7 +84,8 @@ emu_resize(int width, int height) static int emu_start(Uxn *u, char *rom) { - + (void)u; + (void)rom; return 1; } @@ -144,7 +143,7 @@ emu_event(Uxn *u) u->dev[0x0e] = !u->dev[0x0e]; if(sym == XK_F4) if(!emu_start(u, "boot.rom")) - emu_start(u, rom_path); + emu_start(u, boot_rom); controller_down(u, &u->dev[0x80], get_button(sym)); controller_key(u, &u->dev[0x80], sym < 0x80 ? sym : (Uint8)buf[0]); } break; @@ -176,6 +175,13 @@ emu_event(Uxn *u) } } +static int +emu_init(void) +{ + screen_resize(WIDTH, HEIGHT); + return 1; +} + static int emu_run(Uxn *u, char *rom) { @@ -259,24 +265,15 @@ main(int argc, char **argv) /* Read flags */ if(argv[i][0] == '-' && argv[i][1] == 'v') return system_version("Uxn11 - Graphical Varvara Emulator", "16 Aug 2023"); - - rom_path = argv[1]; - if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)))) - return system_error("boot", "Failed"); - /* start sequence */ - screen_resize(WIDTH, HEIGHT); - - if(!system_load(&u, rom_path)) - return 0; - if(!uxn_eval(&u, PAGE_PROGRAM)) - return system_error("boot", "Failed to start rom."); - - /* console vector */ - for(i = 2; i < argc; i++) { - char *p = argv[i]; - while(*p) console_input(&u, *p++, CONSOLE_ARG); - console_input(&u, '\n', i == argc ? CONSOLE_END : CONSOLE_EOA); + if(!emu_init()) + return system_error("Init", "Failed to initialize varvara."); + if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++])) + return system_error("Init", "Failed to initialize uxn."); + /* Game Loop */ + u.dev[0x17] = argc - i; + if(uxn_eval(&u, PAGE_PROGRAM)) { + console_listen(&u, i, argc, argv); + emu_run(&u, boot_rom); } - emu_run(&u, rom_path); return emu_end(&u); } diff --git a/src/uxncli.c b/src/uxncli.c index d792062..93a50ac 100644 --- a/src/uxncli.c +++ b/src/uxncli.c @@ -41,6 +41,23 @@ emu_deo(Uxn *u, Uint8 addr) } } +static void +emu_run(Uxn *u) +{ + while(!u->dev[0x0f]) { + int c = fgetc(stdin); + if(c == EOF) break; + console_input(u, (Uint8)c, CONSOLE_STD); + } +} + +static int +emu_end(Uxn *u) +{ + free(u->ram); + return u->dev[0x0f] & 0x7f; +} + int main(int argc, char **argv) { @@ -56,27 +73,14 @@ main(int argc, char **argv) system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK); /* Read flags */ if(argv[i][0] == '-' && argv[i][1] == 'v') - return system_version("Uxncli - Console Varvara Emulator", "9 Aug 2023"); - /* Continue.. */ - if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)))) - return system_error("Boot", "Failed"); - /* Load rom */ - if(!system_load(&u, argv[i++])) - return system_error("Load", "Failed"); + return system_version("Uxncli - Console Varvara Emulator", "15 Aug 2023"); + if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++])) + return system_error("Init", "Failed to initialize uxn."); /* Game Loop */ u.dev[0x17] = argc - i; if(uxn_eval(&u, PAGE_PROGRAM)) { - for(; i < argc; i++) { - char *p = argv[i]; - while(*p) console_input(&u, *p++, CONSOLE_ARG); - console_input(&u, '\n', i == argc - 1 ? CONSOLE_END : CONSOLE_EOA); - } - while(!u.dev[0x0f]) { - int c = fgetc(stdin); - if(c == EOF) break; - console_input(&u, (Uint8)c, CONSOLE_STD); - } + console_listen(&u, i, argc, argv); + emu_run(&u); } - free(u.ram); - return u.dev[0x0f] & 0x7f; + return emu_end(&u); }