Add support for interrupting Uxn during execution.

This commit is contained in:
Andrew Alderwick 2022-01-12 11:33:49 +00:00
parent b1ba95336c
commit 41de322a75
5 changed files with 26 additions and 7 deletions

View File

@ -22,7 +22,7 @@ The debugger will catch stack errors that arise after that point.
@debug ( pc* -- ) @debug ( pc* -- )
#0001 SUB2 .System/eaddr DEO2 #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/main JMP
@debug-vector ( -> ) @debug-vector ( -> )
@ -126,18 +126,19 @@ The debugger will catch stack errors that arise after that point.
:&rst-msg :&overflow-msg :&rst-msg :&overflow-msg
:&wst-msg :&divzero-msg :&wst-msg :&divzero-msg
:&rst-msg :&divzero-msg :&rst-msg :&divzero-msg
:&emulator-msg :&interrupt-msg
:&userdef-msg :&breakpoint-msg :&userdef-msg :&breakpoint-msg
:&userdef-msg :&custom-msg
&halted-msg "Halted: 2000 ( #0002, at 0x0100 ) &halted-msg "Halted: 2000 ( #0002, at 0x0100 )
&wst-msg "Working-stack 2000 &wst-msg "Working-stack 2000
&rst-msg "Return-stack 2000 &rst-msg "Return-stack 2000
&emulator-msg "Emulator 2000
&userdef-msg "User-defined 2000 &userdef-msg "User-defined 2000
&underflow-msg "underflow 00 &underflow-msg "underflow 00
&overflow-msg "overflow 00 &overflow-msg "overflow 00
&divzero-msg "division 20 "by 20 "zero 00 &divzero-msg "division 20 "by 20 "zero 00
&interrupt-msg "interrupt 00
&breakpoint-msg "breakpoint 00 &breakpoint-msg "breakpoint 00
&custom-msg "custom 20 "error 00
&executing-msg 20 "executing 2000 &executing-msg 20 "executing 2000
&at-msg 20 "at 20 "0x 00 &at-msg 20 "at 20 "0x 00
&contents-msg "contents: 00 &contents-msg "contents: 00

View File

@ -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 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 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 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 int
uxn_eval(Uxn *u, Uint16 pc) uxn_eval(Uxn *u, Uint16 pc)
{ {
unsigned int a, b, c, j, k, bs, instr, errcode; unsigned int a, b, c, j, k, bs, instr, errcode;
Uint16 warp_count = 0;
Uint8 kptr, *sp; Uint8 kptr, *sp;
Stack *src, *dst; Stack *src, *dst;
Device *dev; 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 0x09: /* NEQ */ POP(a) POP(b) PUSH8(src, b != a) break;
case 0x0a: /* GTH */ 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 0x0b: /* LTH */ POP(a) POP(b) PUSH8(src, b < a) break;
case 0x0c: /* JMP */ POP(a) WARP(a) break; case 0x0c: /* JMP */ POP(a) goto warp;
case 0x0d: /* JCN */ POP(a) POP8(b) if(b) WARP(a) break; case 0x0d: /* JCN */ POP(a) POP8(b) if(b) goto warp; break;
case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) WARP(a) break; case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) goto warp;
case 0x0f: /* STH */ POP(a) PUSH(dst, a) break; case 0x0f: /* STH */ POP(a) PUSH(dst, a) break;
/* Memory */ /* Memory */
case 0x10: /* LDZ */ POP8(a) PEEK(b, a) PUSH(src, b) break; 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 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; 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; return 1;

View File

@ -51,4 +51,5 @@ typedef struct Uxn {
int uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devices, Stack *wst, Stack *rst); int uxn_boot(Uxn *u, Uint8 *ram, Uint8 *devices, Stack *wst, Stack *rst);
int uxn_eval(Uxn *u, Uint16 pc); int uxn_eval(Uxn *u, Uint16 pc);
int uxn_halt(Uxn *u, Uint8 error, Uint16 addr); 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)); Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8));

View File

@ -20,6 +20,12 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
int
uxn_interrupt(Uxn *u)
{
return 0;
}
static int static int
error(char *msg, const char *err) error(char *msg, const char *err)
{ {

View File

@ -84,6 +84,12 @@ audio_finished_handler(UxnAudio *c)
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
int
uxn_interrupt(Uxn *u)
{
return 0;
}
static int static int
stdin_handler(void *p) stdin_handler(void *p)
{ {