#include <nds.h>
#include "bang.h"
#include "core.h"
#include "debug.h"
void reset_br(Bedrock *br) {
*br = (Bedrock) {0};
}
// 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;
}
void run_br(Bedrock *br) {
if (br->awake) {
switch (evaluate(br, 1000)) {
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, 0x0800)) { // INPUT
if (br->inp.wake) {
br->inp.wake = FALSE;
br->awake = TRUE;
br->sys.wake = 0x4;
return;
}
}
if (TEST(br->sys.sleep, 0x1000)) { // CLOCK
if (check_timers(&br->clk)) {
br->awake = TRUE;
br->sys.wake = 0x3;
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(br->inp.keyboard);
// TODO: Keyboard input
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;
// 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: printf("%c", v); return 0;
case 0x87: printf("%c", 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;
}
}
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; }
}
Signal evaluate(Bedrock *br, u16 count) {
#define SIGNAL(s) if (s) { return s; } else { continue; };
register u8 a, b, c, d, e, f;
register u16 x, y;
register Signal sig;
for (u16 i=0; i < count; i++) {
switch (MLIT) {
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
}
}
return SIG_NONE;
}