aboutsummaryrefslogtreecommitdiff
path: root/arm9/source/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/source/core.c')
-rw-r--r--arm9/source/core.c851
1 files changed, 371 insertions, 480 deletions
diff --git a/arm9/source/core.c b/arm9/source/core.c
index 26c7bb0..21587b4 100644
--- a/arm9/source/core.c
+++ b/arm9/source/core.c
@@ -1,528 +1,419 @@
-#include <nds.h>
-#include "bang.h"
#include "core.h"
-#include "debug.h"
-void reset_br(Bedrock *br) {
- // TODO
+// Reset a Bedrock instance.
+void br_reset(Bedrock *br) {
+ br->ip = 0;
+ br->wst.p = 0;
+ br->rst.p = 0;
+ dev_reset(&br->dev);
}
-// Load a program into an instance.
-void start_br(Bedrock *br, u8 program[], int size) {
- reset_br(br);
- memcpy(&br->prg.mem, program, size);
- br->alive = TRUE;
- br->awake = TRUE;
- // br->scr.nds = &scr_main;
+// Load a new program into a Bedrock instance.
+void br_load(Bedrock *br, u8 bytecode[], int length) {
+ br_reset(br);
+ memcpy(&br->mem, bytecode, MIN(length, 65536));
+ br->alive = true;
+ br->awake = true;
}
-void run_br(Bedrock *br) {
- if (br->awake) {
- switch (evaluate(br, 65535)) {
- case SIG_HALT: br->alive = FALSE; black_screen(br->scr.nds); br = NULL; return;
- case SIG_SLEEP: br->awake = FALSE; return;
- case SIG_DB1: debug_stacks(br); return;
- case SIG_DB4: debug_assert(br); return;
- default: return;
- }
- }
-}
-
-void rouse_br(Bedrock *br) {
- if (TEST(br->sys.sleep, 0x8000)) { // SYSTEM
- br->awake = TRUE;
- br->sys.wake = 0x0;
- return;
- }
- if (TEST(br->sys.sleep, 0x0400)) { // SCREEN
- if (br->scr.wake) {
- br->scr.wake = FALSE;
- br->awake = TRUE;
- br->sys.wake = 0x5;
+// Attempt to wake a Bedrock instance.
+// TODO: Redo this.
+void br_rouse(Bedrock *br) {
+ if (TEST(br->dev.system.sleep, 0x0400)) { // SCREEN
+ if (br->dev.screen.wake) {
+ br->dev.screen.wake = false;
+ br->dev.system.wake = 0x5;
+ br->awake = true;
return;
}
}
- if (TEST(br->sys.sleep, 0x0800)) { // INPUT
- if (br->inp.wake) {
- br->inp.wake = FALSE;
- br->awake = TRUE;
- br->sys.wake = 0x4;
+ if (TEST(br->dev.system.sleep, 0x0800)) { // INPUT
+ if (br->dev.input.wake) {
+ br->dev.input.wake = false;
+ br->dev.system.wake = 0x4;
+ br->awake = true;
return;
}
}
- if (TEST(br->sys.sleep, 0x1000)) { // CLOCK
- if (check_timers(&br->clk)) {
- br->awake = TRUE;
- br->sys.wake = 0x3;
+ if (TEST(br->dev.system.sleep, 0x1000)) { // CLOCK
+ if (clock_check_timers(&br->dev.clock)) {
+ br->dev.system.wake = 0x3;
+ br->awake = true;
return;
}
}
-}
-
-u8 dev_read(Bedrock *br, u8 port) {
- switch(port) {
-// SYSTEM DEVICE
- // TODO: name and author
- case 0x00: return rb_read(&br->sys.name);
- case 0x01: return rb_read(&br->sys.authors);
- case 0x02: return 0x00; // program memory size
- case 0x03: return 0x00; // program memory size
- case 0x04: return 0x00; // working stack size
- case 0x05: return 0x00; // return stack size
- case 0x06: return devices_high();
- case 0x07: return devices_low();
- case 0x0A: return br->sys.wake;
-// MEMORY DEVICE
- case 0x10: return mem_read1(&br->mem);
- case 0x11: return mem_read1(&br->mem);
- case 0x12: return HIGH(br->mem.offset1);
- case 0x13: return LOW(br->mem.offset1);
- case 0x14: return br->mem.page1;
- case 0x15: return br->mem.byte1;
- case 0x16: return HIGH(br->mem.count);
- case 0x17: return LOW(br->mem.count);
- case 0x18: return mem_read2(&br->mem);
- case 0x19: return mem_read2(&br->mem);
- case 0x1A: return HIGH(br->mem.offset2);
- case 0x1B: return LOW(br->mem.offset2);
- case 0x1C: return br->mem.page2;
- case 0x1D: return br->mem.byte2;
-// MATH DEVICE
- case 0x20: return HIGH(br->math.op1);
- case 0x21: return LOW(br->math.op1);
- case 0x22: return HIGH(br->math.op2);
- case 0x23: return LOW(br->math.op2);
- case 0x24: return HIGH(get_sqrt(&br->math));
- case 0x25: return LOW(get_sqrt(&br->math));
- case 0x26: return HIGH(get_atan(&br->math));
- case 0x27: return LOW(get_atan(&br->math));
- case 0x28: return H_HIGH(get_prod(&br->math));
- case 0x29: return H_LOW(get_prod(&br->math));
- case 0x2A: return L_HIGH(get_prod(&br->math));
- case 0x2B: return L_LOW(get_prod(&br->math));
- case 0x2C: return HIGH(get_quot(&br->math));
- case 0x2D: return LOW(get_quot(&br->math));
- case 0x2E: return HIGH( get_rem(&br->math));
- case 0x2F: return LOW( get_rem(&br->math));
-// CLOCK DEVICE
- case 0x30: return YEAR(get_datetime());
- case 0x31: return MONTH(get_datetime());
- case 0x32: return DAY(get_datetime());
- case 0x33: return HOUR(get_datetime());
- case 0x34: return MINUTE(get_datetime());
- case 0x35: return SECOND(get_datetime());
- case 0x36: return HIGH(get_uptime()-br->clk.start);
- case 0x37: return LOW(get_uptime()-br->clk.start);
- case 0x38: return get_timer_high(&br->clk.t1);
- case 0x39: return get_timer_low( &br->clk.t1);
- case 0x3A: return get_timer_high(&br->clk.t2);
- case 0x3B: return get_timer_low( &br->clk.t2);
- case 0x3C: return get_timer_high(&br->clk.t3);
- case 0x3D: return get_timer_low( &br->clk.t3);
- case 0x3E: return get_timer_high(&br->clk.t4);
- case 0x3F: return get_timer_low( &br->clk.t4);
-// INPUT DEVICE
- case 0x40: return BOOL(br->inp.pointer);
- case 0x41: return br->inp.pointer << 7;
- case 0x44: return HIGH(br->inp.x);
- case 0x45: return LOW(br->inp.x);
- case 0x46: return HIGH(br->inp.y);
- case 0x47: return LOW(br->inp.y);
- case 0x48: return BOOL(is_keyboard_open());
- case 0x49: return cb_read_byte(&br->inp.keybuffer);
- case 0x4A: return br->inp.navigation;
- case 0x4C: return br->inp.gamepad;
-// SCREEN DEVICE
- case 0x50: return HIGH(PIXELS_WIDTH);
- case 0x51: return LOW(PIXELS_WIDTH);
- case 0x52: return HIGH(PIXELS_HEIGHT);
- case 0x53: return LOW(PIXELS_HEIGHT);
- case 0x54: return HIGH(br->scr.x);
- case 0x55: return LOW(br->scr.x);
- case 0x56: return HIGH(br->scr.y);
- case 0x57: return LOW(br->scr.y);
-// FILE DEVICE
- case 0xA0: return BOOL(br->fs.open);
- case 0xA1: return BOOL(br->fs.success);
- case 0xA2: return pb_read(&br->fs.path);
- case 0xA3: return BOOL(br->fs.is_dir);
- case 0xA4: return fs_read_byte(&br->fs);
- case 0xA5: return fs_read_byte(&br->fs);
- case 0xA6: return pb_read(&br->fs.child_path);
- case 0xA7: return BOOL(br->fs.child_is_dir);
- case 0xA8: return H_HIGH(br->fs.pointer);
- case 0xA9: return H_LOW(br->fs.pointer);
- case 0xAA: return L_HIGH(br->fs.pointer);
- case 0xAB: return L_LOW(br->fs.pointer);
- case 0xAC: return H_HIGH(br->fs.length);
- case 0xAD: return H_LOW(br->fs.length);
- case 0xAE: return L_HIGH(br->fs.length);
- case 0xAF: return L_LOW(br->fs.length);
-
- default: return 0;
- }
-}
-
-Signal dev_write(Bedrock *br, u8 port, u8 v) {
- switch(port) {
-// SYSTEM DEVICE
- case 0x00: rb_reset(&br->sys.name); return 0;
- case 0x01: rb_reset(&br->sys.authors); return 0;
- case 0x08: SET_HIGH(br->sys.sleep,v); return 0;
- case 0x09: SET_LOW(br->sys.sleep,v); return SIG_SLEEP;
-// MEMORY DEVICE
- case 0x10: mem_write1(&br->mem,v); return 0;
- case 0x11: mem_write1(&br->mem,v); return 0;
- case 0x12: SET_HIGH(br->mem.offset1,v); mem_load_cache1(&br->mem); return 0;
- case 0x13: SET_LOW(br->mem.offset1,v); mem_load_cache1(&br->mem); return 0;
- case 0x14: br->mem.page1=v; mem_get_page1(&br->mem); return 0;
- case 0x15: br->mem.byte1=v; return 0;
- case 0x16: SET_HIGH(br->mem.count_write,v); return 0;
- case 0x17: SET_LOW(br->mem.count_write,v); mem_allocate(&br->mem); return 0;
- case 0x18: mem_write2(&br->mem,v); return 0;
- case 0x19: mem_write2(&br->mem,v); return 0;
- case 0x1A: SET_HIGH(br->mem.offset2,v); mem_load_cache2(&br->mem); return 0;
- case 0x1B: SET_LOW(br->mem.offset2,v); mem_load_cache2(&br->mem); return 0;
- case 0x1C: br->mem.page2=v; mem_get_page2(&br->mem); return 0;
- case 0x1D: br->mem.byte2=v; return 0;
- case 0x1E: SET_HIGH(br->mem.copy_write,v); return 0;
- case 0x1F: SET_LOW(br->mem.copy_write,v); mem_do_copy(&br->mem); return 0;
-// MATH DEVICE
- case 0x20: set_op1_high(&br->math,v); return 0;
- case 0x21: set_op1_low( &br->math,v); return 0;
- case 0x22: set_op2_high(&br->math,v); return 0;
- case 0x23: set_op2_low( &br->math,v); return 0;
-// CLOCK DEVICE
- // TODO: Set time and date
- case 0x38: set_timer_high(&br->clk.t1,v); return 0;
- case 0x39: set_timer_low( &br->clk.t1,v); return 0;
- case 0x3A: set_timer_high(&br->clk.t2,v); return 0;
- case 0x3B: set_timer_low( &br->clk.t2,v); return 0;
- case 0x3C: set_timer_high(&br->clk.t3,v); return 0;
- case 0x3D: set_timer_low( &br->clk.t3,v); return 0;
- case 0x3E: set_timer_high(&br->clk.t4,v); return 0;
- case 0x3F: set_timer_low( &br->clk.t4,v); return 0;
-// INPUT DEVICE
- case 0x48: v ? open_keyboard() : close_keyboard(); return 0;
- case 0x49: cb_clear(&br->inp.keybuffer); return 0;
-// SCREEN DEVICE
- case 0x54: SET_HIGH(br->scr.x,v); return 0;
- case 0x55: SET_LOW( br->scr.x,v); return 0;
- case 0x56: SET_HIGH(br->scr.y,v); return 0;
- case 0x57: SET_LOW( br->scr.y,v); return 0;
- case 0x58: set_palette_high(&br->scr,v); return 0;
- case 0x59: set_palette_low( &br->scr,v); return 0;
- case 0x5A: SET_HIGH(br->scr.colours,v); return 0;
- case 0x5B: SET_LOW( br->scr.colours,v); return 0;
- case 0x5C: push_sprite(&br->scr.sprite,v); return 0;
- case 0x5D: push_sprite(&br->scr.sprite,v); return 0;
- case 0x5E: draw_dispatch(&br->scr,v); return 0;
- case 0x5F: move_cursor(&br->scr,v); return 0;
-// LOCAL DEVICE
- case 0x86: std_write(v); return 0;
- case 0x87: std_write(v); return 0;
-// FILE DEVICE
- case 0xA0: fs_push_entry(&br->fs,v); return 0;
- case 0xA1: fs_push_action(&br->fs,v); return 0;
- case 0xA2: pb_reset(&br->fs.path,v); return 0;
- case 0xA3: fs_ascend(&br->fs); return 0;
- case 0xA4: fs_write_byte(&br->fs,v); return 0;
- case 0xA5: fs_write_byte(&br->fs,v); return 0;
- case 0xA6: pb_reset(&br->fs.child_path,v); return 0;
- case 0xA7: fs_descend(&br->fs); return 0;
- case 0xA8: SET_H_HIGH(br->fs.pointer_write,v); return 0;
- case 0xA9: SET_H_LOW(br->fs.pointer_write,v); return 0;
- case 0xAA: SET_L_HIGH(br->fs.pointer_write,v); return 0;
- case 0xAB: SET_L_LOW(br->fs.pointer_write,v); fs_seek(&br->fs); return 0;
- case 0xAC: SET_H_HIGH(br->fs.length_write,v); return 0;
- case 0xAD: SET_H_LOW(br->fs.length_write,v); return 0;
- case 0xAE: SET_L_HIGH(br->fs.length_write,v); return 0;
- case 0xAF: SET_L_LOW(br->fs.length_write,v); fs_resize(&br->fs); return 0;
-
- default: return SIG_NONE;
+ // System device is always chosen last.
+ if (TEST(br->dev.system.sleep, 0x8000)) { // SYSTEM
+ br->dev.system.wake = 0x0;
+ br->awake = true;
+ return;
}
}
-Signal dev_write_16(Bedrock *br, u8 port, u8 high, u8 low) {
- Signal s1 = dev_write(br, port, high);
- Signal s2 = dev_write(br, port+1, low);
- if (s1) { return s1; } else { return s2; }
+// Write a double to a device bus.
+Signal dev_write_double(DeviceBus *d, u8 port, u8 h, u8 l) {
+ Signal s1 = dev_write(d, port, h);
+ Signal s2 = dev_write(d, port+1, l);
+ return s1 ? s1 : s2;
}
-Signal evaluate(Bedrock *br, u16 count) {
+// Evaluate a Bedrock instance until a signal is emitted.
+Signal br_eval(Bedrock *br, int count) {
#define SIGNAL(s) if (s) { return s; } else { continue; };
- register u8 a, b, c, d, e, f;
- register u16 x, y;
+ // Helpers.
+ #define WST br->wst
+ #define RST br->rst
+ #define MEM br->mem
+ #define IP br->ip
+ #define WSTV(i) WST.mem[WST.p+(i)]
+ #define RSTV(i) RST.mem[RST.p+(i)]
+ // Push values to a stack.
+ #define WPSH1(x) WST.mem[WST.p++] = (x);
+ #define RPSH1(x) RST.mem[RST.p++] = (x);
+ #define WPSH2(x,y) WPSH1(x); WPSH1(y);
+ #define RPSH2(x,y) RPSH1(x); RPSH1(y);
+ #define WPSHD(d) WPSH1(HIGH((d))); WPSH1(LOW((d)));
+ #define RPSHD(d) RPSH1(HIGH((d))); RPSH1(LOW((d)));
+ #define WPSHB(b) WPSH1(BOOL(b));
+ #define RPSHB(b) RPSH1(BOOL(b));
+ // Pop values from a stack.
+ #define WPOP1(x) (x) = WST.mem[--WST.p];
+ #define RPOP1(x) (x) = RST.mem[--RST.p];
+ #define WPOP2(x,y) WPOP1(y); WPOP1(x);
+ #define RPOP2(x,y) RPOP1(y); RPOP1(x);
+ #define WPOPD(d) d = DOUBLE(WSTV(-2), WSTV(-1)); WST.p-=2;
+ #define RPOPD(d) d = DOUBLE(RSTV(-2), RSTV(-1)); RST.p-=2;
+ // Pop values without affecting the stack pointer.
+ #define WGET1(x) x = WSTV(-1);
+ #define RGET1(x) x = RSTV(-1);
+ #define WGET2(x,y) x = WSTV(-2); y = WSTV(-1);
+ #define RGET2(x,y) x = RSTV(-2); y = RSTV(-1);
+ #define WGETD(x) x = DOUBLE(WSTV(-2), WSTV(-1));
+ #define RGETD(x) x = DOUBLE(RSTV(-2), RSTV(-1));
+ // Read the next value in memory.
+ #define MPOP1(x) (x) = MEM[IP++];
+ #define MPOP2(x,y) MPOP1(x); MPOP1(y);
+ #define MPOPD(d) d = DOUBLE(MEM[IP], MEM[IP+1]); IP+=2;
+ // Read from a device port.
+ #define DGET1(p) dev_read(&br->dev, p)
+ #define DSET2(p,h,l) dev_write_double(&br->dev, p, h, l)
+
+ register u16 u, v, w, x, y, z;
register Signal sig;
- for (u16 i=0; i < count; i++) {
- switch (MLIT) {
+ while (count--) {
+ MPOP1(x);
+ switch (x) {
/* HLT */ case 0x00: return SIG_HALT;
-/* JMP */ case 0x01: WPOP2(a,b); PC=DOUBLE(a,b); continue;
-/* JCN */ case 0x02: WPOP2(b,c); WPOP1(a); if(a) PC=DOUBLE(b,c); continue;
-/* JCK */ case 0x03: WPOP2(b,c); WGET1(a); if(a) PC=DOUBLE(b,c); continue;
-/* LDA */ case 0x04: WPOP2(a,b); x=DOUBLE(a,b); WPSH1(MEM[x]); continue;
-/* STA */ case 0x05: WPOPD(x); WPOP1(a); MEM[x]=a; continue;
-/* LDD */ case 0x06: WPOP1(a); WPSH1(dev_read(br,a)); continue;
-/* STD */ case 0x07: WPOP1(b); WPOP1(a); sig=dev_write(br,b,a); SIGNAL(sig);
-/* PSH */ case 0x08: RPOP1(a); WPSH1(a); continue;
-/* POP */ case 0x09: WST.p-=1; continue;
-/* CPY */ case 0x0A: RGET1(a); WPSH1(a); continue;
-/* SPL */ case 0x0B: WPOP1(a); WPSH2(LEFT(a),RIGHT(a)); continue;
-/* DUP */ case 0x0C: WGET1(a); WPSH1(a); continue;
-/* OVR */ case 0x0D: WPOP1(b); WGET1(a); WPSH1(b); WPSH1(a); continue;
-/* SWP */ case 0x0E: WPOP1(b); WPOP1(a); WPSH1(b); WPSH1(a); continue;
-/* ROT */ case 0x0F: WPOP1(c); WPOP1(b); WPOP1(a); WPSH1(b); WPSH1(c); WPSH1(a); continue;
-/* ADD */ case 0x10: WPOP1(b); WSTV(-1)+=b; continue;
-/* SUB */ case 0x11: WPOP1(b); WSTV(-1)-=b; continue;
+/* PSH */ case 0x01: RPOP1(x); WPSH1(x); continue;
+/* POP */ case 0x02: WST.p-=1; continue;
+/* CPY */ case 0x03: RGET1(x); WPSH1(x); continue;
+/* DUP */ case 0x04: WGET1(x); WPSH1(x); continue;
+/* OVR */ case 0x05: WPOP1(y); WGET1(x); WPSH1(y); WPSH1(x); continue;
+/* SWP */ case 0x06: WPOP1(y); WPOP1(x); WPSH1(y); WPSH1(x); continue;
+/* ROT */ case 0x07: WPOP1(z); WPOP1(y); WPOP1(x); WPSH1(y); WPSH1(z); WPSH1(x); continue;
+/* JMP */ case 0x08: WPOPD(x); IP=x; continue;
+/* JMS */ case 0x09: WPOPD(x); RPSHD(IP); IP=x; continue;
+/* JCN */ case 0x0A: WPOPD(y); WPOP1(x); if(x) IP=y; continue;
+/* JCS */ case 0x0B: WPOPD(y); WPOP1(x); if(x) { RPSHD(IP); IP=y; } continue;
+/* LDA */ case 0x0C: WPOPD(x); WPSH1(MEM[x]); continue;
+/* STA */ case 0x0D: WPOPD(y); WPOP1(x); MEM[y]=x; continue;
+/* LDD */ case 0x0E: WPOP1(x); WPSH1(dev_read(&br->dev,x)); continue;
+/* STD */ case 0x0F: WPOP1(y); WPOP1(x); sig=dev_write(&br->dev,y,x); SIGNAL(sig);
+/* ADD */ case 0x10: WPOP1(x); WSTV(-1)+=x; continue;
+/* SUB */ case 0x11: WPOP1(x); WSTV(-1)-=x; continue;
/* INC */ case 0x12: WSTV(-1)+=1; continue;
/* DEC */ case 0x13: WSTV(-1)-=1; continue;
-/* LTH */ case 0x14: WPOP1(b); WPOP1(a); WPSH1(BOOL(a<b)); continue;
-/* GTH */ case 0x15: WPOP1(b); WPOP1(a); WPSH1(BOOL(a>b)); continue;
-/* EQU */ case 0x16: WPOP1(b); WPOP1(a); WPSH1(BOOL(a==b)); continue;
-/* NQK */ case 0x17: b=WSTV(-1); a=WSTV(-2); WPSH1(BOOL(a!=b)); continue;
-/* IOR */ case 0x18: WPOP1(b); WSTV(-1)|=b; continue;
-/* XOR */ case 0x19: WPOP1(b); WSTV(-1)^=b; continue;
-/* AND */ case 0x1A: WPOP1(b); WSTV(-1)&=b; continue;
-/* NOT */ case 0x1B: WSTV(-1)=~WSTV(-1); continue;
-/* SHF */ case 0x1C: WPOP1(b); WPOP1(a); x=SHF(a,b); WPSH1(x); continue;
-/* SHC */ case 0x1D: WPOP1(b); WPOP1(a); x=shc(a,b); WPSH1(x); continue;
-/* TAL */ case 0x1E: WSTV(-1)=TAL(WSTV(-1)); continue;
-/* REV */ case 0x1F: WSTV(-1)=rev(WSTV(-1)); continue;
+/* LTH */ case 0x14: WPOP1(y); WPOP1(x); WPSHB(x<y); continue;
+/* GTH */ case 0x15: WPOP1(y); WPOP1(x); WPSHB(x>y); continue;
+/* EQU */ case 0x16: WPOP1(y); WPOP1(x); WPSHB(x==y); continue;
+/* NQK */ case 0x17: y=WSTV(-1); x=WSTV(-2); WPSHB(x!=y); continue;
+/* SHL */ case 0x18: WPOP1(y); WPOP1(x); WPSH1(x<<y); continue;
+/* SHR */ case 0x19: WPOP1(y); WPOP1(x); WPSH1(x>>y); continue;
+/* ROL */ case 0x1A: WPOP1(y); WPOP1(x); WPSH1(ROL1(x,y)); continue;
+/* ROR */ case 0x1B: WPOP1(y); WPOP1(x); WPSH1(ROR1(x,y)); continue;
+/* IOR */ case 0x1C: WPOP1(x); WSTV(-1)|=x; continue;
+/* XOR */ case 0x1D: WPOP1(x); WSTV(-1)^=x; continue;
+/* AND */ case 0x1E: WPOP1(x); WSTV(-1)&=x; continue;
+/* NOT */ case 0x1F: WSTV(-1)=~WSTV(-1); continue;
/* NOP */ case 0x20: continue;
-/* JMS */ case 0x21: WPOP2(a,b); RPSHD(PC); PC=DOUBLE(a,b); continue;
-/* JCS */ case 0x22: WPOP2(b,c); WPOP1(a); if(a) {RPSHD(PC); PC=DOUBLE(b,c);} continue;
-/* JCK* */ case 0x23: WPOP2(c,d); WGETD(x); if(x) {PC=DOUBLE(c,d);} continue;
-/* LDA* */ case 0x24: WPOP2(a,b); x=DOUBLE(a,b); WPSH1(MEM[x]); WPSH1(MEM[x+1]); continue;
-/* STA* */ case 0x25: WPOPD(x); WPOP2(a,b); MEM[x]=a; MEM[x+1]=b; continue;
-/* LDD* */ case 0x26: WPOP1(a); WPSH1(dev_read(br,a)); WPSH1(dev_read(br,a+1)); continue;
-/* STD* */ case 0x27: WPOP1(c); WPOP2(a,b); sig=dev_write_16(br,c,a,b); SIGNAL(sig);
-/* PSH* */ case 0x28: RPOP2(a,b); WPSH2(a,b); continue;
-/* POP* */ case 0x29: WST.p-=2; continue;
-/* CPY* */ case 0x2A: RGET2(a,b); WPSH2(a,b); continue;
-/* SPL* */ case 0x2B: WPOP2(a,b); WPSH2(LEFT(a),RIGHT(a)); WPSH2(LEFT(b),RIGHT(b)); continue;
-/* DUP* */ case 0x2C: WGET2(a,b); WPSH2(a,b); continue;
-/* OVR* */ case 0x2D: WPOP2(c,d); WGET2(a,b); WPSH2(c,d); WPSH2(a,b); continue;
-/* SWP* */ case 0x2E: WPOP2(c,d); WPOP2(a,b); WPSH2(c,d); WPSH2(a,b); continue;
-/* ROT* */ case 0x2F: WPOP2(e,f); WPOP2(c,d); WPOP2(a,b); WPSH2(c,d); WPSH2(e,f); WPSH2(a,b); continue;
-/* ADD* */ case 0x30: WPOPD(y); WPOPD(x); WPSHD(x+y); continue;
-/* SUB* */ case 0x31: WPOPD(y); WPOPD(x); WPSHD(x-y); continue;
-/* INC* */ case 0x32: WPOPD(x); WPSHD(x+1); continue;
-/* DEC* */ case 0x33: WPOPD(x); WPSHD(x-1); continue;
-/* LTH* */ case 0x34: WPOPD(y); WPOPD(x); WPSH1(BOOL(x<y)); continue;
-/* GTH* */ case 0x35: WPOPD(y); WPOPD(x); WPSH1(BOOL(x>y)); continue;
-/* EQU* */ case 0x36: WPOP2(c,d); WPOP2(a,b); WPSH1(BOOL(a==c && b==d)); continue;
-/* NQK* */ case 0x37: d=WSTV(-1); c=WSTV(-2); b=WSTV(-3); a=WSTV(-4); WPSH1(BOOL(a!=c || b!=d)); continue;
-/* IOR* */ case 0x38: WPOP2(c,d); WSTV(-1)|=d; WSTV(-2)|=c; continue;
-/* XOR* */ case 0x39: WPOP2(c,d); WSTV(-1)^=d; WSTV(-2)^=c; continue;
-/* AND* */ case 0x3A: WPOP2(c,d); WSTV(-1)&=d; WSTV(-2)&=c; continue;
-/* NOT* */ case 0x3B: WSTV(-1)=~WSTV(-1); WSTV(-2)=~WSTV(-2); continue;
-/* SHF* */ case 0x3C: WPOP1(c); WPOPD(x); x=SHF(x,c); WPSHD(x); continue;
-/* SHC* */ case 0x3D: WPOP1(c); WPOPD(x); x=shcd(x,c); WPSHD(x); continue;
-/* TAL* */ case 0x3E: WPOP2(a,b); WPSH1(TAL(a)+TAL(b)); continue;
-/* REV* */ case 0x3F: WPOP2(a,b); WPSH1(rev(b)); WPSH1(rev(a)); continue;
+/* PSH: */ case 0x21: MPOP1(x); WPSH1(x); continue;
+/* POP: */ case 0x22: IP+=1; continue;
+/* CPY: */ case 0x23: MPOP1(x); RPSH1(x); WPSH1(x); continue;
+/* DUP: */ case 0x24: MPOP1(x); WPSH1(x); WPSH1(x); continue;
+/* OVR: */ case 0x25: MPOP1(y); WGET1(x); WPSH1(y); WPSH1(x); continue;
+/* SWP: */ case 0x26: MPOP1(y); WPOP1(x); WPSH1(y); WPSH1(x); continue;
+/* ROT: */ case 0x27: MPOP1(z); WPOP1(y); WPOP1(x); WPSH1(y); WPSH1(z); WPSH1(x); continue;
+/* JMP: */ case 0x28: MPOPD(x); IP=x; continue;
+/* JMS: */ case 0x29: MPOPD(x); RPSHD(IP); IP=x; continue;
+/* JCN: */ case 0x2A: MPOPD(y); WPOP1(x); if(x) IP=y; continue;
+/* JCS: */ case 0x2B: MPOPD(y); WPOP1(x); if(x) { RPSHD(IP); IP=y; } continue;
+/* LDA: */ case 0x2C: MPOPD(x); WPSH1(MEM[x]); continue;
+/* STA: */ case 0x2D: MPOPD(y); WPOP1(x); MEM[y]=x; continue;
+/* LDD: */ case 0x2E: MPOP1(x); WPSH1(dev_read(&br->dev,x)); continue;
+/* STD: */ case 0x2F: MPOP1(y); WPOP1(x); sig=dev_write(&br->dev,y,x); SIGNAL(sig);
+/* ADD: */ case 0x30: MPOP1(x); WSTV(-1)+=x; continue;
+/* SUB: */ case 0x31: MPOP1(x); WSTV(-1)-=x; continue;
+/* INC: */ case 0x32: MPOP1(x); WPSH1(x+1); continue;
+/* DEC: */ case 0x33: MPOP1(x); WPSH1(x-1); continue;
+/* LTH: */ case 0x34: MPOP1(y); WPOP1(x); WPSHB(x<y); continue;
+/* GTH: */ case 0x35: MPOP1(y); WPOP1(x); WPSHB(x>y); continue;
+/* EQU: */ case 0x36: MPOP1(y); WPOP1(x); WPSHB(x==y); continue;
+/* NQK: */ case 0x37: MPOP1(y); WGET1(x); WPSH1(y); WPSHB(x!=y); continue;
+/* SHL: */ case 0x38: MPOP1(y); WPOP1(x); WPSH1(x<<y); continue;
+/* SHR: */ case 0x39: MPOP1(y); WPOP1(x); WPSH1(x>>y); continue;
+/* ROL: */ case 0x3A: MPOP1(y); WPOP1(x); WPSH1(ROL1(x,y)); continue;
+/* ROR: */ case 0x3B: MPOP1(y); WPOP1(x); WPSH1(ROR1(x,y)); continue;
+/* IOR: */ case 0x3C: MPOP1(x); WSTV(-1)|=x; continue;
+/* XOR: */ case 0x3D: MPOP1(x); WSTV(-1)^=x; continue;
+/* AND: */ case 0x3E: MPOP1(x); WSTV(-1)&=x; continue;
+/* NOT: */ case 0x3F: MPOP1(x); WPSH1(~x); continue;
/* DB1 */ case 0x40: return SIG_DB1;
-/* JMP: */ case 0x41: MLIT2(a,b); PC=DOUBLE(a,b); continue;
-/* JCN: */ case 0x42: MLIT2(b,c); WPOP1(a); if(a) PC=DOUBLE(b,c); continue;
-/* JCK: */ case 0x43: MLIT2(b,c); WGET1(a); if(a) PC=DOUBLE(b,c); continue;
-/* LDA: */ case 0x44: MLIT2(a,b); x=DOUBLE(a,b); WPSH1(MEM[x]); continue;
-/* STA: */ case 0x45: MLITD(x); WPOP1(a); MEM[x]=a; continue;
-/* LDD: */ case 0x46: MLIT1(a); WPSH1(dev_read(br,a)); continue;
-/* STD: */ case 0x47: MLIT1(b); WPOP1(a); sig=dev_write(br,b,a); SIGNAL(sig);
-/* PSH: */ case 0x48: MLIT1(a); WPSH1(a); continue;
-/* POP: */ case 0x49: PC+=1; continue;
-/* CPY: */ case 0x4A: MLIT1(a); RPSH1(a); WPSH1(a); continue;
-/* SPL: */ case 0x4B: MLIT1(a); WPSH2(LEFT(a),RIGHT(a)); continue;
-/* DUP: */ case 0x4C: MLIT1(a); WPSH1(a); WPSH1(a); continue;
-/* OVR: */ case 0x4D: MLIT1(b); WGET1(a); WPSH1(b); WPSH1(a); continue;
-/* SWP: */ case 0x4E: MLIT1(b); WPOP1(a); WPSH1(b); WPSH1(a); continue;
-/* ROT: */ case 0x4F: MLIT1(c); WPOP1(b); WPOP1(a); WPSH1(b); WPSH1(c); WPSH1(a); continue;
-/* ADD: */ case 0x50: MLIT1(b); WSTV(-1)+=b; continue;
-/* SUB: */ case 0x51: MLIT1(b); WSTV(-1)-=b; continue;
-/* INC: */ case 0x52: MLIT1(a); WPSH1(a+1); continue;
-/* DEC: */ case 0x53: MLIT1(a); WPSH1(a-1); continue;
-/* LTH: */ case 0x54: MLIT1(b); WPOP1(a); WPSH1(BOOL(a<b)); continue;
-/* GTH: */ case 0x55: MLIT1(b); WPOP1(a); WPSH1(BOOL(a>b)); continue;
-/* EQU: */ case 0x56: MLIT1(b); WPOP1(a); WPSH1(BOOL(a==b)); continue;
-/* NQK: */ case 0x57: MLIT1(b); WGET1(a); WPSH1(b); WPSH1(BOOL(a!=b)); continue;
-/* IOR: */ case 0x58: MLIT1(b); WSTV(-1)|=b; continue;
-/* XOR: */ case 0x59: MLIT1(b); WSTV(-1)^=b; continue;
-/* AND: */ case 0x5A: MLIT1(b); WSTV(-1)&=b; continue;
-/* NOT: */ case 0x5B: MLIT1(a); WPSH1(~a); continue;
-/* SHF: */ case 0x5C: MLIT1(b); WPOP1(a); x=SHF(a,b); WPSH1(x); continue;
-/* SHC: */ case 0x5D: MLIT1(b); WPOP1(a); x=shc(a,b); WPSH1(x); continue;
-/* TAL: */ case 0x5E: MLIT1(a); WPSH1(TAL(a)); continue;
-/* REV: */ case 0x5F: MLIT1(a); WPSH1(rev(a)); continue;
+/* PSH* */ case 0x41: RPOP2(x,y); WPSH2(x,y); continue;
+/* POP* */ case 0x42: WST.p-=2; continue;
+/* CPY* */ case 0x43: RGET2(x,y); WPSH2(x,y); continue;
+/* DUP* */ case 0x44: WGET2(x,y); WPSH2(x,y); continue;
+/* OVR* */ case 0x45: WPOP2(y,z); WGET2(w,x); WPSH2(y,z); WPSH2(w,x); continue;
+/* SWP* */ case 0x46: WPOP2(y,z); WPOP2(w,x); WPSH2(y,z); WPSH2(w,x); continue;
+/* ROT* */ case 0x47: WPOP2(y,z); WPOP2(w,x); WPOP2(u,v); WPSH2(w,x); WPSH2(y,z); WPSH2(u,v); continue;
+/* JMP* */ case 0x48: WPOPD(x); IP=x; continue;
+/* JMS* */ case 0x49: WPOPD(x); RPSHD(IP); IP=x; continue;
+/* JCN* */ case 0x4A: WPOPD(y); WPOPD(x); if(x) IP=y; continue;
+/* JCS* */ case 0x4B: WPOPD(y); WPOPD(x); if(x) { RPSHD(IP); IP=y; } continue;
+/* LDA* */ case 0x4C: WPOPD(x); WPSH2(MEM[x], MEM[x+1]); continue;
+/* STA* */ case 0x4D: WPOPD(z); WPOP2(x,y); MEM[z]=x; MEM[z+1]=y; continue;
+/* LDD* */ case 0x4E: WPOP1(x); WPSH1(DGET1(x)); WPSH1(DGET1(x+1)); continue;
+/* STD* */ case 0x4F: WPOP1(z); WPOP2(x,y); sig=DSET2(z,x,y); SIGNAL(sig);
+/* ADD* */ case 0x50: WPOPD(y); WPOPD(x); WPSHD(x+y); continue;
+/* SUB* */ case 0x51: WPOPD(y); WPOPD(x); WPSHD(x-y); continue;
+/* INC* */ case 0x52: WPOPD(x); WPSHD(x+1); continue;
+/* DEC* */ case 0x53: WPOPD(x); WPSHD(x-1); continue;
+/* LTH* */ case 0x54: WPOPD(y); WPOPD(x); WPSHB(x<y); continue;
+/* GTH* */ case 0x55: WPOPD(y); WPOPD(x); WPSHB(x>y); continue;
+/* EQU* */ case 0x56: WPOP2(y,z); WPOP2(w,x); WPSHB(w==y && x==z); continue;
+/* NQK* */ case 0x57: z=WSTV(-1); y=WSTV(-2); x=WSTV(-3); w=WSTV(-4); WPSHB(w!=y || x!=z); continue;
+/* SHL* */ case 0x58: WPOP1(y); WPOPD(x); WPSHD(x<<y); continue;
+/* SHR* */ case 0x59: WPOP1(y); WPOPD(x); WPSHD(x>>y); continue;
+/* ROL* */ case 0x5A: WPOP1(y); WPOPD(x); WPSHD(ROLD(x,y)); continue;
+/* ROR* */ case 0x5B: WPOP1(y); WPOPD(x); WPSHD(RORD(x,y)); continue;
+/* IOR* */ case 0x5C: WPOP2(x,y); WSTV(-1)|=y; WSTV(-2)|=x; continue;
+/* XOR* */ case 0x5D: WPOP2(x,y); WSTV(-1)^=y; WSTV(-2)^=x; continue;
+/* AND* */ case 0x5E: WPOP2(x,y); WSTV(-1)&=y; WSTV(-2)&=x; continue;
+/* NOT* */ case 0x5F: WSTV(-1)=~WSTV(-1); WSTV(-2)=~WSTV(-2); continue;
/* DB2 */ case 0x60: return SIG_DB2;
-/* JMS: */ case 0x61: MLIT2(a,b); RPSHD(PC); PC=DOUBLE(a,b); continue;
-/* JCS: */ case 0x62: MLIT2(b,c); WPOP1(a); if(a) {RPSHD(PC); PC=DOUBLE(b,c);} continue;
-/* JCK:* */ case 0x63: MLIT2(c,d); WGETD(x); if(x) {PC=DOUBLE(c,d);} continue;
-/* LDA:* */ case 0x64: MLIT2(a,b); x=DOUBLE(a,b); WPSH1(MEM[x]); WPSH1(MEM[x+1]); continue;
-/* STA:* */ case 0x65: MLITD(x); WPOP2(a,b); MEM[x]=a; MEM[x+1]=b; continue;
-/* LDD:* */ case 0x66: MLIT1(a); WPSH1(dev_read(br,a)); WPSH1(dev_read(br,a+1)); continue;
-/* STD:* */ case 0x67: MLIT1(c); WPOP2(a,b); sig=dev_write_16(br,c,a,b); SIGNAL(sig);
-/* PSH:* */ case 0x68: MLIT2(a,b); WPSH2(a,b); continue;
-/* POP:* */ case 0x69: PC+=2; continue;
-/* CPY:* */ case 0x6A: MLIT2(a,b); RPSH2(a,b); WPSH2(a,b); continue;
-/* SPL:* */ case 0x6B: MLIT2(a,b); WPSH2(LEFT(a),RIGHT(a)); WPSH2(LEFT(b),RIGHT(b)); continue;
-/* DUP:* */ case 0x6C: MLIT2(a,b); WPSH2(a,b); WPSH2(a,b); continue;
-/* OVR:* */ case 0x6D: MLIT2(c,d); WGET2(a,b); WPSH2(c,d); WPSH2(a,b); continue;
-/* SWP:* */ case 0x6E: MLIT2(c,d); WPOP2(a,b); WPSH2(c,d); WPSH2(a,b); continue;
-/* ROT:* */ case 0x6F: MLIT2(e,f); WPOP2(c,d); WPOP2(a,b); WPSH2(c,d); WPSH2(e,f); WPSH2(a,b); continue;
-/* ADD:* */ case 0x70: MLITD(y); WPOPD(x); WPSHD(x+y); continue;
-/* SUB:* */ case 0x71: MLITD(y); WPOPD(x); WPSHD(x-y); continue;
-/* INC:* */ case 0x72: MLITD(x); WPSHD(x+1); continue;
-/* DEC:* */ case 0x73: MLITD(x); WPSHD(x-1); continue;
-/* LTH:* */ case 0x74: MLITD(y); WPOPD(x); WPSH1(BOOL(x<y)); continue;
-/* GTH:* */ case 0x75: MLITD(y); WPOPD(x); WPSH1(BOOL(x>y)); continue;
-/* EQU:* */ case 0x76: MLIT2(c,d); WPOP2(a,b); WPSH1(BOOL(a==c && b==d)); continue;
-/* NQK:* */ case 0x77: MLIT2(c,d); WGET2(a,b); WPSH2(c,d); WPSH1(BOOL(a!=c || b!=d)); continue;
-/* IOR:* */ case 0x78: MLIT2(c,d); WSTV(-1)|=d; WSTV(-2)|=c; continue;
-/* XOR:* */ case 0x79: MLIT2(c,d); WSTV(-1)^=d; WSTV(-2)^=c; continue;
-/* AND:* */ case 0x7A: MLIT2(c,d); WSTV(-1)&=d; WSTV(-2)&=c; continue;
-/* NOT:* */ case 0x7B: MLIT2(a,b); WPSH2(~a,~b); continue;
-/* SHF:* */ case 0x7C: MLIT1(c); WPOPD(x); x=SHF(x,c); WPSHD(x); continue;
-/* SHC:* */ case 0x7D: MLIT1(c); WPOPD(x); x=shcd(x,c); WPSHD(x); continue;
-/* TAL:* */ case 0x7E: MLIT2(a,b); WPSH1(TAL(a)+TAL(b)); continue;
-/* REV:* */ case 0x7F: MLIT2(a,b); WPSH1(rev(b)); WPSH1(rev(a)); continue;
+/* PSH*: */ case 0x61: MPOP2(x,y); WPSH2(x,y); continue;
+/* POP*: */ case 0x62: IP+=2; continue;
+/* CPY*: */ case 0x63: MPOP2(x,y); RPSH2(x,y); WPSH2(x,y); continue;
+/* DUP*: */ case 0x64: MPOP2(x,y); WPSH2(x,y); WPSH2(x,y); continue;
+/* OVR*: */ case 0x65: MPOP2(y,z); WGET2(w,x); WPSH2(y,z); WPSH2(w,x); continue;
+/* SWP*: */ case 0x66: MPOP2(y,z); WPOP2(w,x); WPSH2(y,z); WPSH2(w,x); continue;
+/* ROT*: */ case 0x67: MPOP2(y,z); WPOP2(w,x); WPOP2(u,v); WPSH2(w,x); WPSH2(y,z); WPSH2(u,v); continue;
+/* JMP*: */ case 0x68: MPOPD(x); IP=x; continue;
+/* JMS*: */ case 0x69: MPOPD(x); RPSHD(IP); IP=x; continue;
+/* JCN*: */ case 0x6A: MPOPD(y); WPOPD(x); if(x) IP=y; continue;
+/* JCS*: */ case 0x6B: MPOPD(y); WPOPD(x); if(x) { RPSHD(IP); IP=y; } continue;
+/* LDA*: */ case 0x6C: MPOPD(x); WPSH2(MEM[x], MEM[x+1]); continue;
+/* STA*: */ case 0x6D: MPOPD(z); WPOP2(x,y); MEM[z]=x; MEM[z+1]=y; continue;
+/* LDD*: */ case 0x6E: MPOP1(x); WPSH1(DGET1(x)); WPSH1(DGET1(x+1)); continue;
+/* STD*: */ case 0x6F: MPOP1(z); WPOP2(x,y); sig=DSET2(z,x,y); SIGNAL(sig);
+/* ADD*: */ case 0x70: MPOPD(y); WPOPD(x); WPSHD(x+y); continue;
+/* SUB*: */ case 0x71: MPOPD(y); WPOPD(x); WPSHD(x-y); continue;
+/* INC*: */ case 0x72: MPOPD(x); WPSHD(x+1); continue;
+/* DEC*: */ case 0x73: MPOPD(x); WPSHD(x-1); continue;
+/* LTH*: */ case 0x74: MPOPD(y); WPOPD(x); WPSHB(x<y); continue;
+/* GTH*: */ case 0x75: MPOPD(y); WPOPD(x); WPSHB(x>y); continue;
+/* EQU*: */ case 0x76: MPOP2(y,z); WPOP2(w,x); WPSHB(w==y && x==z); continue;
+/* NQK*: */ case 0x77: MPOP2(y,z); WGET2(w,x); WPSH2(y,z); WPSHB(w!=y || x!=z); continue;
+/* SHL*: */ case 0x78: MPOP1(y); WPOPD(x); WPSHD(x<<y); continue;
+/* SHR*: */ case 0x79: MPOP1(y); WPOPD(x); WPSHD(x>>y); continue;
+/* ROL*: */ case 0x7A: MPOP1(y); WPOPD(x); WPSHD(ROLD(x,y)); continue;
+/* ROR*: */ case 0x7B: MPOP1(y); WPOPD(x); WPSHD(RORD(x,y)); continue;
+/* IOR*: */ case 0x7C: MPOP2(x,y); WSTV(-1)|=y; WSTV(-2)|=x; continue;
+/* XOR*: */ case 0x7D: MPOP2(x,y); WSTV(-1)^=y; WSTV(-2)^=x; continue;
+/* AND*: */ case 0x7E: MPOP2(x,y); WSTV(-1)&=y; WSTV(-2)&=x; continue;
+/* NOT*: */ case 0x7F: MPOP2(x,y); WPSH2(~x,~y); continue;
/* DB3 */ case 0x80: return SIG_DB3;
-/* JMPr */ case 0x81: RPOP2(a,b); PC=DOUBLE(a,b); continue;
-/* JCNr */ case 0x82: RPOP2(b,c); RPOP1(a); if(a) PC=DOUBLE(b,c); continue;
-/* JCKr */ case 0x83: RPOP2(b,c); RGET1(a); if(a) PC=DOUBLE(b,c); continue;
-/* LDAr */ case 0x84: RPOP2(a,b); x=DOUBLE(a,b); RPSH1(MEM[x]); continue;
-/* STAr */ case 0x85: RPOPD(x); RPOP1(a); MEM[x]=a; continue;
-/* LDDr */ case 0x86: RPOP1(a); RPSH1(dev_read(br,a)); continue;
-/* STDr */ case 0x87: RPOP1(b); RPOP1(a); sig=dev_write(br,b,a); SIGNAL(sig);
-/* PSHr */ case 0x88: WPOP1(a); RPSH1(a); continue;
-/* POPr */ case 0x89: RST.p-=1; continue;
-/* CPYr */ case 0x8A: WGET1(a); RPSH1(a); continue;
-/* SPLr */ case 0x8B: RPOP1(a); RPSH2(LEFT(a),RIGHT(a)); continue;
-/* DUPr */ case 0x8C: RGET1(a); RPSH1(a); continue;
-/* OVRr */ case 0x8D: RPOP1(b); RGET1(a); RPSH1(b); RPSH1(a); continue;
-/* SWPr */ case 0x8E: RPOP1(b); RPOP1(a); RPSH1(b); RPSH1(a); continue;
-/* ROTr */ case 0x8F: RPOP1(c); RPOP1(b); RPOP1(a); RPSH1(b); RPSH1(c); RPSH1(a); continue;
-/* ADDr */ case 0x90: RPOP1(b); RSTV(-1)+=b; continue;
-/* SUBr */ case 0x91: RPOP1(b); RSTV(-1)-=b; continue;
+/* PSHr */ case 0x81: WPOP1(x); RPSH1(x); continue;
+/* POPr */ case 0x82: RST.p-=1; continue;
+/* CPYr */ case 0x83: WGET1(x); RPSH1(x); continue;
+/* DUPr */ case 0x84: RGET1(x); RPSH1(x); continue;
+/* OVRr */ case 0x85: RPOP1(y); RGET1(x); RPSH1(y); RPSH1(x); continue;
+/* SWPr */ case 0x86: RPOP1(y); RPOP1(x); RPSH1(y); RPSH1(x); continue;
+/* ROTr */ case 0x87: RPOP1(z); RPOP1(y); RPOP1(x); RPSH1(y); RPSH1(z); RPSH1(x); continue;
+/* JMPr */ case 0x88: RPOPD(x); IP=x; continue;
+/* JMSr */ case 0x89: RPOPD(x); WPSHD(IP); IP=x; continue;
+/* JCNr */ case 0x8A: RPOPD(y); RPOP1(x); if(x) IP=y; continue;
+/* JCSr */ case 0x8B: RPOPD(y); RPOP1(x); if(x) { WPSHD(IP); IP=y; } continue;
+/* LDAr */ case 0x8C: RPOPD(x); RPSH1(MEM[x]); continue;
+/* STAr */ case 0x8D: RPOPD(y); RPOP1(x); MEM[y]=x; continue;
+/* LDDr */ case 0x8E: RPOP1(x); RPSH1(dev_read(&br->dev,x)); continue;
+/* STDr */ case 0x8F: RPOP1(y); RPOP1(x); sig=dev_write(&br->dev,y,x); SIGNAL(sig);
+/* ADDr */ case 0x90: RPOP1(x); RSTV(-1)+=x; continue;
+/* SUBr */ case 0x91: RPOP1(x); RSTV(-1)-=x; continue;
/* INCr */ case 0x92: RSTV(-1)+=1; continue;
/* DECr */ case 0x93: RSTV(-1)-=1; continue;
-/* LTHr */ case 0x94: RPOP1(b); RPOP1(a); RPSH1(BOOL(a<b)); continue;
-/* GTHr */ case 0x95: RPOP1(b); RPOP1(a); RPSH1(BOOL(a>b)); continue;
-/* EQUr */ case 0x96: RPOP1(b); RPOP1(a); RPSH1(BOOL(a==b)); continue;
-/* NQKr */ case 0x97: b=RSTV(-1); a=RSTV(-2); RPSH1(BOOL(a!=b)); continue;
-/* IORr */ case 0x98: RPOP1(b); RSTV(-1)|=b; continue;
-/* XORr */ case 0x99: RPOP1(b); RSTV(-1)^=b; continue;
-/* ANDr */ case 0x9A: RPOP1(b); RSTV(-1)&=b; continue;
-/* NOTr */ case 0x9B: RSTV(-1)=~RSTV(-1); continue;
-/* SHFr */ case 0x9C: RPOP1(b); RPOP1(a); x=SHF(a,b); RPSH1(x); continue;
-/* SHCr */ case 0x9D: RPOP1(b); RPOP1(a); x=shc(a,b); RPSH1(x); continue;
-/* TALr */ case 0x9E: RSTV(-1)=TAL(RSTV(-1)); continue;
-/* REVr */ case 0x9F: RSTV(-1)=rev(RSTV(-1)); continue;
+/* LTHr */ case 0x94: RPOP1(y); RPOP1(x); RPSHB(x<y); continue;
+/* GTHr */ case 0x95: RPOP1(y); RPOP1(x); RPSHB(x>y); continue;
+/* EQUr */ case 0x96: RPOP1(y); RPOP1(x); RPSHB(x==y); continue;
+/* NQKr */ case 0x97: y=RSTV(-1); x=RSTV(-2); RPSHB(x!=y); continue;
+/* SHLr */ case 0x98: RPOP1(y); RPOP1(x); RPSH1(x<<y); continue;
+/* SHRr */ case 0x99: RPOP1(y); RPOP1(x); RPSH1(x>>y); continue;
+/* ROLr */ case 0x9A: RPOP1(y); RPOP1(x); RPSH1(ROL1(x,y)); continue;
+/* RORr */ case 0x9B: RPOP1(y); RPOP1(x); RPSH1(ROR1(x,y)); continue;
+/* IORr */ case 0x9C: RPOP1(x); RSTV(-1)|=x; continue;
+/* XORr */ case 0x9D: RPOP1(x); RSTV(-1)^=x; continue;
+/* ANDr */ case 0x9E: RPOP1(x); RSTV(-1)&=x; continue;
+/* NOTr */ case 0x9F: RSTV(-1)=~RSTV(-1); continue;
/* DB4 */ case 0xA0: return SIG_DB4;
-/* JMSr */ case 0xA1: RPOP2(a,b); WPSHD(PC); PC=DOUBLE(a,b); continue;
-/* JCSr */ case 0xA2: RPOP2(b,c); RPOP1(a); if(a) {WPSHD(PC); PC=DOUBLE(b,c);} continue;
-/* JCKr* */ case 0xA3: RPOP2(c,d); RGETD(x); if(x) {PC=DOUBLE(c,d);} continue;
-/* LDAr* */ case 0xA4: RPOP2(a,b); x=DOUBLE(a,b); RPSH1(MEM[x]); RPSH1(MEM[x+1]); continue;
-/* STAr* */ case 0xA5: RPOPD(x); RPOP2(a,b); MEM[x]=a; MEM[x+1]=b; continue;
-/* LDDr* */ case 0xA6: RPOP1(a); RPSH1(dev_read(br,a)); RPSH1(dev_read(br,a+1)); continue;
-/* STDr* */ case 0xA7: RPOP1(c); RPOP2(a,b); sig=dev_write_16(br,c,a,b); SIGNAL(sig);
-/* PSHr* */ case 0xA8: WPOP2(a,b); RPSH2(a,b); continue;
-/* POPr* */ case 0xA9: RST.p-=2; continue;
-/* CPYr* */ case 0xAA: WGET2(a,b); RPSH2(a,b); continue;
-/* SPLr* */ case 0xAB: RPOP2(a,b); RPSH2(LEFT(a),RIGHT(a)); RPSH2(LEFT(b),RIGHT(b)); continue;
-/* DUPr* */ case 0xAC: RGET2(a,b); RPSH2(a,b); continue;
-/* OVRr* */ case 0xAD: RPOP2(c,d); RGET2(a,b); RPSH2(c,d); RPSH2(a,b); continue;
-/* SWPr* */ case 0xAE: RPOP2(c,d); RPOP2(a,b); RPSH2(c,d); RPSH2(a,b); continue;
-/* ROTr* */ case 0xAF: RPOP2(e,f); RPOP2(c,d); RPOP2(a,b); RPSH2(c,d); RPSH2(e,f); RPSH2(a,b); continue;
-/* ADDr* */ case 0xB0: RPOPD(y); RPOPD(x); RPSHD(x+y); continue;
-/* SUBr* */ case 0xB1: RPOPD(y); RPOPD(x); RPSHD(x-y); continue;
-/* INCr* */ case 0xB2: RPOPD(x); RPSHD(x+1); continue;
-/* DECr* */ case 0xB3: RPOPD(x); RPSHD(x-1); continue;
-/* LTHr* */ case 0xB4: RPOPD(y); RPOPD(x); RPSH1(BOOL(x<y)); continue;
-/* GTHr* */ case 0xB5: RPOPD(y); RPOPD(x); RPSH1(BOOL(x>y)); continue;
-/* EQUr* */ case 0xB6: RPOP2(c,d); RPOP2(a,b); RPSH1(BOOL(a==c && b==d)); continue;
-/* NQKr* */ case 0xB7: d=RSTV(-1); c=RSTV(-2); b=RSTV(-3); a=RSTV(-4); RPSH1(BOOL(a!=c || b!=d)); continue;
-/* IORr* */ case 0xB8: RPOP2(c,d); RSTV(-1)|=d; RSTV(-2)|=c; continue;
-/* XORr* */ case 0xB9: RPOP2(c,d); RSTV(-1)^=d; RSTV(-2)^=c; continue;
-/* ANDr* */ case 0xBA: RPOP2(c,d); RSTV(-1)&=d; RSTV(-2)&=c; continue;
-/* NOTr* */ case 0xBB: RSTV(-1)=~RSTV(-1); RSTV(-2)=~RSTV(-2); continue;
-/* SHFr* */ case 0xBC: RPOP1(c); RPOPD(x); x=SHF(x,c); RPSHD(x); continue;
-/* SHCr* */ case 0xBD: RPOP1(c); RPOPD(x); x=shcd(x,c); RPSHD(x); continue;
-/* TALr* */ case 0xBE: RPOP2(a,b); RPSH1(TAL(a)+TAL(b)); continue;
-/* REVr* */ case 0xBF: RPOP2(a,b); RPSH1(rev(b)); RPSH1(rev(a)); continue;
+/* PSHr: */ case 0xA1: MPOP1(x); RPSH1(x); continue;
+/* POPr: */ case 0xA2: IP+=1; continue;
+/* CPYr: */ case 0xA3: MPOP1(x); WPSH1(x); RPSH1(x); continue;
+/* DUPr: */ case 0xA4: MPOP1(x); RPSH1(x); RPSH1(x); continue;
+/* OVRr: */ case 0xA5: MPOP1(y); RGET1(x); RPSH1(y); RPSH1(x); continue;
+/* SWPr: */ case 0xA6: MPOP1(y); RPOP1(x); RPSH1(y); RPSH1(x); continue;
+/* ROTr: */ case 0xA7: MPOP1(z); RPOP1(y); RPOP1(x); RPSH1(y); RPSH1(z); RPSH1(x); continue;
+/* JMPr: */ case 0xA8: MPOPD(x); IP=x; continue;
+/* JMSr: */ case 0xA9: MPOPD(x); WPSHD(IP); IP=x; continue;
+/* JCNr: */ case 0xAA: MPOPD(y); RPOP1(x); if(x) IP=y; continue;
+/* JCSr: */ case 0xAB: MPOPD(y); RPOP1(x); if(x) { WPSHD(IP); IP=y; } continue;
+/* LDAr: */ case 0xAC: MPOPD(x); RPSH1(MEM[x]); continue;
+/* STAr: */ case 0xAD: MPOPD(y); RPOP1(x); MEM[y]=x; continue;
+/* LDDr: */ case 0xAE: MPOP1(x); RPSH1(dev_read(&br->dev,x)); continue;
+/* STDr: */ case 0xAF: MPOP1(y); RPOP1(x); sig=dev_write(&br->dev,y,x); SIGNAL(sig);
+/* ADDr: */ case 0xB0: MPOP1(x); RSTV(-1)+=x; continue;
+/* SUBr: */ case 0xB1: MPOP1(x); RSTV(-1)-=x; continue;
+/* INCr: */ case 0xB2: MPOP1(x); RPSH1(x+1); continue;
+/* DECr: */ case 0xB3: MPOP1(x); RPSH1(x-1); continue;
+/* LTHr: */ case 0xB4: MPOP1(y); RPOP1(x); RPSHB(x<y); continue;
+/* GTHr: */ case 0xB5: MPOP1(y); RPOP1(x); RPSHB(x>y); continue;
+/* EQUr: */ case 0xB6: MPOP1(y); RPOP1(x); RPSHB(x==y); continue;
+/* NQKr: */ case 0xB7: MPOP1(y); RGET1(x); RPSH1(y); RPSHB(x!=y); continue;
+/* SHLr: */ case 0xB8: MPOP1(y); RPOP1(x); RPSH1(x<<y); continue;
+/* SHRr: */ case 0xB9: MPOP1(y); RPOP1(x); RPSH1(x>>y); continue;
+/* ROLr: */ case 0xBA: MPOP1(y); RPOP1(x); RPSH1(ROL1(x,y)); continue;
+/* RORr: */ case 0xBB: MPOP1(y); RPOP1(x); RPSH1(ROR1(x,y)); continue;
+/* IORr: */ case 0xBC: MPOP1(x); RSTV(-1)|=x; continue;
+/* XORr: */ case 0xBD: MPOP1(x); RSTV(-1)^=x; continue;
+/* ANDr: */ case 0xBE: MPOP1(x); RSTV(-1)&=x; continue;
+/* NOTr: */ case 0xBF: MPOP1(x); RPSH1(~x); continue;
/* DB5 */ case 0xC0: return SIG_DB5;
-/* JMPr: */ case 0xC1: MLIT2(a,b); PC=DOUBLE(a,b); continue;
-/* JCNr: */ case 0xC2: MLIT2(b,c); RPOP1(a); if(a) PC=DOUBLE(b,c); continue;
-/* JCKr: */ case 0xC3: MLIT2(b,c); RGET1(a); if(a) PC=DOUBLE(b,c); continue;
-/* LDAr: */ case 0xC4: MLIT2(a,b); x=DOUBLE(a,b); RPSH1(MEM[x]); continue;
-/* STAr: */ case 0xC5: MLITD(x); RPOP1(a); MEM[x]=a; continue;
-/* LDDr: */ case 0xC6: MLIT1(a); RPSH1(dev_read(br,a)); continue;
-/* STDr: */ case 0xC7: MLIT1(b); RPOP1(a); sig=dev_write(br,b,a); SIGNAL(sig);
-/* PSHr: */ case 0xC8: MLIT1(a); RPSH1(a); continue;
-/* POPr: */ case 0xC9: PC+=1; continue;
-/* CPYr: */ case 0xCA: MLIT1(a); WPSH1(a); RPSH1(a); continue;
-/* SPLr: */ case 0xCB: MLIT1(a); RPSH2(LEFT(a),RIGHT(a)); continue;
-/* DUPr: */ case 0xCC: MLIT1(a); RPSH1(a); RPSH1(a); continue;
-/* OVRr: */ case 0xCD: MLIT1(b); RGET1(a); RPSH1(b); RPSH1(a); continue;
-/* SWPr: */ case 0xCE: MLIT1(b); RPOP1(a); RPSH1(b); RPSH1(a); continue;
-/* ROTr: */ case 0xCF: MLIT1(c); RPOP1(b); RPOP1(a); RPSH1(b); RPSH1(c); RPSH1(a); continue;
-/* ADDr: */ case 0xD0: MLIT1(b); RSTV(-1)+=b; continue;
-/* SUBr: */ case 0xD1: MLIT1(b); RSTV(-1)-=b; continue;
-/* INCr: */ case 0xD2: MLIT1(a); RPSH1(a+1); continue;
-/* DECr: */ case 0xD3: MLIT1(a); RPSH1(a-1); continue;
-/* LTHr: */ case 0xD4: MLIT1(b); RPOP1(a); RPSH1(BOOL(a<b)); continue;
-/* GTHr: */ case 0xD5: MLIT1(b); RPOP1(a); RPSH1(BOOL(a>b)); continue;
-/* EQUr: */ case 0xD6: MLIT1(b); RPOP1(a); RPSH1(BOOL(a==b)); continue;
-/* NQKr: */ case 0xD7: MLIT1(b); RGET1(a); RPSH1(b); RPSH1(BOOL(a!=b)); continue;
-/* IORr: */ case 0xD8: MLIT1(b); RSTV(-1)|=b; continue;
-/* XORr: */ case 0xD9: MLIT1(b); RSTV(-1)^=b; continue;
-/* ANDr: */ case 0xDA: MLIT1(b); RSTV(-1)&=b; continue;
-/* NOTr: */ case 0xDB: MLIT1(a); RPSH1(~a); continue;
-/* SHFr: */ case 0xDC: MLIT1(b); RPOP1(a); x=SHF(a,b); RPSH1(x); continue;
-/* SHCr: */ case 0xDD: MLIT1(b); RPOP1(a); x=shc(a,b); RPSH1(x); continue;
-/* TALr: */ case 0xDE: MLIT1(a); RPSH1(TAL(a)); continue;
-/* REVr: */ case 0xDF: MLIT1(a); RPSH1(rev(a)); continue;
+/* PSHr* */ case 0xC1: WPOP2(x,y); RPSH2(x,y); continue;
+/* POPr* */ case 0xC2: RST.p-=2; continue;
+/* CPYr* */ case 0xC3: WGET2(x,y); RPSH2(x,y); continue;
+/* DUPr* */ case 0xC4: RGET2(x,y); RPSH2(x,y); continue;
+/* OVRr* */ case 0xC5: RPOP2(y,z); RGET2(w,x); RPSH2(y,z); RPSH2(w,x); continue;
+/* SWPr* */ case 0xC6: RPOP2(y,z); RPOP2(w,x); RPSH2(y,z); RPSH2(w,x); continue;
+/* ROTr* */ case 0xC7: RPOP2(y,z); RPOP2(w,x); RPOP2(u,v); RPSH2(w,x); RPSH2(y,z); RPSH2(u,v); continue;
+/* JMPr* */ case 0xC8: RPOPD(x); IP=x; continue;
+/* JMSr* */ case 0xC9: RPOPD(x); WPSHD(IP); IP=x; continue;
+/* JCNr* */ case 0xCA: RPOPD(y); RPOPD(x); if(x) IP=y; continue;
+/* JCSr* */ case 0xCB: RPOPD(y); RPOPD(x); if(x) { WPSHD(IP); IP=y; } continue;
+/* LDAr* */ case 0xCC: RPOPD(x); RPSH2(MEM[x], MEM[x+1]); continue;
+/* STAr* */ case 0xCD: RPOPD(z); RPOP2(x,y); MEM[z]=x; MEM[z+1]=y; continue;
+/* LDDr* */ case 0xCE: RPOP1(x); RPSH1(DGET1(x)); RPSH1(DGET1(x+1)); continue;
+/* STDr* */ case 0xCF: RPOP1(z); RPOP2(x,y); sig=DSET2(z,x,y); SIGNAL(sig);
+/* ADDr* */ case 0xD0: RPOPD(y); RPOPD(x); RPSHD(x+y); continue;
+/* SUBr* */ case 0xD1: RPOPD(y); RPOPD(x); RPSHD(x-y); continue;
+/* INCr* */ case 0xD2: RPOPD(x); RPSHD(x+1); continue;
+/* DECr* */ case 0xD3: RPOPD(x); RPSHD(x-1); continue;
+/* LTHr* */ case 0xD4: RPOPD(y); RPOPD(x); RPSHB(x<y); continue;
+/* GTHr* */ case 0xD5: RPOPD(y); RPOPD(x); RPSHB(x>y); continue;
+/* EQUr* */ case 0xD6: RPOP2(y,z); RPOP2(w,x); RPSHB(w==y && x==z); continue;
+/* NQKr* */ case 0xD7: z=RSTV(-1); y=RSTV(-2); x=RSTV(-3); w=RSTV(-4); RPSHB(w!=y || x!=z); continue;
+/* SHLr* */ case 0xD8: RPOP1(y); RPOPD(x); RPSHD(x<<y); continue;
+/* SHRr* */ case 0xD9: RPOP1(y); RPOPD(x); RPSHD(x>>y); continue;
+/* ROLr* */ case 0xDA: RPOP1(y); RPOPD(x); RPSHD(ROLD(x,y)); continue;
+/* RORr* */ case 0xDB: RPOP1(y); RPOPD(x); RPSHD(RORD(x,y)); continue;
+/* IORr* */ case 0xDC: RPOP2(x,y); RSTV(-1)|=y; RSTV(-2)|=x; continue;
+/* XORr* */ case 0xDD: RPOP2(x,y); RSTV(-1)^=y; RSTV(-2)^=x; continue;
+/* ANDr* */ case 0xDE: RPOP2(x,y); RSTV(-1)&=y; RSTV(-2)&=x; continue;
+/* NOTr* */ case 0xDF: RSTV(-1)=~RSTV(-1); RSTV(-2)=~RSTV(-2); continue;
/* DB6 */ case 0xE0: return SIG_DB6;
-/* JMSr */ case 0xE1: MLIT2(a,b); WPSHD(PC); PC=DOUBLE(a,b); continue;
-/* JCSr */ case 0xE2: MLIT2(b,c); RPOP1(a); if(a) {WPSHD(PC); PC=DOUBLE(b,c);} continue;
-/* JCKr* */ case 0xE3: MLIT2(c,d); RGETD(x); if(x) {PC=DOUBLE(c,d);} continue;
-/* LDAr* */ case 0xE4: MLIT2(a,b); x=DOUBLE(a,b); RPSH1(MEM[x]); RPSH1(MEM[x+1]); continue;
-/* STAr* */ case 0xE5: MLITD(x); RPOP2(a,b); MEM[x]=a; MEM[x+1]=b; continue;
-/* LDDr* */ case 0xE6: MLIT1(a); RPSH1(dev_read(br,a)); RPSH1(dev_read(br,a+1)); continue;
-/* STDr* */ case 0xE7: MLIT1(c); RPOP2(a,b); sig=dev_write_16(br,c,a,b); SIGNAL(sig);
-/* PSHr* */ case 0xE8: MLIT2(a,b); RPSH2(a,b); continue;
-/* POPr* */ case 0xE9: PC+=2; continue;
-/* CPYr* */ case 0xEA: MLIT2(a,b); WPSH2(a,b); RPSH2(a,b); continue;
-/* SPLr* */ case 0xEB: MLIT2(a,b); RPSH2(LEFT(a),RIGHT(a)); RPSH2(LEFT(b),RIGHT(b)); continue;
-/* DUPr* */ case 0xEC: MLIT2(a,b); RPSH2(a,b); RPSH2(a,b); continue;
-/* OVRr* */ case 0xED: MLIT2(c,d); RGET2(a,b); RPSH2(c,d); RPSH2(a,b); continue;
-/* SWPr* */ case 0xEE: MLIT2(c,d); RPOP2(a,b); RPSH2(c,d); RPSH2(a,b); continue;
-/* ROTr* */ case 0xEF: MLIT2(e,f); RPOP2(c,d); RPOP2(a,b); RPSH2(c,d); RPSH2(e,f); RPSH2(a,b); continue;
-/* ADDr* */ case 0xF0: MLITD(y); RPOPD(x); RPSHD(x+y); continue;
-/* SUBr* */ case 0xF1: MLITD(y); RPOPD(x); RPSHD(x-y); continue;
-/* INCr* */ case 0xF2: MLITD(x); RPSHD(x+1); continue;
-/* DECr* */ case 0xF3: MLITD(x); RPSHD(x-1); continue;
-/* LTHr* */ case 0xF4: MLITD(y); RPOPD(x); RPSH1(BOOL(x<y)); continue;
-/* GTHr* */ case 0xF5: MLITD(y); RPOPD(x); RPSH1(BOOL(x>y)); continue;
-/* EQUr* */ case 0xF6: MLIT2(c,d); RPOP2(a,b); RPSH1(BOOL(a==c && b==d)); continue;
-/* NQKr* */ case 0xF7: MLIT2(c,d); RGET2(a,b); RPSH2(c,d); RPSH1(BOOL(a!=c || b!=d)); continue;
-/* IORr* */ case 0xF8: MLIT2(c,d); RSTV(-1)|=d; RSTV(-2)|=c; continue;
-/* XORr* */ case 0xF9: MLIT2(c,d); RSTV(-1)^=d; RSTV(-2)^=c; continue;
-/* ANDr* */ case 0xFA: MLIT2(c,d); RSTV(-1)&=d; RSTV(-2)&=c; continue;
-/* NOTr* */ case 0xFB: MLIT2(a,b); RPSH2(~a,~b); continue;
-/* SHFr* */ case 0xFC: MLIT1(c); RPOPD(x); x=SHF(x,c); RPSHD(x); continue;
-/* SHCr* */ case 0xFD: MLIT1(c); RPOPD(x); x=shcd(x,c); RPSHD(x); continue;
-/* TALr* */ case 0xFE: MLIT2(a,b); RPSH1(TAL(a)+TAL(b)); continue;
-/* REVr* */ case 0xFF: MLIT2(a,b); RPSH1(rev(b)); RPSH1(rev(a)); continue;
+/* PSHr*: */ case 0xE1: MPOP2(x,y); RPSH2(x,y); continue;
+/* POPr*: */ case 0xE2: IP+=2; continue;
+/* CPYr*: */ case 0xE3: MPOP2(x,y); WPSH2(x,y); RPSH2(x,y); continue;
+/* DUPr*: */ case 0xE4: MPOP2(x,y); RPSH2(x,y); RPSH2(x,y); continue;
+/* OVRr*: */ case 0xE5: MPOP2(y,z); RGET2(w,x); RPSH2(y,z); RPSH2(w,x); continue;
+/* SWPr*: */ case 0xE6: MPOP2(y,z); RPOP2(w,x); RPSH2(y,z); RPSH2(w,x); continue;
+/* ROTr*: */ case 0xE7: MPOP2(y,z); RPOP2(w,x); RPOP2(u,v); RPSH2(w,x); RPSH2(y,z); RPSH2(u,v); continue;
+/* JMPr*: */ case 0xE8: MPOPD(x); IP=x; continue;
+/* JMSr*: */ case 0xE9: MPOPD(x); WPSHD(IP); IP=x; continue;
+/* JCNr*: */ case 0xEA: MPOPD(y); RPOPD(x); if(x) IP=y; continue;
+/* JCSr*: */ case 0xEB: MPOPD(y); RPOPD(x); if(x) { WPSHD(IP); IP=y; } continue;
+/* LDAr*: */ case 0xEC: MPOPD(x); RPSH2(MEM[x], MEM[x+1]); continue;
+/* STAr*: */ case 0xED: MPOPD(z); RPOP2(x,y); MEM[z]=x; MEM[z+1]=y; continue;
+/* LDDr*: */ case 0xEE: MPOP1(x); RPSH1(DGET1(x)); RPSH1(DGET1(x+1)); continue;
+/* STDr*: */ case 0xEF: MPOP1(z); RPOP2(x,y); sig=DSET2(z,x,y); SIGNAL(sig);
+/* ADDr*: */ case 0xF0: MPOPD(y); RPOPD(x); RPSHD(x+y); continue;
+/* SUBr*: */ case 0xF1: MPOPD(y); RPOPD(x); RPSHD(x-y); continue;
+/* INCr*: */ case 0xF2: MPOPD(x); RPSHD(x+1); continue;
+/* DECr*: */ case 0xF3: MPOPD(x); RPSHD(x-1); continue;
+/* LTHr*: */ case 0xF4: MPOPD(y); RPOPD(x); RPSHB(x<y); continue;
+/* GTHr*: */ case 0xF5: MPOPD(y); RPOPD(x); RPSHB(x>y); continue;
+/* EQUr*: */ case 0xF6: MPOP2(y,z); RPOP2(w,x); RPSHB(w==y && x==z); continue;
+/* NQKr*: */ case 0xF7: MPOP2(y,z); RGET2(w,x); RPSH2(y,z); RPSHB(w!=y || x!=z); continue;
+/* SHLr*: */ case 0xF8: MPOP1(y); RPOPD(x); RPSHD(x<<y); continue;
+/* SHRr*: */ case 0xF9: MPOP1(y); RPOPD(x); RPSHD(x>>y); continue;
+/* ROLr*: */ case 0xFA: MPOP1(y); RPOPD(x); RPSHD(ROLD(x,y)); continue;
+/* RORr*: */ case 0xFB: MPOP1(y); RPOPD(x); RPSHD(RORD(x,y)); continue;
+/* IORr*: */ case 0xFC: MPOP2(x,y); RSTV(-1)|=y; RSTV(-2)|=x; continue;
+/* XORr*: */ case 0xFD: MPOP2(x,y); RSTV(-1)^=y; RSTV(-2)^=x; continue;
+/* ANDr*: */ case 0xFE: MPOP2(x,y); RSTV(-1)&=y; RSTV(-2)&=x; continue;
+/* NOTr*: */ case 0xFF: MPOP2(x,y); RPSH2(~x,~y); continue;
}
}
return SIG_NONE;
}
+
+// Print a stack to the debug console.
+void debug_print_stack(Stack *stack) {
+ for (int i=0; i<stack->p; i++) {
+ printf("%02x ", stack->mem[i]);
+ }
+}
+
+// Print the state of a Bedrock instance to the debug console.
+void debug_print_state(Bedrock *br) {
+ printf("\nP:0x%04x", br->ip);
+ printf("\nW:"); debug_print_stack(&br->wst);
+ printf("\nR:"); debug_print_stack(&br->rst);
+ printf("\n");
+}
+
+// Print the state of a Bedrock instance to the debug console.
+void debug_print_brief(Bedrock *br) {
+ printf("[%02X %02X]", br->wst.p, br->rst.p);
+}
+
+// Assert the state of a Bedrock instance, print to the debug console..
+void debug_print_assert(Bedrock *br) {
+ if (br->wst.mem[0] == 0xff && br->wst.p == 1 && br->rst.p == 0) {
+ printf(".");
+ } else {
+ printf("X");
+ }
+}
+
+// Run a Bedrock instance for a number of cycles.
+void br_run(Bedrock *br) {
+ if (br->alive && br->awake) {
+ switch (br_eval(br, 50000)) {
+ case SIG_HALT: br->alive = false;
+ ndsscreen_clear(br->dev.screen.nds); return;
+ case SIG_SLEEP: br->awake = false; return;
+ case SIG_DB1: debug_print_state(br); return;
+ case SIG_DB2: debug_print_brief(br); return;
+ case SIG_DB4: debug_print_assert(br); return;
+ default: return;
+ }
+ }
+}