... | ... |
@@ -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 void devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; d->talk(d, a & 0x0f, 1); } |
|
33 |
+static int devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; return d->talk(d, a & 0x0f, 1); } |
|
34 | 34 |
static Uint8 devr8(Device *d, Uint8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; } |
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 void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); } |
|
37 |
+static int devw16(Device *d, Uint8 a, Uint16 b) { return devw8(d, a, b >> 8) && devw8(d, a + 1, b); } |
|
38 | 38 |
|
39 | 39 |
/* clang-format on */ |
40 | 40 |
|
... | ... |
@@ -379,7 +379,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
379 | 379 |
case 0x17: /* DEO */ |
380 | 380 |
{ |
381 | 381 |
Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; |
382 |
- devw8(&u->dev[a >> 4], a, b); |
|
382 |
+ if(!devw8(&u->dev[a >> 4], a, b)) |
|
383 |
+ return 1; |
|
383 | 384 |
#ifndef NO_STACK_CHECKS |
384 | 385 |
if(__builtin_expect(u->wst.ptr < 2, 0)) { |
385 | 386 |
u->wst.error = 1; |
... | ... |
@@ -854,7 +855,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
854 | 855 |
{ |
855 | 856 |
Uint8 a = u->wst.dat[u->wst.ptr - 1]; |
856 | 857 |
Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); |
857 |
- devw16(&u->dev[a >> 4], a, b); |
|
858 |
+ if(!devw16(&u->dev[a >> 4], a, b)) |
|
859 |
+ return 1; |
|
858 | 860 |
#ifndef NO_STACK_CHECKS |
859 | 861 |
if(__builtin_expect(u->wst.ptr < 3, 0)) { |
860 | 862 |
u->wst.error = 1; |
... | ... |
@@ -1310,7 +1312,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
1310 | 1312 |
case 0x57: /* DEOr */ |
1311 | 1313 |
{ |
1312 | 1314 |
Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; |
1313 |
- devw8(&u->dev[a >> 4], a, b); |
|
1315 |
+ if(!devw8(&u->dev[a >> 4], a, b)) |
|
1316 |
+ return 1; |
|
1314 | 1317 |
#ifndef NO_STACK_CHECKS |
1315 | 1318 |
if(__builtin_expect(u->rst.ptr < 2, 0)) { |
1316 | 1319 |
u->rst.error = 1; |
... | ... |
@@ -1785,7 +1788,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
1785 | 1788 |
{ |
1786 | 1789 |
Uint8 a = u->rst.dat[u->rst.ptr - 1]; |
1787 | 1790 |
Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); |
1788 |
- devw16(&u->dev[a >> 4], a, b); |
|
1791 |
+ if(!devw16(&u->dev[a >> 4], a, b)) |
|
1792 |
+ return 1; |
|
1789 | 1793 |
#ifndef NO_STACK_CHECKS |
1790 | 1794 |
if(__builtin_expect(u->rst.ptr < 3, 0)) { |
1791 | 1795 |
u->rst.error = 1; |
... | ... |
@@ -2273,7 +2277,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
2273 | 2277 |
case 0x97: /* DEOk */ |
2274 | 2278 |
{ |
2275 | 2279 |
Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2]; |
2276 |
- devw8(&u->dev[a >> 4], a, b); |
|
2280 |
+ if(!devw8(&u->dev[a >> 4], a, b)) |
|
2281 |
+ return 1; |
|
2277 | 2282 |
#ifndef NO_STACK_CHECKS |
2278 | 2283 |
if(__builtin_expect(u->wst.ptr < 2, 0)) { |
2279 | 2284 |
u->wst.error = 1; |
... | ... |
@@ -2799,7 +2804,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
2799 | 2804 |
{ |
2800 | 2805 |
Uint8 a = u->wst.dat[u->wst.ptr - 1]; |
2801 | 2806 |
Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8)); |
2802 |
- devw16(&u->dev[a >> 4], a, b); |
|
2807 |
+ if(!devw16(&u->dev[a >> 4], a, b)) |
|
2808 |
+ return 1; |
|
2803 | 2809 |
#ifndef NO_STACK_CHECKS |
2804 | 2810 |
if(__builtin_expect(u->wst.ptr < 3, 0)) { |
2805 | 2811 |
u->wst.error = 1; |
... | ... |
@@ -3318,7 +3324,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
3318 | 3324 |
case 0xd7: /* DEOkr */ |
3319 | 3325 |
{ |
3320 | 3326 |
Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2]; |
3321 |
- devw8(&u->dev[a >> 4], a, b); |
|
3327 |
+ if(!devw8(&u->dev[a >> 4], a, b)) |
|
3328 |
+ return 1; |
|
3322 | 3329 |
#ifndef NO_STACK_CHECKS |
3323 | 3330 |
if(__builtin_expect(u->rst.ptr < 2, 0)) { |
3324 | 3331 |
u->rst.error = 1; |
... | ... |
@@ -3844,7 +3851,8 @@ uxn_eval(Uxn *u, Uint16 vec) |
3844 | 3851 |
{ |
3845 | 3852 |
Uint8 a = u->rst.dat[u->rst.ptr - 1]; |
3846 | 3853 |
Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8)); |
3847 |
- devw16(&u->dev[a >> 4], a, b); |
|
3854 |
+ if(!devw16(&u->dev[a >> 4], a, b)) |
|
3855 |
+ return 1; |
|
3848 | 3856 |
#ifndef NO_STACK_CHECKS |
3849 | 3857 |
if(__builtin_expect(u->rst.ptr < 3, 0)) { |
3850 | 3858 |
u->rst.error = 1; |
... | ... |
@@ -4029,7 +4037,7 @@ uxn_boot(Uxn *u) |
4029 | 4037 |
} |
4030 | 4038 |
|
4031 | 4039 |
Device * |
4032 |
-uxn_port(Uxn *u, Uint8 id, void (*talkfn)(Device *d, Uint8 b0, Uint8 w)) |
|
4040 |
+uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *d, Uint8 b0, Uint8 w)) |
|
4033 | 4041 |
{ |
4034 | 4042 |
Device *d = &u->dev[id]; |
4035 | 4043 |
d->addr = id * 0x10; |
... | ... |
@@ -36,7 +36,7 @@ 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 void devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; d->talk(d, a & 0x0f, 1); } |
|
39 |
+static int devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; return d->talk(d, a & 0x0f, 1); } |
|
40 | 40 |
static Uint16 devr8(Device *d, Uint8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; } |
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++)); } |
... | ... |
@@ -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 void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); } |
|
48 |
+static int devw16(Device *d, Uint8 a, Uint16 b) { return 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); devw(&u->dev[a >> 4], a, b); break; |
|
119 |
+ case 0x17: /* DEO */ a = pop8(u->src); b = pop(u->src); if (!devw(&u->dev[a >> 4], a, b)) return 1; 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; |
... | ... |
@@ -148,7 +148,7 @@ uxn_boot(Uxn *u) |
148 | 148 |
} |
149 | 149 |
|
150 | 150 |
Device * |
151 |
-uxn_port(Uxn *u, Uint8 id, void (*talkfn)(Device *d, Uint8 b0, Uint8 w)) |
|
151 |
+uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *d, Uint8 b0, Uint8 w)) |
|
152 | 152 |
{ |
153 | 153 |
Device *d = &u->dev[id]; |
154 | 154 |
d->addr = id * 0x10; |
... | ... |
@@ -29,7 +29,7 @@ typedef struct { |
29 | 29 |
typedef struct Device { |
30 | 30 |
struct Uxn *u; |
31 | 31 |
Uint8 addr, dat[16], *mem; |
32 |
- void (*talk)(struct Device *d, Uint8, Uint8); |
|
32 |
+ int (*talk)(struct Device *d, Uint8, Uint8); |
|
33 | 33 |
} Device; |
34 | 34 |
|
35 | 35 |
typedef struct Uxn { |
... | ... |
@@ -46,4 +46,4 @@ Uint16 peek16(Uint8 *m, Uint16 a); |
46 | 46 |
int uxn_boot(Uxn *c); |
47 | 47 |
int uxn_eval(Uxn *u, Uint16 vec); |
48 | 48 |
int uxn_halt(Uxn *u, Uint8 error, char *name, int id); |
49 |
-Device *uxn_port(Uxn *u, Uint8 id, void (*talkfn)(Device *, Uint8, Uint8)); |
|
49 |
+Device *uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *, Uint8, Uint8)); |
... | ... |
@@ -44,7 +44,7 @@ inspect(Stack *s, char *name) |
44 | 44 |
|
45 | 45 |
#pragma mark - Devices |
46 | 46 |
|
47 |
-static void |
|
47 |
+static int |
|
48 | 48 |
system_talk(Device *d, Uint8 b0, Uint8 w) |
49 | 49 |
{ |
50 | 50 |
if(!w) { /* read */ |
... | ... |
@@ -60,19 +60,21 @@ system_talk(Device *d, Uint8 b0, Uint8 w) |
60 | 60 |
inspect(&d->u->wst, "Working-stack"); |
61 | 61 |
inspect(&d->u->rst, "Return-stack"); |
62 | 62 |
break; |
63 |
- case 0xf: d->u->ram.ptr = 0x0000; break; |
|
63 |
+ case 0xf: return 0; |
|
64 | 64 |
} |
65 | 65 |
} |
66 |
+ return 1; |
|
66 | 67 |
} |
67 | 68 |
|
68 |
-static void |
|
69 |
+static int |
|
69 | 70 |
console_talk(Device *d, Uint8 b0, Uint8 w) |
70 | 71 |
{ |
71 | 72 |
if(w && b0 > 0x7) |
72 | 73 |
write(b0 - 0x7, (char *)&d->dat[b0], 1); |
74 |
+ return 1; |
|
73 | 75 |
} |
74 | 76 |
|
75 |
-static void |
|
77 |
+static int |
|
76 | 78 |
file_talk(Device *d, Uint8 b0, Uint8 w) |
77 | 79 |
{ |
78 | 80 |
Uint8 read = b0 == 0xd; |
... | ... |
@@ -89,9 +91,10 @@ file_talk(Device *d, Uint8 b0, Uint8 w) |
89 | 91 |
} |
90 | 92 |
poke16(d->dat, 0x2, result); |
91 | 93 |
} |
94 |
+ return 1; |
|
92 | 95 |
} |
93 | 96 |
|
94 |
-static void |
|
97 |
+static int |
|
95 | 98 |
datetime_talk(Device *d, Uint8 b0, Uint8 w) |
96 | 99 |
{ |
97 | 100 |
time_t seconds = time(NULL); |
... | ... |
@@ -108,14 +111,16 @@ datetime_talk(Device *d, Uint8 b0, Uint8 w) |
108 | 111 |
d->dat[0xa] = t->tm_isdst; |
109 | 112 |
(void)b0; |
110 | 113 |
(void)w; |
114 |
+ return 1; |
|
111 | 115 |
} |
112 | 116 |
|
113 |
-static void |
|
117 |
+static int |
|
114 | 118 |
nil_talk(Device *d, Uint8 b0, Uint8 w) |
115 | 119 |
{ |
116 | 120 |
(void)d; |
117 | 121 |
(void)b0; |
118 | 122 |
(void)w; |
123 |
+ return 1; |
|
119 | 124 |
} |
120 | 125 |
|
121 | 126 |
#pragma mark - Generics |
... | ... |
@@ -126,7 +131,6 @@ int |
126 | 131 |
uxn_halt(Uxn *u, Uint8 error, char *name, int id) |
127 | 132 |
{ |
128 | 133 |
fprintf(stderr, "Halted: %s %s#%04x, at 0x%04x\n", name, errors[error - 1], id, u->ram.ptr); |
129 |
- u->ram.ptr = 0; |
|
130 | 134 |
return 0; |
131 | 135 |
} |
132 | 136 |
|
... | ... |
@@ -289,7 +289,7 @@ docolors(Device *d) |
289 | 289 |
|
290 | 290 |
#pragma mark - Devices |
291 | 291 |
|
292 |
-static void |
|
292 |
+static int |
|
293 | 293 |
system_talk(Device *d, Uint8 b0, Uint8 w) |
294 | 294 |
{ |
295 | 295 |
if(!w) { /* read */ |
... | ... |
@@ -301,21 +301,23 @@ system_talk(Device *d, Uint8 b0, Uint8 w) |
301 | 301 |
switch(b0) { |
302 | 302 |
case 0x2: d->u->wst.ptr = d->dat[0x2]; break; |
303 | 303 |
case 0x3: d->u->rst.ptr = d->dat[0x3]; break; |
304 |
- case 0xf: d->u->ram.ptr = 0x0000; break; |
|
304 |
+ case 0xf: return 0; |
|
305 | 305 |
} |
306 | 306 |
if(b0 > 0x7 && b0 < 0xe) |
307 | 307 |
docolors(d); |
308 | 308 |
} |
309 |
+ return 1; |
|
309 | 310 |
} |
310 | 311 |
|
311 |
-static void |
|
312 |
+static int |
|
312 | 313 |
console_talk(Device *d, Uint8 b0, Uint8 w) |
313 | 314 |
{ |
314 | 315 |
if(w && b0 > 0x7) |
315 | 316 |
write(b0 - 0x7, (char *)&d->dat[b0], 1); |
317 |
+ return 1; |
|
316 | 318 |
} |
317 | 319 |
|
318 |
-static void |
|
320 |
+static int |
|
319 | 321 |
screen_talk(Device *d, Uint8 b0, Uint8 w) |
320 | 322 |
{ |
321 | 323 |
if(w && b0 == 0xe) { |
... | ... |
@@ -335,9 +337,10 @@ screen_talk(Device *d, Uint8 b0, Uint8 w) |
335 | 337 |
ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1); |
336 | 338 |
reqdraw = 1; |
337 | 339 |
} |
340 |
+ return 1; |
|
338 | 341 |
} |
339 | 342 |
|
340 |
-static void |
|
343 |
+static int |
|
341 | 344 |
file_talk(Device *d, Uint8 b0, Uint8 w) |
342 | 345 |
{ |
343 | 346 |
Uint8 read = b0 == 0xd; |
... | ... |
@@ -356,13 +359,14 @@ file_talk(Device *d, Uint8 b0, Uint8 w) |
356 | 359 |
} |
357 | 360 |
poke16(d->dat, 0x2, result); |
358 | 361 |
} |
362 |
+ return 1; |
|
359 | 363 |
} |
360 | 364 |
|
361 |
-static void |
|
365 |
+static int |
|
362 | 366 |
audio_talk(Device *d, Uint8 b0, Uint8 w) |
363 | 367 |
{ |
364 | 368 |
Apu *c = &apu[d - devaudio0]; |
365 |
- if(!audio_id) return; |
|
369 |
+ if(!audio_id) return 1; |
|
366 | 370 |
if(!w) { |
367 | 371 |
if(b0 == 0x2) |
368 | 372 |
poke16(d->dat, 0x2, c->i); |
... | ... |
@@ -379,9 +383,10 @@ audio_talk(Device *d, Uint8 b0, Uint8 w) |
379 | 383 |
SDL_UnlockAudioDevice(audio_id); |
380 | 384 |
SDL_PauseAudioDevice(audio_id, 0); |
381 | 385 |
} |
386 |
+ return 1; |
|
382 | 387 |
} |
383 | 388 |
|
384 |
-static void |
|
389 |
+static int |
|
385 | 390 |
datetime_talk(Device *d, Uint8 b0, Uint8 w) |
386 | 391 |
{ |
387 | 392 |
time_t seconds = time(NULL); |
... | ... |
@@ -398,14 +403,16 @@ datetime_talk(Device *d, Uint8 b0, Uint8 w) |
398 | 403 |
d->dat[0xa] = t->tm_isdst; |
399 | 404 |
(void)b0; |
400 | 405 |
(void)w; |
406 |
+ return 1; |
|
401 | 407 |
} |
402 | 408 |
|
403 |
-static void |
|
409 |
+static int |
|
404 | 410 |
nil_talk(Device *d, Uint8 b0, Uint8 w) |
405 | 411 |
{ |
406 | 412 |
(void)d; |
407 | 413 |
(void)b0; |
408 | 414 |
(void)w; |
415 |
+ return 1; |
|
409 | 416 |
} |
410 | 417 |
|
411 | 418 |
#pragma mark - Generics |
... | ... |
@@ -435,7 +442,6 @@ int |
435 | 442 |
uxn_halt(Uxn *u, Uint8 error, char *name, int id) |
436 | 443 |
{ |
437 | 444 |
fprintf(stderr, "Halted: %s %s#%04x, at 0x%04x\n", name, errors[error - 1], id, u->ram.ptr); |
438 |
- u->ram.ptr = 0; |
|
439 | 445 |
return 0; |
440 | 446 |
} |
441 | 447 |
|