diff options
Diffstat (limited to 'trunk/src/emu/cpu/v60/op12.c')
-rw-r--r-- | trunk/src/emu/cpu/v60/op12.c | 2391 |
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); +} |