Browse code

Halt when talk function returns false, since setting ram.ptr no longer works

Andrew Alderwick authored on 07/09/2021 21:11:52
Showing 5 changed files
... ...
@@ -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