diff --git a/src/main.c b/src/main.c index e0b3445..2c7fe03 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,8 @@ #include "shorthand.h" #include "ppu.c" -#include "uxn-fast.c" +#include "uxn/src/devices/system.c" +#include "uxn/src/uxn.c" #define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) @@ -18,7 +19,6 @@ static Uxn u; static Device *devscreen; static Device *devctrl; static Device *devmouse; -static Device *devaudio; typedef struct timespec Time; @@ -142,168 +142,168 @@ poll_input(void) { void handle_keyboard(void) { - // Find mod keys. - bool shift_mod = false; - // bool ctrl_mod = false; - // bool alt_mod = false; - // bool meta_mod = false; - for (size_t i = 0; i < sizeof(in.map); i++) { - for (size_t j = 0; j < 8; j++) { - char key = in.map[i] & (1 << j); - if (key) { - char key_code = i * 8 + j; - switch (key_code) { - case KEY_LEFTSHIFT: - case KEY_RIGHTSHIFT: { shift_mod = true; } break; - // case KEY_LEFTCTRL: - // case KEY_RIGHTCTRL: { ctrl_mod = true; } break; - // case KEY_LEFTALT: - // case KEY_RIGHTALT: { alt_mod = true; } break; - // case KEY_LEFTMETA: - // case KEY_RIGHTMETA: { meta_mod = true; } break; - default: break; - } - } - } - } + // // Find mod keys. + // bool shift_mod = false; + // // bool ctrl_mod = false; + // // bool alt_mod = false; + // // bool meta_mod = false; + // for (size_t i = 0; i < sizeof(in.map); i++) { + // for (size_t j = 0; j < 8; j++) { + // char key = in.map[i] & (1 << j); + // if (key) { + // char key_code = i * 8 + j; + // switch (key_code) { + // case KEY_LEFTSHIFT: + // case KEY_RIGHTSHIFT: { shift_mod = true; } break; + // // case KEY_LEFTCTRL: + // // case KEY_RIGHTCTRL: { ctrl_mod = true; } break; + // // case KEY_LEFTALT: + // // case KEY_RIGHTALT: { alt_mod = true; } break; + // // case KEY_LEFTMETA: + // // case KEY_RIGHTMETA: { meta_mod = true; } break; + // default: break; + // } + // } + // } + // } - // Handle normal keys. - u8 controller_now = 0; - for (size_t i = 0; i < sizeof(in.map); i++) { - for (size_t j = 0; j < 8; j++) { - char key = in.map[i] & (1 << j); - if (key) { - char key_code = i * 8 + j; - // Normal keys. - u8 rune = '\0'; - switch (key_code) { - case KEY_KP1: - case KEY_1: { rune = shift_mod ? '!' : '1'; } break; - case KEY_KP2: - case KEY_2: { rune = shift_mod ? '@' : '2'; } break; - case KEY_KP3: - case KEY_3: { rune = shift_mod ? '#' : '3'; } break; - case KEY_KP4: - case KEY_4: { rune = shift_mod ? '$' : '4'; } break; - case KEY_KP5: - case KEY_5: { rune = shift_mod ? '%' : '5'; } break; - case KEY_KP6: - case KEY_6: { rune = shift_mod ? '^' : '6'; } break; - case KEY_KP7: - case KEY_7: { rune = shift_mod ? '&' : '7'; } break; - case KEY_KP8: - case KEY_8: { rune = shift_mod ? '*' : '8'; } break; - case KEY_KP9: - case KEY_9: { rune = shift_mod ? '(' : '9'; } break; - case KEY_KP0: - case KEY_0: { rune = shift_mod ? ')' : '0'; } break; - case KEY_KPMINUS: - case KEY_MINUS: { rune = shift_mod ? '_' : '-'; } break; - case KEY_KPEQUAL: - case KEY_EQUAL: { rune = shift_mod ? '+' : '+'; } break; - case KEY_Q: { rune = shift_mod ? 'Q' : 'q'; } break; - case KEY_W: { rune = shift_mod ? 'W' : 'w'; } break; - case KEY_E: { rune = shift_mod ? 'E' : 'e'; } break; - case KEY_R: { rune = shift_mod ? 'T' : 't'; } break; - case KEY_T: { rune = shift_mod ? 'T' : 't'; } break; - case KEY_Y: { rune = shift_mod ? 'Y' : 'y'; } break; - case KEY_U: { rune = shift_mod ? 'U' : 'u'; } break; - case KEY_I: { rune = shift_mod ? 'I' : 'i'; } break; - case KEY_O: { rune = shift_mod ? 'O' : 'o'; } break; - case KEY_P: { rune = shift_mod ? 'P' : 'p'; } break; - case KEY_LEFTBRACE: { rune = shift_mod ? '{' : '['; } break; - case KEY_RIGHTBRACE: { rune = shift_mod ? '}' : ']'; } break; - case KEY_A: { rune = shift_mod ? 'A' : 'a'; } break; - case KEY_S: { rune = shift_mod ? 'S' : 's'; } break; - case KEY_D: { rune = shift_mod ? 'D' : 'd'; } break; - case KEY_F: { rune = shift_mod ? 'F' : 'f'; } break; - case KEY_G: { rune = shift_mod ? 'G' : 'g'; } break; - case KEY_H: { rune = shift_mod ? 'H' : 'h'; } break; - case KEY_J: { rune = shift_mod ? 'J' : 'j'; } break; - case KEY_K: { rune = shift_mod ? 'K' : 'k'; } break; - case KEY_L: { rune = shift_mod ? 'L' : 'l'; } break; - case KEY_SEMICOLON: { rune = shift_mod ? ':' : ';'; } break; - case KEY_APOSTROPHE: { rune = shift_mod ? '"' : '\''; } break; - case KEY_GRAVE: { rune = shift_mod ? '~' : '`'; } break; - case KEY_BACKSLASH: { rune = shift_mod ? '|' : '\\'; } break; - case KEY_Z: { rune = shift_mod ? 'Z' : 'z'; } break; - case KEY_X: { rune = shift_mod ? 'X' : 'x'; } break; - case KEY_C: { rune = shift_mod ? 'C' : 'c'; } break; - case KEY_V: { rune = shift_mod ? 'V' : 'v'; } break; - case KEY_B: { rune = shift_mod ? 'B' : 'b'; } break; - case KEY_N: { rune = shift_mod ? 'N' : 'n'; } break; - case KEY_M: { rune = shift_mod ? 'M' : 'm'; } break; - case KEY_COMMA: { rune = shift_mod ? '<' : ','; } break; - case KEY_DOT: { rune = shift_mod ? '>' : '.'; } break; - case KEY_KPSLASH: - case KEY_SLASH: { rune = shift_mod ? '?' : '/'; } break; - case KEY_KPASTERISK: { rune = '*'; } break; - case KEY_KPPLUS: { rune = '+'; } break; - case KEY_KPCOMMA: { rune = '.'; } break; - case KEY_SPACE: { rune = ' '; } break; - case KEY_TAB: { rune = '\t'; } break; - case KEY_ESC: { rune = 0x1b; } break; - case KEY_BACKSPACE: { rune = 0x08; } break; - case KEY_ENTER: - case KEY_KPENTER: { rune = 0x0d; } break; - default: break; - } - if (rune) { - devctrl->dat[3] = rune; - uxn_eval(&u, mempeek16(devctrl->dat, 0)); - devctrl->dat[3] = 0; - continue; - } + // // Handle normal keys. + // u8 controller_now = 0; + // for (size_t i = 0; i < sizeof(in.map); i++) { + // for (size_t j = 0; j < 8; j++) { + // char key = in.map[i] & (1 << j); + // if (key) { + // char key_code = i * 8 + j; + // // Normal keys. + // u8 rune = '\0'; + // switch (key_code) { + // case KEY_KP1: + // case KEY_1: { rune = shift_mod ? '!' : '1'; } break; + // case KEY_KP2: + // case KEY_2: { rune = shift_mod ? '@' : '2'; } break; + // case KEY_KP3: + // case KEY_3: { rune = shift_mod ? '#' : '3'; } break; + // case KEY_KP4: + // case KEY_4: { rune = shift_mod ? '$' : '4'; } break; + // case KEY_KP5: + // case KEY_5: { rune = shift_mod ? '%' : '5'; } break; + // case KEY_KP6: + // case KEY_6: { rune = shift_mod ? '^' : '6'; } break; + // case KEY_KP7: + // case KEY_7: { rune = shift_mod ? '&' : '7'; } break; + // case KEY_KP8: + // case KEY_8: { rune = shift_mod ? '*' : '8'; } break; + // case KEY_KP9: + // case KEY_9: { rune = shift_mod ? '(' : '9'; } break; + // case KEY_KP0: + // case KEY_0: { rune = shift_mod ? ')' : '0'; } break; + // case KEY_KPMINUS: + // case KEY_MINUS: { rune = shift_mod ? '_' : '-'; } break; + // case KEY_KPEQUAL: + // case KEY_EQUAL: { rune = shift_mod ? '+' : '+'; } break; + // case KEY_Q: { rune = shift_mod ? 'Q' : 'q'; } break; + // case KEY_W: { rune = shift_mod ? 'W' : 'w'; } break; + // case KEY_E: { rune = shift_mod ? 'E' : 'e'; } break; + // case KEY_R: { rune = shift_mod ? 'T' : 't'; } break; + // case KEY_T: { rune = shift_mod ? 'T' : 't'; } break; + // case KEY_Y: { rune = shift_mod ? 'Y' : 'y'; } break; + // case KEY_U: { rune = shift_mod ? 'U' : 'u'; } break; + // case KEY_I: { rune = shift_mod ? 'I' : 'i'; } break; + // case KEY_O: { rune = shift_mod ? 'O' : 'o'; } break; + // case KEY_P: { rune = shift_mod ? 'P' : 'p'; } break; + // case KEY_LEFTBRACE: { rune = shift_mod ? '{' : '['; } break; + // case KEY_RIGHTBRACE: { rune = shift_mod ? '}' : ']'; } break; + // case KEY_A: { rune = shift_mod ? 'A' : 'a'; } break; + // case KEY_S: { rune = shift_mod ? 'S' : 's'; } break; + // case KEY_D: { rune = shift_mod ? 'D' : 'd'; } break; + // case KEY_F: { rune = shift_mod ? 'F' : 'f'; } break; + // case KEY_G: { rune = shift_mod ? 'G' : 'g'; } break; + // case KEY_H: { rune = shift_mod ? 'H' : 'h'; } break; + // case KEY_J: { rune = shift_mod ? 'J' : 'j'; } break; + // case KEY_K: { rune = shift_mod ? 'K' : 'k'; } break; + // case KEY_L: { rune = shift_mod ? 'L' : 'l'; } break; + // case KEY_SEMICOLON: { rune = shift_mod ? ':' : ';'; } break; + // case KEY_APOSTROPHE: { rune = shift_mod ? '"' : '\''; } break; + // case KEY_GRAVE: { rune = shift_mod ? '~' : '`'; } break; + // case KEY_BACKSLASH: { rune = shift_mod ? '|' : '\\'; } break; + // case KEY_Z: { rune = shift_mod ? 'Z' : 'z'; } break; + // case KEY_X: { rune = shift_mod ? 'X' : 'x'; } break; + // case KEY_C: { rune = shift_mod ? 'C' : 'c'; } break; + // case KEY_V: { rune = shift_mod ? 'V' : 'v'; } break; + // case KEY_B: { rune = shift_mod ? 'B' : 'b'; } break; + // case KEY_N: { rune = shift_mod ? 'N' : 'n'; } break; + // case KEY_M: { rune = shift_mod ? 'M' : 'm'; } break; + // case KEY_COMMA: { rune = shift_mod ? '<' : ','; } break; + // case KEY_DOT: { rune = shift_mod ? '>' : '.'; } break; + // case KEY_KPSLASH: + // case KEY_SLASH: { rune = shift_mod ? '?' : '/'; } break; + // case KEY_KPASTERISK: { rune = '*'; } break; + // case KEY_KPPLUS: { rune = '+'; } break; + // case KEY_KPCOMMA: { rune = '.'; } break; + // case KEY_SPACE: { rune = ' '; } break; + // case KEY_TAB: { rune = '\t'; } break; + // case KEY_ESC: { rune = 0x1b; } break; + // case KEY_BACKSPACE: { rune = 0x08; } break; + // case KEY_ENTER: + // case KEY_KPENTER: { rune = 0x0d; } break; + // default: break; + // } + // if (rune) { + // devctrl->dat[3] = rune; + // uxn_eval(&u, mempeek16(devctrl->dat, 0)); + // devctrl->dat[3] = 0; + // continue; + // } - // Special keys. - switch (key_code) { - case KEY_LEFTCTRL: { rune = 0x01; } break; - case KEY_LEFTALT: { rune = 0x02; } break; - case KEY_LEFTSHIFT: { rune = 0x04; } break; - case KEY_HOME: { rune = 0x08; } break; - case KEY_UP: { rune = 0x10; } break; - case KEY_DOWN: { rune = 0x20; } break; - case KEY_LEFT: { rune = 0x40; } break; - case KEY_RIGHT: { rune = 0x80; } break; - default: break; - } - if (rune) { - controller_now |= rune; - continue; - } - } - } - } + // // Special keys. + // switch (key_code) { + // case KEY_LEFTCTRL: { rune = 0x01; } break; + // case KEY_LEFTALT: { rune = 0x02; } break; + // case KEY_LEFTSHIFT: { rune = 0x04; } break; + // case KEY_HOME: { rune = 0x08; } break; + // case KEY_UP: { rune = 0x10; } break; + // case KEY_DOWN: { rune = 0x20; } break; + // case KEY_LEFT: { rune = 0x40; } break; + // case KEY_RIGHT: { rune = 0x80; } break; + // default: break; + // } + // if (rune) { + // controller_now |= rune; + // continue; + // } + // } + // } + // } - if (controller_now != in.controller) { - devctrl->dat[2] = controller_now; - uxn_eval(&u, mempeek16(devctrl->dat, 0)); - in.controller = controller_now; - } + // if (controller_now != in.controller) { + // devctrl->dat[2] = controller_now; + // uxn_eval(&u, mempeek16(devctrl->dat, 0)); + // in.controller = controller_now; + // } - // Reset input state. - devctrl->dat[3] = 0; - memset(in.map, 0, sizeof(in.map)); + // // Reset input state. + // devctrl->dat[3] = 0; + // memset(in.map, 0, sizeof(in.map)); } void handle_mouse(void) { - if (in.mouse.update) { - // Handle mouse keys. - devmouse->dat[6] = in.mouse.buttons; - if(in.mouse.buttons == 0x10 && (devmouse->dat[6] & 0x01)) { - devmouse->dat[7] = 0x01; - } - if(in.mouse.buttons == 0x01 && (devmouse->dat[6] & 0x10)) { - devmouse->dat[7] = 0x10; - } + // if (in.mouse.update) { + // // Handle mouse keys. + // devmouse->dat[6] = in.mouse.buttons; + // if(in.mouse.buttons == 0x10 && (devmouse->dat[6] & 0x01)) { + // devmouse->dat[7] = 0x01; + // } + // if(in.mouse.buttons == 0x01 && (devmouse->dat[6] & 0x10)) { + // devmouse->dat[7] = 0x10; + // } - // Handle mouse location. - mempoke16(devmouse->dat, 0x2, in.mouse.x); - mempoke16(devmouse->dat, 0x4, in.mouse.y); - uxn_eval(&u, mempeek16(devmouse->dat, 0)); - in.mouse.update = false; - } + // // Handle mouse location. + // mempoke16(devmouse->dat, 0x2, in.mouse.x); + // mempoke16(devmouse->dat, 0x4, in.mouse.y); + // uxn_eval(&u, mempeek16(devmouse->dat, 0)); + // in.mouse.update = false; + // } } void @@ -312,11 +312,24 @@ handle_input(void) { handle_mouse(); } -void -nil_talk(Device *d, u8 b0, u8 w) { +static Uint8 +nil_dei(Device *d, Uint8 port) { + return d->dat[port]; +} + +static void +nil_deo(Device *d, Uint8 port) { (void)d; - (void)b0; - (void)w; + (void)port; +} + +static void +console_deo(Device *d, Uint8 port) { + FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr : 0; + if(fd) { + fputc(d->dat[port], fd); + fflush(fd); + } } void @@ -338,8 +351,58 @@ console_talk(Device *d, u8 b0, u8 w) { // } } +Uint8 +screen_dei(Device *d, Uint8 port) { + switch(port) { + case 0x2: return screen_width >> 8; + case 0x3: return screen_width; + case 0x4: return screen_height >> 8; + case 0x5: return screen_height; + default: return d->dat[port]; + } +} + +void +screen_deo(Device *d, Uint8 port) { + switch(port) { + case 0xe: { + Uint16 x, y; + Uint8 layer = d->dat[0xe] & 0x40; + DEVPEEK16(x, 0x8); + DEVPEEK16(y, 0xa); + ppu_pixel(layer ? pixels_fg : pixels_bg, x, y, d->dat[0xe] & 0x3); + if(d->dat[0x6] & 0x01) DEVPOKE16(0x8, x + 1); /* auto x+1 */ + if(d->dat[0x6] & 0x02) DEVPOKE16(0xa, y + 1); /* auto y+1 */ + } break; + case 0xf: { + Uint16 x, y, addr; + Uint8 twobpp = !!(d->dat[0xf] & 0x80); + DEVPEEK16(x, 0x8); + DEVPEEK16(y, 0xa); + DEVPEEK16(addr, 0xc); + if(addr > 0xfff8 - twobpp * 8) { + return; + } + u8 *layer = (d->dat[0xf] & 0x40) ? pixels_fg : pixels_bg; + u8 color = d->dat[0xf] & 0xf; + u8 flipx = d->dat[0xf] & 0x10; + u8 flipy = d->dat[0xf] & 0x20; + u8 *sprite = &d->u->ram[addr]; + if (twobpp) { + ppu_2bpp(layer, x, y, sprite, color, flipx, flipy); + } else { + ppu_1bpp(layer, x, y, sprite, color, flipx, flipy); + } + if(d->dat[0x6] & 0x04) DEVPOKE16(0xc, addr + 8 + twobpp * 8); /* auto addr+length */ + if(d->dat[0x6] & 0x01) DEVPOKE16(0x8, x + 8); /* auto x+8 */ + if(d->dat[0x6] & 0x02) DEVPOKE16(0xa, y + 8); /* auto y+8 */ + } break; + } + reqdraw = 1; +} + static void -docolors(Device *d) { +screen_palette(Device *d) { for(size_t i = 0; i < 4; ++i) { u8 r = ((d->dat[0x8 + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; @@ -361,106 +424,12 @@ docolors(Device *d) { } void -system_talk(Device *d, u8 b0, u8 w) { - if(!w) { /* read */ - switch(b0) { - case 0x2: d->dat[0x2] = d->u->wst.ptr; break; - case 0x3: d->dat[0x3] = d->u->rst.ptr; break; - } - } else { /* write */ - switch(b0) { - case 0x2: d->u->wst.ptr = d->dat[0x2]; break; - case 0x3: d->u->rst.ptr = d->dat[0x3]; break; - case 0xf: d->u->ram.ptr = 0x0000; break; - } - if(b0 > 0x7 && b0 < 0xe) { - docolors(d); - } +system_deo_special(Device *d, Uint8 port) { + if(port > 0x7 && port < 0xe) { + screen_palette(d); } - (void)b0; } -void -screen_talk(Device *d, u8 b0, u8 w) { - if (w) { - switch (b0) { - case 0x1: { - d->vector = mempeek16(d->dat, 0x0); - } break; - case 0xe: { - u16 x = mempeek16(d->dat, 0x8); - u16 y = mempeek16(d->dat, 0xa); - u8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; - u8 *layer = d->dat[0xe] >> 4 & 0x1 ? pixels_fg : pixels_bg; - u8 mode = d->dat[0xe] >> 5; - u8 color = d->dat[0xf] & 0xf; - if(!mode) { - ppu_pixel(layer, x, y, d->dat[0xe] & 0x3); - } else if(mode-- & 0x1) { - u8 flipx = mode & 0x2; - u8 flipy = mode & 0x4; - ppu_1bpp(layer, x, y, addr, color, flipx, flipy); - } else { - u8 flipx = mode & 0x2; - u8 flipy = mode & 0x4; - ppu_2bpp(layer, x, y, addr, color, flipx, flipy); - } - if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 1); } - if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 1); } - } break; - case 0xf: { - u16 x = mempeek16(d->dat, 0x8); - u16 y = mempeek16(d->dat, 0xa); - u8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; - u8 *layer = d->dat[0xf] >> 6 & 0x1 ? pixels_fg : pixels_bg; - u8 color = d->dat[0xf] & 0xf; - u8 flipx = (d->dat[0xf] >> 0x4) & 0x1; - u8 flipy = (d->dat[0xf] >> 0x5) & 0x1; - if(d->dat[0xf] >> 0x7 & 0x1) { - ppu_2bpp(layer, x, y, addr, color, flipx, flipy); - if(d->dat[0x6] & 0x04) { - mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 16); - } - } else { - ppu_1bpp(layer, x, y, addr, color, flipx, flipy); - if(d->dat[0x6] & 0x04) { - mempoke16(d->dat, 0xc, mempeek16(d->dat, 0xc) + 8); - } - } - if(d->dat[0x6] & 0x01) { mempoke16(d->dat, 0x8, x + 8); } - if(d->dat[0x6] & 0x02) { mempoke16(d->dat, 0xa, y + 8); } - } break; - default: break; - } - } - reqdraw = 1; -} - -static void -audio_talk(Device *d, u8 b0, u8 w) { - // TODO: Implement... - (void)d; - (void)b0; - (void)w; -} - -void -datetime_talk(Device *d, u8 b0, u8 w) { - // TODO: Implement... - (void)d; - (void)b0; - (void)w; -} - -void -file_talk(Device *d, u8 b0, u8 w) { - // TODO: Implement... - (void)d; - (void)b0; - (void)w; -} - - void load_rom(char *file_name) { FILE *file = fopen(file_name, "r"); @@ -474,15 +443,16 @@ load_rom(char *file_name) { fseek(file, 0, SEEK_SET); char *uxn_rom = malloc(rom_size); fread(uxn_rom, 1, rom_size, file); - memcpy(u.ram.dat + PAGE_PROGRAM, uxn_rom, rom_size); + memcpy(u.ram + PAGE_PROGRAM, uxn_rom, rom_size); + fclose(file); free(uxn_rom); } void -init_uxn(char *file_name) { - // Clear UXN memory. - memset(&u, 0, sizeof(Uxn)); +init_uxn(Uxn *u, char *file_name) { + // Setup UXN memory. + uxn_boot(u, calloc(0x10000, sizeof(Uint8))); // Copy rom to VM. load_rom(file_name); @@ -494,24 +464,30 @@ init_uxn(char *file_name) { init_input(); // Prepare devices. - uxn_port(&u, 0x0, "system", system_talk); - uxn_port(&u, 0x1, "console", console_talk); - devscreen = uxn_port(&u, 0x2, "screen", screen_talk); - devaudio = uxn_port(&u, 0x3, "audio0", audio_talk); - uxn_port(&u, 0x4, "audio1", audio_talk); - uxn_port(&u, 0x5, "audio2", audio_talk); - uxn_port(&u, 0x6, "audio3", audio_talk); - uxn_port(&u, 0x7, "---", nil_talk); - devctrl = uxn_port(&u, 0x8, "controller", nil_talk); - devmouse = uxn_port(&u, 0x9, "mouse", nil_talk); - uxn_port(&u, 0xa, "file", file_talk); - uxn_port(&u, 0xb, "datetime", datetime_talk); - uxn_port(&u, 0xc, "---", nil_talk); - uxn_port(&u, 0xd, "---", nil_talk); - uxn_port(&u, 0xe, "---", nil_talk); - uxn_port(&u, 0xf, "---", nil_talk); - mempoke16(devscreen->dat, 2, screen_width); - mempoke16(devscreen->dat, 4, screen_height); + /* system */ uxn_port(u, 0x0, system_dei, system_deo); + /* console */ uxn_port(u, 0x1, nil_dei, console_deo); + /* screen */ devscreen = uxn_port(u, 0x2, screen_dei, screen_deo); + // TODO: + // /* audio0 */ devaudio0 = uxn_port(u, 0x3, audio_dei, audio_deo); + // /* audio1 */ uxn_port(u, 0x4, audio_dei, audio_deo); + // /* audio2 */ uxn_port(u, 0x5, audio_dei, audio_deo); + // /* audio3 */ uxn_port(u, 0x6, audio_dei, audio_deo); + /* audio0 */ uxn_port(u, 0x3, nil_dei, nil_deo); + /* audio1 */ uxn_port(u, 0x4, nil_dei, nil_deo); + /* audio2 */ uxn_port(u, 0x5, nil_dei, nil_deo); + /* audio3 */ uxn_port(u, 0x6, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0x7, nil_dei, nil_deo); + /* control */ devctrl = uxn_port(u, 0x8, nil_dei, nil_deo); + /* mouse */ devmouse = uxn_port(u, 0x9, nil_dei, nil_deo); + // TODO: + // /* file */ uxn_port(u, 0xa, nil_dei, file_deo); + // /* datetime */ uxn_port(u, 0xb, datetime_dei, nil_deo); + /* file */ uxn_port(u, 0xa, nil_dei, nil_deo); + /* datetime */ uxn_port(u, 0xb, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xc, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xd, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xe, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xf, nil_dei, nil_deo); } int @@ -521,10 +497,10 @@ main(int argc, char *argv[]) { fprintf(stderr, "error: no rom selected\n"); exit(EXIT_FAILURE); } - init_uxn(argv[1]); + init_uxn(&u, argv[1]); // Main loop. - uxn_eval(&u, 0x0100); + uxn_eval(&u, PAGE_PROGRAM); Time frame_time = time_now(); while (true) { poll_input(); @@ -533,7 +509,7 @@ main(int argc, char *argv[]) { handle_input(); // Echo input to standard output. - uxn_eval(&u, mempeek16(devscreen->dat, 0)); + uxn_eval(&u, GETVECTOR(devscreen)); // Blit ppu.pixels to the framebuffer. blit_framebuffer();