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