| ... | ... |
@@ -30,11 +30,11 @@ See etc/mkuxn-fast.moon for instructions. |
| 30 | 30 |
/* clang-format off */ |
| 31 | 31 |
static void poke8(Uint8 *m, Uint16 a, Uint8 b) { m[a] = b; }
|
| 32 | 32 |
static Uint8 peek8(Uint8 *m, Uint16 a) { return m[a]; }
|
| 33 |
-static int devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; return d->talk(d, a & 0x0f, 1); }
|
|
| 34 |
-static Uint8 devr8(Device *d, Uint8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; }
|
|
| 33 |
+static void devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; d->deo(d, a & 0x0f); }
|
|
| 34 |
+static Uint8 devr8(Device *d, Uint8 a) { return d->dei(d, a & 0x0f); }
|
|
| 35 | 35 |
void poke16(Uint8 *m, Uint16 a, Uint16 b) { poke8(m, a, b >> 8); poke8(m, a + 1, b); }
|
| 36 | 36 |
Uint16 peek16(Uint8 *m, Uint16 a) { return (peek8(m, a) << 8) + peek8(m, a + 1); }
|
| 37 |
-static int devw16(Device *d, Uint8 a, Uint16 b) { return devw8(d, a, b >> 8) && devw8(d, a + 1, b); }
|
|
| 37 |
+static void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); }
|
|
| 38 | 38 |
|
| 39 | 39 |
/* clang-format on */ |
| 40 | 40 |
|
| ... | ... |
@@ -366,8 +366,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 366 | 366 |
case 0x17: /* DEO */ |
| 367 | 367 |
{
|
| 368 | 368 |
Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; |
| 369 |
- if(!devw8(&u->dev[a >> 4], a, b)) |
|
| 370 |
- return 1; |
|
| 369 |
+ devw8(&u->dev[a >> 4], a, b); |
|
| 371 | 370 |
#ifndef NO_STACK_CHECKS |
| 372 | 371 |
if(__builtin_expect(u->wst.ptr < 2, 0)) {
|
| 373 | 372 |
u->wst.error = 1; |
| ... | ... |
@@ -828,8 +827,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 828 | 827 |
{
|
| 829 | 828 |
Uint8 a = u->wst.dat[u->wst.ptr - 1]; |
| 830 | 829 |
Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); |
| 831 |
- if(!devw16(&u->dev[a >> 4], a, b)) |
|
| 832 |
- return 1; |
|
| 830 |
+ devw16(&u->dev[a >> 4], a, b); |
|
| 833 | 831 |
#ifndef NO_STACK_CHECKS |
| 834 | 832 |
if(__builtin_expect(u->wst.ptr < 3, 0)) {
|
| 835 | 833 |
u->wst.error = 1; |
| ... | ... |
@@ -1272,8 +1270,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 1272 | 1270 |
case 0x57: /* DEOr */ |
| 1273 | 1271 |
{
|
| 1274 | 1272 |
Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; |
| 1275 |
- if(!devw8(&u->dev[a >> 4], a, b)) |
|
| 1276 |
- return 1; |
|
| 1273 |
+ devw8(&u->dev[a >> 4], a, b); |
|
| 1277 | 1274 |
#ifndef NO_STACK_CHECKS |
| 1278 | 1275 |
if(__builtin_expect(u->rst.ptr < 2, 0)) {
|
| 1279 | 1276 |
u->rst.error = 1; |
| ... | ... |
@@ -1734,8 +1731,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 1734 | 1731 |
{
|
| 1735 | 1732 |
Uint8 a = u->rst.dat[u->rst.ptr - 1]; |
| 1736 | 1733 |
Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); |
| 1737 |
- if(!devw16(&u->dev[a >> 4], a, b)) |
|
| 1738 |
- return 1; |
|
| 1734 |
+ devw16(&u->dev[a >> 4], a, b); |
|
| 1739 | 1735 |
#ifndef NO_STACK_CHECKS |
| 1740 | 1736 |
if(__builtin_expect(u->rst.ptr < 3, 0)) {
|
| 1741 | 1737 |
u->rst.error = 1; |
| ... | ... |
@@ -2235,8 +2231,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 2235 | 2231 |
case 0x97: /* DEOk */ |
| 2236 | 2232 |
{
|
| 2237 | 2233 |
Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; |
| 2238 |
- if(!devw8(&u->dev[a >> 4], a, b)) |
|
| 2239 |
- return 1; |
|
| 2234 |
+ devw8(&u->dev[a >> 4], a, b); |
|
| 2240 | 2235 |
#ifndef NO_STACK_CHECKS |
| 2241 | 2236 |
if(__builtin_expect(u->wst.ptr < 2, 0)) {
|
| 2242 | 2237 |
u->wst.error = 1; |
| ... | ... |
@@ -2776,8 +2771,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 2776 | 2771 |
{
|
| 2777 | 2772 |
Uint8 a = u->wst.dat[u->wst.ptr - 1]; |
| 2778 | 2773 |
Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); |
| 2779 |
- if(!devw16(&u->dev[a >> 4], a, b)) |
|
| 2780 |
- return 1; |
|
| 2774 |
+ devw16(&u->dev[a >> 4], a, b); |
|
| 2781 | 2775 |
#ifndef NO_STACK_CHECKS |
| 2782 | 2776 |
if(__builtin_expect(u->wst.ptr < 3, 0)) {
|
| 2783 | 2777 |
u->wst.error = 1; |
| ... | ... |
@@ -3309,8 +3303,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 3309 | 3303 |
case 0xd7: /* DEOkr */ |
| 3310 | 3304 |
{
|
| 3311 | 3305 |
Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; |
| 3312 |
- if(!devw8(&u->dev[a >> 4], a, b)) |
|
| 3313 |
- return 1; |
|
| 3306 |
+ devw8(&u->dev[a >> 4], a, b); |
|
| 3314 | 3307 |
#ifndef NO_STACK_CHECKS |
| 3315 | 3308 |
if(__builtin_expect(u->rst.ptr < 2, 0)) {
|
| 3316 | 3309 |
u->rst.error = 1; |
| ... | ... |
@@ -3850,8 +3843,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 3850 | 3843 |
{
|
| 3851 | 3844 |
Uint8 a = u->rst.dat[u->rst.ptr - 1]; |
| 3852 | 3845 |
Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); |
| 3853 |
- if(!devw16(&u->dev[a >> 4], a, b)) |
|
| 3854 |
- return 1; |
|
| 3846 |
+ devw16(&u->dev[a >> 4], a, b); |
|
| 3855 | 3847 |
#ifndef NO_STACK_CHECKS |
| 3856 | 3848 |
if(__builtin_expect(u->rst.ptr < 3, 0)) {
|
| 3857 | 3849 |
u->rst.error = 1; |
| ... | ... |
@@ -4036,12 +4028,13 @@ uxn_boot(Uxn *u) |
| 4036 | 4028 |
} |
| 4037 | 4029 |
|
| 4038 | 4030 |
Device * |
| 4039 |
-uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *d, Uint8 b0, Uint8 w)) |
|
| 4031 |
+uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *d, Uint8 b0), void (*deofn)(Device *d, Uint8 b0)) |
|
| 4040 | 4032 |
{
|
| 4041 | 4033 |
Device *d = &u->dev[id]; |
| 4042 | 4034 |
d->addr = id * 0x10; |
| 4043 | 4035 |
d->u = u; |
| 4044 | 4036 |
d->mem = u->ram.dat; |
| 4045 |
- d->talk = talkfn; |
|
| 4037 |
+ d->dei = deifn; |
|
| 4038 |
+ d->deo = deofn; |
|
| 4046 | 4039 |
return d; |
| 4047 | 4040 |
} |
| ... | ... |
@@ -26,7 +26,7 @@ static Uint16 (*pop8)(Stack *s); |
| 26 | 26 |
static Uint16 (*pop)(Stack *s); |
| 27 | 27 |
static void (*poke)(Uint8 *m, Uint16 a, Uint16 b); |
| 28 | 28 |
static Uint16 (*peek)(Uint8 *m, Uint16 a); |
| 29 |
-static int (*devw)(Device *d, Uint8 a, Uint16 b); |
|
| 29 |
+static void (*devw)(Device *d, Uint8 a, Uint16 b); |
|
| 30 | 30 |
static Uint16 (*devr)(Device *d, Uint8 a); |
| 31 | 31 |
static void (*warp)(Uxn *u, Uint16 a); |
| 32 | 32 |
static void (*pull)(Uxn *u); |
| ... | ... |
@@ -36,8 +36,8 @@ static Uint16 pop8k(Stack *s) { if(s->kptr == 0) { s->error = 1; return 0; } ret
|
| 36 | 36 |
static Uint16 pop8d(Stack *s) { if(s->ptr == 0) { s->error = 1; return 0; } return s->dat[--s->ptr]; }
|
| 37 | 37 |
static void poke8(Uint8 *m, Uint16 a, Uint16 b) { m[a] = b; }
|
| 38 | 38 |
static Uint16 peek8(Uint8 *m, Uint16 a) { return m[a]; }
|
| 39 |
-static int devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; return d->talk(d, a & 0x0f, 1); }
|
|
| 40 |
-static Uint16 devr8(Device *d, Uint8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; }
|
|
| 39 |
+static void devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; d->deo(d, a & 0x0f); }
|
|
| 40 |
+static Uint16 devr8(Device *d, Uint8 a) { return d->dei(d, a & 0x0f); }
|
|
| 41 | 41 |
static void warp8(Uxn *u, Uint16 a){ u->ram.ptr += (Sint8)a; }
|
| 42 | 42 |
static void pull8(Uxn *u){ push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); }
|
| 43 | 43 |
/* short mode */ |
| ... | ... |
@@ -45,7 +45,7 @@ static void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
|
| 45 | 45 |
static Uint16 pop16(Stack *s) { Uint8 a = pop8(s), b = pop8(s); return a + (b << 8); }
|
| 46 | 46 |
void poke16(Uint8 *m, Uint16 a, Uint16 b) { poke8(m, a, b >> 8); poke8(m, a + 1, b); }
|
| 47 | 47 |
Uint16 peek16(Uint8 *m, Uint16 a) { return (peek8(m, a) << 8) + peek8(m, a + 1); }
|
| 48 |
-static int devw16(Device *d, Uint8 a, Uint16 b) { return devw8(d, a, b >> 8) && devw8(d, a + 1, b); }
|
|
| 48 |
+static void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); }
|
|
| 49 | 49 |
static Uint16 devr16(Device *d, Uint8 a) { return (devr8(d, a) << 8) + devr8(d, a + 1); }
|
| 50 | 50 |
static void warp16(Uxn *u, Uint16 a){ u->ram.ptr = a; }
|
| 51 | 51 |
static void pull16(Uxn *u){ push16(u->src, peek16(u->ram.dat, u->ram.ptr++)); u->ram.ptr++; }
|
| ... | ... |
@@ -116,7 +116,7 @@ uxn_eval(Uxn *u, Uint16 vec) |
| 116 | 116 |
case 0x14: /* LDA */ a = pop16(u->src); push(u->src, peek(u->ram.dat, a)); break; |
| 117 | 117 |
case 0x15: /* STA */ a = pop16(u->src); b = pop(u->src); poke(u->ram.dat, a, b); break; |
| 118 | 118 |
case 0x16: /* DEI */ a = pop8(u->src); push(u->src, devr(&u->dev[a >> 4], a)); break; |
| 119 |
- case 0x17: /* DEO */ a = pop8(u->src); b = pop(u->src); if (!devw(&u->dev[a >> 4], a, b)) return 1; break; |
|
| 119 |
+ case 0x17: /* DEO */ a = pop8(u->src); b = pop(u->src); devw(&u->dev[a >> 4], a, b); break; |
|
| 120 | 120 |
/* Arithmetic */ |
| 121 | 121 |
case 0x18: /* ADD */ a = pop(u->src), b = pop(u->src); push(u->src, b + a); break; |
| 122 | 122 |
case 0x19: /* SUB */ a = pop(u->src), b = pop(u->src); push(u->src, b - a); break; |
| ... | ... |
@@ -146,12 +146,13 @@ uxn_boot(Uxn *u) |
| 146 | 146 |
} |
| 147 | 147 |
|
| 148 | 148 |
Device * |
| 149 |
-uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *d, Uint8 b0, Uint8 w)) |
|
| 149 |
+uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *d, Uint8 b0), void (*deofn)(Device *d, Uint8 b0)) |
|
| 150 | 150 |
{
|
| 151 | 151 |
Device *d = &u->dev[id]; |
| 152 | 152 |
d->addr = id * 0x10; |
| 153 | 153 |
d->u = u; |
| 154 | 154 |
d->mem = u->ram.dat; |
| 155 |
- d->talk = talkfn; |
|
| 155 |
+ d->dei = deifn; |
|
| 156 |
+ d->deo = deofn; |
|
| 156 | 157 |
return d; |
| 157 | 158 |
} |
| ... | ... |
@@ -30,7 +30,8 @@ typedef struct Device {
|
| 30 | 30 |
struct Uxn *u; |
| 31 | 31 |
Uint8 addr, dat[16], *mem; |
| 32 | 32 |
Uint16 vector; |
| 33 |
- int (*talk)(struct Device *d, Uint8, Uint8); |
|
| 33 |
+ Uint8 (*dei)(struct Device *d, Uint8); |
|
| 34 |
+ void (*deo)(struct Device *d, Uint8); |
|
| 34 | 35 |
} Device; |
| 35 | 36 |
|
| 36 | 37 |
typedef struct Uxn {
|
| ... | ... |
@@ -47,4 +48,4 @@ Uint16 peek16(Uint8 *m, Uint16 a); |
| 47 | 48 |
int uxn_boot(Uxn *c); |
| 48 | 49 |
int uxn_eval(Uxn *u, Uint16 vec); |
| 49 | 50 |
int uxn_halt(Uxn *u, Uint8 error, char *name, int id); |
| 50 |
-Device *uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *, Uint8, Uint8)); |
|
| 51 |
+Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8)); |
| ... | ... |
@@ -43,43 +43,43 @@ inspect(Stack *s, char *name) |
| 43 | 43 |
|
| 44 | 44 |
#pragma mark - Devices |
| 45 | 45 |
|
| 46 |
-static int |
|
| 47 |
-system_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 46 |
+static Uint8 |
|
| 47 |
+system_dei(Device *d, Uint8 b0) |
|
| 48 | 48 |
{
|
| 49 |
- if(!w) { /* read */
|
|
| 50 |
- switch(b0) {
|
|
| 51 |
- case 0x2: d->dat[0x2] = d->u->wst.ptr; break; |
|
| 52 |
- case 0x3: d->dat[0x3] = d->u->rst.ptr; break; |
|
| 53 |
- } |
|
| 54 |
- } else { /* write */
|
|
| 55 |
- switch(b0) {
|
|
| 56 |
- case 0x2: d->u->wst.ptr = d->dat[0x2]; break; |
|
| 57 |
- case 0x3: d->u->rst.ptr = d->dat[0x3]; break; |
|
| 58 |
- case 0xe: |
|
| 59 |
- inspect(&d->u->wst, "Working-stack"); |
|
| 60 |
- inspect(&d->u->rst, "Return-stack"); |
|
| 61 |
- break; |
|
| 62 |
- case 0xf: return 0; |
|
| 63 |
- } |
|
| 49 |
+ switch(b0) {
|
|
| 50 |
+ case 0x2: return d->u->wst.ptr; |
|
| 51 |
+ case 0x3: return d->u->rst.ptr; |
|
| 52 |
+ default: return d->dat[b0]; |
|
| 64 | 53 |
} |
| 65 |
- return 1; |
|
| 66 | 54 |
} |
| 67 | 55 |
|
| 68 |
-static int |
|
| 69 |
-console_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 56 |
+static void |
|
| 57 |
+system_deo(Device *d, Uint8 b0) |
|
| 58 |
+{
|
|
| 59 |
+ switch(b0) {
|
|
| 60 |
+ case 0x2: d->u->wst.ptr = d->dat[b0]; break; |
|
| 61 |
+ case 0x3: d->u->rst.ptr = d->dat[b0]; break; |
|
| 62 |
+ case 0xe: |
|
| 63 |
+ inspect(&d->u->wst, "Working-stack"); |
|
| 64 |
+ inspect(&d->u->rst, "Return-stack"); |
|
| 65 |
+ break; |
|
| 66 |
+ } |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+static void |
|
| 70 |
+console_deo(Device *d, Uint8 b0) |
|
| 70 | 71 |
{
|
| 71 | 72 |
if(b0 == 0x1) |
| 72 | 73 |
d->vector = peek16(d->dat, 0x0); |
| 73 |
- if(w && b0 > 0x7) |
|
| 74 |
+ if(b0 > 0x7) |
|
| 74 | 75 |
write(b0 - 0x7, (char *)&d->dat[b0], 1); |
| 75 |
- return 1; |
|
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 |
-static int |
|
| 79 |
-file_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 78 |
+static void |
|
| 79 |
+file_deo(Device *d, Uint8 b0) |
|
| 80 | 80 |
{
|
| 81 | 81 |
Uint8 read = b0 == 0xd; |
| 82 |
- if(w && (read || b0 == 0xf)) {
|
|
| 82 |
+ if(read || b0 == 0xf) {
|
|
| 83 | 83 |
char *name = (char *)&d->mem[peek16(d->dat, 0x8)]; |
| 84 | 84 |
Uint16 result = 0, length = peek16(d->dat, 0xa); |
| 85 | 85 |
long offset = (peek16(d->dat, 0x4) << 16) + peek16(d->dat, 0x6); |
| ... | ... |
@@ -92,36 +92,39 @@ file_talk(Device *d, Uint8 b0, Uint8 w) |
| 92 | 92 |
} |
| 93 | 93 |
poke16(d->dat, 0x2, result); |
| 94 | 94 |
} |
| 95 |
- return 1; |
|
| 96 | 95 |
} |
| 97 | 96 |
|
| 98 |
-static int |
|
| 99 |
-datetime_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 97 |
+static Uint8 |
|
| 98 |
+datetime_dei(Device *d, Uint8 b0) |
|
| 100 | 99 |
{
|
| 101 | 100 |
time_t seconds = time(NULL); |
| 102 | 101 |
struct tm *t = localtime(&seconds); |
| 103 |
- t->tm_year += 1900; |
|
| 104 |
- poke16(d->dat, 0x0, t->tm_year); |
|
| 105 |
- d->dat[0x2] = t->tm_mon; |
|
| 106 |
- d->dat[0x3] = t->tm_mday; |
|
| 107 |
- d->dat[0x4] = t->tm_hour; |
|
| 108 |
- d->dat[0x5] = t->tm_min; |
|
| 109 |
- d->dat[0x6] = t->tm_sec; |
|
| 110 |
- d->dat[0x7] = t->tm_wday; |
|
| 111 |
- poke16(d->dat, 0x08, t->tm_yday); |
|
| 112 |
- d->dat[0xa] = t->tm_isdst; |
|
| 113 |
- (void)b0; |
|
| 114 |
- (void)w; |
|
| 115 |
- return 1; |
|
| 102 |
+ switch(b0) {
|
|
| 103 |
+ case 0x0: return (t->tm_year + 1900) >> 8; |
|
| 104 |
+ case 0x1: return (t->tm_year + 1900); |
|
| 105 |
+ case 0x2: return t->tm_mon; |
|
| 106 |
+ case 0x3: return t->tm_mday; |
|
| 107 |
+ case 0x4: return t->tm_hour; |
|
| 108 |
+ case 0x5: return t->tm_min; |
|
| 109 |
+ case 0x6: return t->tm_sec; |
|
| 110 |
+ case 0x7: return t->tm_wday; |
|
| 111 |
+ case 0x8: return t->tm_yday >> 8; |
|
| 112 |
+ case 0x9: return t->tm_yday; |
|
| 113 |
+ case 0xa: return t->tm_isdst; |
|
| 114 |
+ default: return d->dat[b0]; |
|
| 115 |
+ } |
|
| 116 | 116 |
} |
| 117 | 117 |
|
| 118 |
-static int |
|
| 119 |
-nil_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 118 |
+static Uint8 |
|
| 119 |
+nil_dei(Device *d, Uint8 b0) |
|
| 120 | 120 |
{
|
| 121 |
- (void)d; |
|
| 122 |
- (void)b0; |
|
| 123 |
- (void)w; |
|
| 124 |
- return 1; |
|
| 121 |
+ return d->dat[b0]; |
|
| 122 |
+} |
|
| 123 |
+ |
|
| 124 |
+static void |
|
| 125 |
+nil_deo(Device *d, Uint8 b0) |
|
| 126 |
+{
|
|
| 127 |
+ if(b0 == 0x1) d->vector = peek16(d->dat, 0x0); |
|
| 125 | 128 |
} |
| 126 | 129 |
|
| 127 | 130 |
#pragma mark - Generics |
| ... | ... |
@@ -173,22 +176,22 @@ main(int argc, char **argv) |
| 173 | 176 |
if(!uxn_boot(&u)) |
| 174 | 177 |
return error("Boot", "Failed");
|
| 175 | 178 |
|
| 176 |
- /* system */ devsystem = uxn_port(&u, 0x0, system_talk); |
|
| 177 |
- /* console */ devconsole = uxn_port(&u, 0x1, console_talk); |
|
| 178 |
- /* empty */ uxn_port(&u, 0x2, nil_talk); |
|
| 179 |
- /* empty */ uxn_port(&u, 0x3, nil_talk); |
|
| 180 |
- /* empty */ uxn_port(&u, 0x4, nil_talk); |
|
| 181 |
- /* empty */ uxn_port(&u, 0x5, nil_talk); |
|
| 182 |
- /* empty */ uxn_port(&u, 0x6, nil_talk); |
|
| 183 |
- /* empty */ uxn_port(&u, 0x7, nil_talk); |
|
| 184 |
- /* empty */ uxn_port(&u, 0x8, nil_talk); |
|
| 185 |
- /* empty */ uxn_port(&u, 0x9, nil_talk); |
|
| 186 |
- /* file */ uxn_port(&u, 0xa, file_talk); |
|
| 187 |
- /* datetime */ uxn_port(&u, 0xb, datetime_talk); |
|
| 188 |
- /* empty */ uxn_port(&u, 0xc, nil_talk); |
|
| 189 |
- /* empty */ uxn_port(&u, 0xd, nil_talk); |
|
| 190 |
- /* empty */ uxn_port(&u, 0xe, nil_talk); |
|
| 191 |
- /* empty */ uxn_port(&u, 0xf, nil_talk); |
|
| 179 |
+ /* system */ devsystem = uxn_port(&u, 0x0, system_dei, system_deo); |
|
| 180 |
+ /* console */ devconsole = uxn_port(&u, 0x1, nil_dei, console_deo); |
|
| 181 |
+ /* empty */ uxn_port(&u, 0x2, nil_dei, nil_deo); |
|
| 182 |
+ /* empty */ uxn_port(&u, 0x3, nil_dei, nil_deo); |
|
| 183 |
+ /* empty */ uxn_port(&u, 0x4, nil_dei, nil_deo); |
|
| 184 |
+ /* empty */ uxn_port(&u, 0x5, nil_dei, nil_deo); |
|
| 185 |
+ /* empty */ uxn_port(&u, 0x6, nil_dei, nil_deo); |
|
| 186 |
+ /* empty */ uxn_port(&u, 0x7, nil_dei, nil_deo); |
|
| 187 |
+ /* empty */ uxn_port(&u, 0x8, nil_dei, nil_deo); |
|
| 188 |
+ /* empty */ uxn_port(&u, 0x9, nil_dei, nil_deo); |
|
| 189 |
+ /* file */ uxn_port(&u, 0xa, nil_dei, file_deo); |
|
| 190 |
+ /* datetime */ uxn_port(&u, 0xb, datetime_dei, nil_deo); |
|
| 191 |
+ /* empty */ uxn_port(&u, 0xc, nil_dei, nil_deo); |
|
| 192 |
+ /* empty */ uxn_port(&u, 0xd, nil_dei, nil_deo); |
|
| 193 |
+ /* empty */ uxn_port(&u, 0xe, nil_dei, nil_deo); |
|
| 194 |
+ /* empty */ uxn_port(&u, 0xf, nil_dei, nil_deo); |
|
| 192 | 195 |
|
| 193 | 196 |
for(i = 1; i < argc; ++i) {
|
| 194 | 197 |
if(!loaded++) {
|
| ... | ... |
@@ -289,87 +289,89 @@ doctrl(SDL_Event *event, int z) |
| 289 | 289 |
|
| 290 | 290 |
#pragma mark - Devices |
| 291 | 291 |
|
| 292 |
-static int |
|
| 293 |
-system_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 292 |
+static Uint8 |
|
| 293 |
+system_dei(Device *d, Uint8 b0) |
|
| 294 | 294 |
{
|
| 295 |
- if(!w) { /* read */
|
|
| 296 |
- switch(b0) {
|
|
| 297 |
- case 0x2: d->dat[0x2] = d->u->wst.ptr; break; |
|
| 298 |
- case 0x3: d->dat[0x3] = d->u->rst.ptr; break; |
|
| 299 |
- } |
|
| 300 |
- } else { /* write */
|
|
| 301 |
- switch(b0) {
|
|
| 302 |
- case 0x2: d->u->wst.ptr = d->dat[0x2]; break; |
|
| 303 |
- case 0x3: d->u->rst.ptr = d->dat[0x3]; break; |
|
| 304 |
- case 0xf: return 0; |
|
| 305 |
- } |
|
| 306 |
- if(b0 > 0x7 && b0 < 0xe) |
|
| 307 |
- set_palette(&d->dat[0x8]); |
|
| 295 |
+ switch(b0) {
|
|
| 296 |
+ case 0x2: return d->u->wst.ptr; |
|
| 297 |
+ case 0x3: return d->u->rst.ptr; |
|
| 298 |
+ default: return d->dat[b0]; |
|
| 308 | 299 |
} |
| 309 |
- return 1; |
|
| 310 | 300 |
} |
| 311 | 301 |
|
| 312 |
-static int |
|
| 313 |
-console_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 302 |
+static void |
|
| 303 |
+system_deo(Device *d, Uint8 b0) |
|
| 314 | 304 |
{
|
| 315 |
- if(w) {
|
|
| 316 |
- if(b0 == 0x1) |
|
| 317 |
- d->vector = peek16(d->dat, 0x0); |
|
| 318 |
- if(b0 > 0x7) |
|
| 319 |
- write(b0 - 0x7, (char *)&d->dat[b0], 1); |
|
| 305 |
+ switch(b0) {
|
|
| 306 |
+ case 0x2: d->u->wst.ptr = d->dat[b0]; break; |
|
| 307 |
+ case 0x3: d->u->rst.ptr = d->dat[b0]; break; |
|
| 320 | 308 |
} |
| 321 |
- return 1; |
|
| 309 |
+ if(b0 > 0x7 && b0 < 0xe) |
|
| 310 |
+ set_palette(&d->dat[0x8]); |
|
| 322 | 311 |
} |
| 323 | 312 |
|
| 324 |
-static int |
|
| 325 |
-screen_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 313 |
+static void |
|
| 314 |
+console_deo(Device *d, Uint8 b0) |
|
| 326 | 315 |
{
|
| 327 |
- if(!w) switch(b0) {
|
|
| 328 |
- case 0x2: d->dat[0x2] = ppu.width >> 8; break; |
|
| 329 |
- case 0x3: d->dat[0x3] = ppu.width; break; |
|
| 330 |
- case 0x4: d->dat[0x4] = ppu.height >> 8; break; |
|
| 331 |
- case 0x5: d->dat[0x5] = ppu.height; break; |
|
| 332 |
- } |
|
| 333 |
- else |
|
| 334 |
- switch(b0) {
|
|
| 335 |
- case 0x1: d->vector = peek16(d->dat, 0x0); break; |
|
| 336 |
- case 0x5: |
|
| 337 |
- if(!FIXED_SIZE) return set_size(peek16(d->dat, 0x2), peek16(d->dat, 0x4), 1); |
|
| 338 |
- break; |
|
| 339 |
- case 0xe: {
|
|
| 340 |
- Uint16 x = peek16(d->dat, 0x8); |
|
| 341 |
- Uint16 y = peek16(d->dat, 0xa); |
|
| 342 |
- Uint8 layer = d->dat[0xe] & 0x40; |
|
| 343 |
- ppu_write(&ppu, !!layer, x, y, d->dat[0xe] & 0x3); |
|
| 344 |
- if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 1); /* auto x+1 */ |
|
| 345 |
- if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 1); /* auto y+1 */ |
|
| 346 |
- break; |
|
| 347 |
- } |
|
| 348 |
- case 0xf: {
|
|
| 349 |
- Uint16 x = peek16(d->dat, 0x8); |
|
| 350 |
- Uint16 y = peek16(d->dat, 0xa); |
|
| 351 |
- Uint8 layer = d->dat[0xf] & 0x40; |
|
| 352 |
- Uint8 *addr = &d->mem[peek16(d->dat, 0xc)]; |
|
| 353 |
- if(d->dat[0xf] & 0x80) {
|
|
| 354 |
- ppu_2bpp(&ppu, !!layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
| 355 |
- if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 16); /* auto addr+16 */ |
|
| 356 |
- } else {
|
|
| 357 |
- ppu_1bpp(&ppu, !!layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
| 358 |
- if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 8); /* auto addr+8 */ |
|
| 359 |
- } |
|
| 360 |
- if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 8); /* auto x+8 */ |
|
| 361 |
- if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 8); /* auto y+8 */ |
|
| 362 |
- break; |
|
| 363 |
- } |
|
| 316 |
+ if(b0 == 0x1) |
|
| 317 |
+ d->vector = peek16(d->dat, 0x0); |
|
| 318 |
+ if(b0 > 0x7) |
|
| 319 |
+ write(b0 - 0x7, (char *)&d->dat[b0], 1); |
|
| 320 |
+} |
|
| 321 |
+ |
|
| 322 |
+static Uint8 |
|
| 323 |
+screen_dei(Device *d, Uint8 b0) |
|
| 324 |
+{
|
|
| 325 |
+ switch(b0) {
|
|
| 326 |
+ case 0x2: return ppu.width >> 8; |
|
| 327 |
+ case 0x3: return ppu.width; |
|
| 328 |
+ case 0x4: return ppu.height >> 8; |
|
| 329 |
+ case 0x5: return ppu.height; |
|
| 330 |
+ default: return d->dat[b0]; |
|
| 331 |
+ } |
|
| 332 |
+} |
|
| 333 |
+ |
|
| 334 |
+static void |
|
| 335 |
+screen_deo(Device *d, Uint8 b0) |
|
| 336 |
+{
|
|
| 337 |
+ switch(b0) {
|
|
| 338 |
+ case 0x1: d->vector = peek16(d->dat, 0x0); break; |
|
| 339 |
+ case 0x5: |
|
| 340 |
+ if(!FIXED_SIZE) set_size(peek16(d->dat, 0x2), peek16(d->dat, 0x4), 1); |
|
| 341 |
+ break; |
|
| 342 |
+ case 0xe: {
|
|
| 343 |
+ Uint16 x = peek16(d->dat, 0x8); |
|
| 344 |
+ Uint16 y = peek16(d->dat, 0xa); |
|
| 345 |
+ Uint8 layer = d->dat[0xe] & 0x40; |
|
| 346 |
+ ppu_write(&ppu, !!layer, x, y, d->dat[0xe] & 0x3); |
|
| 347 |
+ if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 1); /* auto x+1 */ |
|
| 348 |
+ if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 1); /* auto y+1 */ |
|
| 349 |
+ break; |
|
| 350 |
+ } |
|
| 351 |
+ case 0xf: {
|
|
| 352 |
+ Uint16 x = peek16(d->dat, 0x8); |
|
| 353 |
+ Uint16 y = peek16(d->dat, 0xa); |
|
| 354 |
+ Uint8 layer = d->dat[0xf] & 0x40; |
|
| 355 |
+ Uint8 *addr = &d->mem[peek16(d->dat, 0xc)]; |
|
| 356 |
+ if(d->dat[0xf] & 0x80) {
|
|
| 357 |
+ ppu_2bpp(&ppu, !!layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
| 358 |
+ if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 16); /* auto addr+16 */ |
|
| 359 |
+ } else {
|
|
| 360 |
+ ppu_1bpp(&ppu, !!layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); |
|
| 361 |
+ if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 8); /* auto addr+8 */ |
|
| 364 | 362 |
} |
| 365 |
- return 1; |
|
| 363 |
+ if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 8); /* auto x+8 */ |
|
| 364 |
+ if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 8); /* auto y+8 */ |
|
| 365 |
+ break; |
|
| 366 |
+ } |
|
| 367 |
+ } |
|
| 366 | 368 |
} |
| 367 | 369 |
|
| 368 |
-static int |
|
| 369 |
-file_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 370 |
+static void |
|
| 371 |
+file_deo(Device *d, Uint8 b0) |
|
| 370 | 372 |
{
|
| 371 | 373 |
Uint8 read = b0 == 0xd; |
| 372 |
- if(w && (read || b0 == 0xf)) {
|
|
| 374 |
+ if(read || b0 == 0xf) {
|
|
| 373 | 375 |
char *name = (char *)&d->mem[peek16(d->dat, 0x8)]; |
| 374 | 376 |
Uint16 result = 0, length = peek16(d->dat, 0xa); |
| 375 | 377 |
long offset = (peek16(d->dat, 0x4) << 16) + peek16(d->dat, 0x6); |
| ... | ... |
@@ -382,20 +384,26 @@ file_talk(Device *d, Uint8 b0, Uint8 w) |
| 382 | 384 |
} |
| 383 | 385 |
poke16(d->dat, 0x2, result); |
| 384 | 386 |
} |
| 385 |
- return 1; |
|
| 386 | 387 |
} |
| 387 | 388 |
|
| 388 |
-static int |
|
| 389 |
-audio_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 389 |
+static Uint8 |
|
| 390 |
+audio_dei(Device *d, Uint8 b0) |
|
| 390 | 391 |
{
|
| 391 | 392 |
Apu *c = &apu[d - devaudio0]; |
| 392 |
- if(!audio_id) return 1; |
|
| 393 |
- if(!w) {
|
|
| 394 |
- if(b0 == 0x2) |
|
| 395 |
- poke16(d->dat, 0x2, c->i); |
|
| 396 |
- else if(b0 == 0x4) |
|
| 397 |
- d->dat[0x4] = apu_get_vu(c); |
|
| 398 |
- } else if(b0 == 0xf) {
|
|
| 393 |
+ if(!audio_id) return d->dat[b0]; |
|
| 394 |
+ switch(b0) {
|
|
| 395 |
+ case 0x4: return apu_get_vu(c); |
|
| 396 |
+ case 0x2: poke16(d->dat, 0x2, c->i); /* fall through */ |
|
| 397 |
+ default: return d->dat[b0]; |
|
| 398 |
+ } |
|
| 399 |
+} |
|
| 400 |
+ |
|
| 401 |
+static void |
|
| 402 |
+audio_deo(Device *d, Uint8 b0) |
|
| 403 |
+{
|
|
| 404 |
+ Apu *c = &apu[d - devaudio0]; |
|
| 405 |
+ if(!audio_id) return; |
|
| 406 |
+ if(b0 == 0xf) {
|
|
| 399 | 407 |
SDL_LockAudioDevice(audio_id); |
| 400 | 408 |
c->len = peek16(d->dat, 0xa); |
| 401 | 409 |
c->addr = &d->mem[peek16(d->dat, 0xc)]; |
| ... | ... |
@@ -406,38 +414,39 @@ audio_talk(Device *d, Uint8 b0, Uint8 w) |
| 406 | 414 |
SDL_UnlockAudioDevice(audio_id); |
| 407 | 415 |
SDL_PauseAudioDevice(audio_id, 0); |
| 408 | 416 |
} |
| 409 |
- return 1; |
|
| 410 | 417 |
} |
| 411 | 418 |
|
| 412 |
-static int |
|
| 413 |
-datetime_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 419 |
+static Uint8 |
|
| 420 |
+datetime_dei(Device *d, Uint8 b0) |
|
| 414 | 421 |
{
|
| 415 | 422 |
time_t seconds = time(NULL); |
| 416 | 423 |
struct tm *t = localtime(&seconds); |
| 417 |
- t->tm_year += 1900; |
|
| 418 |
- poke16(d->dat, 0x0, t->tm_year); |
|
| 419 |
- d->dat[0x2] = t->tm_mon; |
|
| 420 |
- d->dat[0x3] = t->tm_mday; |
|
| 421 |
- d->dat[0x4] = t->tm_hour; |
|
| 422 |
- d->dat[0x5] = t->tm_min; |
|
| 423 |
- d->dat[0x6] = t->tm_sec; |
|
| 424 |
- d->dat[0x7] = t->tm_wday; |
|
| 425 |
- poke16(d->dat, 0x08, t->tm_yday); |
|
| 426 |
- d->dat[0xa] = t->tm_isdst; |
|
| 427 |
- (void)b0; |
|
| 428 |
- (void)w; |
|
| 429 |
- return 1; |
|
| 424 |
+ switch(b0) {
|
|
| 425 |
+ case 0x0: return (t->tm_year + 1900) >> 8; |
|
| 426 |
+ case 0x1: return (t->tm_year + 1900); |
|
| 427 |
+ case 0x2: return t->tm_mon; |
|
| 428 |
+ case 0x3: return t->tm_mday; |
|
| 429 |
+ case 0x4: return t->tm_hour; |
|
| 430 |
+ case 0x5: return t->tm_min; |
|
| 431 |
+ case 0x6: return t->tm_sec; |
|
| 432 |
+ case 0x7: return t->tm_wday; |
|
| 433 |
+ case 0x8: return t->tm_yday >> 8; |
|
| 434 |
+ case 0x9: return t->tm_yday; |
|
| 435 |
+ case 0xa: return t->tm_isdst; |
|
| 436 |
+ default: return d->dat[b0]; |
|
| 437 |
+ } |
|
| 430 | 438 |
} |
| 431 | 439 |
|
| 432 |
-static int |
|
| 433 |
-nil_talk(Device *d, Uint8 b0, Uint8 w) |
|
| 440 |
+static Uint8 |
|
| 441 |
+nil_dei(Device *d, Uint8 b0) |
|
| 434 | 442 |
{
|
| 435 |
- if(w && b0 == 0x1) |
|
| 436 |
- d->vector = peek16(d->dat, 0x0); |
|
| 437 |
- (void)d; |
|
| 438 |
- (void)b0; |
|
| 439 |
- (void)w; |
|
| 440 |
- return 1; |
|
| 443 |
+ return d->dat[b0]; |
|
| 444 |
+} |
|
| 445 |
+ |
|
| 446 |
+static void |
|
| 447 |
+nil_deo(Device *d, Uint8 b0) |
|
| 448 |
+{
|
|
| 449 |
+ if(b0 == 0x1) d->vector = peek16(d->dat, 0x0); |
|
| 441 | 450 |
} |
| 442 | 451 |
|
| 443 | 452 |
static const char *errors[] = {"underflow", "overflow", "division by zero"};
|
| ... | ... |
@@ -526,22 +535,22 @@ main(int argc, char **argv) |
| 526 | 535 |
if(!uxn_boot(&u)) |
| 527 | 536 |
return error("Boot", "Failed to start uxn.");
|
| 528 | 537 |
|
| 529 |
- /* system */ devsystem = uxn_port(&u, 0x0, system_talk); |
|
| 530 |
- /* console */ devconsole = uxn_port(&u, 0x1, console_talk); |
|
| 531 |
- /* screen */ devscreen = uxn_port(&u, 0x2, screen_talk); |
|
| 532 |
- /* audio0 */ devaudio0 = uxn_port(&u, 0x3, audio_talk); |
|
| 533 |
- /* audio1 */ uxn_port(&u, 0x4, audio_talk); |
|
| 534 |
- /* audio2 */ uxn_port(&u, 0x5, audio_talk); |
|
| 535 |
- /* audio3 */ uxn_port(&u, 0x6, audio_talk); |
|
| 536 |
- /* unused */ uxn_port(&u, 0x7, nil_talk); |
|
| 537 |
- /* control */ devctrl = uxn_port(&u, 0x8, nil_talk); |
|
| 538 |
- /* mouse */ devmouse = uxn_port(&u, 0x9, nil_talk); |
|
| 539 |
- /* file */ uxn_port(&u, 0xa, file_talk); |
|
| 540 |
- /* datetime */ uxn_port(&u, 0xb, datetime_talk); |
|
| 541 |
- /* unused */ uxn_port(&u, 0xc, nil_talk); |
|
| 542 |
- /* unused */ uxn_port(&u, 0xd, nil_talk); |
|
| 543 |
- /* unused */ uxn_port(&u, 0xe, nil_talk); |
|
| 544 |
- /* unused */ uxn_port(&u, 0xf, nil_talk); |
|
| 538 |
+ /* system */ devsystem = uxn_port(&u, 0x0, system_dei, system_deo); |
|
| 539 |
+ /* console */ devconsole = uxn_port(&u, 0x1, nil_dei, console_deo); |
|
| 540 |
+ /* screen */ devscreen = uxn_port(&u, 0x2, screen_dei, screen_deo); |
|
| 541 |
+ /* audio0 */ devaudio0 = uxn_port(&u, 0x3, audio_dei, audio_deo); |
|
| 542 |
+ /* audio1 */ uxn_port(&u, 0x4, audio_dei, audio_deo); |
|
| 543 |
+ /* audio2 */ uxn_port(&u, 0x5, audio_dei, audio_deo); |
|
| 544 |
+ /* audio3 */ uxn_port(&u, 0x6, audio_dei, audio_deo); |
|
| 545 |
+ /* unused */ uxn_port(&u, 0x7, nil_dei, nil_deo); |
|
| 546 |
+ /* control */ devctrl = uxn_port(&u, 0x8, nil_dei, nil_deo); |
|
| 547 |
+ /* mouse */ devmouse = uxn_port(&u, 0x9, nil_dei, nil_deo); |
|
| 548 |
+ /* file */ uxn_port(&u, 0xa, nil_dei, file_deo); |
|
| 549 |
+ /* datetime */ uxn_port(&u, 0xb, datetime_dei, nil_deo); |
|
| 550 |
+ /* unused */ uxn_port(&u, 0xc, nil_dei, nil_deo); |
|
| 551 |
+ /* unused */ uxn_port(&u, 0xd, nil_dei, nil_deo); |
|
| 552 |
+ /* unused */ uxn_port(&u, 0xe, nil_dei, nil_deo); |
|
| 553 |
+ /* unused */ uxn_port(&u, 0xf, nil_dei, nil_deo); |
|
| 545 | 554 |
|
| 546 | 555 |
/* set default zoom */ |
| 547 | 556 |
if(SDL_GetCurrentDisplayMode(0, &DM) == 0) |