summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/v60/op12.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/v60/op12.c')
-rw-r--r--trunk/src/emu/cpu/v60/op12.c2391
1 files changed, 2391 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/v60/op12.c b/trunk/src/emu/cpu/v60/op12.c
new file mode 100644
index 00000000000..ef5944cdfda
--- /dev/null
+++ b/trunk/src/emu/cpu/v60/op12.c
@@ -0,0 +1,2391 @@
+/*
+ * MUL* and MULU* do not set OV correctly
+ * DIVX: the second operand should be treated as dword instead of word
+ * GETATE, GETPTE and GETRA should not be used
+ * UPDPSW: cpustate->_CY and cpustate->_OV must be cleared or unchanged? I suppose
+ * cleared, like TEST being done on the mask operand.
+ * MOVT: I cannot understand exactly what happens to the result
+ * when an overflow occurs
+ *
+ * Unimplemented opcodes:
+ * ROTC, UPDATE, UPDPTE
+ */
+
+
+/*
+ * Macro to access data in operands decoded with ReadAMAddress(cpustate)
+ */
+
+#define F12LOADOPBYTE(cs, num) \
+ if ((cs)->flag##num) \
+ appb = (UINT8)(cs)->reg[(cs)->op##num]; \
+ else \
+ appb = (cs)->program->read_byte((cs)->op##num);
+
+#define F12LOADOPHALF(cs, num) \
+ if ((cs)->flag##num) \
+ apph = (UINT16)(cs)->reg[(cs)->op##num]; \
+ else \
+ apph = (cs)->program->read_word_unaligned((cs)->op##num);
+
+#define F12LOADOPWORD(cs, num) \
+ if ((cs)->flag##num) \
+ appw = (cs)->reg[(cs)->op##num]; \
+ else \
+ appw = (cs)->program->read_dword_unaligned((cs)->op##num);
+
+#define F12STOREOPBYTE(cs, num) \
+ if ((cs)->flag##num) \
+ SETREG8((cs)->reg[(cs)->op##num], appb); \
+ else \
+ (cs)->program->write_byte((cs)->op##num, appb);
+
+#define F12STOREOPHALF(cs, num) \
+ if ((cs)->flag##num) \
+ SETREG16((cs)->reg[(cs)->op##num], apph); \
+ else \
+ (cs)->program->write_word_unaligned((cs)->op##num, apph);
+
+#define F12STOREOPWORD(cs, num) \
+ if ((cs)->flag##num) \
+ (cs)->reg[(cs)->op##num] = appw; \
+ else \
+ (cs)->program->write_dword_unaligned((cs)->op##num, appw);
+
+#define F12LOADOP1BYTE(cs) F12LOADOPBYTE(cs, 1)
+#define F12LOADOP1HALF(cs) F12LOADOPHALF(cs, 1)
+#define F12LOADOP1WORD(cs) F12LOADOPWORD(cs, 1)
+
+#define F12LOADOP2BYTE(cs) F12LOADOPBYTE(cs, 2)
+#define F12LOADOP2HALF(cs) F12LOADOPHALF(cs, 2)
+#define F12LOADOP2WORD(cs) F12LOADOPWORD(cs, 2)
+
+#define F12STOREOP1BYTE(cs) F12STOREOPBYTE(cs, 1)
+#define F12STOREOP1HALF(cs) F12STOREOPHALF(cs, 1)
+#define F12STOREOP1WORD(cs) F12STOREOPWORD(cs, 1)
+
+#define F12STOREOP2BYTE(cs) F12STOREOPBYTE(cs, 2)
+#define F12STOREOP2HALF(cs) F12STOREOPHALF(cs, 2)
+#define F12STOREOP2WORD(cs) F12STOREOPWORD(cs, 2)
+
+#define F12END(cs) \
+ return (cs)->amlength1 + (cs)->amlength2 + 2;
+
+
+// Decode the first operand of the instruction and prepare
+// writing to the second operand.
+static void F12DecodeFirstOperand(v60_state *cpustate, UINT32 (*DecodeOp1)(v60_state *), UINT8 dim1)
+{
+ cpustate->instflags = OpRead8(cpustate, cpustate->PC + 1);
+
+ // Check if F1 or F2
+ if (cpustate->instflags & 0x80)
+ {
+ cpustate->moddim = dim1;
+ cpustate->modm = cpustate->instflags & 0x40;
+ cpustate->modadd = cpustate->PC + 2;
+ cpustate->amlength1 = DecodeOp1(cpustate);
+ cpustate->op1 = cpustate->amout;
+ cpustate->flag1 = cpustate->amflag;
+ }
+ else
+ {
+ // Check D flag
+ if (cpustate->instflags & 0x20)
+ {
+ cpustate->moddim = dim1;
+ cpustate->modm = cpustate->instflags & 0x40;
+ cpustate->modadd = cpustate->PC + 2;
+ cpustate->amlength1 = DecodeOp1(cpustate);
+ cpustate->op1 = cpustate->amout;
+ cpustate->flag1 = cpustate->amflag;
+ }
+ else
+ {
+ if (DecodeOp1 == ReadAM)
+ {
+ switch (dim1)
+ {
+ case 0:
+ cpustate->op1 = (UINT8)cpustate->reg[cpustate->instflags & 0x1F];
+ break;
+ case 1:
+ cpustate->op1 = (UINT16)cpustate->reg[cpustate->instflags & 0x1F];
+ break;
+ case 2:
+ cpustate->op1 = cpustate->reg[cpustate->instflags & 0x1F];
+ break;
+ }
+
+ cpustate->flag1 = 0;
+ }
+ else
+ {
+ cpustate->flag1 = 1;
+ cpustate->op1 = cpustate->instflags & 0x1F;
+ }
+
+ cpustate->amlength1 = 0;
+ }
+ }
+}
+
+static void F12WriteSecondOperand(v60_state *cpustate, UINT8 dim2)
+{
+ cpustate->moddim = dim2;
+
+ // Check if F1 or F2
+ if (cpustate->instflags & 0x80)
+ {
+ cpustate->modm = cpustate->instflags & 0x20;
+ cpustate->modadd = cpustate->PC + 2 + cpustate->amlength1;
+ cpustate->moddim = dim2;
+ cpustate->amlength2 = WriteAM(cpustate);
+ }
+ else
+ {
+ // Check D flag
+ if (cpustate->instflags & 0x20)
+ {
+ switch (dim2)
+ {
+ case 0:
+ SETREG8(cpustate->reg[cpustate->instflags & 0x1F], cpustate->modwritevalb);
+ break;
+ case 1:
+ SETREG16(cpustate->reg[cpustate->instflags & 0x1F], cpustate->modwritevalh);
+ break;
+ case 2:
+ cpustate->reg[cpustate->instflags & 0x1F] = cpustate->modwritevalw;
+ break;
+ }
+
+ cpustate->amlength2 = 0;
+ }
+ else
+ {
+ cpustate->modm = cpustate->instflags & 0x40;
+ cpustate->modadd = cpustate->PC + 2;
+ cpustate->moddim = dim2;
+ cpustate->amlength2 = WriteAM(cpustate);
+ }
+ }
+}
+
+
+
+// Decode both format 1 / 2 operands
+static void F12DecodeOperands(v60_state *cpustate, UINT32 (*DecodeOp1)(v60_state *), UINT8 dim1, UINT32 (*DecodeOp2)(v60_state *), UINT8 dim2)
+{
+ UINT8 _if12 = OpRead8(cpustate, cpustate->PC + 1);
+
+ // Check if F1 or F2
+ if (_if12 & 0x80)
+ {
+ cpustate->moddim = dim1;
+ cpustate->modm = _if12 & 0x40;
+ cpustate->modadd = cpustate->PC + 2;
+ cpustate->amlength1 = DecodeOp1(cpustate);
+ cpustate->op1 = cpustate->amout;
+ cpustate->flag1 = cpustate->amflag;
+
+ cpustate->moddim = dim2;
+ cpustate->modm = _if12 & 0x20;
+ cpustate->modadd = cpustate->PC + 2 + cpustate->amlength1;
+ cpustate->amlength2 = DecodeOp2(cpustate);
+ cpustate->op2 = cpustate->amout;
+ cpustate->flag2 = cpustate->amflag;
+ }
+ else
+ {
+ // Check D flag
+ if (_if12 & 0x20)
+ {
+ if (DecodeOp2 == ReadAMAddress)
+ {
+ cpustate->op2 = _if12 & 0x1F;
+ cpustate->flag2 = 1;
+ }
+ else
+ {
+ switch (dim2)
+ {
+ case 0:
+ cpustate->op2 = (UINT8)cpustate->reg[_if12 & 0x1F];
+ break;
+ case 1:
+ cpustate->op2 = (UINT16)cpustate->reg[_if12 & 0x1F];
+ break;
+ case 2:
+ cpustate->op2 = cpustate->reg[_if12 & 0x1F];
+ break;
+ }
+ }
+
+ cpustate->amlength2 = 0;
+
+ cpustate->moddim = dim1;
+ cpustate->modm = _if12 & 0x40;
+ cpustate->modadd = cpustate->PC + 2;
+ cpustate->amlength1 = DecodeOp1(cpustate);
+ cpustate->op1 = cpustate->amout;
+ cpustate->flag1 = cpustate->amflag;
+ }
+ else
+ {
+ if (DecodeOp1 == ReadAMAddress)
+ {
+ cpustate->op1 = _if12 & 0x1F;
+ cpustate->flag1 = 1;
+ }
+ else
+ {
+ switch (dim1)
+ {
+ case 0:
+ cpustate->op1 = (UINT8)cpustate->reg[_if12 & 0x1F];
+ break;
+ case 1:
+ cpustate->op1 = (UINT16)cpustate->reg[_if12 & 0x1F];
+ break;
+ case 2:
+ cpustate->op1 = cpustate->reg[_if12 & 0x1F];
+ break;
+ }
+ }
+ cpustate->amlength1 = 0;
+
+ cpustate->moddim = dim2;
+ cpustate->modm = _if12 & 0x40;
+ cpustate->modadd = cpustate->PC + 2 + cpustate->amlength1;
+ cpustate->amlength2 = DecodeOp2(cpustate);
+ cpustate->op2 = cpustate->amout;
+ cpustate->flag2 = cpustate->amflag;
+ }
+ }
+}
+
+static UINT32 opADDB(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ ADDB(appb, (UINT8)cpustate->op1);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opADDH(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ ADDW(apph, (UINT16)cpustate->op1);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opADDW(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ ADDL(appw, (UINT32)cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opADDCB(v60_state *cpustate)
+{
+ UINT8 appb, temp;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ temp = ((UINT8)cpustate->op1 + (cpustate->_CY?1:0));
+ ADDB(appb, temp);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opADDCH(v60_state *cpustate)
+{
+ UINT16 apph, temp;
+
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ temp = ((UINT16)cpustate->op1 + (cpustate->_CY?1:0));
+ ADDW(apph, temp);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opADDCW(v60_state *cpustate)
+{
+ UINT32 appw, temp;
+
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ temp = cpustate->op1 + (cpustate->_CY?1:0);
+ ADDL(appw, temp);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opANDB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ appb &= cpustate->op1;
+ cpustate->_OV = 0;
+ cpustate->_S = ((appb & 0x80) != 0);
+ cpustate->_Z = (appb == 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opANDH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ apph &= cpustate->op1;
+ cpustate->_OV = 0;
+ cpustate->_S = ((apph & 0x8000) != 0);
+ cpustate->_Z = (apph == 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opANDW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ appw &= cpustate->op1;
+ cpustate->_OV = 0;
+ cpustate->_S = ((appw & 0x80000000) != 0);
+ cpustate->_Z = (appw == 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opCALL(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeOperands(cpustate, ReadAMAddress, 0,ReadAMAddress, 2);
+
+ cpustate->SP -= 4;
+ cpustate->program->write_dword_unaligned(cpustate->SP, cpustate->AP);
+ cpustate->AP = cpustate->op2;
+
+ cpustate->SP -= 4;
+ cpustate->program->write_dword_unaligned(cpustate->SP, cpustate->PC + cpustate->amlength1 + cpustate->amlength2 + 2);
+ cpustate->PC = cpustate->op1;
+
+ return 0;
+}
+
+static UINT32 opCHKAR(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAM, 0);
+
+ // No MMU and memory permissions yet @@@
+ cpustate->_Z = 1;
+ cpustate->_CY = 0;
+ cpustate->_S = 0;
+
+ F12END(cpustate);
+}
+
+static UINT32 opCHKAW(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAM, 0);
+
+ // No MMU and memory permissions yet @@@
+ cpustate->_Z = 1;
+ cpustate->_CY = 0;
+ cpustate->_S = 0;
+
+ F12END(cpustate);
+}
+
+static UINT32 opCHKAE(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAM, 0);
+
+ // No MMU and memory permissions yet @@@
+ cpustate->_Z = 1;
+ cpustate->_CY = 0;
+ cpustate->_S = 0;
+
+ F12END(cpustate);
+}
+
+static UINT32 opCHLVL(v60_state *cpustate)
+{
+ UINT32 oldPSW;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAM, 0);
+
+ if (cpustate->op1 > 3)
+ {
+ fatalerror("Illegal data field on opCHLVL, cpustate->PC=%x", cpustate->PC);
+ }
+
+ oldPSW = v60_update_psw_for_exception(cpustate, 0, cpustate->op1);
+
+ cpustate->SP -= 4;
+ cpustate->program->write_dword_unaligned(cpustate->SP, cpustate->op2);
+
+ cpustate->SP -= 4;
+ cpustate->program->write_dword_unaligned(cpustate->SP, EXCEPTION_CODE_AND_SIZE(0x1800 + cpustate->op1 * 0x100, 8));
+
+ cpustate->SP -= 4;
+ cpustate->program->write_dword_unaligned(cpustate->SP, oldPSW);
+
+ cpustate->SP -= 4;
+ cpustate->program->write_dword_unaligned(cpustate->SP, cpustate->PC + cpustate->amlength1 + cpustate->amlength2 + 2);
+
+ cpustate->PC = GETINTVECT(cpustate, 24 + cpustate->op1);
+
+ return 0;
+}
+
+static UINT32 opCLR1(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_CY = ((appw & (1 << cpustate->op1)) != 0);
+ cpustate->_Z = !(cpustate->_CY);
+
+ appw &= ~(1 << cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opCMPB(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAM, 0);
+
+ appb = (UINT8)cpustate->op2;
+ SUBB(appb, (UINT8)cpustate->op1);
+
+ F12END(cpustate);
+}
+
+static UINT32 opCMPH(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAM, 1);
+
+ apph = (UINT16)cpustate->op2;
+ SUBW(apph, (UINT16)cpustate->op1);
+
+ F12END(cpustate);
+}
+
+
+static UINT32 opCMPW(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAM, 2);
+
+ SUBL(cpustate->op2, (UINT32)cpustate->op1);
+
+ F12END(cpustate);
+}
+
+static UINT32 opDIVB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ cpustate->_OV = ((appb == 0x80) && (cpustate->op1 == 0xFF));
+ if (cpustate->op1 && !cpustate->_OV)
+ appb= (INT8)appb / (INT8)cpustate->op1;
+ cpustate->_Z = (appb == 0);
+ cpustate->_S = ((appb & 0x80) != 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opDIVH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ cpustate->_OV = ((apph == 0x8000) && (cpustate->op1 == 0xFFFF));
+ if (cpustate->op1 && !cpustate->_OV)
+ apph = (INT16)apph / (INT16)cpustate->op1;
+ cpustate->_Z = (apph == 0);
+ cpustate->_S = ((apph & 0x8000) != 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opDIVW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_OV = ((appw == 0x80000000) && (cpustate->op1 == 0xFFFFFFFF));
+ if (cpustate->op1 && !cpustate->_OV)
+ appw = (INT32)appw / (INT32)cpustate->op1;
+ cpustate->_Z = (appw == 0);
+ cpustate->_S = ((appw & 0x80000000) != 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opDIVX(v60_state *cpustate)
+{
+ UINT32 a, b;
+ INT64 dv;
+
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 3);
+
+ if (cpustate->flag2)
+ {
+ a = cpustate->reg[cpustate->op2 & 0x1F];
+ b = cpustate->reg[(cpustate->op2 & 0x1F) + 1];
+ }
+ else
+ {
+ a = cpustate->program->read_dword_unaligned(cpustate->op2);
+ b = cpustate->program->read_dword_unaligned(cpustate->op2 + 4);
+ }
+
+ dv = ((UINT64)b << 32) | ((UINT64)a);
+
+ a = dv / (INT64)((INT32)cpustate->op1);
+ b = dv % (INT64)((INT32)cpustate->op1);
+
+ cpustate->_S = ((a & 0x80000000) != 0);
+ cpustate->_Z = (a == 0);
+
+ if (cpustate->flag2)
+ {
+ cpustate->reg[cpustate->op2 & 0x1F] = a;
+ cpustate->reg[(cpustate->op2 & 0x1F) + 1] = b;
+ }
+ else
+ {
+ cpustate->program->write_dword_unaligned(cpustate->op2, a);
+ cpustate->program->write_dword_unaligned(cpustate->op2 + 4, b);
+ }
+
+ F12END(cpustate);
+}
+
+static UINT32 opDIVUX(v60_state *cpustate)
+{
+ UINT32 a, b;
+ UINT64 dv;
+
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 3);
+
+ if (cpustate->flag2)
+ {
+ a = cpustate->reg[cpustate->op2 & 0x1F];
+ b = cpustate->reg[(cpustate->op2 & 0x1F) + 1];
+ }
+ else
+ {
+ a = cpustate->program->read_dword_unaligned(cpustate->op2);
+ b = cpustate->program->read_dword_unaligned(cpustate->op2 + 4);
+ }
+
+ dv = (UINT64)(((UINT64)b << 32) | (UINT64)a);
+ a = (UINT32)(dv / (UINT64)cpustate->op1);
+ b = (UINT32)(dv % (UINT64)cpustate->op1);
+
+ cpustate->_S = ((a & 0x80000000) != 0);
+ cpustate->_Z = (a == 0);
+
+ if (cpustate->flag2)
+ {
+ cpustate->reg[cpustate->op2 & 0x1F] = a;
+ cpustate->reg[(cpustate->op2 & 0x1F) + 1] = b;
+ }
+ else
+ {
+ cpustate->program->write_dword_unaligned(cpustate->op2, a);
+ cpustate->program->write_dword_unaligned(cpustate->op2 + 4, b);
+ }
+
+ F12END(cpustate);
+}
+
+
+static UINT32 opDIVUB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1) appb /= (UINT8)cpustate->op1;
+ cpustate->_Z = (appb == 0);
+ cpustate->_S = ((appb & 0x80) != 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opDIVUH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1) apph /= (UINT16)cpustate->op1;
+ cpustate->_Z = (apph == 0);
+ cpustate->_S = ((apph & 0x8000) != 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opDIVUW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1) appw /= cpustate->op1;
+ cpustate->_Z = (appw == 0);
+ cpustate->_S = ((appw & 0x80000000) != 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opINB(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAMAddress, 0);
+ cpustate->modwritevalb = cpustate->io->read_byte(cpustate->op1);
+
+ if ( cpustate->stall_io )
+ {
+ cpustate->stall_io = 0;
+ return 0;
+ }
+
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opINH(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAMAddress, 1);
+ cpustate->modwritevalh = cpustate->io->read_word_unaligned(cpustate->op1);
+
+ if ( cpustate->stall_io )
+ {
+ cpustate->stall_io = 0;
+ return 0;
+ }
+
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+static UINT32 opINW(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAMAddress, 2);
+ cpustate->modwritevalw = cpustate->io->read_dword_unaligned(cpustate->op1);
+
+ if ( cpustate->stall_io )
+ {
+ cpustate->stall_io = 0;
+ return 0;
+ }
+
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opLDPR(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAMAddress, 2,ReadAM, 2);
+ if (cpustate->op2 <= 28)
+ {
+ if (cpustate->flag1 &&(!(OpRead8(cpustate, cpustate->PC + 1)&0x80 && OpRead8(cpustate, cpustate->PC + 2) == 0xf4 ) ))
+ cpustate->reg[cpustate->op2 + 36] = cpustate->reg[cpustate->op1];
+ else
+ cpustate->reg[cpustate->op2 + 36] = cpustate->op1;
+ }
+ else
+ {
+ fatalerror("Invalid operand on LDPR cpustate->PC=%x", cpustate->PC);
+ }
+ F12END(cpustate);
+}
+
+static UINT32 opLDTASK(v60_state *cpustate)
+{
+ int i;
+ F12DecodeOperands(cpustate, ReadAMAddress, 2,ReadAM, 2);
+
+ v60WritePSW(cpustate, v60ReadPSW(cpustate) & 0xefffffff);
+
+ cpustate->TR = cpustate->op2;
+
+ cpustate->TKCW = cpustate->program->read_dword_unaligned(cpustate->op2);
+ cpustate->op2 += 4;
+ if(cpustate->SYCW & 0x100) {
+ cpustate->L0SP = cpustate->program->read_dword_unaligned(cpustate->op2);
+ cpustate->op2 += 4;
+ }
+ if(cpustate->SYCW & 0x200) {
+ cpustate->L1SP = cpustate->program->read_dword_unaligned(cpustate->op2);
+ cpustate->op2 += 4;
+ }
+ if(cpustate->SYCW & 0x400) {
+ cpustate->L2SP = cpustate->program->read_dword_unaligned(cpustate->op2);
+ cpustate->op2 += 4;
+ }
+ if(cpustate->SYCW & 0x800) {
+ cpustate->L3SP = cpustate->program->read_dword_unaligned(cpustate->op2);
+ cpustate->op2 += 4;
+ }
+
+ v60ReloadStack(cpustate);
+
+ // 31 registers supported, _not_ 32
+ for(i = 0; i < 31; i++)
+ if(cpustate->op1 & (1 << i)) {
+ cpustate->reg[i] = cpustate->program->read_dword_unaligned(cpustate->op2);
+ cpustate->op2 += 4;
+ }
+
+ // #### Ignore the virtual addressing crap.
+
+ F12END(cpustate);
+}
+
+static UINT32 opMOVD(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 a, b;
+
+ F12DecodeOperands(cpustate, ReadAMAddress, 3,ReadAMAddress, 3);
+
+ if (cpustate->flag1)
+ {
+ a = cpustate->reg[cpustate->op1 & 0x1F];
+ b = cpustate->reg[(cpustate->op1 & 0x1F) + 1];
+ }
+ else
+ {
+ a = cpustate->program->read_dword_unaligned(cpustate->op1);
+ b = cpustate->program->read_dword_unaligned(cpustate->op1 + 4);
+ }
+
+ if (cpustate->flag2)
+ {
+ cpustate->reg[cpustate->op2 & 0x1F] = a;
+ cpustate->reg[(cpustate->op2 & 0x1F) + 1] = b;
+ }
+ else
+ {
+ cpustate->program->write_dword_unaligned(cpustate->op2, a);
+ cpustate->program->write_dword_unaligned(cpustate->op2 + 4, b);
+ }
+
+ F12END(cpustate);
+}
+
+static UINT32 opMOVB(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+ cpustate->modwritevalb = (UINT8)cpustate->op1;
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVH(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 1);
+ cpustate->modwritevalh = (UINT16)cpustate->op1;
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+ cpustate->modwritevalw = cpustate->op1;
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVEAB(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAMAddress, 0);
+ cpustate->modwritevalw = cpustate->op1;
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVEAH(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAMAddress, 1);
+ cpustate->modwritevalw = cpustate->op1;
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVEAW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAMAddress, 2);
+ cpustate->modwritevalw = cpustate->op1;
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVSBH(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+ cpustate->modwritevalh = (INT8)(cpustate->op1 & 0xFF);
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVSBW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+ cpustate->modwritevalw = (INT8)(cpustate->op1 & 0xFF);
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVSHW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 1);
+ cpustate->modwritevalw = (INT16)(cpustate->op1 & 0xFFFF);
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVTHB(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 1);
+ cpustate->modwritevalb = (UINT8)(cpustate->op1 & 0xFF);
+
+ // Check for overflow: the truncated bits must match the sign
+ // of the result, otherwise overflow
+ if (((cpustate->modwritevalb & 0x80) == 0x80 && ((cpustate->op1 & 0xFF00) == 0xFF00)) ||
+ ((cpustate->modwritevalb & 0x80) == 0 && ((cpustate->op1 & 0xFF00) == 0x0000)))
+ cpustate->_OV = 0;
+ else
+ cpustate->_OV = 1;
+
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVTWB(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+ cpustate->modwritevalb = (UINT8)(cpustate->op1 & 0xFF);
+
+ // Check for overflow: the truncated bits must match the sign
+ // of the result, otherwise overflow
+ if (((cpustate->modwritevalb & 0x80) == 0x80 && ((cpustate->op1 & 0xFFFFFF00) == 0xFFFFFF00)) ||
+ ((cpustate->modwritevalb & 0x80) == 0 && ((cpustate->op1 & 0xFFFFFF00) == 0x00000000)))
+ cpustate->_OV = 0;
+ else
+ cpustate->_OV = 1;
+
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVTWH(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+ cpustate->modwritevalh = (UINT16)(cpustate->op1 & 0xFFFF);
+
+ // Check for overflow: the truncated bits must match the sign
+ // of the result, otherwise overflow
+ if (((cpustate->modwritevalh & 0x8000) == 0x8000 && ((cpustate->op1 & 0xFFFF0000) == 0xFFFF0000)) ||
+ ((cpustate->modwritevalh & 0x8000) == 0 && ((cpustate->op1 & 0xFFFF0000) == 0x00000000)))
+ cpustate->_OV = 0;
+ else
+ cpustate->_OV = 1;
+
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+
+static UINT32 opMOVZBH(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+ cpustate->modwritevalh = (UINT16)cpustate->op1;
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVZBW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+ cpustate->modwritevalw = cpustate->op1;
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMOVZHW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 1);
+ cpustate->modwritevalw = cpustate->op1;
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opMULB(v60_state *cpustate)
+{
+ UINT8 appb;
+ UINT32 tmp;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ // @@@ OV not set!!
+ tmp = (INT8)appb * (INT32)(INT8)cpustate->op1;
+ appb = tmp;
+ cpustate->_Z = (appb == 0);
+ cpustate->_S = ((appb & 0x80) != 0);
+ cpustate->_OV = ((tmp >> 8) != 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opMULH(v60_state *cpustate)
+{
+ UINT16 apph;
+ UINT32 tmp;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ // @@@ OV not set!!
+ tmp = (INT16)apph * (INT32)(INT16)cpustate->op1;
+ apph = tmp;
+ cpustate->_Z = (apph == 0);
+ cpustate->_S = ((apph & 0x8000) != 0);
+ cpustate->_OV = ((tmp >> 16) != 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opMULW(v60_state *cpustate)
+{
+ UINT32 appw;
+ UINT64 tmp;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ // @@@ OV not set!!
+ tmp = (INT32)appw * (INT64)(INT32)cpustate->op1;
+ appw = tmp;
+ cpustate->_Z = (appw == 0);
+ cpustate->_S = ((appw & 0x80000000) != 0);
+ cpustate->_OV = ((tmp >> 32) != 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opMULUB(v60_state *cpustate)
+{
+ UINT8 appb;
+ UINT32 tmp;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ // @@@ OV not set!!
+ tmp = appb * (UINT8)cpustate->op1;
+ appb = tmp;
+ cpustate->_Z = (appb == 0);
+ cpustate->_S = ((appb & 0x80) != 0);
+ cpustate->_OV = ((tmp >> 8) != 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opMULUH(v60_state *cpustate)
+{
+ UINT16 apph;
+ UINT32 tmp;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ // @@@ OV not set!!
+ tmp = apph * (UINT16)cpustate->op1;
+ apph = tmp;
+ cpustate->_Z = (apph == 0);
+ cpustate->_S = ((apph & 0x8000) != 0);
+ cpustate->_OV = ((tmp >> 16) != 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opMULUW(v60_state *cpustate)
+{
+ UINT32 appw;
+ UINT64 tmp;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ // @@@ OV not set!!
+ tmp = (UINT64)appw * (UINT64)cpustate->op1;
+ appw = tmp;
+ cpustate->_Z = (appw == 0);
+ cpustate->_S = ((appw & 0x80000000) != 0);
+ cpustate->_OV = ((tmp >> 32) != 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opNEGB(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+
+ cpustate->modwritevalb = 0;
+ SUBB(cpustate->modwritevalb, (INT8)cpustate->op1);
+
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opNEGH(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 1);
+
+ cpustate->modwritevalh = 0;
+ SUBW(cpustate->modwritevalh, (INT16)cpustate->op1);
+
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+static UINT32 opNEGW(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+
+ cpustate->modwritevalw = 0;
+ SUBL(cpustate->modwritevalw, (INT32)cpustate->op1);
+
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opNOTB(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+ cpustate->modwritevalb=~cpustate->op1;
+
+ cpustate->_OV = 0;
+ cpustate->_S = ((cpustate->modwritevalb & 0x80) != 0);
+ cpustate->_Z = (cpustate->modwritevalb == 0);
+
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opNOTH(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 1);
+ cpustate->modwritevalh=~cpustate->op1;
+
+ cpustate->_OV = 0;
+ cpustate->_S = ((cpustate->modwritevalh & 0x8000) != 0);
+ cpustate->_Z = (cpustate->modwritevalh == 0);
+
+ F12WriteSecondOperand(cpustate, 1);
+ F12END(cpustate);
+}
+
+static UINT32 opNOTW(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+ cpustate->modwritevalw=~cpustate->op1;
+
+ cpustate->_OV = 0;
+ cpustate->_S = ((cpustate->modwritevalw & 0x80000000) != 0);
+ cpustate->_Z = (cpustate->modwritevalw == 0);
+
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opNOT1(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_CY = ((appw & (1 << cpustate->op1)) != 0);
+ cpustate->_Z = !(cpustate->_CY);
+
+ if (cpustate->_CY)
+ appw &= ~(1 << cpustate->op1);
+ else
+ appw |= (1 << cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opORB(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ ORB(appb, (UINT8)cpustate->op1);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opORH(v60_state *cpustate) /* TRUSTED (C too!)*/
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ ORW(apph, (UINT16)cpustate->op1);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opORW(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ ORL(appw, (UINT32)cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opOUTB(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 2);
+ cpustate->io->write_byte(cpustate->op2,(UINT8)cpustate->op1);
+ F12END(cpustate);
+}
+
+static UINT32 opOUTH(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 2);
+ cpustate->io->write_word_unaligned(cpustate->op2,(UINT16)cpustate->op1);
+ F12END(cpustate);
+}
+
+static UINT32 opOUTW(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+ cpustate->io->write_dword_unaligned(cpustate->op2, cpustate->op1);
+ F12END(cpustate);
+}
+
+static UINT32 opREMB(v60_state *cpustate)
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1)
+ appb= (INT8)appb % (INT8)cpustate->op1;
+ cpustate->_Z = (appb == 0);
+ cpustate->_S = ((appb & 0x80) != 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opREMH(v60_state *cpustate)
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1)
+ apph = (INT16)apph % (INT16)cpustate->op1;
+ cpustate->_Z = (apph == 0);
+ cpustate->_S = ((apph & 0x8000) != 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opREMW(v60_state *cpustate)
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1)
+ appw = (INT32)appw % (INT32)cpustate->op1;
+ cpustate->_Z = (appw == 0);
+ cpustate->_S = ((appw & 0x80000000) != 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opREMUB(v60_state *cpustate)
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1)
+ appb %= (UINT8)cpustate->op1;
+ cpustate->_Z = (appb == 0);
+ cpustate->_S = ((appb & 0x80) != 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opREMUH(v60_state *cpustate)
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1)
+ apph %= (UINT16)cpustate->op1;
+ cpustate->_Z = (apph == 0);
+ cpustate->_S = ((apph & 0x8000) != 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opREMUW(v60_state *cpustate)
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_OV = 0;
+ if (cpustate->op1)
+ appw %= cpustate->op1;
+ cpustate->_Z = (appw == 0);
+ cpustate->_S = ((appw & 0x80000000) != 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opROTB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb;
+ INT8 i, count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ for (i = 0;i < count;i++)
+ appb = (appb << 1) | ((appb & 0x80) >> 7);
+
+ cpustate->_CY = (appb & 0x1) != 0;
+ }
+ else if (count < 0)
+ {
+ count=-count;
+ for (i = 0;i < count;i++)
+ appb = (appb >> 1) | ((appb & 0x1) << 7);
+
+ cpustate->_CY = (appb & 0x80) != 0;
+ }
+ else
+ cpustate->_CY = 0;
+
+ cpustate->_OV = 0;
+ cpustate->_S = (appb & 0x80) != 0;
+ cpustate->_Z = (appb == 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opROTH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph;
+ INT8 i, count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ for (i = 0;i < count;i++)
+ apph = (apph << 1) | ((apph & 0x8000) >> 15);
+
+ cpustate->_CY = (apph & 0x1) != 0;
+ }
+ else if (count < 0)
+ {
+ count=-count;
+ for (i = 0;i < count;i++)
+ apph = (apph >> 1) | ((apph & 0x1) << 15);
+
+ cpustate->_CY = (apph & 0x8000) != 0;
+ }
+ else
+ cpustate->_CY = 0;
+
+ cpustate->_OV = 0;
+ cpustate->_S = (apph & 0x8000) != 0;
+ cpustate->_Z = (apph == 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opROTW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ INT8 i, count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ for (i = 0;i < count;i++)
+ appw = (appw << 1) | ((appw & 0x80000000) >> 31);
+
+ cpustate->_CY = (appw & 0x1) != 0;
+ }
+ else if (count < 0)
+ {
+ count=-count;
+ for (i = 0;i < count;i++)
+ appw = (appw >> 1) | ((appw & 0x1) << 31);
+
+ cpustate->_CY = (appw & 0x80000000) != 0;
+ }
+ else
+ cpustate->_CY = 0;
+
+ cpustate->_OV = 0;
+ cpustate->_S = (appw & 0x80000000) != 0;
+ cpustate->_Z = (appw == 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opROTCB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb;
+ INT8 i, cy, count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+ NORMALIZEFLAGS(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ for (i = 0;i < count;i++)
+ {
+ cy = cpustate->_CY;
+ cpustate->_CY = (UINT8)((appb & 0x80) >> 7);
+ appb = (appb << 1) | cy;
+ }
+ }
+ else if (count < 0)
+ {
+ count=-count;
+ for (i = 0;i < count;i++)
+ {
+ cy = cpustate->_CY;
+ cpustate->_CY = (appb & 1);
+ appb = (appb >> 1) | (cy << 7);
+ }
+ }
+ else
+ cpustate->_CY = 0;
+
+ cpustate->_OV = 0;
+ cpustate->_S = (appb & 0x80) != 0;
+ cpustate->_Z = (appb == 0);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opROTCH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph;
+ INT8 i, cy, count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+ NORMALIZEFLAGS(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ for (i = 0;i < count;i++)
+ {
+ cy = cpustate->_CY;
+ cpustate->_CY = (UINT8)((apph & 0x8000) >> 15);
+ apph = (apph << 1) | cy;
+ }
+ }
+ else if (count < 0)
+ {
+ count=-count;
+ for (i = 0;i < count;i++)
+ {
+ cy = cpustate->_CY;
+ cpustate->_CY = (UINT8)(apph & 1);
+ apph = (apph >> 1) | ((UINT16)cy << 15);
+ }
+ }
+ else
+ cpustate->_CY = 0;
+
+ cpustate->_OV = 0;
+ cpustate->_S = (apph & 0x8000) != 0;
+ cpustate->_Z = (apph == 0);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opROTCW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ INT8 i, cy, count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+ NORMALIZEFLAGS(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ for (i = 0;i < count;i++)
+ {
+ cy = cpustate->_CY;
+ cpustate->_CY = (UINT8)((appw & 0x80000000) >> 31);
+ appw = (appw << 1) | cy;
+ }
+ }
+ else if (count < 0)
+ {
+ count=-count;
+ for (i = 0;i < count;i++)
+ {
+ cy = cpustate->_CY;
+ cpustate->_CY = (UINT8)(appw & 1);
+ appw = (appw >> 1) | ((UINT32)cy << 31);
+ }
+ }
+ else
+ cpustate->_CY = 0;
+
+ cpustate->_OV = 0;
+ cpustate->_S = (appw & 0x80000000) != 0;
+ cpustate->_Z = (appw == 0);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opRVBIT(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+
+ cpustate->modwritevalb =(UINT8)
+ (((cpustate->op1 & (1 << 0)) << 7) |
+ ((cpustate->op1 & (1 << 1)) << 5) |
+ ((cpustate->op1 & (1 << 2)) << 3) |
+ ((cpustate->op1 & (1 << 3)) << 1) |
+ ((cpustate->op1 & (1 << 4)) >> 1) |
+ ((cpustate->op1 & (1 << 5)) >> 3) |
+ ((cpustate->op1 & (1 << 6)) >> 5) |
+ ((cpustate->op1 & (1 << 7)) >> 7));
+
+ F12WriteSecondOperand(cpustate, 0);
+ F12END(cpustate);
+}
+
+static UINT32 opRVBYT(v60_state *cpustate) /* TRUSTED */
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+
+ cpustate->modwritevalw = ((cpustate->op1 & 0x000000FF) << 24) |
+ ((cpustate->op1 & 0x0000FF00) << 8) |
+ ((cpustate->op1 & 0x00FF0000) >> 8) |
+ ((cpustate->op1 & 0xFF000000) >> 24);
+
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+static UINT32 opSET1(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ cpustate->_CY = ((appw & (1 << cpustate->op1)) != 0);
+ cpustate->_Z = !(cpustate->_CY);
+
+ appw |= (1 << cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+
+static UINT32 opSETF(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 0);
+
+ // Normalize the flags
+ NORMALIZEFLAGS(cpustate);
+
+ switch (cpustate->op1 & 0xF)
+ {
+ case 0:
+ if (!cpustate->_OV) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 1:
+ if (cpustate->_OV) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 2:
+ if (!cpustate->_CY) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 3:
+ if (cpustate->_CY) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 4:
+ if (!cpustate->_Z) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 5:
+ if (cpustate->_Z) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 6:
+ if (!(cpustate->_CY | cpustate->_Z)) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 7:
+ if ((cpustate->_CY | cpustate->_Z)) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 8:
+ if (!cpustate->_S) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 9:
+ if (cpustate->_S) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 10:
+ cpustate->modwritevalb = 1;
+ break;
+ case 11:
+ cpustate->modwritevalb = 0;
+ break;
+ case 12:
+ if (!(cpustate->_S^cpustate->_OV)) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 13:
+ if ((cpustate->_S^cpustate->_OV)) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 14:
+ if (!((cpustate->_S^cpustate->_OV)|cpustate->_Z)) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ case 15:
+ if (((cpustate->_S^cpustate->_OV)|cpustate->_Z)) cpustate->modwritevalb = 0;
+ else cpustate->modwritevalb = 1;
+ break;
+ }
+
+ F12WriteSecondOperand(cpustate, 0);
+
+ F12END(cpustate);
+}
+
+/*
+#define SHIFTLEFT_OY(val, count, bitsize) \
+{\
+ UINT32 tmp = ((val) >> (bitsize - 1)) & 1; \
+ tmp <<= count; \
+ tmp -= 1; \
+ tmp <<= (bitsize - (count)); \
+ cpustate->_OV = (((val) & tmp) != tmp); \
+ cpustate->_CY = (((val) & (1 << (count - 1))) != 0); \
+}
+*/
+
+// During the shift, the overflow is set if the sign bit changes at any point during the shift
+#define SHIFTLEFT_OV(val, count, bitsize) \
+{\
+ UINT32 tmp; \
+ if (count == 32) \
+ tmp = 0xFFFFFFFF; \
+ else \
+ tmp = ((1 << (count)) - 1); \
+ tmp <<= (bitsize - (count)); \
+ if (((val) >> (bitsize - 1)) & 1) \
+ cpustate->_OV = (((val) & tmp) != tmp); \
+ else \
+ cpustate->_OV = (((val) & tmp) != 0); \
+}
+
+#define SHIFTLEFT_CY(val, count, bitsize) \
+ cpustate->_CY = (UINT8)(((val) >> (bitsize - count)) & 1);
+
+
+
+#define SHIFTARITHMETICRIGHT_OV(val, count, bitsize) \
+ cpustate->_OV = 0;
+
+#define SHIFTARITHMETICRIGHT_CY(val, count, bitsize) \
+ cpustate->_CY = (UINT8)(((val) >> (count - 1)) & 1);
+
+
+
+static UINT32 opSHAB(v60_state *cpustate)
+{
+ UINT8 appb;
+ INT8 count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+
+ // Special case: destination unchanged, flags set
+ if (count == 0)
+ {
+ cpustate->_CY = cpustate->_OV = 0;
+ SetSZPF_Byte(appb);
+ }
+ else if (count > 0)
+ {
+ SHIFTLEFT_OV(appb, count, 8);
+
+ // @@@ Undefined what happens to CY when count >= bitsize
+ SHIFTLEFT_CY(appb, count, 8);
+
+ // do the actual shift...
+ if (count >= 8)
+ appb = 0;
+ else
+ appb <<= count;
+
+ // and set zero and sign
+ SetSZPF_Byte(appb);
+ }
+ else
+ {
+ count = -count;
+
+ SHIFTARITHMETICRIGHT_OV(appb, count, 8);
+ SHIFTARITHMETICRIGHT_CY(appb, count, 8);
+
+ if (count >= 8)
+ appb = (appb & 0x80) ? 0xFF : 0;
+ else
+ appb = ((INT8)appb) >> count;
+
+ SetSZPF_Byte(appb);
+ }
+
+// mame_printf_debug("SHAB: %x cpustate->_CY: %d cpustate->_Z: %d cpustate->_OV: %d cpustate->_S: %d\n", appb, cpustate->_CY, cpustate->_Z, cpustate->_OV, cpustate->_S);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSHAH(v60_state *cpustate)
+{
+ UINT16 apph;
+ INT8 count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+
+ // Special case: destination unchanged, flags set
+ if (count == 0)
+ {
+ cpustate->_CY = cpustate->_OV = 0;
+ SetSZPF_Word(apph);
+ }
+ else if (count > 0)
+ {
+ SHIFTLEFT_OV(apph, count, 16);
+
+ // @@@ Undefined what happens to CY when count >= bitsize
+ SHIFTLEFT_CY(apph, count, 16);
+
+ // do the actual shift...
+ if (count >= 16)
+ apph = 0;
+ else
+ apph <<= count;
+
+ // and set zero and sign
+ SetSZPF_Word(apph);
+ }
+ else
+ {
+ count = -count;
+
+ SHIFTARITHMETICRIGHT_OV(apph, count, 16);
+ SHIFTARITHMETICRIGHT_CY(apph, count, 16);
+
+ if (count >= 16)
+ apph = (apph & 0x8000) ? 0xFFFF : 0;
+ else
+ apph = ((INT16)apph) >> count;
+
+ SetSZPF_Word(apph);
+ }
+
+// mame_printf_debug("SHAH: %x >> %d = %x cpustate->_CY: %d cpustate->_Z: %d cpustate->_OV: %d cpustate->_S: %d\n", oldval, count, apph, cpustate->_CY, cpustate->_Z, cpustate->_OV, cpustate->_S);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSHAW(v60_state *cpustate)
+{
+ UINT32 appw;
+ INT8 count;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+
+ // Special case: destination unchanged, flags set
+ if (count == 0)
+ {
+ cpustate->_CY = cpustate->_OV = 0;
+ SetSZPF_Long(appw);
+ }
+ else if (count > 0)
+ {
+ SHIFTLEFT_OV(appw, count, 32);
+
+ // @@@ Undefined what happens to CY when count >= bitsize
+ SHIFTLEFT_CY(appw, count, 32);
+
+ // do the actual shift...
+ if (count >= 32)
+ appw = 0;
+ else
+ appw <<= count;
+
+ // and set zero and sign
+ SetSZPF_Long(appw);
+ }
+ else
+ {
+ count = -count;
+
+ SHIFTARITHMETICRIGHT_OV(appw, count, 32);
+ SHIFTARITHMETICRIGHT_CY(appw, count, 32);
+
+ if (count >= 32)
+ appw = (appw & 0x80000000) ? 0xFFFFFFFF : 0;
+ else
+ appw = ((INT32)appw) >> count;
+
+ SetSZPF_Long(appw);
+ }
+
+// mame_printf_debug("SHAW: %x >> %d = %x cpustate->_CY: %d cpustate->_Z: %d cpustate->_OV: %d cpustate->_S: %d\n", oldval, count, appw, cpustate->_CY, cpustate->_Z, cpustate->_OV, cpustate->_S);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+
+static UINT32 opSHLB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb;
+ INT8 count;
+ UINT32 tmp;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ // left shift flags:
+ // carry gets the last bit shifted out,
+ // overflow is always CLEARed
+
+ cpustate->_OV = 0; // default to no overflow
+
+ // now handle carry
+ tmp = appb & 0xff;
+ tmp <<= count;
+ SetCFB(tmp); // set carry properly
+
+ // do the actual shift...
+ appb <<= count;
+
+ // and set zero and sign
+ SetSZPF_Byte(appb);
+ }
+ else
+ {
+ if (count == 0)
+ {
+ // special case: clear carry and overflow, do nothing else
+ cpustate->_CY = cpustate->_OV = 0;
+ SetSZPF_Byte(appb); // doc. is unclear if this is true...
+ }
+ else
+ {
+ // right shift flags:
+ // carry = last bit shifted out
+ // overflow always cleared
+ tmp = appb & 0xff;
+ tmp >>= ((-count) - 1);
+ cpustate->_CY = (UINT8)(tmp & 0x1);
+ cpustate->_OV = 0;
+
+ appb >>= -count;
+ SetSZPF_Byte(appb);
+ }
+ }
+
+// mame_printf_debug("SHLB: %x cpustate->_CY: %d cpustate->_Z: %d cpustate->_OV: %d cpustate->_S: %d\n", appb, cpustate->_CY, cpustate->_Z, cpustate->_OV, cpustate->_S);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSHLH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph;
+ INT8 count;
+ UINT32 tmp;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+// mame_printf_debug("apph: %x count: %d ", apph, count);
+ if (count > 0)
+ {
+ // left shift flags:
+ // carry gets the last bit shifted out,
+ // overflow is always CLEARed
+
+ cpustate->_OV = 0;
+
+ // now handle carry
+ tmp = apph & 0xffff;
+ tmp <<= count;
+ SetCFW(tmp); // set carry properly
+
+ // do the actual shift...
+ apph <<= count;
+
+ // and set zero and sign
+ SetSZPF_Word(apph);
+ }
+ else
+ {
+ if (count == 0)
+ {
+ // special case: clear carry and overflow, do nothing else
+ cpustate->_CY = cpustate->_OV = 0;
+ SetSZPF_Word(apph); // doc. is unclear if this is true...
+ }
+ else
+ {
+ // right shift flags:
+ // carry = last bit shifted out
+ // overflow always cleared
+ tmp = apph & 0xffff;
+ tmp >>= ((-count) - 1);
+ cpustate->_CY = (UINT8)(tmp & 0x1);
+ cpustate->_OV = 0;
+
+ apph >>= -count;
+ SetSZPF_Word(apph);
+ }
+ }
+
+// mame_printf_debug("SHLH: %x cpustate->_CY: %d cpustate->_Z: %d cpustate->_OV: %d cpustate->_S: %d\n", apph, cpustate->_CY, cpustate->_Z, cpustate->_OV, cpustate->_S);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSHLW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw;
+ INT8 count;
+ UINT64 tmp;
+
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ count = (INT8)(cpustate->op1 & 0xFF);
+ if (count > 0)
+ {
+ // left shift flags:
+ // carry gets the last bit shifted out,
+ // overflow is always CLEARed
+
+ cpustate->_OV = 0;
+
+ // now handle carry
+ tmp = appw & 0xffffffff;
+ tmp <<= count;
+ SetCFL(tmp); // set carry properly
+
+ // do the actual shift...
+ appw <<= count;
+
+ // and set zero and sign
+ SetSZPF_Long(appw);
+ }
+ else
+ {
+ if (count == 0)
+ {
+ // special case: clear carry and overflow, do nothing else
+ cpustate->_CY = cpustate->_OV = 0;
+ SetSZPF_Long(appw); // doc. is unclear if this is true...
+ }
+ else
+ {
+ // right shift flags:
+ // carry = last bit shifted out
+ // overflow always cleared
+ tmp = (UINT64)(appw & 0xffffffff);
+ tmp >>= ((-count) - 1);
+ cpustate->_CY = (UINT8)(tmp & 0x1);
+ cpustate->_OV = 0;
+
+ appw >>= -count;
+ SetSZPF_Long(appw);
+ }
+ }
+
+// mame_printf_debug("SHLW: %x cpustate->_CY: %d cpustate->_Z: %d cpustate->_OV: %d cpustate->_S: %d\n", appw, cpustate->_CY, cpustate->_Z, cpustate->_OV, cpustate->_S);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSTPR(v60_state *cpustate)
+{
+ F12DecodeFirstOperand(cpustate, ReadAM, 2);
+ if (cpustate->op1 <= 28)
+ cpustate->modwritevalw = cpustate->reg[cpustate->op1 + 36];
+ else
+ {
+ fatalerror("Invalid operand on STPR cpustate->PC=%x", cpustate->PC);
+ }
+ F12WriteSecondOperand(cpustate, 2);
+ F12END(cpustate);
+}
+
+
+static UINT32 opSUBB(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ SUBB(appb, (UINT8)cpustate->op1);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSUBH(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ SUBW(apph, (UINT16)cpustate->op1);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSUBW(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ SUBL(appw, (UINT32)cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+
+static UINT32 opSUBCB(v60_state *cpustate)
+{
+ UINT8 appb;
+ UINT8 src;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ src = (UINT8)cpustate->op1 + (cpustate->_CY?1:0);
+ SUBB(appb, src);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSUBCH(v60_state *cpustate)
+{
+ UINT16 apph;
+ UINT16 src;
+
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ src = (UINT16)cpustate->op1 + (cpustate->_CY?1:0);
+ SUBW(apph, src);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opSUBCW(v60_state *cpustate)
+{
+ UINT32 appw;
+ UINT32 src;
+
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ src = (UINT32)cpustate->op1 + (cpustate->_CY?1:0);
+ SUBL(appw, src);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opTEST1(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAM, 2);
+
+ cpustate->_CY = ((cpustate->op2 & (1 << cpustate->op1)) != 0);
+ cpustate->_Z = !(cpustate->_CY);
+
+ F12END(cpustate);
+}
+
+static UINT32 opUPDPSWW(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAM, 2);
+
+ /* can only modify condition code and control fields */
+ cpustate->op2 &= 0xFFFFFF;
+ cpustate->op1 &= 0xFFFFFF;
+ v60WritePSW(cpustate, (v60ReadPSW(cpustate) & (~cpustate->op2)) | (cpustate->op1 & cpustate->op2));
+
+ F12END(cpustate);
+}
+
+static UINT32 opUPDPSWH(v60_state *cpustate)
+{
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAM, 2);
+
+ /* can only modify condition code fields */
+ cpustate->op2 &= 0xFFFF;
+ cpustate->op1 &= 0xFFFF;
+ v60WritePSW(cpustate, (v60ReadPSW(cpustate) & (~cpustate->op2)) | (cpustate->op1 & cpustate->op2));
+
+ F12END(cpustate);
+}
+
+static UINT32 opXCHB(v60_state *cpustate) /* TRUSTED */
+{
+ UINT8 appb, temp;
+
+ F12DecodeOperands(cpustate, ReadAMAddress, 0,ReadAMAddress, 0);
+
+ F12LOADOP1BYTE(cpustate);
+ temp = appb;
+ F12LOADOP2BYTE(cpustate);
+ F12STOREOP1BYTE(cpustate);
+ appb = temp;
+ F12STOREOP2BYTE(cpustate);
+
+ F12END(cpustate)
+}
+
+static UINT32 opXCHH(v60_state *cpustate) /* TRUSTED */
+{
+ UINT16 apph, temp;
+
+ F12DecodeOperands(cpustate, ReadAMAddress, 1,ReadAMAddress, 1);
+
+ F12LOADOP1HALF(cpustate);
+ temp = apph;
+ F12LOADOP2HALF(cpustate);
+ F12STOREOP1HALF(cpustate);
+ apph = temp;
+ F12STOREOP2HALF(cpustate);
+
+ F12END(cpustate)
+}
+
+static UINT32 opXCHW(v60_state *cpustate) /* TRUSTED */
+{
+ UINT32 appw, temp;
+
+ F12DecodeOperands(cpustate, ReadAMAddress, 2,ReadAMAddress, 2);
+
+ F12LOADOP1WORD(cpustate);
+ temp = appw;
+ F12LOADOP2WORD(cpustate);
+ F12STOREOP1WORD(cpustate);
+ appw = temp;
+ F12STOREOP2WORD(cpustate);
+
+ F12END(cpustate)
+}
+
+static UINT32 opXORB(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT8 appb;
+ F12DecodeOperands(cpustate, ReadAM, 0,ReadAMAddress, 0);
+
+ F12LOADOP2BYTE(cpustate);
+
+ XORB(appb, (UINT8)cpustate->op1);
+
+ F12STOREOP2BYTE(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opXORH(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT16 apph;
+ F12DecodeOperands(cpustate, ReadAM, 1,ReadAMAddress, 1);
+
+ F12LOADOP2HALF(cpustate);
+
+ XORW(apph, (UINT16)cpustate->op1);
+
+ F12STOREOP2HALF(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opXORW(v60_state *cpustate) /* TRUSTED (C too!) */
+{
+ UINT32 appw;
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 2);
+
+ F12LOADOP2WORD(cpustate);
+
+ XORL(appw, (UINT32)cpustate->op1);
+
+ F12STOREOP2WORD(cpustate);
+ F12END(cpustate);
+}
+
+static UINT32 opMULX(v60_state *cpustate)
+{
+ INT32 a, b;
+ INT64 res;
+
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 3);
+
+ if (cpustate->flag2)
+ {
+ a = cpustate->reg[cpustate->op2 & 0x1F];
+ }
+ else
+ {
+ a = cpustate->program->read_dword_unaligned(cpustate->op2);
+ }
+
+ res = (INT64)a * (INT64)(INT32)cpustate->op1;
+
+ b = (INT32)((res >> 32)&0xffffffff);
+ a = (INT32)(res & 0xffffffff);
+
+ cpustate->_S = ((b & 0x80000000) != 0);
+ cpustate->_Z = (a == 0 && b == 0);
+
+ if (cpustate->flag2)
+ {
+ cpustate->reg[cpustate->op2 & 0x1F] = a;
+ cpustate->reg[(cpustate->op2 & 0x1F) + 1] = b;
+ }
+ else
+ {
+ cpustate->program->write_dword_unaligned(cpustate->op2, a);
+ cpustate->program->write_dword_unaligned(cpustate->op2 + 4, b);
+ }
+
+ F12END(cpustate);
+}
+
+static UINT32 opMULUX(v60_state *cpustate)
+{
+ INT32 a, b;
+ UINT64 res;
+
+ F12DecodeOperands(cpustate, ReadAM, 2,ReadAMAddress, 3);
+
+ if (cpustate->flag2)
+ {
+ a = cpustate->reg[cpustate->op2 & 0x1F];
+ }
+ else
+ {
+ a = cpustate->program->read_dword_unaligned(cpustate->op2);
+ }
+
+ res = (UINT64)a * (UINT64)cpustate->op1;
+ b = (INT32)((res >> 32)&0xffffffff);
+ a = (INT32)(res & 0xffffffff);
+
+ cpustate->_S = ((b & 0x80000000) != 0);
+ cpustate->_Z = (a == 0 && b == 0);
+
+ if (cpustate->flag2)
+ {
+ cpustate->reg[cpustate->op2 & 0x1F] = a;
+ cpustate->reg[(cpustate->op2 & 0x1F) + 1] = b;
+ }
+ else
+ {
+ cpustate->program->write_dword_unaligned(cpustate->op2, a);
+ cpustate->program->write_dword_unaligned(cpustate->op2 + 4, b);
+ }
+
+ F12END(cpustate);
+}