diff --git a/Source/Core/DSPCore/Src/DSPCore.h b/Source/Core/DSPCore/Src/DSPCore.h index b64c12e58c..0e093f57d4 100644 --- a/Source/Core/DSPCore/Src/DSPCore.h +++ b/Source/Core/DSPCore/Src/DSPCore.h @@ -154,10 +154,10 @@ #define SR_OVERFLOW 0x0002 #define SR_ARITH_ZERO 0x0004 #define SR_SIGN 0x0008 -#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_OVER_S32 0x0010 // set when there there was mod/tst/cmp on accu and result is over s32 +#define SR_TOP2BITS 0x0020 // if the upper (ac?.m/ax?.h) 2 bits are equal #define SR_LOGIC_ZERO 0x0040 -#define SR_80 0x0080 // Unknown, set by add +#define SR_80 0x0080 // Unknown, set by add, sub #define SR_INT_ENABLE 0x0200 // Not 100% sure but duddie says so. This should replace the hack, if so. #define SR_EXT_INT_ENABLE 0x0800 // Appears in zelda - seems to disable external interupts #define SR_MUL_MODIFY 0x2000 // 1 = normal. 0 = x2 (M0, M2) diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp index ac687b15f9..c62aa25637 100644 --- a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp +++ b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp @@ -26,7 +26,7 @@ namespace DSPInterpreter { -void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10) +void Update_SR_Register64(s64 _Value, bool carry, bool overflow) { // TODO: recheck 0x1,0x2,even 0x80... implement... g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; @@ -55,10 +55,10 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10) g_dsp.r[DSP_REG_SR] |= SR_SIGN; } - // 0x10 - abs((u40)acc?) >= 0x80000000 - if (sr10) + // 0x10 + if (_Value != (s32)_Value) { - g_dsp.r[DSP_REG_SR] |= SR_10; + g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; } // 0x20 - Checks if top bits of m are equal, what is it good for? @@ -66,10 +66,14 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow, bool sr10) { g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; } + + // 0x80 + { + } } -void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10) +void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32) { // TODO: recheck 0x1,0x2,even 0x80... implement... g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; @@ -98,10 +102,10 @@ void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10) g_dsp.r[DSP_REG_SR] |= SR_SIGN; } - // 0x10 - abs((u40)acc?) >= 0x80000000 - if (sr10) + // 0x10 + if (overS32) { - g_dsp.r[DSP_REG_SR] |= SR_10; + g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; } // 0x20 - Checks if top bits of m are equal, what is it good for? @@ -109,6 +113,10 @@ void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool sr10) { g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; } + + // 0x80 + { + } } void Update_SR_LZ(bool value) { diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.h b/Source/Core/DSPCore/Src/DSPIntCCUtil.h index dba5800143..b1b622de85 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, bool sr10 = false); -void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false, bool sr10 = false); +void Update_SR_Register16(s16 _Value, bool carry = false, bool overflow = false, bool overS32 = false); +void Update_SR_Register64(s64 _Value, bool carry = false, bool overflow = false); void Update_SR_LZ(bool value); inline bool isAddCarry(u64 val, u64 result) { @@ -46,9 +46,8 @@ 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 +inline bool isOverS32(s64 acc) { + return (acc != (s32)acc) ? true : false; } } // namespace diff --git a/Source/Core/DSPCore/Src/DSPIntUtil.h b/Source/Core/DSPCore/Src/DSPIntUtil.h index f9f369e3e7..8d63aa578e 100644 --- a/Source/Core/DSPCore/Src/DSPIntUtil.h +++ b/Source/Core/DSPCore/Src/DSPIntUtil.h @@ -251,6 +251,10 @@ inline void dsp_set_long_acc(int _reg, s64 val) g_dsp.r[DSP_REG_ACH0 + _reg] = (u16)(s16)(s8)(u8)val; } +inline s64 dsp_convert_long_acc(s64 val) // s64 -> s40 +{ + return ((s64)(s8)(val >> 32))<<32 | (u32)val; +} inline s16 dsp_get_acc_l(int _reg) { diff --git a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp index 3d03ad334c..aa7b95b5d6 100644 --- a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp +++ b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp @@ -339,7 +339,7 @@ void ori(const UDSPInstruction& opc) g_dsp.r[DSP_REG_ACM0 + reg] |= imm; - Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isSR10(dsp_get_long_acc(reg))); + Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg))); } //------------------------------------------------------------- @@ -350,17 +350,18 @@ void ori(const UDSPInstruction& opc) // Adds accumulator $ac(1-D) to accumulator register $acD. void add(const UDSPInstruction& opc) { - u8 areg = (opc.hex >> 8) & 0x1; - s64 acc0 = dsp_get_long_acc(0); - s64 acc1 = dsp_get_long_acc(1); + u8 dreg = (opc.hex >> 8) & 0x1; + s64 acc0 = dsp_get_long_acc(dreg); + s64 acc1 = dsp_get_long_acc(1 - dreg); s64 res = acc0 + acc1; zeroWriteBackLog(); - dsp_set_long_acc(areg, res); - res = dsp_get_long_acc(areg); - Update_SR_Register64(res, false, false, isSR10(res)); + dsp_set_long_acc(dreg, res); + res = dsp_get_long_acc(dreg); + + Update_SR_Register64(res, isAddCarry(acc0, res), isOverflow(acc0, acc1, res)); } // ADDP $acD