diff --git a/Source/Core/DSPCore/Src/DSPCore.h b/Source/Core/DSPCore/Src/DSPCore.h index 969f404eb8..b64c12e58c 100644 --- a/Source/Core/DSPCore/Src/DSPCore.h +++ b/Source/Core/DSPCore/Src/DSPCore.h @@ -154,7 +154,7 @@ #define SR_OVERFLOW 0x0002 #define SR_ARITH_ZERO 0x0004 #define SR_SIGN 0x0008 -#define SR_10 0x0010 // seem to be set by tst +#define SR_10 0x0010 // set when there there was mod/tst/cmp on accu and abs(acc?)>=0x80000000, tstaxh never modifies it #define SR_TOP2BITS 0x0020 // if the upper 2 bits are equal #define SR_LOGIC_ZERO 0x0040 #define SR_80 0x0080 // Unknown, set by add diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp index 880e730a1f..ac687b15f9 100644 --- a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp +++ b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp @@ -26,32 +26,42 @@ namespace DSPInterpreter { -void Update_SR_Register64(s64 _Value, bool carry, bool overflow) +void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10) { - // TODO: Should also set 0x10 and 0x01 (also 0x02?) + // TODO: recheck 0x1,0x2,even 0x80... implement... g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; - if (_Value < 0) - { - g_dsp.r[DSP_REG_SR] |= SR_SIGN; - } - - if (_Value == 0) - { - g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO; - } - + // 0x01 if (carry) { g_dsp.r[DSP_REG_SR] |= SR_CARRY; } + // 0x02 if (overflow) { g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW; } - - // Checks if top bits of m are equal, what is it good for? + + // 0x04 + if (_Value == 0) + { + g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO; + } + + // 0x08 + if (_Value < 0) + { + g_dsp.r[DSP_REG_SR] |= SR_SIGN; + } + + // 0x10 - abs((u40)acc?) >= 0x80000000 + if (sr10) + { + g_dsp.r[DSP_REG_SR] |= SR_10; + } + + // 0x20 - Checks if top bits of m are equal, what is it good for? if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000)) { g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; @@ -59,32 +69,42 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow) } -void Update_SR_Register16(s16 _Value, bool carry, bool overflow) +void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10) { + // TODO: recheck 0x1,0x2,even 0x80... implement... g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; - - if (_Value < 0) - { - g_dsp.r[DSP_REG_SR] |= SR_SIGN; - } - - if (_Value == 0) - { - g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO; - } - + // 0x01 if (carry) { g_dsp.r[DSP_REG_SR] |= SR_CARRY; } + // 0x02 if (overflow) { g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW; } + + // 0x04 + if (_Value == 0) + { + g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO; + } - // Checks if top bits are equal, what is it good for? + // 0x08 + if (_Value < 0) + { + g_dsp.r[DSP_REG_SR] |= SR_SIGN; + } + + // 0x10 - abs((u40)acc?) >= 0x80000000 + if (sr10) + { + g_dsp.r[DSP_REG_SR] |= SR_10; + } + + // 0x20 - Checks if top bits of m are equal, what is it good for? if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3)) { g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.h b/Source/Core/DSPCore/Src/DSPIntCCUtil.h index 1533fbd3db..dba5800143 100644 --- a/Source/Core/DSPCore/Src/DSPIntCCUtil.h +++ b/Source/Core/DSPCore/Src/DSPIntCCUtil.h @@ -30,8 +30,8 @@ bool CheckCondition(u8 _Condition); int GetMultiplyModifier(); -void Update_SR_Register16(s16 _Value, bool carry = false, bool overflow = false); -void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false); +void Update_SR_Register16(s16 _Value, bool carry = false, bool overflow = false, bool sr10 = false); +void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false, bool sr10 = false); void Update_SR_LZ(bool value); inline bool isAddCarry(u64 val, u64 result) { @@ -46,6 +46,11 @@ inline bool isOverflow(s64 val1, s64 val2, s64 res) { return ((val1 ^ res) & (val2 ^ res)) < 0; } +inline bool isSR10(s64 acc) { + return (((u64)acc >= 0x80000000ULL) && ((u64)acc < 0xffffffff80000000ULL)) ? true : false; + //return (_abs64(acc) < 0x80000000) ? false : true; // working too - easier to understand +} + } // namespace #endif // _GDSP_CONDITION_CODES_H diff --git a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp index 680ae08cc3..728a612eab 100644 --- a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp +++ b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp @@ -334,12 +334,12 @@ void andi(const UDSPInstruction& opc) // Logic OR of accumulator mid part $acD.m with immediate value I. void ori(const UDSPInstruction& opc) { - u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1); + u8 reg = (opc.hex >> 8) & 0x1; u16 imm = dsp_fetch_code(); - g_dsp.r[reg] |= imm; + g_dsp.r[DSP_REG_ACM0 + reg] |= imm; - Update_SR_Register16((s16)g_dsp.r[reg]); + Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isSR10(dsp_get_long_acc(reg))); } //------------------------------------------------------------- @@ -358,8 +358,9 @@ void add(const UDSPInstruction& opc) zeroWriteBackLog(); dsp_set_long_acc(areg, res); + res = dsp_get_long_acc(areg); - Update_SR_Register64(res); + Update_SR_Register64(res, false, false, isSR10(res)); } // ADDP $acD