From 208d25c3f515c23b6c5989e2abc72a6423a38341 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Fri, 7 Sep 2012 01:09:49 +0200 Subject: [PATCH] Revert merges of aram-dma-fixes and memcard-delay These merges, while in theory improving emulation accuracy, cause issues in other parts of the emulator based on invalid assumptions. memcard-delay fixed some of these issues in the EXI memcard code, but several other problems still exist and I don't have the time to debug that right now. --- Source/Core/Core/Src/HW/DSP.cpp | 10 +++-- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp | 38 ++++++------------- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.h | 11 +----- .../Interpreter_SystemRegisters.cpp | 1 - Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 3 +- .../Src/PowerPC/Jit64/Jit_SystemRegisters.cpp | 18 --------- Source/Core/Core/Src/PowerPC/Jit64IL/IR.h | 4 +- .../Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp | 18 --------- .../PowerPC/Jit64IL/JitIL_SystemRegisters.cpp | 2 +- 9 files changed, 23 insertions(+), 82 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 799fb62f0e..f2509555ed 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -436,6 +436,10 @@ void Write16(const u16 _Value, const u32 _Address) if (tmpControl.ARAM) g_dspState.DSPControl.ARAM = 0; if (tmpControl.DSP) g_dspState.DSPControl.DSP = 0; + // Tracking DMAState fixes Knockout Kings 2003 in DSP HLE mode + if (GetDSPEmulator()->IsLLE()) + g_dspState.DSPControl.DMAState = 0; // keep g_ARAM DMA State zero + // unknown g_dspState.DSPControl.unk3 = tmpControl.unk3; g_dspState.DSPControl.pad = tmpControl.pad; @@ -697,9 +701,9 @@ void Do_ARAM_DMA() // seems like a good estimate CoreTiming::ScheduleEvent_Threadsafe(g_arDMA.Cnt.count >> 1, et_GenerateDSPInterrupt, INT_ARAM | (1<<16)); - // Set the "DMA in progress" flag. It will be cleared when the interrupt will - // be triggered, after the simulated delay. - g_dspState.DSPControl.DMAState = 1; + // Emulating the DMA wait time fixes Knockout Kings 2003 in DSP HLE mode + if (!GetDSPEmulator()->IsLLE()) + g_dspState.DSPControl.DMAState = 1; // Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks if (g_arDMA.Cnt.dir) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index 4705e849be..6f4bc502b6 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -47,22 +47,13 @@ void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate) pThis->Flush(); } -void CEXIMemoryCard::CmdDoneCallback(u64 userdata, int cyclesLate) -{ - int card_index = (int)userdata; - CEXIMemoryCard* pThis = (CEXIMemoryCard*)ExpansionInterface::FindDevice(EXIDEVICE_MEMORYCARD, card_index); - if (pThis) - pThis->CmdDone(); -} - CEXIMemoryCard::CEXIMemoryCard(const int index) : card_index(index) , m_bDirty(false) { m_strFilename = (card_index == 0) ? SConfig::GetInstance().m_strMemoryCardA : SConfig::GetInstance().m_strMemoryCardB; // we're potentially leaking events here, since there's no UnregisterEvent until emu shutdown, but I guess it's inconsequential - et_this_card = CoreTiming::RegisterEvent((card_index == 0) ? "memcardFlushA" : "memcardFlushB", FlushCallback); - et_cmd_done = CoreTiming::RegisterEvent((card_index == 0) ? "memcardDoneA" : "memcardDoneB", CmdDoneCallback); + et_this_card = CoreTiming::RegisterEvent((card_index == 0) ? "memcardA" : "memcardB", FlushCallback); interruptSwitch = 0; m_bInterruptSet = 0; @@ -184,21 +175,6 @@ bool CEXIMemoryCard::IsPresent() return true; } -void CEXIMemoryCard::CmdDone() -{ - status |= MC_STATUS_READY; - status &= ~MC_STATUS_BUSY; - - m_bInterruptSet = 1; - m_bDirty = true; -} - -void CEXIMemoryCard::CmdDoneLater(u64 cycles) -{ - CoreTiming::RemoveEvent(et_cmd_done); - CoreTiming::ScheduleEvent(cycles, et_cmd_done, (u64)card_index); -} - void CEXIMemoryCard::SetCS(int cs) { // So that memory card won't be invalidated during flushing @@ -222,7 +198,11 @@ void CEXIMemoryCard::SetCS(int cs) //??? - CmdDoneLater(5000); + status |= MC_STATUS_READY; + status &= ~MC_STATUS_BUSY; + + m_bInterruptSet = 1; + m_bDirty = true; } break; @@ -249,7 +229,11 @@ void CEXIMemoryCard::SetCS(int cs) address = (address & ~0x1FF) | ((address+1) & 0x1FF); } - CmdDoneLater(5000); + status |= MC_STATUS_READY; + status &= ~MC_STATUS_BUSY; + + m_bInterruptSet = 1; + m_bDirty = true; } // Page written to memory card, not just to buffer - let's schedule a flush 0.5b cycles into the future (1 sec) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h index 33b94ca530..dfdc6349aa 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h @@ -47,18 +47,9 @@ private: // through the userdata parameter, so that it can then call Flush on the right card. static void FlushCallback(u64 userdata, int cyclesLate); - // Scheduled when a command that required delayed end signaling is done. - static void CmdDoneCallback(u64 userdata, int cyclesLate); - // Flushes the memory card contents to disk. void Flush(bool exiting = false); - // Signals that the command that was previously executed is now done. - void CmdDone(); - - // Variant of CmdDone which schedules an event later in the future to complete the command. - void CmdDoneLater(u64 cycles); - enum { cmdNintendoID = 0x00, @@ -80,7 +71,7 @@ private: std::string m_strFilename; int card_index; - int et_this_card, et_cmd_done; + int et_this_card; //! memory card state // STATE_TO_SAVE diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 19fe74b3f2..bc7e37b533 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -234,7 +234,6 @@ void Interpreter::mtmsr(UGeckoInstruction _inst) { // Privileged? MSR = m_GPR[_inst.RS]; - PowerPC::CheckExceptions(); m_EndBlock = true; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 04015afca6..357eeb7809 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -303,8 +303,7 @@ void Jit64::Cleanup() void Jit64::WriteExit(u32 destination, int exit_num) { Cleanup(); - - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); + SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp index b977e82b28..14827129f8 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -122,25 +122,7 @@ void Jit64::mtmsr(UGeckoInstruction inst) gpr.UnlockAll(); gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); - - // If some exceptions are pending and EE are now enabled, force checking - // external exceptions when going out of mtmsr in order to execute delayed - // interrupts as soon as possible. - MOV(32, R(EAX), M(&MSR)); - TEST(32, R(EAX), Imm32(0x8000)); - FixupBranch eeDisabled = J_CC(CC_Z); - - MOV(32, R(EAX), M((void*)&PowerPC::ppcState.Exceptions)); - TEST(32, R(EAX), R(EAX)); - FixupBranch noExceptionsPending = J_CC(CC_Z); - - MOV(32, M(&PC), Imm32(js.compilerPC + 4)); - WriteExternalExceptionExit(); - - SetJumpTarget(eeDisabled); - SetJumpTarget(noExceptionsPending); WriteExit(js.compilerPC + 4, 0); - js.firstFPInstructionFound = false; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index 7fabd946f9..77f7d6977b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -276,8 +276,8 @@ public: InstLoc EmitLoadMSR() { return FoldZeroOp(LoadMSR, 0); } - InstLoc EmitStoreMSR(InstLoc val, InstLoc pc) { - return FoldBiOp(StoreMSR, val, pc); + InstLoc EmitStoreMSR(InstLoc val) { + return FoldUOp(StoreMSR, val); } InstLoc EmitStoreFPRF(InstLoc value) { return FoldUOp(StoreFPRF, value); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index d9aa46f6b5..e91291fa90 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -994,26 +994,8 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak break; } case StoreMSR: { - unsigned InstLoc = ibuild->GetImmValue(getOp2(I)); regStoreInstToConstLoc(RI, 32, getOp1(I), &MSR); regNormalRegClear(RI, I); - - // If some exceptions are pending and EE are now enabled, force checking - // external exceptions when going out of mtmsr in order to execute delayed - // interrupts as soon as possible. - Jit->MOV(32, R(EAX), M(&MSR)); - Jit->TEST(32, R(EAX), Imm32(0x8000)); - FixupBranch eeDisabled = Jit->J_CC(CC_Z); - - Jit->MOV(32, R(EAX), M((void*)&PowerPC::ppcState.Exceptions)); - Jit->TEST(32, R(EAX), R(EAX)); - FixupBranch noExceptionsPending = Jit->J_CC(CC_Z); - - Jit->MOV(32, M(&PC), Imm32(InstLoc + 4)); - Jit->WriteExceptionExit(); // TODO: Implement WriteExternalExceptionExit for JitIL - - Jit->SetJumpTarget(eeDisabled); - Jit->SetJumpTarget(noExceptionsPending); break; } case StoreGQR: { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp index ac914bec94..f3e25dc2dd 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp @@ -106,7 +106,7 @@ void JitIL::mfspr(UGeckoInstruction inst) // -------------- void JitIL::mtmsr(UGeckoInstruction inst) { - ibuild.EmitStoreMSR(ibuild.EmitLoadGReg(inst.RS), ibuild.EmitIntConst(js.compilerPC)); + ibuild.EmitStoreMSR(ibuild.EmitLoadGReg(inst.RS)); ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4)); } // ==============