diff --git a/README.md b/README.md index 0f4de2f..f8f6162 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Uxn +# Uxn11 An emulator for the [Uxn stack-machine](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. diff --git a/build.sh b/build.sh index dc9a63c..c19e65d 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,12 @@ #!/bin/sh -e -clang-format -i src/uxn11.c -clang-format -i src/devices/* +if [ "${1}" = '--format' ]; +then + echo "Formatting.." + clang-format -i src/uxn11.c + clang-format -i src/devices/* +fi + echo "Cleaning.." rm -f ./bin/* @@ -9,7 +14,7 @@ rm -f ./bin/* echo "Building.." mkdir -p bin -if [ "${1}" = '--install' ]; +if [ "${1}" = '--install' ]; then echo "Installing.." gcc src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/devices/mouse.c src/devices/file.c src/devices/datetime.c src/uxn11.c -D_POSIX_C_SOURCE=199309L -DNDEBUG -Os -g0 -s -o bin/uxn11 -lX11 diff --git a/src/devices/file.c b/src/devices/file.c index 57579d3..36a1523 100644 --- a/src/devices/file.c +++ b/src/devices/file.c @@ -154,43 +154,43 @@ file_delete(UxnFile *c) /* IO */ void -file_deo(Uint8 id, Uint8 *ram, Device *d, Uint8 port) +file_deo(Uint8 id, Uint8 *ram, Uint8 *d, Uint8 port) { UxnFile *c = &uxn_file[id]; Uint16 addr, len, res; switch(port) { case 0x5: - DEVPEEK16(addr, 0x4); - DEVPEEK16(len, 0xa); + PEKDEV(addr, 0x4); + PEKDEV(len, 0xa); if(len > 0x10000 - addr) len = 0x10000 - addr; res = file_stat(c, &ram[addr], len); - DEVPOKE16(0x2, res); + POKDEV(0x2, res); break; case 0x6: res = file_delete(c); - DEVPOKE16(0x2, res); + POKDEV(0x2, res); break; case 0x9: - DEVPEEK16(addr, 0x8); + PEKDEV(addr, 0x8); res = file_init(c, (char *)&ram[addr], 0x10000 - addr); - DEVPOKE16(0x2, res); + POKDEV(0x2, res); break; case 0xd: - DEVPEEK16(addr, 0xc); - DEVPEEK16(len, 0xa); + PEKDEV(addr, 0xc); + PEKDEV(len, 0xa); if(len > 0x10000 - addr) len = 0x10000 - addr; res = file_read(c, &ram[addr], len); - DEVPOKE16(0x2, res); + POKDEV(0x2, res); break; case 0xf: - DEVPEEK16(addr, 0xe); - DEVPEEK16(len, 0xa); + PEKDEV(addr, 0xe); + PEKDEV(len, 0xa); if(len > 0x10000 - addr) len = 0x10000 - addr; - res = file_write(c, &ram[addr], len, d->dat[0x7]); - DEVPOKE16(0x2, res); + res = file_write(c, &ram[addr], len, d[0x7]); + POKDEV(0x2, res); break; } } diff --git a/src/devices/file.h b/src/devices/file.h index 1afa1ba..0cdb57a 100644 --- a/src/devices/file.h +++ b/src/devices/file.h @@ -13,6 +13,6 @@ WITH REGARD TO THIS SOFTWARE. #define POLYFILEY 2 #define DEV_FILE0 0xa -void file_deo(Uint8 id, Uint8 *ram, Device *d, Uint8 port); +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/uxn.c b/src/uxn.c index 6acb74c..6fcd39c 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -32,7 +32,7 @@ uxn_eval(Uxn *u, Uint16 pc) unsigned int a, b, c, j, k, bs, instr, errcode; Uint8 kptr, *sp; Stack *src, *dst; - if(!pc || u->dev[0].dat[0xf]) return 0; + if(!pc || u->dev[0x0f]) return 0; while((instr = u->ram[pc++])) { /* Return Mode */ if(instr & 0x40) { @@ -108,8 +108,8 @@ uxn_boot(Uxn *u, Uint8 *ram) for(i = 0; i < sizeof(*u); i++) cptr[i] = 0x00; u->ram = ram; - u->wst = (Stack*)(ram + 0x10000); - u->rst = (Stack*)(ram + 0x10100); - u->dpg = (Uint8*)(ram + 0x10200); + u->wst = (Stack *)(ram + 0x10000); + u->rst = (Stack *)(ram + 0x10100); + u->dev = (Uint8 *)(ram + 0x10200); return 1; } diff --git a/src/uxn.h b/src/uxn.h index 9516493..57459ca 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -19,10 +19,6 @@ typedef unsigned int Uint32; /* clang-format off */ -#define DEVPEEK16(o, x) { (o) = (d->dat[(x)] << 8) + d->dat[(x) + 1]; } -#define DEVPOKE16(x, y) { d->dat[(x)] = (y) >> 8; d->dat[(x) + 1] = (y); } -#define GETVECTOR(d) ((d)->dat[0] << 8 | (d)->dat[1]) - #define GETVEC(d) ((d)[0] << 8 | (d)[1]) #define POKDEV(x, y) { d[(x)] = (y) >> 8; d[(x) + 1] = (y); } #define PEKDEV(o, x) { (o) = (d[(x)] << 8) + d[(x) + 1]; } @@ -30,19 +26,14 @@ typedef unsigned int Uint32; /* clang-format on */ typedef struct { - Uint8 dat[255],ptr; + Uint8 dat[255], ptr; } Stack; -typedef struct Device { - Uint8 dat[16]; -} Device; - typedef struct Uxn { - Uint8 *ram, *dpg; + Uint8 *ram, *dev; Stack *wst, *rst; Uint8 (*dei)(struct Uxn *u, Uint8 address); void (*deo)(struct Uxn *u, Uint8 address, Uint8 value); - Device dev[16]; } Uxn; int uxn_boot(Uxn *u, Uint8 *ram); diff --git a/src/uxn11.c b/src/uxn11.c index b013066..caa88ee 100644 --- a/src/uxn11.c +++ b/src/uxn11.c @@ -40,8 +40,8 @@ system_deo_special(Uint8 *d, Uint8 port) static int console_input(Uxn *u, char c) { - Uint8 *d = u->dev[1].dat; - d[0x2] = c; + Uint8 *d = &u->dev[0x10]; + d[0x02] = c; return uxn_eval(u, GETVEC(d)); } @@ -59,33 +59,27 @@ console_deo(Uint8 *d, Uint8 port) static Uint8 uxn11_dei(struct Uxn *u, Uint8 addr) { - Uint8 p = addr & 0x0f; - Device *d = &u->dev[addr >> 4]; - switch(addr & 0xf0) { - case 0x20: return screen_dei(d->dat, p); break; - case 0x80: return u->dpg[0x80 + p]; break; - case 0x90: return u->dpg[0x90 + p]; break; - case 0xa0: return file_dei(0, d->dat, p); break; - case 0xb0: return file_dei(1, d->dat, p); break; - case 0xc0: return datetime_dei(d->dat, p); break; + Uint8 p = addr & 0x0f, d = addr & 0xf0; + switch(d) { + case 0x20: return screen_dei(&u->dev[d], p); break; + case 0xa0: return file_dei(0, &u->dev[d], p); break; + case 0xb0: return file_dei(1, &u->dev[d], p); break; + case 0xc0: return datetime_dei(&u->dev[d], p); break; } - return d->dat[p]; + return u->dev[addr]; } static void uxn11_deo(Uxn *u, Uint8 addr, Uint8 v) { - Uint8 p = addr & 0x0f; - Device *d = &u->dev[addr >> 4]; - d->dat[p] = v; - switch(addr & 0xf0) { - case 0x00: system_deo(u, d->dat, p); break; - case 0x10: console_deo(d->dat, p); break; - case 0x20: screen_deo(u->ram, d->dat, p); break; - case 0x80: u->dpg[0x80 + p] = v; break; - case 0x90: u->dpg[0x90 + p] = v; break; - case 0xa0: file_deo(0, u->ram, d, p); break; - case 0xb0: file_deo(1, u->ram, d, p); break; + Uint8 p = addr & 0x0f, d = addr & 0xf0; + u->dev[addr] = v; + switch(d) { + case 0x00: system_deo(u, &u->dev[d], p); break; + case 0x10: console_deo(&u->dev[d], p); break; + case 0x20: screen_deo(u->ram, &u->dev[d], p); break; + case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; + case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; } } @@ -146,26 +140,26 @@ processEvent(Uxn *u) KeySym sym; char buf[7]; XLookupString((XKeyPressedEvent *)&ev, buf, 7, &sym, 0); - controller_down(u, &u->dpg[0x80], get_button(sym)); - controller_key(u, &u->dpg[0x80], sym < 0x80 ? sym : buf[0]); + controller_down(u, &u->dev[0x80], get_button(sym)); + controller_key(u, &u->dev[0x80], sym < 0x80 ? sym : buf[0]); } break; case KeyRelease: { KeySym sym; char buf[7]; XLookupString((XKeyPressedEvent *)&ev, buf, 7, &sym, 0); - controller_up(u, &u->dpg[0x80], get_button(sym)); + controller_up(u, &u->dev[0x80], get_button(sym)); } break; case ButtonPress: { XButtonPressedEvent *e = (XButtonPressedEvent *)&ev; - mouse_down(u, &u->dpg[0x90], 0x1 << (e->button - 1)); + mouse_down(u, &u->dev[0x90], 0x1 << (e->button - 1)); } break; case ButtonRelease: { XButtonPressedEvent *e = (XButtonPressedEvent *)&ev; - mouse_up(u, &u->dpg[0x90], 0x1 << (e->button - 1)); + mouse_up(u, &u->dev[0x90], 0x1 << (e->button - 1)); } break; case MotionNotify: { XMotionEvent *e = (XMotionEvent *)&ev; - mouse_pos(u, &u->dpg[0x90], e->x, e->y); + mouse_pos(u, &u->dev[0x90], e->x, e->y); } break; } } @@ -235,8 +229,8 @@ main(int argc, char **argv) while(XPending(display)) processEvent(&u); if(poll(&fds[1], 1, 0)) { - read(fds[1].fd, expirations, 8); /* Indicate we handled the timer */ - uxn_eval(&u, GETVEC(u.dev[0x2].dat)); /* Call the vector once, even if the timer fired multiple times */ + read(fds[1].fd, expirations, 8); /* Indicate we handled the timer */ + uxn_eval(&u, GETVEC(&u.dev[0x20])); /* Call the vector once, even if the timer fired multiple times */ } if(uxn_screen.fg.changed || uxn_screen.bg.changed) redraw(); diff --git a/src/uxncli.c b/src/uxncli.c index ee591cb..e20d849 100644 --- a/src/uxncli.c +++ b/src/uxncli.c @@ -25,7 +25,7 @@ error(char *msg, const char *err) } void -system_deo_special(Device *d, Uint8 port) +system_deo_special(Uint8 *d, Uint8 port) { (void)d; (void)port;