... | ... |
@@ -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) |