| ... | ... |
@@ -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)); |