From b787f5f8f7709cff763c2f3a13b90455a0c8ee18 Mon Sep 17 00:00:00 2001 From: nakeee Date: Wed, 19 Aug 2009 21:37:24 +0000 Subject: [PATCH] DSPLLE: attempt to fix extended ops please review this patch carefully. thinks to note - All ext commands should call zeroWriteBackLog() (before changing any reg) - increase/decrease ar functions now only return a value not actually change anything git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4018 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DSPCore/Src/DSPIntExtOps.cpp | 298 +++++++------------ Source/Core/DSPCore/Src/DSPIntExtOps.h | 19 +- Source/Core/DSPCore/Src/DSPIntUtil.h | 44 ++- Source/Core/DSPCore/Src/DSPTables.cpp | 11 +- Source/Core/DSPCore/Src/DSPTables.h | 13 +- Source/Core/DSPCore/Src/DspIntArithmetic.cpp | 94 +++++- Source/Core/DSPCore/Src/DspIntLoadStore.cpp | 18 +- Source/Core/DSPCore/Src/DspIntMisc.cpp | 8 +- Source/Core/DSPCore/Src/DspIntMultiplier.cpp | 101 +++++-- 9 files changed, 340 insertions(+), 266 deletions(-) diff --git a/Source/Core/DSPCore/Src/DSPIntExtOps.cpp b/Source/Core/DSPCore/Src/DSPIntExtOps.cpp index a95ddb523f..37e803bdb3 100644 --- a/Source/Core/DSPCore/Src/DSPIntExtOps.cpp +++ b/Source/Core/DSPCore/Src/DSPIntExtOps.cpp @@ -40,20 +40,18 @@ namespace DSPInterpreter namespace Ext { -u16 cache1; - // DR $arR // xxxx xxxx 0000 01rr // Decrement addressing register $arR. void dr(const UDSPInstruction& opc) { - dsp_decrement_addr_reg(opc.hex & 0x3); + writeToBackLog(0, opc.hex & 0x3, dsp_decrement_addr_reg(opc.hex & 0x3)); } // IR $arR // xxxx xxxx 0000 10rr // Increment addressing register $arR. void ir(const UDSPInstruction& opc) { - dsp_increment_addr_reg(opc.hex & 0x3); + writeToBackLog(0, opc.hex & 0x3, dsp_increment_addr_reg(opc.hex & 0x3)); } // NR $arR @@ -61,8 +59,8 @@ void ir(const UDSPInstruction& opc) { // Add corresponding indexing register $ixR to addressing register $arR. void nr(const UDSPInstruction& opc) { u8 reg = opc.hex & 0x3; - - dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]); + + writeToBackLog(0, reg, dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg])); } // MV $axD, $acS.l @@ -71,19 +69,11 @@ void nr(const UDSPInstruction& opc) { void mv(const UDSPInstruction& opc) { u8 sreg = opc.hex & 0x3; - - cache1 = g_dsp.r[sreg + DSP_REG_ACC0]; - - currentEpilogeFunc = mv_epi; + u8 dreg = ((opc.hex >> 2) & 0x3); + + writeToBackLog(0, dreg + DSP_REG_AXL0, g_dsp.r[sreg + DSP_REG_ACC0]); } - -void mv_epi(const UDSPInstruction& opc) -{ - u8 dreg = ((opc.hex >> 2) & 0x3); - - g_dsp.r[dreg + DSP_REG_AXL0] = cache1; -} - + // S @$D, $acD.l // xxxx xxxx 001s s0dd // Store value of $(acS.l) in the memory pointed by register $D. @@ -94,15 +84,7 @@ void s(const UDSPInstruction& opc) u8 sreg = ((opc.hex >> 3) & 0x3) + DSP_REG_ACC0; dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]); - - currentEpilogeFunc = s_epi; -} - -void s_epi(const UDSPInstruction& opc) -{ - u8 dreg = opc.hex & 0x3; - - dsp_increment_addr_reg(dreg); + writeToBackLog(0, dreg, dsp_increment_addr_reg(dreg)); } // SN @$D, $acD.l @@ -116,14 +98,7 @@ void sn(const UDSPInstruction& opc) dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]); - currentEpilogeFunc = sn_epi; -} - -void sn_epi(const UDSPInstruction& opc) -{ - u8 dreg = opc.hex & 0x3; - - dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]); + writeToBackLog(0, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg])); } // L axD.l, @$S @@ -133,18 +108,10 @@ void sn_epi(const UDSPInstruction& opc) void l(const UDSPInstruction& opc) { u8 sreg = opc.hex & 0x3; - - cache1 = dsp_dmem_read(g_dsp.r[sreg]); - - currentEpilogeFunc = l_epi; -} - -void l_epi(const UDSPInstruction& opc) { - u8 sreg = opc.hex & 0x3; u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0; - - g_dsp.r[dreg] = cache1; - dsp_increment_addr_reg(sreg); + + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg)); } // LN axD.l, @$S @@ -156,17 +123,8 @@ void ln(const UDSPInstruction& opc) u8 sreg = opc.hex & 0x3; u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0; - cache1 = dsp_dmem_read(g_dsp.r[sreg]); - - currentEpilogeFunc = ln_epi; -} -void ln_epi(const UDSPInstruction& opc) -{ - u8 sreg = opc.hex & 0x3; - u8 dreg = ((opc.hex >> 3) & 0x7) + DSP_REG_AXL0; - - g_dsp.r[dreg] = cache1; - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); } // LS $axD.l, $acS.m @@ -178,20 +136,15 @@ void ls(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; u8 sreg = 0x03; + u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; + dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); - dsp_increment_addr_reg(sreg); - currentEpilogeFunc = ls_epi; + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00])); + writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg)); + writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00)); } -void ls_epi(const UDSPInstruction& opc) -{ - u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; - u16 val = dsp_dmem_read(g_dsp.r[0x00]); - dsp_op_write_reg(dreg, val); - - dsp_increment_addr_reg(0x00); -} // LSN $acD.l, $acS.m // xxxx xxxx 10dd 010s @@ -203,19 +156,13 @@ void lsn(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; u8 sreg = 0x03; - - dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); - dsp_increment_addr_reg(sreg); - currentEpilogeFunc = lsn_epi; -} - -void lsn_epi(const UDSPInstruction& opc) -{ u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; - u16 val = dsp_dmem_read(g_dsp.r[0x00]); - dsp_op_write_reg(dreg, val); - - dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]); + + dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); + + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00])); + writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg)); + writeToBackLog(2, 0x00,dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0])); } // LSM $acD.l, $acS.m @@ -228,20 +175,13 @@ void lsm(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; u8 sreg = 0x03; - - dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); - currentEpilogeFunc = lsm_epi; - -} - -void lsm_epi(const UDSPInstruction& opc) -{ u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; - u16 val = dsp_dmem_read(g_dsp.r[0x00]); - dsp_op_write_reg(dreg, val); + + dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); - dsp_increment_addr_reg(0x00); + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00])); + writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); + writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00)); } // LSMN $acD.l, $acS.m @@ -255,20 +195,13 @@ void lsnm(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; u8 sreg = 0x03; - - dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); - currentEpilogeFunc = lsnm_epi; - -} - -void lsnm_epi(const UDSPInstruction& opc) -{ u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; - u16 val = dsp_dmem_read(g_dsp.r[0x00]); + + dsp_dmem_write(g_dsp.r[sreg], g_dsp.r[areg]); - dsp_op_write_reg(dreg, val); - dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]); + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[0x00])); + writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); + writeToBackLog(2, 0x00, dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0])); } // SL $acS.m, $acD.l @@ -279,20 +212,14 @@ void lsnm_epi(const UDSPInstruction& opc) void sl(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; + u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; + const u8 sreg = 0x03; dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); - dsp_increment_addr_reg(0x00); - currentEpilogeFunc = sl_epi; -} -void sl_epi(const UDSPInstruction& opc) -{ - u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18; - const u8 sreg = 0x03; - u16 val = dsp_dmem_read(g_dsp.r[sreg]); - - dsp_op_write_reg(dreg, val); - dsp_increment_addr_reg(sreg); + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg)); + writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00)); } // SLN $acS.m, $acD.l @@ -304,20 +231,14 @@ void sl_epi(const UDSPInstruction& opc) void sln(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; + u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; + const u8 sreg = 0x03; dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); - dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]); - currentEpilogeFunc = sln_epi; -} - -void sln_epi(const UDSPInstruction& opc) -{ - u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18; - const u8 sreg = 0x03; - u16 val = dsp_dmem_read(g_dsp.r[sreg]); - - dsp_op_write_reg(dreg, val); - dsp_increment_addr_reg(sreg); + + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg)); + writeToBackLog(2, 0x00, dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0])); } // SLM $acS.m, $acD.l @@ -329,20 +250,14 @@ void sln_epi(const UDSPInstruction& opc) void slm(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; - - dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); - dsp_increment_addr_reg(0x00); - currentEpilogeFunc = slm_epi; -} - -void slm_epi(const UDSPInstruction& opc) -{ - u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18; + u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; const u8 sreg = 0x03; - u16 val = dsp_dmem_read(g_dsp.r[sreg]); + + dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); - dsp_op_write_reg(dreg, val); - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); + writeToBackLog(2, 0x00, dsp_increment_addr_reg(0x00)); } // SLMN $acS.m, $acD.l @@ -354,21 +269,14 @@ void slm_epi(const UDSPInstruction& opc) void slnm(const UDSPInstruction& opc) { u8 areg = (opc.hex & 0x1) + DSP_REG_ACM0; - - dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); - dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0]); - currentEpilogeFunc = slnm_epi; - -} - -void slnm_epi(const UDSPInstruction& opc) -{ - u8 dreg = ((opc.hex >> 4) & 0x3) + 0x18; + u8 dreg = ((opc.hex >> 4) & 0x3) + DSP_REG_AXL0; const u8 sreg = 0x03; - u16 val = dsp_dmem_read(g_dsp.r[sreg]); + + dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); - dsp_op_write_reg(dreg, val); - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); + writeToBackLog(2, 0x00, dsp_increase_addr_reg(0x00, (s16)g_dsp.r[DSP_REG_IX0])); } // Not in duddie's doc @@ -381,18 +289,16 @@ void ld(const UDSPInstruction& opc) u8 sreg = opc.hex & 0x3; if (sreg != 0x03) { - g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]); - g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]); - - dsp_increment_addr_reg(sreg); + writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg)); } else { - g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]); - g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]); - - dsp_increment_addr_reg(dreg); + writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg)); } - - dsp_increment_addr_reg(DSP_REG_AR3); + + writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3)); } // Not in duddie's doc @@ -403,20 +309,18 @@ void ldn(const UDSPInstruction& opc) u8 dreg = (opc.hex >> 5) & 0x1; u8 rreg = (opc.hex >> 4) & 0x1; u8 sreg = opc.hex & 0x3; - + if (sreg != 0x03) { - g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]); - g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]); - - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); } else { - g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]); - g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]); - - dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]); + writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg])); } - dsp_increment_addr_reg(DSP_REG_AR3); + writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3)); } @@ -430,18 +334,17 @@ void ldm(const UDSPInstruction& opc) u8 sreg = opc.hex & 0x3; if (sreg != 0x03) { - g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]); - g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]); - - dsp_increment_addr_reg(sreg); + writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg)); } else { - g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]); - g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]); - - dsp_increment_addr_reg(dreg); + writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg)); } - dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3]); + writeToBackLog(3, DSP_REG_AR3, + dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3])); } // Not in duddie's doc @@ -454,20 +357,20 @@ void ldnm(const UDSPInstruction& opc) u8 sreg = opc.hex & 0x3; if (sreg != 0x03) { - g_dsp.r[(dreg << 1) + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[sreg]); - g_dsp.r[(rreg << 1) + DSP_REG_AXL1] = dsp_dmem_read(g_dsp.r[sreg]); - - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg])); + writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg])); } else { - g_dsp.r[rreg + DSP_REG_AXL0] = dsp_dmem_read(g_dsp.r[dreg]); - g_dsp.r[rreg + DSP_REG_AXH0] = dsp_dmem_read(g_dsp.r[dreg]); - - dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]); + writeToBackLog(0, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(1, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg])); + writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg])); } - dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3]); + writeToBackLog(3, DSP_REG_AR3, + dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX0 + DSP_REG_AR3])); } + void nop(const UDSPInstruction& opc) { } @@ -475,4 +378,21 @@ void nop(const UDSPInstruction& opc) } // end namespace ext } // end namespace DSPInterpeter +void applyWriteBackLog() +{ + for (int i=0;i < WRITEBACKLOGSIZE;i++) { + + if (writeBackLogIdx[i] != -1) { + dsp_op_write_reg(writeBackLogIdx[i], g_dsp.r[writeBackLogIdx[i]] | writeBackLog[i]); + // Clear back log + writeBackLogIdx[i] = -1; + } + } +} +void zeroWriteBackLog() +{ + for (int i=0;i < WRITEBACKLOGSIZE;i++) + if (writeBackLogIdx[i] != -1) + dsp_op_write_reg(writeBackLogIdx[i], 0); +} diff --git a/Source/Core/DSPCore/Src/DSPIntExtOps.h b/Source/Core/DSPCore/Src/DSPIntExtOps.h index 7ee6590f6d..1d0287bbed 100644 --- a/Source/Core/DSPCore/Src/DSPIntExtOps.h +++ b/Source/Core/DSPCore/Src/DSPIntExtOps.h @@ -39,9 +39,7 @@ namespace DSPInterpreter namespace Ext { void l(const UDSPInstruction& opc); -void l_epi(const UDSPInstruction& opc); void ln(const UDSPInstruction& opc); -void ln_epi(const UDSPInstruction& opc); void ls(const UDSPInstruction& opc); void lsn(const UDSPInstruction& opc); void lsm(const UDSPInstruction& opc); @@ -52,22 +50,11 @@ void slm(const UDSPInstruction& opc); void slnm(const UDSPInstruction& opc); void s(const UDSPInstruction& opc); void sn(const UDSPInstruction& opc); -void ls_epi(const UDSPInstruction& opc); -void lsn_epi(const UDSPInstruction& opc); -void lsm_epi(const UDSPInstruction& opc); -void lsnm_epi(const UDSPInstruction& opc); -void sl_epi(const UDSPInstruction& opc); -void sln_epi(const UDSPInstruction& opc); -void slm_epi(const UDSPInstruction& opc); -void slnm_epi(const UDSPInstruction& opc); -void s_epi(const UDSPInstruction& opc); -void sn_epi(const UDSPInstruction& opc); void ld(const UDSPInstruction& opc); void ldn(const UDSPInstruction& opc); void ldm(const UDSPInstruction& opc); void ldnm(const UDSPInstruction& opc); void mv(const UDSPInstruction& opc); -void mv_epi(const UDSPInstruction& opc); void dr(const UDSPInstruction& opc); void ir(const UDSPInstruction& opc); void nr(const UDSPInstruction& opc); @@ -76,4 +63,10 @@ void nop(const UDSPInstruction& opc); } // end namespace Ext } // end namespace DSPinterpeter +inline void writeToBackLog(int i, int idx, u16 value) +{ + writeBackLog[i] = value; + writeBackLogIdx[i] = idx; +} + #endif diff --git a/Source/Core/DSPCore/Src/DSPIntUtil.h b/Source/Core/DSPCore/Src/DSPIntUtil.h index 96e24389fe..86ba5f316b 100644 --- a/Source/Core/DSPCore/Src/DSPIntUtil.h +++ b/Source/Core/DSPCore/Src/DSPIntUtil.h @@ -58,37 +58,57 @@ inline u16 ToMask(u16 a) return a | (a >> 1); } -inline void dsp_increment_addr_reg(int reg) +inline u16 dsp_increment_addr_reg(int reg, int value = -1) { u16 tmb = ToMask(g_dsp.r[DSP_REG_WR0 + reg]); - if ((g_dsp.r[reg] & tmb) == tmb) - g_dsp.r[reg] ^= g_dsp.r[DSP_REG_WR0 + reg]; + u16 tmp; + if (value == -1) + tmp = g_dsp.r[reg]; else - g_dsp.r[reg]++; + tmp = value; + + if ((tmp & tmb) == tmb) + tmp ^= g_dsp.r[DSP_REG_WR0 + reg]; + else + tmp++; + + return tmp; } // See http://code.google.com/p/dolphin-emu/source/detail?r=3125 -inline void dsp_decrement_addr_reg(int reg) +inline u16 dsp_decrement_addr_reg(int reg, int value = -1) { - // This one is easy. Looks like a hw implementation. Increment is worse... - if ((g_dsp.r[reg] & g_dsp.r[DSP_REG_WR0 + reg]) == 0) - g_dsp.r[reg] |= g_dsp.r[DSP_REG_WR0 + reg]; + u16 tmp; + if (value == -1) + tmp = g_dsp.r[reg]; else - g_dsp.r[reg]--; + tmp = value; + + // This one is easy. Looks like a hw implementation. Increment is worse... + if ((tmp & g_dsp.r[DSP_REG_WR0 + reg]) == 0) + tmp |= g_dsp.r[DSP_REG_WR0 + reg]; + else + tmp--; + + return tmp; } -inline void dsp_increase_addr_reg(int reg, s16 value) +inline u16 dsp_increase_addr_reg(int reg, s16 value) { + u16 tmp = - 1; + // TODO: DO RIGHT! if (value > 0) { for (int i = 0; i < value; i++) { - dsp_increment_addr_reg(reg); + tmp = dsp_increment_addr_reg(reg, tmp); } } else if (value < 0) { for (int i = 0; i < (int)(-value); i++) { - dsp_decrement_addr_reg(reg); + tmp = dsp_decrement_addr_reg(reg, tmp); } } + + return tmp; } diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 7a80c014b4..b0afdeb4c8 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -498,8 +498,8 @@ u8 opSize[OPTABLE_SIZE]; dspInstFunc opTable[OPTABLE_SIZE]; dspInstFunc extOpTable[EXT_OPTABLE_SIZE]; bool opTableUseExt[OPTABLE_SIZE]; - -dspInstFunc currentEpilogeFunc = NULL; +u16 writeBackLog[WRITEBACKLOGSIZE]; +int writeBackLogIdx[WRITEBACKLOGSIZE]; const char* pdname(u16 val) { @@ -577,10 +577,6 @@ void InitInstructionTable() for (int j = 0; j < opcodes_size; j++) { u16 mask = opcodes[j].opcode_mask; - // if (opcodes[j].size & P_EXT) { - // Ignore extension bits. - // mask &= 0xFF00; - // } if ((mask & i) == opcodes[j].opcode) { if (opTable[i] == DSPInterpreter::unknown) @@ -596,4 +592,7 @@ void InitInstructionTable() } } } + + for (int i=0; i < WRITEBACKLOGSIZE; i++) + writeBackLogIdx[i] = -1; } diff --git a/Source/Core/DSPCore/Src/DSPTables.h b/Source/Core/DSPCore/Src/DSPTables.h index 7484a34360..e6966b8596 100644 --- a/Source/Core/DSPCore/Src/DSPTables.h +++ b/Source/Core/DSPCore/Src/DSPTables.h @@ -128,11 +128,13 @@ extern const int opcodes_ext_size; extern u8 opSize[OPTABLE_SIZE]; extern const DSPOPCTemplate cw; +#define WRITEBACKLOGSIZE 7 + extern dspInstFunc opTable[]; extern bool opTableUseExt[OPTABLE_SIZE]; extern dspInstFunc extOpTable[EXT_OPTABLE_SIZE]; -extern dspInstFunc currentEpilogeFunc; - +extern u16 writeBackLog[WRITEBACKLOGSIZE]; +extern int writeBackLogIdx[WRITEBACKLOGSIZE]; // Predefined labels struct pdlabel_t @@ -151,15 +153,16 @@ const char *pdregname(int val); const char *pdregnamelong(int val); void InitInstructionTable(); +void applyWriteBackLog(); +void zeroWriteBackLog(); inline void ExecuteInstruction(const UDSPInstruction& inst) { if (opTableUseExt[inst.hex]) extOpTable[inst.hex & 0xFF](inst); opTable[inst.hex](inst); - if (currentEpilogeFunc) { - currentEpilogeFunc(inst); - currentEpilogeFunc = NULL; + if (opTableUseExt[inst.hex]) { + applyWriteBackLog(); } } diff --git a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp index ad517a28e5..c4c9018ddc 100644 --- a/Source/Core/DSPCore/Src/DspIntArithmetic.cpp +++ b/Source/Core/DSPCore/Src/DspIntArithmetic.cpp @@ -33,8 +33,8 @@ void clr(const UDSPInstruction& opc) u8 reg = (opc.hex >> 11) & 0x1; dsp_set_long_acc(reg, 0); - Update_SR_Register64((s64)0); // really? + zeroWriteBackLog(); } // CLRL $acR.l @@ -48,6 +48,7 @@ void clrl(const UDSPInstruction& opc) // Should this be 64bit? // nakee: it says the whole reg in duddie's doc sounds weird Update_SR_Register64((s64)reg); + zeroWriteBackLog(); } @@ -64,8 +65,9 @@ void addaxl(const UDSPInstruction& opc) acc += acx; - dsp_set_long_acc(dreg, acc); + zeroWriteBackLog(); + dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); } @@ -78,6 +80,7 @@ void tstaxh(const UDSPInstruction& opc) s16 val = dsp_get_ax_h(reg); Update_SR_Register16(val); + zeroWriteBackLog(); } // SUB $acD, $ac(1-D) @@ -91,8 +94,9 @@ void sub(const UDSPInstruction& opc) acc1 -= acc2; - dsp_set_long_acc(D, acc1); - + zeroWriteBackLog(); + + dsp_set_long_acc(D, acc1); Update_SR_Register64(acc1); } @@ -110,8 +114,9 @@ void movr(const UDSPInstruction& opc) acc <<= 16; acc &= ~0xffff; - dsp_set_long_acc(areg, acc); + zeroWriteBackLog(); + dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); } @@ -124,8 +129,10 @@ void movax(const UDSPInstruction& opc) u8 sreg = (opc.hex >> 9) & 0x1; s64 acx = dsp_get_long_acx(sreg); - dsp_set_long_acc(dreg, acx); + zeroWriteBackLog(); + + dsp_set_long_acc(dreg, acx); Update_SR_Register64(acx); } @@ -138,6 +145,8 @@ void xorr(const UDSPInstruction& opc) u8 sreg = (opc.hex >> 9) & 0x1; u8 dreg = (opc.hex >> 8) & 0x1; + zeroWriteBackLog(); + g_dsp.r[DSP_REG_ACM0 + dreg] ^= g_dsp.r[DSP_REG_AXH0 + sreg]; s64 acc = dsp_get_long_acc(dreg); @@ -153,10 +162,11 @@ void andr(const UDSPInstruction& opc) u8 sreg = (opc.hex >> 9) & 0x1; u8 dreg = (opc.hex >> 8) & 0x1; + zeroWriteBackLog(); + g_dsp.r[DSP_REG_ACM0 + dreg] &= g_dsp.r[DSP_REG_AXH0 + sreg]; s64 acc = dsp_get_long_acc(dreg); - Update_SR_Register64(acc); } @@ -169,10 +179,11 @@ void orr(const UDSPInstruction& opc) u8 sreg = (opc.hex >> 9) & 0x1; u8 dreg = (opc.hex >> 8) & 0x1; + zeroWriteBackLog(); + g_dsp.r[DSP_REG_ACM0 + dreg] |= g_dsp.r[DSP_REG_AXH0 + sreg]; s64 acc = dsp_get_long_acc(dreg); - Update_SR_Register64(acc); } @@ -184,6 +195,9 @@ void orr(const UDSPInstruction& opc) void andc(const UDSPInstruction& opc) { u8 D = (opc.hex >> 8) & 0x1; + + zeroWriteBackLog(); + g_dsp.r[DSP_REG_ACM0+D] &= dsp_get_acc_m(1-D); Update_SR_Register16(dsp_get_acc_m(D)); @@ -197,6 +211,9 @@ void andc(const UDSPInstruction& opc) void orc(const UDSPInstruction& opc) { u8 D = (opc.hex >> 8) & 0x1; + + zeroWriteBackLog(); + g_dsp.r[DSP_REG_ACM0+D] |= dsp_get_acc_m(1-D); Update_SR_Register16(dsp_get_acc_m(D)); @@ -220,6 +237,8 @@ void andcf(const UDSPInstruction& opc) u16 val = dsp_get_acc_m(reg); Update_SR_LZ(((val & imm) == imm) ? 0 : 1); + + zeroWriteBackLog(); } // Hermes switched andf and andcf, so check to make sure they are still correct @@ -237,6 +256,8 @@ void andf(const UDSPInstruction& opc) u16 val = dsp_get_acc_m(reg); Update_SR_LZ(((val & imm) == 0) ? 0 : 1); + + zeroWriteBackLog(); } // CMPI $amD, #I @@ -252,6 +273,8 @@ void cmpi(const UDSPInstruction& opc) s64 imm = (s64)(s16)dsp_fetch_code() << 16; s64 val = dsp_get_long_acc(reg); Update_SR_Register64(val - imm); + + zeroWriteBackLog(); } // XORI $acD.m, #I @@ -263,6 +286,9 @@ void xori(const UDSPInstruction& opc) { u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1); u16 imm = dsp_fetch_code(); + + zeroWriteBackLog(); + g_dsp.r[reg] ^= imm; Update_SR_Register16((s16)g_dsp.r[reg]); @@ -276,13 +302,14 @@ void andi(const UDSPInstruction& opc) { u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1); u16 imm = dsp_fetch_code(); + zeroWriteBackLog(); + g_dsp.r[reg] &= imm; Update_SR_Register16((s16)g_dsp.r[reg]); } -// F|RES: i am not sure if this shouldnt be the whole ACC // ORI $acD.m, #I // 0000 001r 0110 0000 // iiii iiii iiii iiii @@ -291,6 +318,8 @@ void ori(const UDSPInstruction& opc) { u8 reg = DSP_REG_ACM0 + ((opc.hex >> 8) & 0x1); u16 imm = dsp_fetch_code(); + zeroWriteBackLog(); + g_dsp.r[reg] |= imm; Update_SR_Register16((s16)g_dsp.r[reg]); @@ -310,6 +339,7 @@ void add(const UDSPInstruction& opc) s64 res = acc0 + acc1; + zeroWriteBackLog(); dsp_set_long_acc(areg, res); Update_SR_Register64(res); @@ -323,6 +353,8 @@ void addp(const UDSPInstruction& opc) u8 dreg = (opc.hex >> 8) & 0x1; s64 acc = dsp_get_long_acc(dreg); acc += dsp_get_long_prod(); + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -336,6 +368,8 @@ void subp(const UDSPInstruction& opc) u8 dreg = (opc.hex >> 8) & 0x1; s64 acc = dsp_get_long_acc(dreg); acc -= dsp_get_long_prod(); + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -358,6 +392,7 @@ void cmpis(const UDSPInstruction& opc) s64 res = acc - val; Update_SR_Register64(res); + zeroWriteBackLog(); } @@ -371,6 +406,8 @@ void decm(const UDSPInstruction& opc) s64 sub = 0x10000; s64 acc = dsp_get_long_acc(dreg); acc -= sub; + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -384,6 +421,8 @@ void dec(const UDSPInstruction& opc) u8 dreg = (opc.hex >> 8) & 0x01; s64 acc = dsp_get_long_acc(dreg) - 1; + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -399,6 +438,8 @@ void incm(const UDSPInstruction& opc) s64 sub = 0x10000; s64 acc = dsp_get_long_acc(dreg); acc += sub; + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -412,6 +453,8 @@ void inc(const UDSPInstruction& opc) u8 dreg = (opc.hex >> 8) & 0x1; s64 acc = dsp_get_long_acc(dreg) + 1; + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -426,6 +469,8 @@ void neg(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(areg); acc = 0 - acc; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -438,6 +483,8 @@ void mov(const UDSPInstruction& opc) { u8 D = (opc.hex >> 8) & 0x1; u64 acc = dsp_get_long_acc(1 - D); + + zeroWriteBackLog(); dsp_set_long_acc(D, acc); Update_SR_Register64(acc); @@ -454,6 +501,8 @@ void addax(const UDSPInstruction& opc) s64 ax = dsp_get_long_acx(sreg); s64 acc = dsp_get_long_acc(areg); acc += ax; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -472,6 +521,8 @@ void addr(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(areg); acc += ax; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -490,6 +541,8 @@ void subr(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(areg); acc -= ax; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -505,6 +558,7 @@ void subax(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regS); + zeroWriteBackLog(); dsp_set_long_acc(regD, acc); Update_SR_Register64(acc); } @@ -520,6 +574,8 @@ void addis(const UDSPInstruction& opc) Imm <<= 16; s64 acc = dsp_get_long_acc(areg); acc += Imm; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -537,6 +593,8 @@ void addi(const UDSPInstruction& opc) sub <<= 16; s64 acc = dsp_get_long_acc(areg); acc += sub; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -551,6 +609,8 @@ void lsl16(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(areg); acc <<= 16; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); } @@ -565,6 +625,8 @@ void lsr16(const UDSPInstruction& opc) u64 acc = dsp_get_long_acc(areg); acc >>= 16; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); } @@ -579,6 +641,8 @@ void asr16(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(areg); acc >>= 16; + + zeroWriteBackLog(); dsp_set_long_acc(areg, acc); Update_SR_Register64(acc); @@ -593,6 +657,8 @@ void lsl(const UDSPInstruction& opc) u64 acc = dsp_get_long_acc(opc.areg); acc <<= shift; + + zeroWriteBackLog(); dsp_set_long_acc(opc.areg, acc); Update_SR_Register64(acc); } @@ -608,6 +674,8 @@ void lsr(const UDSPInstruction& opc) // Lop off the extraneous sign extension our 64-bit fake accum causes acc &= 0x000000FFFFFFFFFFULL; acc >>= shift; + + zeroWriteBackLog(); dsp_set_long_acc(opc.areg, (s64)acc); Update_SR_Register64(acc); } @@ -623,6 +691,7 @@ void asl(const UDSPInstruction& opc) u64 acc = dsp_get_long_acc(opc.areg); acc <<= shift; + zeroWriteBackLog(); dsp_set_long_acc(opc.areg, acc); Update_SR_Register64(acc); @@ -640,6 +709,7 @@ void asr(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(opc.areg); acc >>= shift; + zeroWriteBackLog(); dsp_set_long_acc(opc.areg, acc); Update_SR_Register64(acc); @@ -662,6 +732,7 @@ void lsrn(const UDSPInstruction& opc) } else if (shift < 0) { acc <<= -shift; } + zeroWriteBackLog(); dsp_set_long_acc(0, (s64)acc); Update_SR_Register64(acc); } @@ -680,6 +751,7 @@ void asrn(const UDSPInstruction& opc) } else if (shift < 0) { acc <<= -shift; } + zeroWriteBackLog(); dsp_set_long_acc(0, acc); Update_SR_Register64(acc); } @@ -699,6 +771,7 @@ void lsrnr(const UDSPInstruction& opc) } else if (shift < 0) { acc >>= -shift; } + zeroWriteBackLog(); dsp_set_long_acc(sreg, acc); Update_SR_Register64(acc); } @@ -719,6 +792,7 @@ void cmpar(const UDSPInstruction& opc) s64 sr = dsp_get_long_acc(sreg); Update_SR_Register64(sr - rr); + zeroWriteBackLog(); } @@ -731,6 +805,7 @@ void cmp(const UDSPInstruction& opc) s64 acc1 = dsp_get_long_acc(1); Update_SR_Register64(acc0 - acc1); + zeroWriteBackLog(); } // TST @@ -742,6 +817,7 @@ void tst(const UDSPInstruction& opc) s64 acc = dsp_get_long_acc(reg); Update_SR_Register64(acc); + zeroWriteBackLog(); } } // namespace diff --git a/Source/Core/DSPCore/Src/DspIntLoadStore.cpp b/Source/Core/DSPCore/Src/DspIntLoadStore.cpp index d0e50dd278..975ef3bccd 100644 --- a/Source/Core/DSPCore/Src/DspIntLoadStore.cpp +++ b/Source/Core/DSPCore/Src/DspIntLoadStore.cpp @@ -115,7 +115,7 @@ void lrrd(const UDSPInstruction& opc) u16 val = dsp_dmem_read(dsp_op_read_reg(sreg)); dsp_op_write_reg(dreg, val); dsp_conditional_extend_accum(dreg); - dsp_decrement_addr_reg(sreg); + g_dsp.r[sreg] = dsp_decrement_addr_reg(sreg); } // LRRI $D, @$S @@ -131,7 +131,7 @@ void lrri(const UDSPInstruction& opc) u16 val = dsp_dmem_read(dsp_op_read_reg(sreg)); dsp_op_write_reg(dreg, val); dsp_conditional_extend_accum(dreg); - dsp_increment_addr_reg(sreg); + g_dsp.r[sreg] = dsp_increment_addr_reg(sreg); } // LRRN $D, @$S @@ -147,7 +147,7 @@ void lrrn(const UDSPInstruction& opc) u16 val = dsp_dmem_read(dsp_op_read_reg(sreg)); dsp_op_write_reg(dreg, val); dsp_conditional_extend_accum(dreg); - dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + g_dsp.r[sreg] = dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); } // SRR @$D, $S @@ -176,7 +176,7 @@ void srrd(const UDSPInstruction& opc) u16 val = dsp_op_read_reg(sreg); dsp_dmem_write(g_dsp.r[dreg], val); - dsp_decrement_addr_reg(dreg); + g_dsp.r[sreg] = dsp_decrement_addr_reg(dreg); } // SRRI @$D, $S @@ -191,7 +191,7 @@ void srri(const UDSPInstruction& opc) u16 val = dsp_op_read_reg(sreg); dsp_dmem_write(g_dsp.r[dreg], val); - dsp_increment_addr_reg(dreg); + g_dsp.r[dreg] = dsp_increment_addr_reg(dreg); } // SRRN @$D, $S @@ -206,7 +206,7 @@ void srrn(const UDSPInstruction& opc) u16 val = dsp_op_read_reg(sreg); dsp_dmem_write(g_dsp.r[dreg], val); - dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]); + g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]); } // ILRR $acD.m, @$arS @@ -234,7 +234,7 @@ void ilrrd(const UDSPInstruction& opc) g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); dsp_conditional_extend_accum(dreg); - dsp_decrement_addr_reg(reg); + g_dsp.r[reg] = dsp_decrement_addr_reg(reg); } // ILRRI $acD.m, @$S @@ -248,7 +248,7 @@ void ilrri(const UDSPInstruction& opc) g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); - dsp_increment_addr_reg(reg); + g_dsp.r[reg] = dsp_increment_addr_reg(reg); } // ILRRN $acD.m, @$arS @@ -263,7 +263,7 @@ void ilrrn(const UDSPInstruction& opc) g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); dsp_conditional_extend_accum(dreg); - dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]); + g_dsp.r[reg] = dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]); } } // namespace diff --git a/Source/Core/DSPCore/Src/DspIntMisc.cpp b/Source/Core/DSPCore/Src/DspIntMisc.cpp index 904b793ed0..8e674f54c4 100644 --- a/Source/Core/DSPCore/Src/DspIntMisc.cpp +++ b/Source/Core/DSPCore/Src/DspIntMisc.cpp @@ -97,7 +97,7 @@ void addarn(const UDSPInstruction& opc) u8 dreg = opc.hex & 0x3; u8 sreg = (opc.hex >> 2) & 0x3; - dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); + g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]); // It is critical for the Zelda ucode that this one wraps correctly. } @@ -107,6 +107,7 @@ void addarn(const UDSPInstruction& opc) // No operation, but can be extended with extended opcode. void nx(const UDSPInstruction& opc) { + zeroWriteBackLog(); // This opcode is supposed to do nothing - it's used if you want to use // an opcode extension but not do anything. At least according to duddie. } @@ -117,7 +118,7 @@ void nx(const UDSPInstruction& opc) // Decrement address register $arD. void dar(const UDSPInstruction& opc) { - dsp_decrement_addr_reg(opc.hex & 0x3); + g_dsp.r[opc.hex & 0x3] = dsp_decrement_addr_reg(opc.hex & 0x3); } // IAR $arD ? @@ -125,7 +126,7 @@ void dar(const UDSPInstruction& opc) // Increment address register $arD. void iar(const UDSPInstruction& opc) { - dsp_increment_addr_reg(opc.hex & 0x3); + g_dsp.r[opc.hex & 0x3] = dsp_increment_addr_reg(opc.hex & 0x3); } // SBCLR #I @@ -153,6 +154,7 @@ void sbset(const UDSPInstruction& opc) // but it's harder to know exactly what effect they have. void srbith(const UDSPInstruction& opc) { + zeroWriteBackLog(); switch ((opc.hex >> 8) & 0xf) { // M0/M2 change the multiplier mode (it can multiply by 2 for free). diff --git a/Source/Core/DSPCore/Src/DspIntMultiplier.cpp b/Source/Core/DSPCore/Src/DspIntMultiplier.cpp index 2be101012a..a4d63e3846 100644 --- a/Source/Core/DSPCore/Src/DspIntMultiplier.cpp +++ b/Source/Core/DSPCore/Src/DspIntMultiplier.cpp @@ -103,6 +103,7 @@ void clrp(const UDSPInstruction& opc) { // Magic numbers taken from duddie's doc // These are probably a bad idea to put here. + zeroWriteBackLog(); g_dsp.r[0x14] = 0x0000; g_dsp.r[0x15] = 0xfff0; g_dsp.r[0x16] = 0x00ff; @@ -117,6 +118,7 @@ void movp(const UDSPInstruction& opc) u8 dreg = (opc.hex >> 8) & 0x1; s64 prod = dsp_get_long_prod(); + zeroWriteBackLog(); dsp_set_long_acc(dreg, prod); Update_SR_Register64(prod); @@ -132,6 +134,7 @@ void movnp(const UDSPInstruction& opc) s64 prod = dsp_get_long_prod(); s64 acc = -prod; + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -150,6 +153,7 @@ void addpaxz(const UDSPInstruction& opc) s64 ax = dsp_get_long_acx(sreg); s64 acc = (prod + ax) & ~0xffff; + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -166,6 +170,8 @@ void movpz(const UDSPInstruction& opc) // overwrite acc and clear low part s64 prod = dsp_get_long_prod(); s64 acc = prod & ~0xffff; + + zeroWriteBackLog(); dsp_set_long_acc(dreg, acc); Update_SR_Register64(acc); @@ -180,7 +186,12 @@ void mulc(const UDSPInstruction& opc) { u8 sreg = (opc.hex >> 11) & 0x1; u8 treg = (opc.hex >> 12) & 0x1; - s64 prod = dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); + u16 accm = dsp_get_acc_m(sreg); + u16 axh = dsp_get_ax_h(treg); + + zeroWriteBackLog(); + + s64 prod = dsp_multiply(accm, axh); Update_SR_Register64(prod); } @@ -198,8 +209,13 @@ void mulcmvz(const UDSPInstruction& opc) // update prod u8 sreg = (opc.hex >> 12) & 0x1; u8 treg = (opc.hex >> 11) & 0x1; - dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); + u16 accm = dsp_get_acc_m(sreg); + u16 axh = dsp_get_ax_h(treg); + + zeroWriteBackLog(); + + dsp_multiply(accm, axh); // update acc u8 rreg = (opc.hex >> 8) & 0x1; s64 acc = TempProd & ~0xffff; // clear lower 4 bytes @@ -221,7 +237,12 @@ void mulcmv(const UDSPInstruction& opc) // update prod u8 sreg = (opc.hex >> 12) & 0x1; u8 treg = (opc.hex >> 11) & 0x1; - dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); + u16 accm = dsp_get_acc_m(sreg); + u16 axh = dsp_get_ax_h(treg); + + zeroWriteBackLog(); + + dsp_multiply(accm, axh); // update acc u8 rreg = (opc.hex >> 8) & 0x1; @@ -242,7 +263,12 @@ void mulcac(const UDSPInstruction& opc) // update prod u8 sreg = (opc.hex >> 12) & 0x1; u8 treg = (opc.hex >> 11) & 0x1; - dsp_multiply(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); + u16 accm = dsp_get_acc_m(sreg); + u16 axh = dsp_get_ax_h(treg); + + zeroWriteBackLog(); + + dsp_multiply(accm, axh); // update acc u8 rreg = (opc.hex >> 8) & 0x1; @@ -260,7 +286,12 @@ void mulcac(const UDSPInstruction& opc) void mul(const UDSPInstruction& opc) { u8 sreg = (opc.hex >> 11) & 0x1; - s64 prod = dsp_multiply(dsp_get_ax_h(sreg), dsp_get_ax_l(sreg)); + u16 axl = dsp_get_ax_l(sreg); + u16 axh = dsp_get_ax_h(sreg); + + zeroWriteBackLog(); + + s64 prod = dsp_multiply(axh, axl); // FIXME: no update in duddie's docs Update_SR_Register64(prod); } @@ -274,12 +305,19 @@ void mulac(const UDSPInstruction& opc) { // add old prod to acc u8 rreg = (opc.hex >> 8) & 0x1; + u8 sreg = (opc.hex >> 11) & 0x1; + s64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod(); + u16 axl = dsp_get_ax_l(sreg); + u16 axh = dsp_get_ax_h(sreg); + + zeroWriteBackLog(); + + dsp_set_long_acc(rreg, acR); // calculate new prod - u8 sreg = (opc.hex >> 11) & 0x1; - s64 prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg)); + s64 prod = dsp_multiply(axl, axh); // FIXME: no update in duddie's docs Update_SR_Register64(prod); @@ -296,9 +334,13 @@ void mulmv(const UDSPInstruction& opc) u8 sreg = ((opc.hex >> 11) & 0x1); s64 prod = dsp_get_long_prod(); s64 acc = prod; + u16 axl = dsp_get_ax_l(sreg); + u16 axh = dsp_get_ax_h(sreg); + + zeroWriteBackLog(); dsp_set_long_acc(rreg, acc); - prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg)); + prod = dsp_multiply(axl, axh); Update_SR_Register64(prod); } @@ -316,10 +358,15 @@ void mulmvz(const UDSPInstruction& opc) // overwrite acc and clear low part s64 prod = dsp_get_long_prod(); s64 acc = prod & ~0xffff; + u16 axl = dsp_get_ax_l(sreg); + u16 axh = dsp_get_ax_h(sreg); + + zeroWriteBackLog(); + dsp_set_long_acc(rreg, acc); // math prod - prod = dsp_multiply(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg)); + prod = dsp_multiply(axl, axh); Update_SR_Register64(prod); } @@ -335,6 +382,7 @@ void mulx(const UDSPInstruction& opc) u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + zeroWriteBackLog(); s64 prod = dsp_multiply_conditional_unsigned(val1, val2); Update_SR_Register64(prod); } @@ -357,7 +405,8 @@ void mulxac(const UDSPInstruction& opc) u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); - + zeroWriteBackLog(); + s64 prod = dsp_multiply_conditional_unsigned(val1, val2); Update_SR_Register64(prod); } @@ -380,7 +429,7 @@ void mulxmv(const UDSPInstruction& opc) s16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); s16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); - + zeroWriteBackLog(); s64 prod = dsp_multiply_conditional_unsigned(val1, val2); Update_SR_Register64(prod); } @@ -405,7 +454,7 @@ void mulxmvz(const UDSPInstruction& opc) u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); - + zeroWriteBackLog(); prod = dsp_multiply_conditional_unsigned(val1, val2); Update_SR_Register64(prod); } @@ -422,7 +471,7 @@ void maddx(const UDSPInstruction& opc) u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); - + zeroWriteBackLog(); s64 prod = dsp_multiply_add(val1, val2); Update_SR_Register64(prod); } @@ -439,7 +488,7 @@ void msubx(const UDSPInstruction& opc) u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); - + zeroWriteBackLog(); s64 prod = dsp_multiply_sub(val1, val2); Update_SR_Register64(prod); } @@ -453,8 +502,10 @@ void maddc(const UDSPInstruction& opc) { u32 sreg = (opc.hex >> 9) & 0x1; u32 treg = (opc.hex >> 8) & 0x1; - - s64 prod = dsp_multiply_add(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); + u16 accm = dsp_get_acc_m(sreg); + u16 axh = dsp_get_ax_h(treg); + zeroWriteBackLog(); + s64 prod = dsp_multiply_add(accm, axh); Update_SR_Register64(prod); } @@ -467,8 +518,10 @@ void msubc(const UDSPInstruction& opc) { u32 sreg = (opc.hex >> 9) & 0x1; u32 treg = (opc.hex >> 8) & 0x1; - - s64 prod = dsp_multiply_sub(dsp_get_acc_m(sreg), dsp_get_ax_h(treg)); + u16 accm = dsp_get_acc_m(sreg); + u16 axh = dsp_get_ax_h(treg); + zeroWriteBackLog(); + s64 prod = dsp_multiply_sub(accm, axh); Update_SR_Register64(prod); } @@ -480,8 +533,12 @@ void msubc(const UDSPInstruction& opc) void madd(const UDSPInstruction& opc) { u8 sreg = (opc.hex >> 8) & 0x1; + u16 axl = dsp_get_ax_l(sreg); + u16 axh = dsp_get_ax_h(sreg); + + zeroWriteBackLog(); - s64 prod = dsp_multiply_add(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg)); + s64 prod = dsp_multiply_add(axl, axh); Update_SR_Register64(prod); } @@ -493,8 +550,12 @@ void madd(const UDSPInstruction& opc) void msub(const UDSPInstruction& opc) { u8 sreg = (opc.hex >> 8) & 0x1; + u16 axl = dsp_get_ax_l(sreg); + u16 axh = dsp_get_ax_h(sreg); + + zeroWriteBackLog(); - s64 prod = dsp_multiply_sub(dsp_get_ax_l(sreg), dsp_get_ax_h(sreg)); + s64 prod = dsp_multiply_sub(axl, axh); Update_SR_Register64(prod); }