diff --git a/build.sh b/build.sh index c3c2177..6c96432 100755 --- a/build.sh +++ b/build.sh @@ -59,6 +59,8 @@ then clang-format -i src/devices/mouse.c clang-format -i src/devices/controller.h clang-format -i src/devices/controller.c + clang-format -i src/devices/datetime.h + clang-format -i src/devices/datetime.c clang-format -i src/uxnasm.c clang-format -i src/uxnemu.c clang-format -i src/uxncli.c @@ -97,8 +99,8 @@ fi echo "Building.." ${CC} ${CFLAGS} src/uxnasm.c -o bin/uxnasm -${CC} ${CFLAGS} ${CORE} src/devices/system.c src/devices/file.c src/devices/mouse.c src/devices/controller.c src/devices/screen.c src/devices/audio.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu -${CC} ${CFLAGS} ${CORE} src/devices/system.c src/devices/file.c src/uxncli.c -o bin/uxncli +${CC} ${CFLAGS} ${CORE} src/devices/system.c src/devices/file.c src/devices/datetime.c src/devices/mouse.c src/devices/controller.c src/devices/screen.c src/devices/audio.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu +${CC} ${CFLAGS} ${CORE} src/devices/system.c src/devices/file.c src/devices/datetime.c src/uxncli.c -o bin/uxncli if [ -d "$HOME/bin" ] then diff --git a/src/devices/datetime.c b/src/devices/datetime.c new file mode 100644 index 0000000..270c41e --- /dev/null +++ b/src/devices/datetime.c @@ -0,0 +1,40 @@ +#include + +#include "../uxn.h" +#include "datetime.h" + +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 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 +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +Uint8 +datetime_dei(Device *d, Uint8 port) +{ + time_t seconds = time(NULL); + struct tm zt = {0}; + struct tm *t = localtime(&seconds); + if(t == NULL) + t = &zt; + switch(port) { + case 0x0: return (t->tm_year + 1900) >> 8; + case 0x1: return (t->tm_year + 1900); + case 0x2: return t->tm_mon; + case 0x3: return t->tm_mday; + case 0x4: return t->tm_hour; + case 0x5: return t->tm_min; + case 0x6: return t->tm_sec; + case 0x7: return t->tm_wday; + case 0x8: return t->tm_yday >> 8; + case 0x9: return t->tm_yday; + case 0xa: return t->tm_isdst; + default: return d->dat[port]; + } +} \ No newline at end of file diff --git a/src/devices/datetime.h b/src/devices/datetime.h new file mode 100644 index 0000000..69edcde --- /dev/null +++ b/src/devices/datetime.h @@ -0,0 +1,13 @@ +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 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 +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +Uint8 datetime_dei(Device *d, Uint8 port); \ No newline at end of file diff --git a/src/devices/file.c b/src/devices/file.c index 6d3e598..b3b76f2 100644 --- a/src/devices/file.c +++ b/src/devices/file.c @@ -149,6 +149,16 @@ file_deo(Device *d, Uint8 port) case 0x1: DEVPEEK16(d->vector, 0x0); break; + case 0x5: + DEVPEEK16(a, 0x4); + DEVPEEK16(b, 0xa); + res = file_stat(&d->mem[a], b); + DEVPOKE16(0x2, res); + break; + case 0x6: + res = file_delete(); + DEVPOKE16(0x2, res); + break; case 0x9: DEVPEEK16(a, 0x8); res = file_init(&d->mem[a]); @@ -166,15 +176,5 @@ file_deo(Device *d, Uint8 port) res = file_write(&d->mem[a], b, d->dat[0x7]); DEVPOKE16(0x2, res); break; - case 0x5: - DEVPEEK16(a, 0x4); - DEVPEEK16(b, 0xa); - res = file_stat(&d->mem[a], b); - DEVPOKE16(0x2, res); - break; - case 0x6: - res = file_delete(); - DEVPOKE16(0x2, res); - break; } } \ No newline at end of file diff --git a/src/uxn.c b/src/uxn.c index 4cc92fd..0131a46 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -122,10 +122,11 @@ uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devpage, Stack *wst, Stack *rst) } Device * -uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *d, Uint8 port), void (*deofn)(Device *d, Uint8 port)) +uxn_port(Uxn *u, Uint8 id, Uint16 mask, Uint8 (*deifn)(Device *d, Uint8 port), void (*deofn)(Device *d, Uint8 port)) { Device *d = &u->dev[id]; d->u = u; + d->mask = mask; d->mem = u->ram; d->dei = deifn; d->deo = deofn; diff --git a/src/uxn.h b/src/uxn.h index 797b414..8b2d0fe 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -37,7 +37,7 @@ typedef struct { typedef struct Device { struct Uxn *u; Uint8 *dat, *mem; - Uint16 vector; + Uint16 vector, mask; Uint8 (*dei)(struct Device *d, Uint8); void (*deo)(struct Device *d, Uint8); } Device; @@ -51,4 +51,4 @@ typedef struct Uxn { int uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devpage, Stack *wst, Stack *rst); int uxn_eval(Uxn *u, Uint16 pc); int uxn_halt(Uxn *u, Uint8 error, Uint16 addr); -Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8)); +Device *uxn_port(Uxn *u, Uint8 id, Uint16 mask, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8)); diff --git a/src/uxncli.c b/src/uxncli.c index ff82b69..d95585f 100644 --- a/src/uxncli.c +++ b/src/uxncli.c @@ -2,9 +2,11 @@ #include #include #include + #include "uxn.h" #include "devices/system.h" #include "devices/file.h" +#include "devices/datetime.h" /* Copyright (c) 2021 Devine Lu Linvega @@ -64,30 +66,6 @@ console_deo(Device *d, Uint8 port) write(port - 0x7, (char *)&d->dat[port], 1); } -static Uint8 -datetime_dei(Device *d, Uint8 port) -{ - time_t seconds = time(NULL); - struct tm zt = {0}; - struct tm *t = localtime(&seconds); - if(t == NULL) - t = &zt; - switch(port) { - case 0x0: return (t->tm_year + 1900) >> 8; - case 0x1: return (t->tm_year + 1900); - case 0x2: return t->tm_mon; - case 0x3: return t->tm_mday; - case 0x4: return t->tm_hour; - case 0x5: return t->tm_min; - case 0x6: return t->tm_sec; - case 0x7: return t->tm_wday; - case 0x8: return t->tm_yday >> 8; - case 0x9: return t->tm_yday; - case 0xa: return t->tm_isdst; - default: return d->dat[port]; - } -} - static Uint8 nil_dei(Device *d, Uint8 port) { @@ -146,22 +124,22 @@ main(int argc, char **argv) if(!uxn_boot(&u, memory, shadow + PAGE_DEV, (Stack *)(shadow + PAGE_WST), (Stack *)(shadow + PAGE_RST))) return error("Boot", "Failed"); - /* system */ devsystem = uxn_port(&u, 0x0, system_dei, system_deo); - /* console */ devconsole = uxn_port(&u, 0x1, nil_dei, console_deo); - /* empty */ uxn_port(&u, 0x2, nil_dei, nil_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); - /* empty */ uxn_port(&u, 0x8, nil_dei, nil_deo); - /* empty */ uxn_port(&u, 0x9, nil_dei, nil_deo); - /* file */ uxn_port(&u, 0xa, nil_dei, file_deo); - /* datetime */ uxn_port(&u, 0xb, datetime_dei, nil_deo); - /* empty */ uxn_port(&u, 0xc, nil_dei, nil_deo); - /* empty */ uxn_port(&u, 0xd, nil_dei, nil_deo); - /* empty */ uxn_port(&u, 0xe, nil_dei, nil_deo); - /* empty */ uxn_port(&u, 0xf, nil_dei, nil_deo); + /* system */ devsystem = uxn_port(&u, 0x0, 0xffff, system_dei, system_deo); + /* console */ devconsole = uxn_port(&u, 0x1, 0xffff, nil_dei, console_deo); + /* empty */ uxn_port(&u, 0x2, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x3, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x4, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x5, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x6, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x7, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x8, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0x9, 0xffff, nil_dei, nil_deo); + /* file */ uxn_port(&u, 0xa, 0xffff, nil_dei, file_deo); + /* datetime */ uxn_port(&u, 0xb, 0xffff, datetime_dei, nil_deo); + /* empty */ uxn_port(&u, 0xc, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0xd, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0xe, 0xffff, nil_dei, nil_deo); + /* empty */ uxn_port(&u, 0xf, 0xffff, nil_dei, nil_deo); for(i = 1; i < argc; i++) { if(!loaded++) { diff --git a/src/uxnemu.c b/src/uxnemu.c index 34e35a9..143828f 100644 --- a/src/uxnemu.c +++ b/src/uxnemu.c @@ -14,6 +14,7 @@ #include "devices/file.h" #include "devices/controller.h" #include "devices/mouse.h" +#include "devices/datetime.h" #pragma GCC diagnostic pop #pragma clang diagnostic pop @@ -218,30 +219,6 @@ audio_deo(Device *d, Uint8 port) } } -static Uint8 -datetime_dei(Device *d, Uint8 port) -{ - time_t seconds = time(NULL); - struct tm zt = {0}; - struct tm *t = localtime(&seconds); - if(t == NULL) - t = &zt; - switch(port) { - case 0x0: return (t->tm_year + 1900) >> 8; - case 0x1: return (t->tm_year + 1900); - case 0x2: return t->tm_mon; - case 0x3: return t->tm_mday; - case 0x4: return t->tm_hour; - case 0x5: return t->tm_min; - case 0x6: return t->tm_sec; - case 0x7: return t->tm_wday; - case 0x8: return t->tm_yday >> 8; - case 0x9: return t->tm_yday; - case 0xa: return t->tm_isdst; - default: return d->dat[port]; - } -} - static Uint8 nil_dei(Device *d, Uint8 port) { @@ -287,27 +264,27 @@ start(Uxn *u, char *rom) if(!load(u, rom)) return error("Boot", "Failed to load rom."); - /* system */ devsystem = uxn_port(u, 0x0, system_dei, system_deo); - /* console */ devconsole = uxn_port(u, 0x1, nil_dei, console_deo); - /* screen */ devscreen = uxn_port(u, 0x2, screen_dei, screen_deo); - /* 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); - /* 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); - /* file */ uxn_port(u, 0xa, nil_dei, file_deo); - /* datetime */ uxn_port(u, 0xb, datetime_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); + /* system */ devsystem = uxn_port(u, 0x0, 0xffff, system_dei, system_deo); + /* console */ devconsole = uxn_port(u, 0x1, 0xffff, nil_dei, console_deo); + /* screen */ devscreen = uxn_port(u, 0x2, 0xffff, screen_dei, screen_deo); + /* audio0 */ devaudio0 = uxn_port(u, 0x3, 0xffff, audio_dei, audio_deo); + /* audio1 */ uxn_port(u, 0x4, 0xffff, audio_dei, audio_deo); + /* audio2 */ uxn_port(u, 0x5, 0xffff, audio_dei, audio_deo); + /* audio3 */ uxn_port(u, 0x6, 0xffff, audio_dei, audio_deo); + /* unused */ uxn_port(u, 0x7, 0xffff, nil_dei, nil_deo); + /* control */ devctrl = uxn_port(u, 0x8, 0xffff, nil_dei, nil_deo); + /* mouse */ devmouse = uxn_port(u, 0x9, 0xffff, nil_dei, nil_deo); + /* file */ uxn_port(u, 0xa, 0xffff, nil_dei, file_deo); + /* datetime */ uxn_port(u, 0xb, 0xffff, datetime_dei, nil_deo); + /* unused */ uxn_port(u, 0xc, 0xffff, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xd, 0xffff, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xe, 0xffff, nil_dei, nil_deo); + /* unused */ uxn_port(u, 0xf, 0xffff, nil_dei, nil_deo); /* Supervisor */ - uxn_port(&supervisor, 0x0, system_dei, system_deo); - uxn_port(&supervisor, 0x1, nil_dei, console_deo); - uxn_port(&supervisor, 0x2, screen_dei, screen_deo); + uxn_port(&supervisor, 0x0, 0xffff, system_dei, system_deo); + uxn_port(&supervisor, 0x1, 0xffff, nil_dei, console_deo); + uxn_port(&supervisor, 0x2, 0xffff, screen_dei, screen_deo); uxn_eval(&supervisor, PAGE_PROGRAM);