diff --git a/Source/Core/DSPCore/Src/DSPAccelerator.cpp b/Source/Core/DSPCore/Src/DSPAccelerator.cpp index e50c2ef2f6..4a90ba4198 100644 --- a/Source/Core/DSPCore/Src/DSPAccelerator.cpp +++ b/Source/Core/DSPCore/Src/DSPAccelerator.cpp @@ -59,15 +59,14 @@ s16 ADPCM_Step(u32& _rSamplePos) _rSamplePos++; - // The advanced interpolation (linear, polyphase,...) is done by the UCode, so we don't - // need to bother with it here. + // The advanced interpolation (linear, polyphase,...) is done by the UCode, + // so we don't need to bother with it here. return val; } u16 dsp_read_aram_d3() { // Zelda ucode reads ARAM through 0xffd3. - u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL]; u8 value = 0; switch (gdsp_ifx_regs[DSP_FORMAT]) { @@ -75,7 +74,7 @@ u16 dsp_read_aram_d3() value = DSPHost_ReadHostMemory(Address); break; default: - ERROR_LOG(DSPLLE, "dsp_write_aram_d3: Unseen Format %i", gdsp_ifx_regs[DSP_FORMAT]); + ERROR_LOG(DSPLLE, "dsp_read_aram_d3: Unseen Format %i", gdsp_ifx_regs[DSP_FORMAT]); break; } return value; @@ -83,9 +82,8 @@ u16 dsp_read_aram_d3() void dsp_write_aram_d3(u16 value) { - // Zelda ucode writes a bunch of zeros to ARAM through d3 during initialization. - // Don't know if it ever does it later, too. - + // Zelda ucode writes a bunch of zeros to ARAM through d3 during + // initialization. Don't know if it ever does it later, too. const u32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL]; u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL]; switch (gdsp_ifx_regs[DSP_FORMAT]) { diff --git a/Source/Core/DSPCore/Src/DSPHWInterface.cpp b/Source/Core/DSPCore/Src/DSPHWInterface.cpp index a4da019c24..e7a9b700ce 100644 --- a/Source/Core/DSPCore/Src/DSPHWInterface.cpp +++ b/Source/Core/DSPCore/Src/DSPHWInterface.cpp @@ -161,7 +161,7 @@ void gdsp_ifx_write(u16 addr, u16 val) break; case 0xd3: // ZeldaUnk (accelerator WRITE) - INFO_LOG(DSPLLE, "Write To ZeldaUnk pc=%04x (%04x)", g_dsp.pc, val); + NOTICE_LOG(DSPLLE, "Write To ZeldaUnk pc=%04x (%04x)", g_dsp.pc, val); dsp_write_aram_d3(val); break; @@ -215,7 +215,7 @@ u16 gdsp_ifx_read(u16 addr) return dsp_read_accelerator(); case 0xd3: - ERROR_LOG(DSPLLE, "DSP read aram D3"); + NOTICE_LOG(DSPLLE, "Read from ZeldaUnk pc=%04x", g_dsp.pc); return dsp_read_aram_d3(); default: diff --git a/Source/Core/DSPCore/Src/DSPInterpreter.cpp b/Source/Core/DSPCore/Src/DSPInterpreter.cpp index 91ba88c7d0..ffb96f50e0 100644 --- a/Source/Core/DSPCore/Src/DSPInterpreter.cpp +++ b/Source/Core/DSPCore/Src/DSPInterpreter.cpp @@ -91,7 +91,9 @@ void Step() ProfilerDump(g_dsp.step_counter); } #endif - + // if (g_dsp.pc >= 0x0272 && g_dsp.pc <= 0x0282) + // printf("pc %04x acc0 %04x acc1 %04x\n", g_dsp.pc, dsp_get_acc_m(0), dsp_get_acc_m(1)); + u16 opc = dsp_fetch_code(); ExecuteInstruction(UDSPInstruction(opc)); HandleLoop(); diff --git a/Source/Core/DSPCore/Src/DSPInterpreter.h b/Source/Core/DSPCore/Src/DSPInterpreter.h index 3bad4ec4f0..b3bcb0035d 100644 --- a/Source/Core/DSPCore/Src/DSPInterpreter.h +++ b/Source/Core/DSPCore/Src/DSPInterpreter.h @@ -118,6 +118,7 @@ void asl(const UDSPInstruction& opc); void asr(const UDSPInstruction& opc); void lsrn(const UDSPInstruction& opc); void asrn(const UDSPInstruction& opc); +void lsrnr(const UDSPInstruction& opc); void dar(const UDSPInstruction& opc); void iar(const UDSPInstruction& opc); void sbclr(const UDSPInstruction& opc); diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 25eb4c87d7..3f6dd8146c 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -162,7 +162,8 @@ const DSPOPCTemplate opcodes[] = // discovered by ector! {"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, nop, 1, 0, {}, NULL, NULL}, {"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, nop, 1, 0, {}, NULL, NULL}, - + {"LSRNR", 0x3c80, 0xfeff, DSPInterpreter::lsrnr, nop, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, NULL, NULL}, + {"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, NULL, NULL}, {"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, nop, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, NULL, NULL}, {"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, nop, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, NULL, NULL}, @@ -269,8 +270,6 @@ const DSPOPCTemplate opcodes[] = {"XORR", 0x3000, 0xfcff, DSPInterpreter::xorr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, {"ANDR", 0x3400, 0xfcff, DSPInterpreter::andr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, {"ORR", 0x3800, 0xfcff, DSPInterpreter::orr, nop, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, - {"ANDC", 0x3C00, 0xfeff, DSPInterpreter::andc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this - {"ORC", 0x3E00, 0xfeff, DSPInterpreter::orc, nop, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // Hermes doesn't list this {"MULX", 0xa000, 0xe7ff, DSPInterpreter::mulx, nop, 1 | P_EXT, 2, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, {"MULXMVZ", 0xa200, 0xe6ff, DSPInterpreter::mulxmvz, nop, 1 | P_EXT, 3, {{P_REGM18, 1, 0, 11, 0x1000}, {P_REGM19, 1, 0, 10, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, diff --git a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp index ecd220d7a3..dc02d5af59 100644 --- a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp +++ b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp @@ -176,6 +176,7 @@ void orr(const UDSPInstruction& opc) Update_SR_Register64(acc); } + /* // ANDC $acD.m, $ac(1-D).m // 0011 110d xxxx xxxx // Logic AND middle part of accumulator $acD.m with middle part of @@ -207,7 +208,7 @@ void orc(const UDSPInstruction& opc) Update_SR_Register64(dsp_get_long_acc(D)); } - +*/ void orf(const UDSPInstruction& opc) { ERROR_LOG(DSPLLE, "orf not implemented"); @@ -659,7 +660,7 @@ void asr(const UDSPInstruction& opc) // (if value negative, becomes left shift). void lsrn(const UDSPInstruction& opc) { - s16 shift = (s16)g_dsp.r[DSP_REG_ACM1]; + s16 shift = dsp_get_acc_m(1); u64 acc = dsp_get_long_acc(0); // Lop off the extraneous sign extension our 64-bit fake accum causes acc &= 0x000000FFFFFFFFFFULL; @@ -679,7 +680,7 @@ void lsrn(const UDSPInstruction& opc) // (if value negative, becomes left shift). void asrn(const UDSPInstruction& opc) { - s16 shift = (s16)g_dsp.r[DSP_REG_ACM1]; + s16 shift = dsp_get_acc_m(1); s64 acc = dsp_get_long_acc(0); if (shift > 0) { acc >>= shift; @@ -690,6 +691,24 @@ void asrn(const UDSPInstruction& opc) Update_SR_Register64(acc); } +// LSRNR $acR +// 0011 110d 1100 0000 +// Logically shifts right accumulator $ACC0 by signed 16-bit value $AC0.M +// Not described by Duddie's doc - at least not as a separate instruction. +void lsrnr(const UDSPInstruction& opc) +{ + u8 sreg = 1;//Check if it should be (opc.hex >> 8) & 0x1; + s16 shift = dsp_get_acc_m(0); + u64 acc = dsp_get_long_acc(sreg); + acc &= 0x000000FFFFFFFFFFULL; + if (shift > 0) { + acc <<= shift; + } else if (shift < 0) { + acc >>= -shift; + } + dsp_set_long_acc(sreg, acc); + Update_SR_Register64(acc); +} // CMPAR $acS axR.h // 1100 0001 xxxx xxxx @@ -709,6 +728,7 @@ void cmpar(const UDSPInstruction& opc) Update_SR_Register64(sr - rr); } + // CMP // 1000 0010 xxxx xxxx // Compares accumulator $ac0 with accumulator $ac1.