diff --git a/build.sh b/build.sh index 28c2576..9cd0c1f 100755 --- a/build.sh +++ b/build.sh @@ -22,4 +22,4 @@ fi echo "Done." # echo "Running.." -# uxnasm etc/repl.tal bin/repl.rom && bin/uxn11 bin/repl.rom +bin/uxn11 ~/roms/left.rom diff --git a/src/uxn.c b/src/uxn.c index 13cdae0..8f4a74d 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -22,9 +22,8 @@ WITH REGARD TO THIS SOFTWARE. #define POKE(x, y) { if(bs) { u->ram[(x)] = (y) >> 8; u->ram[(x) + 1] = (y); } else { u->ram[(x)] = y; } } #define PEEK16(o, x) { o = (u->ram[(x)] << 8) + u->ram[(x) + 1]; } #define PEEK(o, x) { if(bs) { PEEK16(o, x) } else { o = u->ram[(x)]; } } -#define DEVR(o, d, x) { dev = (d); o = dev->dei(dev, (x) & 0x0f); if(bs) { o = (o << 8) + dev->dei(dev, ((x) + 1) & 0x0f); } } -#define DEVW8(x, y) { dev->dat[(x) & 0xf] = y; dev->deo(dev, (x) & 0x0f); } -#define DEVW(d, x, y) { dev = (d); if(bs) { DEVW8((x), (y) >> 8); DEVW8((x) + 1, (y)); } else { DEVW8((x), (y)) } } +#define DEVR(o, x) { o = u->dei(u, x); if (bs) o = (o << 8) + u->dei(u, ((x) + 1) & 0xFF); } +#define DEVW(x, y) { if (bs) { u->deo(u, (x), (y) >> 8); u->deo(u, ((x) + 1) & 0xFF, (y)); } else { u->deo(u, x, (y)); } } #define WARP(x) { if(bs) pc = (x); else pc += (Sint8)(x); } int @@ -78,8 +77,8 @@ uxn_eval(Uxn *u, Uint16 pc) case 0x13: /* STR */ POP8(a) POP(b) c = pc + (Sint8)a; POKE(c, b) break; case 0x14: /* LDA */ POP16(a) PEEK(b, a) PUSH(src, b) break; case 0x15: /* STA */ POP16(a) POP(b) POKE(a, b) break; - case 0x16: /* DEI */ POP8(a) DEVR(b, &u->dev[a >> 4], a) PUSH(src, b) break; - case 0x17: /* DEO */ POP8(a) POP(b) DEVW(&u->dev[a >> 4], a, b) break; + case 0x16: /* DEI */ POP8(a) DEVR(b, a) PUSH(src, b) break; + case 0x17: /* DEO */ POP8(a) POP(b) DEVW(a, b) break; /* Arithmetic */ case 0x18: /* ADD */ POP(a) POP(b) PUSH(src, b + a) break; case 0x19: /* SUB */ POP(a) POP(b) PUSH(src, b - a) break; @@ -112,6 +111,7 @@ uxn_boot(Uxn *u, Uint8 *ram) u->ram = ram; u->wst = (Stack*)(ram + 0x10000); u->rst = (Stack*)(ram + 0x10100); + u->dev2 = (Uint8*)(ram + 0x10200); return 1; } diff --git a/src/uxn.h b/src/uxn.h index c1c5645..bb41e23 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -37,8 +37,10 @@ typedef struct Device { } Device; typedef struct Uxn { - Uint8 *ram; + Uint8 *ram, *dev2; Stack *wst, *rst; + Uint8 (*dei)(struct Uxn *u, Uint8 address); + void (*deo)(struct Uxn *u, Uint8 address, Uint8 value); Device dev[16]; } Uxn; diff --git a/src/uxn11.c b/src/uxn11.c index 443df5c..71b7db9 100644 --- a/src/uxn11.c +++ b/src/uxn11.c @@ -59,16 +59,32 @@ console_deo(Device *d, Uint8 port) } static Uint8 -nil_dei(Device *d, Uint8 port) +uxn11_dei(struct Uxn *u, Uint8 addr) { - return d->dat[port]; + Uint8 p = addr & 0x0f; + Device *d = &u->dev[addr >> 4]; + switch(addr & 0xf0) { + case 0x20: screen_dei(d, p); break; + case 0xa0: file_dei(d, p); break; + case 0xb0: file_dei(d, p); break; + case 0xc0: datetime_dei(d, p); break; + } + return d->dat[p]; } static void -nil_deo(Device *d, Uint8 port) +uxn11_deo(Uxn *u, Uint8 addr, Uint8 v) { - (void)d; - (void)port; + Uint8 p = addr & 0x0f; + Device *d = &u->dev[addr >> 4]; + d->dat[p] = v; + switch(addr & 0xf0) { + case 0x00: system_deo(d, p); break; + case 0x10: console_deo(d, p); break; + case 0x20: screen_deo(d, p); break; + case 0xa0: file_deo(d, p); break; + case 0xb0: file_deo(d, p); break; + } } static void @@ -160,22 +176,8 @@ start(Uxn *u, char *rom) if(!load_rom(u, rom)) return error("Load", "Failed"); fprintf(stderr, "Loaded %s\n", rom); - /* system */ uxn_port(u, 0x0, nil_dei, system_deo); - /* console */ uxn_port(u, 0x1, nil_dei, console_deo); - /* screen */ devscreen = uxn_port(u, 0x2, screen_dei, screen_deo); - /* empty */ uxn_port(u, 0x3, nil_dei, nil_deo); - /* empty */ uxn_port(u, 0x4, nil_dei, nil_deo); - /* empty */ uxn_port(u, 0x5, nil_dei, nil_deo); - /* empty */ uxn_port(u, 0x6, nil_dei, nil_deo); - /* empty */ 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); - /* file0 */ uxn_port(u, 0xa, file_dei, file_deo); - /* file1 */ uxn_port(u, 0xb, file_dei, file_deo); - /* datetime */ uxn_port(u, 0xc, datetime_dei, nil_deo); - /* empty */ uxn_port(u, 0xd, nil_dei, nil_deo); - /* reserved */ uxn_port(u, 0xe, nil_dei, nil_deo); - /* reserved */ uxn_port(u, 0xf, nil_dei, nil_deo); + u->dei = uxn11_dei; + u->deo = uxn11_deo; screen_resize(&uxn_screen, WIDTH, HEIGHT); if(!uxn_eval(u, PAGE_PROGRAM)) return error("Boot", "Failed to start rom.");