commit 41de322a75b0d505529d97f2f7844eb0e1ae8158
parent b1ba95336c5208bbf0f7a15b294007e9ccf9bfbc
Author: Andrew Alderwick <andrew@alderwick.co.uk>
Date: Wed, 12 Jan 2022 11:33:49 +0000
Add support for interrupting Uxn during execution.
Diffstat:
5 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/projects/library/debugger.tal b/projects/library/debugger.tal
@@ -22,7 +22,7 @@ The debugger will catch stack errors that arise after that point.
@debug ( pc* -- )
#0001 SUB2 .System/eaddr DEO2
- .System/ecode DEIk #f8 AND #06 EOR SWP DEO
+ .System/ecode DEIk #07 EOR SWP DEO
,debug-vector/main JMP
@debug-vector ( -> )
@@ -126,18 +126,19 @@ The debugger will catch stack errors that arise after that point.
:&rst-msg :&overflow-msg
:&wst-msg :&divzero-msg
:&rst-msg :&divzero-msg
+ :&emulator-msg :&interrupt-msg
:&userdef-msg :&breakpoint-msg
- :&userdef-msg :&custom-msg
&halted-msg "Halted: 2000 ( #0002, at 0x0100 )
&wst-msg "Working-stack 2000
&rst-msg "Return-stack 2000
+ &emulator-msg "Emulator 2000
&userdef-msg "User-defined 2000
&underflow-msg "underflow 00
&overflow-msg "overflow 00
&divzero-msg "division 20 "by 20 "zero 00
+ &interrupt-msg "interrupt 00
&breakpoint-msg "breakpoint 00
- &custom-msg "custom 20 "error 00
&executing-msg 20 "executing 2000
&at-msg 20 "at 20 "0x 00
&contents-msg "contents: 00
diff --git a/src/uxn.c b/src/uxn.c
@@ -29,12 +29,12 @@ WITH REGARD TO THIS SOFTWARE.
#define DEVR(o, d, x) { dev = (d); o = dev->dei(dev, (x) & 0x0f); if(bs) { o = (o << 8) + dev->dei(dev, ((x) + 1) & 0x0f); } }
#define DEVW8(x, y) { dev->dat[(x) & 0xf] = y; dev->deo(dev, (x) & 0x0f); }
#define DEVW(d, x, y) { dev = (d); if(bs) { DEVW8((x), (y) >> 8); DEVW8((x) + 1, (y)); } else { DEVW8((x), (y)) } }
-#define WARP(x) { if(bs) pc = (x); else pc += (Sint8)(x); }
int
uxn_eval(Uxn *u, Uint16 pc)
{
unsigned int a, b, c, j, k, bs, instr, errcode;
+ Uint16 warp_count = 0;
Uint8 kptr, *sp;
Stack *src, *dst;
Device *dev;
@@ -72,9 +72,9 @@ uxn_eval(Uxn *u, Uint16 pc)
case 0x09: /* NEQ */ POP(a) POP(b) PUSH8(src, b != a) break;
case 0x0a: /* GTH */ POP(a) POP(b) PUSH8(src, b > a) break;
case 0x0b: /* LTH */ POP(a) POP(b) PUSH8(src, b < a) break;
- case 0x0c: /* JMP */ POP(a) WARP(a) break;
- case 0x0d: /* JCN */ POP(a) POP8(b) if(b) WARP(a) break;
- case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) WARP(a) break;
+ case 0x0c: /* JMP */ POP(a) goto warp;
+ case 0x0d: /* JCN */ POP(a) POP8(b) if(b) goto warp; break;
+ case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) goto warp;
case 0x0f: /* STH */ POP(a) PUSH(dst, a) break;
/* Memory */
case 0x10: /* LDZ */ POP8(a) PEEK(b, a) PUSH(src, b) break;
@@ -95,6 +95,11 @@ uxn_eval(Uxn *u, Uint16 pc)
case 0x1e: /* EOR */ POP(a) POP(b) PUSH(src, b ^ a) break;
case 0x1f: /* SFT */ POP8(a) POP(b) c = b >> (a & 0x0f) << ((a & 0xf0) >> 4); PUSH(src, c) break;
}
+ continue;
+
+ warp:
+ if(bs) pc = a; else pc += (Sint8)(a);
+ if(!++warp_count && uxn_interrupt(u)) return uxn_halt(u, 6, pc - 1);
}
return 1;
diff --git a/src/uxn.h b/src/uxn.h
@@ -51,4 +51,5 @@ typedef struct Uxn {
int uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devices, Stack *wst, Stack *rst);
int uxn_eval(Uxn *u, Uint16 pc);
int uxn_halt(Uxn *u, Uint8 error, Uint16 addr);
+int uxn_interrupt(Uxn *u);
Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8));
diff --git a/src/uxncli.c b/src/uxncli.c
@@ -20,6 +20,12 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
+int
+uxn_interrupt(Uxn *u)
+{
+ return 0;
+}
+
static int
error(char *msg, const char *err)
{
diff --git a/src/uxnemu.c b/src/uxnemu.c
@@ -84,6 +84,12 @@ audio_finished_handler(UxnAudio *c)
SDL_PushEvent(&event);
}
+int
+uxn_interrupt(Uxn *u)
+{
+ return 0;
+}
+
static int
stdin_handler(void *p)
{