/* * 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: _CY and _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 */ static UINT32 f12Op1, f12Op2; static UINT8 f12Flag1, f12Flag2; /* * Macro to access data in operands decoded with ReadAMAddress() */ #define F12LOADOPBYTE(num) \ if (f12Flag##num) \ appb = (UINT8)v60.reg[f12Op##num]; \ else \ appb = MemRead8(f12Op##num); #define F12LOADOPHALF(num) \ if (f12Flag##num) \ apph = (UINT16)v60.reg[f12Op##num]; \ else \ apph = MemRead16(f12Op##num); #define F12LOADOPWORD(num) \ if (f12Flag##num) \ appw = v60.reg[f12Op##num]; \ else \ appw = MemRead32(f12Op##num); #define F12STOREOPBYTE(num) \ if (f12Flag##num) \ SETREG8(v60.reg[f12Op##num], appb); \ else \ MemWrite8(f12Op##num,appb); #define F12STOREOPHALF(num) \ if (f12Flag##num) \ SETREG16(v60.reg[f12Op##num], apph); \ else \ MemWrite16(f12Op##num,apph); #define F12STOREOPWORD(num) \ if (f12Flag##num) \ v60.reg[f12Op##num] = appw; \ else \ MemWrite32(f12Op##num,appw); #define F12LOADOP1BYTE() F12LOADOPBYTE(1) #define F12LOADOP1HALF() F12LOADOPHALF(1) #define F12LOADOP1WORD() F12LOADOPWORD(1) #define F12LOADOP2BYTE() F12LOADOPBYTE(2) #define F12LOADOP2HALF() F12LOADOPHALF(2) #define F12LOADOP2WORD() F12LOADOPWORD(2) #define F12STOREOP1BYTE() F12STOREOPBYTE(1) #define F12STOREOP1HALF() F12STOREOPHALF(1) #define F12STOREOP1WORD() F12STOREOPWORD(1) #define F12STOREOP2BYTE() F12STOREOPBYTE(2) #define F12STOREOP2HALF() F12STOREOPHALF(2) #define F12STOREOP2WORD() F12STOREOPWORD(2) #define F12END() \ return amLength1 + amLength2 + 2; static UINT8 if12; // Decode the first operand of the instruction and prepare // writing to the second operand. static void F12DecodeFirstOperand(UINT32 (*DecodeOp1)(void), UINT8 dim1) { if12 = OpRead8(PC + 1); // Check if F1 or F2 if (if12 & 0x80) { modDim = dim1; modM = if12 & 0x40; modAdd = PC + 2; amLength1 = DecodeOp1(); f12Op1 = amOut; f12Flag1 = amFlag; } else { // Check D flag if (if12 & 0x20) { modDim = dim1; modM = if12 & 0x40; modAdd = PC + 2; amLength1 = DecodeOp1(); f12Op1 = amOut; f12Flag1 = amFlag; } else { if (DecodeOp1==ReadAM) { switch (dim1) { case 0: f12Op1 = (UINT8)v60.reg[if12 & 0x1F]; break; case 1: f12Op1 = (UINT16)v60.reg[if12 & 0x1F]; break; case 2: f12Op1 = v60.reg[if12 & 0x1F]; break; } f12Flag1 = 0; } else { f12Flag1 = 1; f12Op1 = if12 & 0x1F; } amLength1 = 0; } } } static void F12WriteSecondOperand(UINT8 dim2) { modDim = dim2; // Check if F1 or F2 if (if12 & 0x80) { modM = if12 & 0x20; modAdd = PC + 2 + amLength1; modDim = dim2; amLength2 = WriteAM(); } else { // Check D flag if (if12 & 0x20) { switch (dim2) { case 0: SETREG8(v60.reg[if12 & 0x1F], modWriteValB); break; case 1: SETREG16(v60.reg[if12 & 0x1F], modWriteValH); break; case 2: v60.reg[if12 & 0x1F] = modWriteValW; break; } amLength2 = 0; } else { modM = if12 & 0x40; modAdd = PC + 2; modDim = dim2; amLength2 = WriteAM(); } } } // Decode both format 1/2 operands static void F12DecodeOperands(UINT32 (*DecodeOp1)(void), UINT8 dim1, UINT32 (*DecodeOp2)(void), UINT8 dim2) { UINT8 _if12 = OpRead8(PC + 1); // Check if F1 or F2 if (_if12 & 0x80) { modDim = dim1; modM = _if12 & 0x40; modAdd = PC + 2; amLength1 = DecodeOp1(); f12Op1 = amOut; f12Flag1 = amFlag; modDim = dim2; modM = _if12 & 0x20; modAdd = PC + 2 + amLength1; amLength2 = DecodeOp2(); f12Op2 = amOut; f12Flag2 = amFlag; } else { // Check D flag if (_if12 & 0x20) { if (DecodeOp2==ReadAMAddress) { f12Op2 = _if12 & 0x1F; f12Flag2 = 1; } else { switch (dim2) { case 0: f12Op2 = (UINT8)v60.reg[_if12 & 0x1F]; break; case 1: f12Op2 = (UINT16)v60.reg[_if12 & 0x1F]; break; case 2: f12Op2 = v60.reg[_if12 & 0x1F]; break; } } amLength2 = 0; modDim = dim1; modM = _if12 & 0x40; modAdd = PC + 2; amLength1 = DecodeOp1(); f12Op1 = amOut; f12Flag1 = amFlag; } else { if (DecodeOp1==ReadAMAddress) { f12Op1 = _if12 & 0x1F; f12Flag1 = 1; } else { switch (dim1) { case 0: f12Op1 = (UINT8)v60.reg[_if12 & 0x1F]; break; case 1: f12Op1 = (UINT16)v60.reg[_if12 & 0x1F]; break; case 2: f12Op1 = v60.reg[_if12 & 0x1F]; break; } } amLength1 = 0; modDim = dim2; modM = _if12 & 0x40; modAdd = PC + 2 + amLength1; amLength2 = DecodeOp2(); f12Op2 = amOut; f12Flag2 = amFlag; } } } static UINT32 opADDB(void) /* TRUSTED (C too!)*/ { UINT8 appb; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); ADDB(appb, (UINT8)f12Op1); F12STOREOP2BYTE(); F12END(); } static UINT32 opADDH(void) /* TRUSTED (C too!)*/ { UINT16 apph; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); ADDW(apph, (UINT16)f12Op1); F12STOREOP2HALF(); F12END(); } static UINT32 opADDW(void) /* TRUSTED (C too!) */ { UINT32 appw; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); ADDL(appw, (UINT32)f12Op1); F12STOREOP2WORD(); F12END(); } static UINT32 opADDCB(void) { UINT8 appb, temp; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); temp = ((UINT8)f12Op1 + (_CY?1:0)); ADDB(appb, temp); F12STOREOP2BYTE(); F12END(); } static UINT32 opADDCH(void) { UINT16 apph, temp; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); temp = ((UINT16)f12Op1 + (_CY?1:0)); ADDW(apph, temp); F12STOREOP2HALF(); F12END(); } static UINT32 opADDCW(void) { UINT32 appw, temp; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); temp = f12Op1 + (_CY?1:0); ADDL(appw, temp); F12STOREOP2WORD(); F12END(); } static UINT32 opANDB(void) /* TRUSTED */ { UINT8 appb; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); appb &= f12Op1; _OV = 0; _S = ((appb&0x80)!=0); _Z = (appb==0); F12STOREOP2BYTE(); F12END(); } static UINT32 opANDH(void) /* TRUSTED */ { UINT16 apph; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); apph &= f12Op1; _OV = 0; _S = ((apph&0x8000)!=0); _Z = (apph==0); F12STOREOP2HALF(); F12END(); } static UINT32 opANDW(void) /* TRUSTED */ { UINT32 appw; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); appw &= f12Op1; _OV = 0; _S = ((appw&0x80000000)!=0); _Z = (appw==0); F12STOREOP2WORD(); F12END(); } static UINT32 opCALL(void) /* TRUSTED */ { F12DecodeOperands(ReadAMAddress,0,ReadAMAddress,2); SP -= 4; MemWrite32(SP, AP); AP = f12Op2; SP -= 4; MemWrite32(SP, PC + amLength1 + amLength2 + 2); PC = f12Op1; ChangePC(PC); return 0; } static UINT32 opCHKAR(void) { F12DecodeOperands(ReadAM,0,ReadAM,0); // No MMU and memory permissions yet @@@ _Z = 1; _CY = 0; _S = 0; F12END(); } static UINT32 opCHKAW(void) { F12DecodeOperands(ReadAM,0,ReadAM,0); // No MMU and memory permissions yet @@@ _Z = 1; _CY = 0; _S = 0; F12END(); } static UINT32 opCHKAE(void) { F12DecodeOperands(ReadAM,0,ReadAM,0); // No MMU and memory permissions yet @@@ _Z = 1; _CY = 0; _S = 0; F12END(); } static UINT32 opCHLVL(void) { UINT32 oldPSW; F12DecodeOperands(ReadAM,0,ReadAM,0); if (f12Op1>3) { fatalerror("Illegal data field on opCHLVL, PC=%x", PC); } oldPSW = v60_update_psw_for_exception(0, f12Op1); SP -= 4; MemWrite32(SP,f12Op2); SP -= 4; MemWrite32(SP,EXCEPTION_CODE_AND_SIZE(0x1800 + f12Op1*0x100, 8)); SP -= 4; MemWrite32(SP,oldPSW); SP -= 4; MemWrite32(SP,PC + amLength1 + amLength2 + 2); PC = GETINTVECT(24+f12Op1); ChangePC(PC); return 0; } static UINT32 opCLR1(void) /* TRUSTED */ { UINT32 appw; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); _CY = ((appw & (1<= 0 && f12Op2 <= 28) { if (f12Flag1 &&(!(OpRead8(PC + 1)&0x80 && OpRead8(PC + 2)==0xf4 ) )) v60.reg[f12Op2 + 36] = v60.reg[f12Op1]; else v60.reg[f12Op2 + 36] = f12Op1; } else { fatalerror("Invalid operand on LDPR PC=%x", PC); } F12END(); } static UINT32 opLDTASK(void) { int i; F12DecodeOperands(ReadAMAddress,2,ReadAM,2); v60WritePSW(v60ReadPSW() & 0xefffffff); TR = f12Op2; TKCW = MemRead32(f12Op2); f12Op2 += 4; if(SYCW & 0x100) { L0SP = MemRead32(f12Op2); f12Op2 += 4; } if(SYCW & 0x200) { L1SP = MemRead32(f12Op2); f12Op2 += 4; } if(SYCW & 0x400) { L2SP = MemRead32(f12Op2); f12Op2 += 4; } if(SYCW & 0x800) { L3SP = MemRead32(f12Op2); f12Op2 += 4; } v60ReloadStack(); // 31 registers supported, _not_ 32 for(i=0; i<31; i++) if(f12Op1 & (1<> 8)!=0); F12STOREOP2BYTE(); F12END(); } static UINT32 opMULH(void) { UINT16 apph; UINT32 tmp; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); // @@@ OV not set!! tmp=(INT16)apph * (INT32)(INT16)f12Op1; apph = tmp; _Z = (apph == 0); _S = ((apph & 0x8000)!=0); _OV = ((tmp >> 16)!=0); F12STOREOP2HALF(); F12END(); } static UINT32 opMULW(void) { UINT32 appw; UINT64 tmp; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); // @@@ OV not set!! tmp=(INT32)appw * (INT64)(INT32)f12Op1; appw = tmp; _Z = (appw == 0); _S = ((appw & 0x80000000)!=0); _OV = ((tmp >> 32) != 0); F12STOREOP2WORD(); F12END(); } static UINT32 opMULUB(void) { UINT8 appb; UINT32 tmp; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); // @@@ OV not set!! tmp = appb * (UINT8)f12Op1; appb = tmp; _Z = (appb == 0); _S = ((appb & 0x80)!=0); _OV = ((tmp >> 8)!=0); F12STOREOP2BYTE(); F12END(); } static UINT32 opMULUH(void) { UINT16 apph; UINT32 tmp; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); // @@@ OV not set!! tmp=apph * (UINT16)f12Op1; apph = tmp; _Z = (apph == 0); _S = ((apph & 0x8000)!=0); _OV = ((tmp >> 16)!=0); F12STOREOP2HALF(); F12END(); } static UINT32 opMULUW(void) { UINT32 appw; UINT64 tmp; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); // @@@ OV not set!! tmp=(UINT64)appw * (UINT64)f12Op1; appw = tmp; _Z = (appw == 0); _S = ((appw & 0x80000000)!=0); _OV = ((tmp >> 32)!=0); F12STOREOP2WORD(); F12END(); } static UINT32 opNEGB(void) /* TRUSTED (C too!)*/ { F12DecodeFirstOperand(ReadAM,0); modWriteValB = 0; SUBB(modWriteValB, (INT8)f12Op1); F12WriteSecondOperand(0); F12END(); } static UINT32 opNEGH(void) /* TRUSTED (C too!)*/ { F12DecodeFirstOperand(ReadAM,1); modWriteValH = 0; SUBW(modWriteValH, (INT16)f12Op1); F12WriteSecondOperand(1); F12END(); } static UINT32 opNEGW(void) /* TRUSTED (C too!)*/ { F12DecodeFirstOperand(ReadAM,2); modWriteValW = 0; SUBL(modWriteValW, (INT32)f12Op1); F12WriteSecondOperand(2); F12END(); } static UINT32 opNOTB(void) /* TRUSTED */ { F12DecodeFirstOperand(ReadAM,0); modWriteValB=~f12Op1; _OV=0; _S=((modWriteValB&0x80)!=0); _Z=(modWriteValB==0); F12WriteSecondOperand(0); F12END(); } static UINT32 opNOTH(void) /* TRUSTED */ { F12DecodeFirstOperand(ReadAM,1); modWriteValH=~f12Op1; _OV=0; _S=((modWriteValH&0x8000)!=0); _Z=(modWriteValH==0); F12WriteSecondOperand(1); F12END(); } static UINT32 opNOTW(void) /* TRUSTED */ { F12DecodeFirstOperand(ReadAM,2); modWriteValW=~f12Op1; _OV=0; _S=((modWriteValW&0x80000000)!=0); _Z=(modWriteValW==0); F12WriteSecondOperand(2); F12END(); } static UINT32 opNOT1(void) /* TRUSTED */ { UINT32 appw; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); _CY = ((appw & (1<0) { for (i=0;i> 7); _CY=(appb&0x1)!=0; } else if (count<0) { count=-count; for (i=0;i>1) | ((appb&0x1) << 7); _CY=(appb&0x80)!=0; } else _CY=0; _OV=0; _S=(appb&0x80)!=0; _Z=(appb==0); F12STOREOP2BYTE(); F12END(); } static UINT32 opROTH(void) /* TRUSTED */ { UINT16 apph; INT8 i,count; F12DecodeOperands(ReadAM,0,ReadAMAddress,1); F12LOADOP2HALF(); count=(INT8)(f12Op1&0xFF); if (count>0) { for (i=0;i> 15); _CY=(apph&0x1)!=0; } else if (count<0) { count=-count; for (i=0;i>1) | ((apph&0x1) << 15); _CY=(apph&0x8000)!=0; } else _CY=0; _OV=0; _S=(apph&0x8000)!=0; _Z=(apph==0); F12STOREOP2HALF(); F12END(); } static UINT32 opROTW(void) /* TRUSTED */ { UINT32 appw; INT8 i,count; F12DecodeOperands(ReadAM,0,ReadAMAddress,2); F12LOADOP2WORD(); count=(INT8)(f12Op1&0xFF); if (count>0) { for (i=0;i> 31); _CY=(appw&0x1)!=0; } else if (count<0) { count=-count; for (i=0;i>1) | ((appw&0x1) << 31); _CY=(appw&0x80000000)!=0; } else _CY=0; _OV=0; _S=(appw&0x80000000)!=0; _Z=(appw==0); F12STOREOP2WORD(); F12END(); } static UINT32 opROTCB(void) /* TRUSTED */ { UINT8 appb; INT8 i,cy,count; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); NORMALIZEFLAGS(); count=(INT8)(f12Op1&0xFF); if (count>0) { for (i=0;i> 7); appb = (appb<<1) | cy; } } else if (count<0) { count=-count; for (i=0;i>1) | (cy << 7); } } else _CY = 0; _OV=0; _S=(appb&0x80)!=0; _Z=(appb==0); F12STOREOP2BYTE(); F12END(); } static UINT32 opROTCH(void) /* TRUSTED */ { UINT16 apph; INT8 i,cy,count; F12DecodeOperands(ReadAM,0,ReadAMAddress,1); F12LOADOP2HALF(); NORMALIZEFLAGS(); count=(INT8)(f12Op1&0xFF); if (count>0) { for (i=0;i> 15); apph = (apph<<1) | cy; } } else if (count<0) { count=-count; for (i=0;i>1) | ((UINT16)cy << 15); } } else _CY = 0; _OV=0; _S=(apph&0x8000)!=0; _Z=(apph==0); F12STOREOP2HALF(); F12END(); } static UINT32 opROTCW(void) /* TRUSTED */ { UINT32 appw; INT8 i,cy,count; F12DecodeOperands(ReadAM,0,ReadAMAddress,2); F12LOADOP2WORD(); NORMALIZEFLAGS(); count=(INT8)(f12Op1&0xFF); if (count>0) { for (i=0;i> 31); appw = (appw<<1) | cy; } } else if (count<0) { count=-count; for (i=0;i>1) | ((UINT32)cy << 31); } } else _CY=0; _OV=0; _S=(appw&0x80000000)!=0; _Z=(appw==0); F12STOREOP2WORD(); F12END(); } static UINT32 opRVBIT(void) { F12DecodeFirstOperand(ReadAM,0); modWriteValB =(UINT8) (((f12Op1 & (1<<0)) << 7) | ((f12Op1 & (1<<1)) << 5) | ((f12Op1 & (1<<2)) << 3) | ((f12Op1 & (1<<3)) << 1) | ((f12Op1 & (1<<4)) >> 1) | ((f12Op1 & (1<<5)) >> 3) | ((f12Op1 & (1<<6)) >> 5) | ((f12Op1 & (1<<7)) >> 7)); F12WriteSecondOperand(0); F12END(); } static UINT32 opRVBYT(void) /* TRUSTED */ { F12DecodeFirstOperand(ReadAM,2); modWriteValW = ((f12Op1 & 0x000000FF) << 24) | ((f12Op1 & 0x0000FF00) << 8) | ((f12Op1 & 0x00FF0000) >> 8) | ((f12Op1 & 0xFF000000) >> 24); F12WriteSecondOperand(2); F12END(); } static UINT32 opSET1(void) /* TRUSTED */ { UINT32 appw; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); _CY = ((appw & (1<> (bitsize-1)) & 1; \ tmp <<= count; \ tmp -= 1; \ tmp <<= (bitsize - (count)); \ _OV = (((val) & tmp) != tmp); \ _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) \ _OV = (((val) & tmp) != tmp); \ else \ _OV = (((val) & tmp) != 0); \ } #define SHIFTLEFT_CY(val, count, bitsize) \ _CY = (UINT8)(((val) >> (bitsize - count)) & 1); #define SHIFTARITHMETICRIGHT_OV(val, count, bitsize) \ _OV = 0; #define SHIFTARITHMETICRIGHT_CY(val, count, bitsize) \ _CY = (UINT8)(((val) >> (count-1)) & 1); static UINT32 opSHAB(void) { UINT8 appb; INT8 count; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); count=(INT8)(f12Op1&0xFF); // Special case: destination unchanged, flags set if (count == 0) { _CY = _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 _CY: %d _Z: %d _OV: %d _S: %d\n", appb, _CY, _Z, _OV, _S); F12STOREOP2BYTE(); F12END(); } static UINT32 opSHAH(void) { UINT16 apph; INT8 count; F12DecodeOperands(ReadAM,0,ReadAMAddress,1); F12LOADOP2HALF(); count=(INT8)(f12Op1&0xFF); // Special case: destination unchanged, flags set if (count == 0) { _CY = _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 _CY: %d _Z: %d _OV: %d _S: %d\n", oldval, count, apph, _CY, _Z, _OV, _S); F12STOREOP2HALF(); F12END(); } static UINT32 opSHAW(void) { UINT32 appw; INT8 count; F12DecodeOperands(ReadAM,0,ReadAMAddress,2); F12LOADOP2WORD(); count=(INT8)(f12Op1&0xFF); // Special case: destination unchanged, flags set if (count == 0) { _CY = _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 _CY: %d _Z: %d _OV: %d _S: %d\n", oldval, count, appw, _CY, _Z, _OV, _S); F12STOREOP2WORD(); F12END(); } static UINT32 opSHLB(void) /* TRUSTED */ { UINT8 appb; INT8 count; UINT32 tmp; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); count=(INT8)(f12Op1&0xFF); if (count>0) { // left shift flags: // carry gets the last bit shifted out, // overflow is always CLEARed _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 _CY = _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); _CY = (UINT8)(tmp & 0x1); _OV = 0; appb >>= -count; SetSZPF_Byte(appb); } } // mame_printf_debug("SHLB: %x _CY: %d _Z: %d _OV: %d _S: %d\n", appb, _CY, _Z, _OV, _S); F12STOREOP2BYTE(); F12END(); } static UINT32 opSHLH(void) /* TRUSTED */ { UINT16 apph; INT8 count; UINT32 tmp; F12DecodeOperands(ReadAM,0,ReadAMAddress,1); F12LOADOP2HALF(); count=(INT8)(f12Op1&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 _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 _CY = _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); _CY = (UINT8)(tmp & 0x1); _OV = 0; apph >>= -count; SetSZPF_Word(apph); } } // mame_printf_debug("SHLH: %x _CY: %d _Z: %d _OV: %d _S: %d\n", apph, _CY, _Z, _OV, _S); F12STOREOP2HALF(); F12END(); } static UINT32 opSHLW(void) /* TRUSTED */ { UINT32 appw; INT8 count; UINT64 tmp; F12DecodeOperands(ReadAM,0,ReadAMAddress,2); F12LOADOP2WORD(); count=(INT8)(f12Op1&0xFF); if (count>0) { // left shift flags: // carry gets the last bit shifted out, // overflow is always CLEARed _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 _CY = _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); _CY = (UINT8)(tmp & 0x1); _OV = 0; appw >>= -count; SetSZPF_Long(appw); } } // mame_printf_debug("SHLW: %x _CY: %d _Z: %d _OV: %d _S: %d\n", appw, _CY, _Z, _OV, _S); F12STOREOP2WORD(); F12END(); } static UINT32 opSTPR(void) { F12DecodeFirstOperand(ReadAM,2); if (f12Op1 >= 0 && f12Op1 <= 28) modWriteValW = v60.reg[f12Op1 + 36]; else { fatalerror("Invalid operand on STPR PC=%x", PC); } F12WriteSecondOperand(2); F12END(); } static UINT32 opSUBB(void) /* TRUSTED (C too!) */ { UINT8 appb; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); SUBB(appb, (UINT8)f12Op1); F12STOREOP2BYTE(); F12END(); } static UINT32 opSUBH(void) /* TRUSTED (C too!) */ { UINT16 apph; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); SUBW(apph, (UINT16)f12Op1); F12STOREOP2HALF(); F12END(); } static UINT32 opSUBW(void) /* TRUSTED (C too!) */ { UINT32 appw; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); SUBL(appw, (UINT32)f12Op1); F12STOREOP2WORD(); F12END(); } static UINT32 opSUBCB(void) { UINT8 appb; UINT8 src; F12DecodeOperands(ReadAM,0,ReadAMAddress,0); F12LOADOP2BYTE(); src = (UINT8)f12Op1 + (_CY?1:0); SUBB(appb, src); F12STOREOP2BYTE(); F12END(); } static UINT32 opSUBCH(void) { UINT16 apph; UINT16 src; F12DecodeOperands(ReadAM,1,ReadAMAddress,1); F12LOADOP2HALF(); src = (UINT16)f12Op1 + (_CY?1:0); SUBW(apph, src); F12STOREOP2HALF(); F12END(); } static UINT32 opSUBCW(void) { UINT32 appw; UINT32 src; F12DecodeOperands(ReadAM,2,ReadAMAddress,2); F12LOADOP2WORD(); src = (UINT32)f12Op1 + (_CY?1:0); SUBL(appw, src); F12STOREOP2WORD(); F12END(); } static UINT32 opTEST1(void) { F12DecodeOperands(ReadAM,2,ReadAM,2); _CY = ((f12Op2 & (1<> 32)&0xffffffff); a = (INT32)(res&0xffffffff); _S = ((b & 0x80000000) != 0); _Z = (a == 0 && b == 0); if (f12Flag2) { v60.reg[f12Op2&0x1F]=a; v60.reg[(f12Op2&0x1F)+1]=b; } else { MemWrite32(f12Op2,a); MemWrite32(f12Op2+4,b); } F12END(); } static UINT32 opMULUX(void) { INT32 a,b; UINT64 res; F12DecodeOperands(ReadAM,2,ReadAMAddress,3); if (f12Flag2) { a=v60.reg[f12Op2&0x1F]; } else { a=MemRead32(f12Op2); } res = (UINT64)a * (UINT64)f12Op1; b = (INT32)((res >> 32)&0xffffffff); a = (INT32)(res&0xffffffff); _S = ((b & 0x80000000) != 0); _Z = (a == 0 && b == 0); if (f12Flag2) { v60.reg[f12Op2&0x1F]=a; v60.reg[(f12Op2&0x1F)+1]=b; } else { MemWrite32(f12Op2,a); MemWrite32(f12Op2+4,b); } F12END(); }