Browse code

Add support for interrupting Uxn during execution.

Andrew Alderwick authored on 12/01/2022 11:33:49
Showing 5 changed files
... ...
@@ -22,7 +22,7 @@ The debugger will catch stack errors that arise after that point.
22 22
 
23 23
 @debug ( pc* -- )
24 24
 	#0001 SUB2 .System/eaddr DEO2
25
-	.System/ecode DEIk #f8 AND #06 EOR SWP DEO
25
+	.System/ecode DEIk #07 EOR SWP DEO
26 26
 	,debug-vector/main JMP
27 27
 
28 28
 @debug-vector ( -> )
... ...
@@ -126,18 +126,19 @@ The debugger will catch stack errors that arise after that point.
126 126
 		:&rst-msg :&overflow-msg
127 127
 		:&wst-msg :&divzero-msg
128 128
 		:&rst-msg :&divzero-msg
129
+		:&emulator-msg :&interrupt-msg
129 130
 		:&userdef-msg :&breakpoint-msg
130
-		:&userdef-msg :&custom-msg
131 131
 
132 132
 	&halted-msg "Halted: 2000 ( #0002, at 0x0100 )
133 133
 	&wst-msg "Working-stack 2000
134 134
 	&rst-msg "Return-stack 2000
135
+	&emulator-msg "Emulator 2000
135 136
 	&userdef-msg "User-defined 2000
136 137
 	&underflow-msg "underflow 00
137 138
 	&overflow-msg "overflow 00
138 139
 	&divzero-msg "division 20 "by 20 "zero 00
140
+	&interrupt-msg "interrupt 00
139 141
 	&breakpoint-msg "breakpoint 00
140
-	&custom-msg "custom 20 "error 00
141 142
 	&executing-msg 20 "executing 2000
142 143
 	&at-msg 20 "at 20 "0x 00
143 144
 	&contents-msg "contents: 00
... ...
@@ -29,12 +29,12 @@ WITH REGARD TO THIS SOFTWARE.
29 29
 #define DEVR(o, d, x) { dev = (d); o = dev->dei(dev, (x) & 0x0f); if(bs) { o = (o << 8) + dev->dei(dev, ((x) + 1) & 0x0f); } }
30 30
 #define DEVW8(x, y) { dev->dat[(x) & 0xf] = y; dev->deo(dev, (x) & 0x0f); }
31 31
 #define DEVW(d, x, y) { dev = (d); if(bs) { DEVW8((x), (y) >> 8); DEVW8((x) + 1, (y)); } else { DEVW8((x), (y)) } }
32
-#define WARP(x) { if(bs) pc = (x); else pc += (Sint8)(x); }
33 32
 
34 33
 int
35 34
 uxn_eval(Uxn *u, Uint16 pc)
36 35
 {
37 36
 	unsigned int a, b, c, j, k, bs, instr, errcode;
37
+	Uint16 warp_count = 0;
38 38
 	Uint8 kptr, *sp;
39 39
 	Stack *src, *dst;
40 40
 	Device *dev;
... ...
@@ -72,9 +72,9 @@ uxn_eval(Uxn *u, Uint16 pc)
72 72
 		case 0x09: /* NEQ */ POP(a) POP(b) PUSH8(src, b != a) break;
73 73
 		case 0x0a: /* GTH */ POP(a) POP(b) PUSH8(src, b > a) break;
74 74
 		case 0x0b: /* LTH */ POP(a) POP(b) PUSH8(src, b < a) break;
75
-		case 0x0c: /* JMP */ POP(a) WARP(a) break;
76
-		case 0x0d: /* JCN */ POP(a) POP8(b) if(b) WARP(a) break;
77
-		case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) WARP(a) break;
75
+		case 0x0c: /* JMP */ POP(a) goto warp;
76
+		case 0x0d: /* JCN */ POP(a) POP8(b) if(b) goto warp; break;
77
+		case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) goto warp;
78 78
 		case 0x0f: /* STH */ POP(a) PUSH(dst, a) break;
79 79
 		/* Memory */
80 80
 		case 0x10: /* LDZ */ POP8(a) PEEK(b, a) PUSH(src, b) break;
... ...
@@ -95,6 +95,11 @@ uxn_eval(Uxn *u, Uint16 pc)
95 95
 		case 0x1e: /* EOR */ POP(a) POP(b) PUSH(src, b ^ a) break;
96 96
 		case 0x1f: /* SFT */ POP8(a) POP(b) c = b >> (a & 0x0f) << ((a & 0xf0) >> 4); PUSH(src, c) break;
97 97
 		}
98
+		continue;
99
+
100
+		warp:
101
+		if(bs) pc = a; else pc += (Sint8)(a);
102
+		if(!++warp_count && uxn_interrupt(u)) return uxn_halt(u, 6, pc - 1);
98 103
 	}
99 104
 	return 1;
100 105
 
... ...
@@ -51,4 +51,5 @@ typedef struct Uxn {
51 51
 int uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devices, Stack *wst, Stack *rst);
52 52
 int uxn_eval(Uxn *u, Uint16 pc);
53 53
 int uxn_halt(Uxn *u, Uint8 error, Uint16 addr);
54
+int uxn_interrupt(Uxn *u);
54 55
 Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8));
... ...
@@ -20,6 +20,12 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
20 20
 WITH REGARD TO THIS SOFTWARE.
21 21
 */
22 22
 
23
+int
24
+uxn_interrupt(Uxn *u)
25
+{
26
+	return 0;
27
+}
28
+
23 29
 static int
24 30
 error(char *msg, const char *err)
25 31
 {
... ...
@@ -84,6 +84,12 @@ audio_finished_handler(UxnAudio *c)
84 84
 	SDL_PushEvent(&event);
85 85
 }
86 86
 
87
+int
88
+uxn_interrupt(Uxn *u)
89
+{
90
+	return 0;
91
+}
92
+
87 93
 static int
88 94
 stdin_handler(void *p)
89 95
 {