uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

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:
Mprojects/library/debugger.tal | 7++++---
Msrc/uxn.c | 13+++++++++----
Msrc/uxn.h | 1+
Msrc/uxncli.c | 6++++++
Msrc/uxnemu.c | 6++++++
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) {