diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp index 740002ba75..9dc09eba2a 100644 --- a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp +++ b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp @@ -30,7 +30,7 @@ u8 code_flags[ISPACE]; // as well give up its time slice immediately, after executing once. // Max signature length is 6. A 0 in a signature is ignored. -#define NUM_IDLE_SIGS 7 +#define NUM_IDLE_SIGS 8 #define MAX_IDLE_SIG_SIZE 6 // 0xFFFF means ignore. @@ -65,7 +65,12 @@ const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = { 0x00de, 0xFFFE, // LR $AC0.M, @CMBH 0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000 0x029c, 0xFFFF, // JLNZ 0x05cf - 0 } + 0 }, + // From Zelda - experimental + { 0x00da, 0x0352, // lr $AX0.H, @0x0352 + 0x8600, // tstaxh $AX0.H + 0x0295, 0xFFFF, // jz 0x???? + 0, 0 } }; void Reset() @@ -121,7 +126,7 @@ void AnalyzeRange(int start_addr, int end_addr) } if (found) { - NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr); + NOTICE_LOG(DSPLLE, "Idle skip location found at %02x (sigNum:%d)", addr, s+1); code_flags[addr] |= CODE_IDLE_SKIP; } } diff --git a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp index fe19f57390..91581b4b29 100644 --- a/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp +++ b/Source/Core/DSPCore/Src/DSPIntCCUtil.cpp @@ -61,7 +61,7 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; } - // 0x20 - Checks if top bits of m are equal, what is it good for? + // 0x20 - Checks if top bits of m are equal if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000)) { g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; @@ -104,7 +104,7 @@ void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; } - // 0x20 - Checks if top bits of m are equal, what is it good for? + // 0x20 - Checks if top bits of m are equal if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3)) { g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; @@ -152,7 +152,7 @@ inline bool isConditionA() { return (((g_dsp.r[DSP_REG_SR] & SR_OVER_S32) || (g_dsp.r[DSP_REG_SR] & SR_TOP2BITS)) && !(g_dsp.r[DSP_REG_SR] & SR_ARITH_ZERO)) ? true : false; } -//see gdsp_registers.h for flags +//see DSPCore.h for flags bool CheckCondition(u8 _Condition) { switch (_Condition & 0xf) @@ -190,8 +190,7 @@ bool CheckCondition(u8 _Condition) case 0xf: // Empty - always true. return true; default: - ERROR_LOG(DSPLLE, "Unknown condition check: 0x%04x", _Condition & 0xf); - return false; + return true; } } diff --git a/Source/Core/DSPCore/Src/DSPIntUtil.h b/Source/Core/DSPCore/Src/DSPIntUtil.h index 4b9a8eaf2e..5aa81b2d13 100644 --- a/Source/Core/DSPCore/Src/DSPIntUtil.h +++ b/Source/Core/DSPCore/Src/DSPIntUtil.h @@ -220,7 +220,7 @@ inline s64 dsp_get_long_prod() inline s64 dsp_get_long_prod_round_prodl() { - return (dsp_get_long_prod() + 0x8000) & ~0xffff; + return (dsp_get_long_prod() + 0x7fff) & ~0xffff; } // For accurate emulation, this is wrong - but the real prod registers behave diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 3666430d55..cc67c717ba 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -108,7 +108,7 @@ const DSPOPCTemplate opcodes[] = {"JMPxB", 0x029b, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true}, {"JLNZ", 0x029c, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true}, {"JLZ", 0x029d, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true}, - {"JMPO", 0x029e, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true}, + {"JO", 0x029e, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true}, {"JMP", 0x029f, 0xffff, DSPInterpreter::jcc, nop, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true}, {"JRGE", 0x1700, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, @@ -125,7 +125,7 @@ const DSPOPCTemplate opcodes[] = {"JMPRxB", 0x170b, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, {"JRLNZ", 0x170c, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, {"JRLZ", 0x170d, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, - {"JMPRO", 0x170e, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, + {"JRO", 0x170e, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, {"JMPR", 0x170f, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, {"CALLRGE", 0x1710, 0xff1f, DSPInterpreter::callr, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true}, diff --git a/Source/Core/DSPCore/Src/DspIntMultiplier.cpp b/Source/Core/DSPCore/Src/DspIntMultiplier.cpp index 110673a976..ead12a2313 100644 --- a/Source/Core/DSPCore/Src/DspIntMultiplier.cpp +++ b/Source/Core/DSPCore/Src/DspIntMultiplier.cpp @@ -46,25 +46,25 @@ inline s64 dsp_get_multiply_prod(u16 a, u16 b, u8 sign) return prod; } -s64 dsp_multiply(u16 a, u16 b, u8 sign = 0) +inline s64 dsp_multiply(u16 a, u16 b, u8 sign = 0) { s64 prod = dsp_get_multiply_prod(a, b, sign); return prod; } -s64 dsp_multiply_add(u16 a, u16 b, u8 sign = 0) +inline s64 dsp_multiply_add(u16 a, u16 b, u8 sign = 0) { s64 prod = dsp_get_long_prod() + dsp_get_multiply_prod(a, b, sign); return prod; } -s64 dsp_multiply_sub(u16 a, u16 b, u8 sign = 0) +inline s64 dsp_multiply_sub(u16 a, u16 b, u8 sign = 0) { s64 prod = dsp_get_long_prod() - dsp_get_multiply_prod(a, b, sign); return prod; } -s64 dsp_multiply_mulx(u8 axh0, u8 axh1, u16 val1, u16 val2) +inline s64 dsp_multiply_mulx(u8 axh0, u8 axh1, u16 val1, u16 val2) { s64 result; @@ -122,7 +122,7 @@ void clrp(const UDSPInstruction opc) // 1000 0101 xxxx xxxx // Test prod regs value. // -// flags out: xx xx0x <- CF?? +// flags out: --xx xx0x void tstprod(const UDSPInstruction opc) { s64 prod = dsp_get_long_prod(); @@ -136,7 +136,7 @@ void tstprod(const UDSPInstruction opc) // 0110 111d xxxx xxxx // Moves multiply product from $prod register to accumulator $acD register. // -// flags out: xx xx00 +// flags out: --xx xx0x void movp(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; @@ -154,7 +154,7 @@ void movp(const UDSPInstruction opc) // Moves negative of multiply product from $prod register to accumulator // $acD register. // -// flags out: xx xx0x <- CF?? +// flags out: --xx xx0x void movnp(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; @@ -172,7 +172,7 @@ void movnp(const UDSPInstruction opc) // Moves multiply product from $prod register to accumulator $acD // register and sets $acD.l to 0 // -// flags out: xx xx0x <- CF?? +// flags out: --xx xx0x void movpz(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x01; @@ -190,12 +190,13 @@ void movpz(const UDSPInstruction opc) // Adds secondary accumulator $axS to product register and stores result // in accumulator register. Low 16-bits of $acD ($acD.l) are set to 0. // -// flags out: ?-xx xx?? +// flags out: --xx xx0x void addpaxz(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; u8 sreg = (opc >> 9) & 0x1; + s64 oldprod = dsp_get_long_prod(); s64 prod = dsp_get_long_prod_round_prodl(); s64 ax = dsp_get_long_acx(sreg); s64 res = prod + (ax & ~0xffff); @@ -204,7 +205,7 @@ void addpaxz(const UDSPInstruction opc) dsp_set_long_acc(dreg, res); res = dsp_get_long_acc(dreg); - Update_SR_Register64(res); + Update_SR_Register64(res, isCarry(oldprod, res), false); } //---- @@ -246,7 +247,7 @@ void mul(const UDSPInstruction opc) // $axS.l of secondary accumulator $axS by high part $axS.h of secondary // accumulator $axS (treat them both as signed). // -// flags out: xx xx00 +// flags out: --xx xx0x void mulac(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -270,7 +271,7 @@ void mulac(const UDSPInstruction opc) // $axS.l of secondary accumulator $axS by high part $axS.h of secondary // accumulator $axS (treat them both as signed). // -// flags out: xx xx00 +// flags out: --xx xx0x void mulmv(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -295,7 +296,7 @@ void mulmv(const UDSPInstruction opc) // accumulator $axS by high part $axS.h of secondary accumulator $axS (treat // them both as signed). // -// flags out: xx xx0x +// flags out: --xx xx0x void mulmvz(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -339,7 +340,7 @@ void mulx(const UDSPInstruction opc) // $ax0 by one part $ax1. Part is selected by S and // T bits. Zero selects low part, one selects high part. // -// flags out: xx xx00 +// flags out: --xx xx0x void mulxac(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -364,7 +365,7 @@ void mulxac(const UDSPInstruction opc) // $ax0 by one part $ax1. Part is selected by S and // T bits. Zero selects low part, one selects high part. // -// flags out: xx xx00 +// flags out: --xx xx0x void mulxmv(const UDSPInstruction opc) { u8 rreg = ((opc >> 8) & 0x1); @@ -390,7 +391,7 @@ void mulxmv(const UDSPInstruction opc) // Part is selected by S and T bits. Zero selects low part, // one selects high part. // -// flags out: xx xx00 +// flags out: --xx xx0x void mulxmvz(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -435,7 +436,7 @@ void mulc(const UDSPInstruction opc) // secondary accumulator $axS (treat them both as signed). Add product // register before multiplication to accumulator $acR. // -// flags out: xx xx00 +// flags out: --xx xx0x void mulcac(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -461,7 +462,7 @@ void mulcac(const UDSPInstruction opc) // register before multiplication to accumulator $acR. // possible mistake in duddie's doc axT.h rather than axS.h // -// flags out: xx xx00 +// flags out: --xx xx0x void mulcmv(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1; @@ -488,7 +489,7 @@ void mulcmv(const UDSPInstruction opc) // register before multiplication to accumulator $acR, set low part of // accumulator $acR.l to zero. // -// flags out: xx xx00 +// flags out: --xx xx0x void mulcmvz(const UDSPInstruction opc) { u8 rreg = (opc >> 8) & 0x1;