From 9b16d2979239d7aef2989cb7dd16c67842e85e28 Mon Sep 17 00:00:00 2001 From: zilmar Date: Mon, 22 Aug 2022 12:47:44 +0930 Subject: [PATCH] Core: Add rom write decay and some code clean up --- .../N64System/FramePerSecond.cpp | 12 ++-- .../PeripheralInterfaceHandler.cpp | 10 ++-- .../MemoryHandler/RomMemoryHandler.cpp | 11 +++- .../MemoryHandler/RomMemoryHandler.h | 2 + .../N64System/Mips/MemoryVirtualMem.h | 1 + .../N64System/Mips/SystemTiming.cpp | 59 ++++++++++--------- .../N64System/Mips/SystemTiming.h | 7 ++- Source/Project64-core/N64System/N64System.cpp | 2 +- .../Recompiler/x86/x86RecompilerOps.cpp | 25 +++++++- 9 files changed, 81 insertions(+), 48 deletions(-) diff --git a/Source/Project64-core/N64System/FramePerSecond.cpp b/Source/Project64-core/N64System/FramePerSecond.cpp index 4c7e06841..9a8a416e9 100644 --- a/Source/Project64-core/N64System/FramePerSecond.cpp +++ b/Source/Project64-core/N64System/FramePerSecond.cpp @@ -3,12 +3,12 @@ #include CFramePerSecond::CFramePerSecond() : -m_CurrentViFrame(0), -m_CurrentDlistFrame(0), -m_iFrameRateType(g_Settings->LoadDword(UserInterface_FrameDisplayType)), -m_ScreenHertz(g_Settings->LoadDword(GameRunning_ScreenHertz)), -m_ViFrameRateWhole(0), -m_ViFrameRateFraction(0) + m_CurrentViFrame(0), + m_CurrentDlistFrame(0), + m_iFrameRateType(g_Settings->LoadDword(UserInterface_FrameDisplayType)), + m_ScreenHertz(g_Settings->LoadDword(GameRunning_ScreenHertz)), + m_ViFrameRateWhole(0), + m_ViFrameRateFraction(0) { g_Settings->RegisterChangeCB(UserInterface_FrameDisplayType, this, (CSettings::SettingChangedFunc)FrameRateTypeChanged); g_Settings->RegisterChangeCB(GameRunning_ScreenHertz, this, (CSettings::SettingChangedFunc)ScreenHertzChanged); diff --git a/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp index ceb10fa19..77444e982 100644 --- a/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp +++ b/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp @@ -175,8 +175,6 @@ void PeripheralInterfaceHandler::SystemReset(void) void PeripheralInterfaceHandler::OnFirstDMA() { int16_t offset; - const uint32_t rt = g_MMU->RdramSize(); - switch (g_Rom->CicChipID()) { case CIC_NUS_6101: @@ -199,7 +197,7 @@ void PeripheralInterfaceHandler::OnFirstDMA() g_Notify->DisplayError(stdstr_f("Unhandled CicChip(%d) in first DMA", g_Rom->CicChipID()).c_str()); return; } - g_MMU->UpdateMemoryValue32(0x80000000 + offset, rt); + m_MMU.UpdateMemoryValue32(0x80000000 + offset, m_MMU.RdramSize()); } void PeripheralInterfaceHandler::PI_DMA_READ() @@ -216,7 +214,7 @@ void PeripheralInterfaceHandler::PI_DMA_READ() PI_RD_LEN += 1; } - if (PI_DRAM_ADDR_REG + PI_RD_LEN > g_MMU->RdramSize()) + if (PI_DRAM_ADDR_REG + PI_RD_LEN > m_MMU.RdramSize()) { PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; PI_STATUS_REG |= PI_STATUS_INTERRUPT; @@ -237,7 +235,7 @@ void PeripheralInterfaceHandler::PI_DMA_READ() { // 64DD user sector uint32_t i; - uint8_t * RDRAM = g_MMU->Rdram(); + uint8_t * RDRAM = m_MMU.Rdram(); uint8_t * DISK = g_Disk->GetDiskAddressBuffer(); for (i = 0; i < PI_RD_LEN_REG; i++) { @@ -262,7 +260,7 @@ void PeripheralInterfaceHandler::PI_DMA_READ() { uint32_t i; uint8_t * ROM = g_Rom->GetRomAddress(); - uint8_t * RDRAM = g_MMU->Rdram(); + uint8_t * RDRAM = m_MMU.Rdram(); ProtectMemory(ROM, g_Rom->GetRomSize(), MEM_READWRITE); PI_CART_ADDR_REG -= 0x10000000; diff --git a/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.cpp index be6b98667..f9ec4b5ca 100644 --- a/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.cpp +++ b/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.cpp @@ -27,8 +27,7 @@ bool RomMemoryHandler::Read32(uint32_t Address, uint32_t & Value) if (m_RomWrittenTo) { Value = m_RomWroteValue; - m_Reg.PI_STATUS_REG &= ~PI_STATUS_IO_BUSY; - m_RomWrittenTo = false; + RomWriteDecayed(); } else if ((Address & 0xFFFFFFF) < m_Rom.GetRomSize()) { @@ -60,10 +59,18 @@ bool RomMemoryHandler::Write32(uint32_t /*Address*/, uint32_t Value, uint32_t Ma m_RomWrittenTo = true; m_RomWroteValue = (Value & Mask); m_Reg.PI_STATUS_REG |= PI_STATUS_IO_BUSY; + g_SystemTimer->SetTimer(CSystemTimer::RomWriteDecay, 0x5E, false); } return true; } +void RomMemoryHandler::RomWriteDecayed(void) +{ + g_SystemTimer->StopTimer(CSystemTimer::RomWriteDecay); + m_Reg.PI_STATUS_REG &= ~PI_STATUS_IO_BUSY; + m_RomWrittenTo = false; +} + void RomMemoryHandler::SystemReset(void) { m_RomWrittenTo = false; diff --git a/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.h b/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.h index ce2245e4d..5eb3b1737 100644 --- a/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.h +++ b/Source/Project64-core/N64System/MemoryHandler/RomMemoryHandler.h @@ -19,6 +19,8 @@ public: bool Read32(uint32_t Address, uint32_t & Value); bool Write32(uint32_t Address, uint32_t Value, uint32_t Mask); + void RomWriteDecayed(void); + private: RomMemoryHandler(); RomMemoryHandler(const RomMemoryHandler&); diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h index e3730c9e7..bf8f44648 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h @@ -118,6 +118,7 @@ public: AudioInterfaceHandler & AudioInterface(void) { return m_AudioInterfaceHandler; } VideoInterfaceHandler & VideoInterface(void) { return m_VideoInterfaceHandler; } + RomMemoryHandler & RomMemory(void) { return m_RomMemoryHandler; }; private: CMipsMemoryVM(); diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.cpp b/Source/Project64-core/N64System/Mips/SystemTiming.cpp index fa9226716..7fc20c696 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.cpp +++ b/Source/Project64-core/N64System/Mips/SystemTiming.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include #include #include #include @@ -7,13 +8,15 @@ #include #include -CSystemTimer::CSystemTimer(CRegisters &Reg, AudioInterfaceHandler & AudioInterface, int32_t & NextTimer) : +CSystemTimer::CSystemTimer(CN64System & System) : + m_System(System), m_LastUpdate(0), - m_NextTimer(NextTimer), + m_NextTimer(System.m_NextTimer), m_Current(UnknownTimer), m_inFixTimer(false), - m_Reg(Reg), - m_AudioInterface(AudioInterface) + m_Reg(System.m_Reg), + m_RomMemoryHandler(System.m_MMU_VM.RomMemory()), + m_AudioInterface(System.m_MMU_VM.AudioInterface()) { memset(m_TimerDetatils, 0, sizeof(m_TimerDetatils)); } @@ -161,7 +164,7 @@ void CSystemTimer::UpdateTimers() int32_t random, wired; m_LastUpdate = m_NextTimer; m_Reg.COUNT_REGISTER += TimeTaken; - random = m_Reg.RANDOM_REGISTER - ((TimeTaken * CGameSettings::OverClockModifier()) / g_System->CountPerOp()); + random = m_Reg.RANDOM_REGISTER - ((TimeTaken * CGameSettings::OverClockModifier()) / m_System.CountPerOp()); wired = m_Reg.WIRED_REGISTER; if (random < wired) { @@ -191,24 +194,24 @@ void CSystemTimer::TimerDone() UpdateCompareTimer(); break; case CSystemTimer::SoftResetTimer: - g_SystemTimer->StopTimer(CSystemTimer::SoftResetTimer); - g_System->ExternalEvent(SysEvent_ResetCPU_SoftDone); + StopTimer(CSystemTimer::SoftResetTimer); + m_System.ExternalEvent(SysEvent_ResetCPU_SoftDone); break; case CSystemTimer::SiTimer: - g_SystemTimer->StopTimer(CSystemTimer::SiTimer); + StopTimer(CSystemTimer::SiTimer); m_Reg.MI_INTR_REG |= MI_INTR_SI; m_Reg.SI_STATUS_REG |= SI_STATUS_INTERRUPT; m_Reg.CheckInterrupts(); break; case CSystemTimer::PiTimer: - g_SystemTimer->StopTimer(CSystemTimer::PiTimer); + StopTimer(CSystemTimer::PiTimer); m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; m_Reg.PI_STATUS_REG |= PI_STATUS_INTERRUPT; m_Reg.MI_INTR_REG |= MI_INTR_PI; m_Reg.CheckInterrupts(); break; case CSystemTimer::DDPiTimer: - g_SystemTimer->StopTimer(CSystemTimer::DDPiTimer); + StopTimer(CSystemTimer::DDPiTimer); m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; DiskBMUpdate(); m_Reg.MI_INTR_REG |= MI_INTR_PI; @@ -216,19 +219,19 @@ void CSystemTimer::TimerDone() m_Reg.CheckInterrupts(); break; case CSystemTimer::DDSeekTimer: - g_SystemTimer->StopTimer(CSystemTimer::DDSeekTimer); - g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT; - g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3; - g_Reg->CheckInterrupts(); + StopTimer(CSystemTimer::DDSeekTimer); + m_Reg.ASIC_STATUS |= DD_STATUS_MECHA_INT; + m_Reg.FAKE_CAUSE_REGISTER |= CAUSE_IP3; + m_Reg.CheckInterrupts(); break; case CSystemTimer::DDMotorTimer: - g_SystemTimer->StopTimer(CSystemTimer::DDMotorTimer); - g_Reg->ASIC_STATUS |= DD_STATUS_MTR_N_SPIN; + StopTimer(CSystemTimer::DDMotorTimer); + m_Reg.ASIC_STATUS |= DD_STATUS_MTR_N_SPIN; break; case CSystemTimer::ViTimer: try { - g_System->RefreshScreen(); + m_System.RefreshScreen(); } catch (...) { @@ -238,10 +241,10 @@ void CSystemTimer::TimerDone() m_Reg.CheckInterrupts(); break; case CSystemTimer::RspTimer: - g_SystemTimer->StopTimer(CSystemTimer::RspTimer); + StopTimer(CSystemTimer::RspTimer); try { - g_System->RunRSP(); + m_System.RunRSP(); } catch (...) { @@ -249,18 +252,21 @@ void CSystemTimer::TimerDone() } break; case CSystemTimer::RSPTimerDlist: - g_SystemTimer->StopTimer(CSystemTimer::RSPTimerDlist); + StopTimer(CSystemTimer::RSPTimerDlist); m_Reg.m_GfxIntrReg |= MI_INTR_DP; m_Reg.CheckInterrupts(); break; case CSystemTimer::AiTimerInterrupt: - g_SystemTimer->StopTimer(CSystemTimer::AiTimerInterrupt); + StopTimer(CSystemTimer::AiTimerInterrupt); m_AudioInterface.TimerInterrupt(); break; case CSystemTimer::AiTimerBusy: - g_SystemTimer->StopTimer(CSystemTimer::AiTimerBusy); + StopTimer(CSystemTimer::AiTimerBusy); m_AudioInterface.TimerBusy(); break; + case CSystemTimer::RomWriteDecay: + m_RomMemoryHandler.RomWriteDecayed(); + break; default: g_Notify->BreakPoint(__FILE__, __LINE__); } @@ -274,13 +280,10 @@ void CSystemTimer::TimerDone() void CSystemTimer::SetCompareTimer() { uint32_t NextCompare = 0x7FFFFFFF; - if (g_Reg) + NextCompare = m_Reg.COMPARE_REGISTER - m_Reg.COUNT_REGISTER; + if ((NextCompare & 0x80000000) != 0) { - NextCompare = m_Reg.COMPARE_REGISTER - m_Reg.COUNT_REGISTER; - if ((NextCompare & 0x80000000) != 0) - { - NextCompare = 0x7FFFFFFF; - } + NextCompare = 0x7FFFFFFF; } SetTimer(CompareTimer, NextCompare, false); } diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.h b/Source/Project64-core/N64System/Mips/SystemTiming.h index 6fc8411c9..1f48c79d3 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.h +++ b/Source/Project64-core/N64System/Mips/SystemTiming.h @@ -26,6 +26,7 @@ public: DDPiTimer, DDSeekTimer, DDMotorTimer, + RomWriteDecay, MaxTimer }; @@ -39,7 +40,7 @@ public: int64_t CyclesToTimer; }; - CSystemTimer(CRegisters &Reg, AudioInterfaceHandler & AudioInterface, int32_t & NextTimer); + CSystemTimer(CN64System & System); void SetTimer(TimerType Type, uint32_t Cycles, bool bRelative); uint32_t GetTimer(TimerType Type); void StopTimer(TimerType Type); @@ -68,12 +69,14 @@ private: void SetCompareTimer(); void FixTimers(); - + + CN64System & m_System; TIMER_DETAILS m_TimerDetatils[MaxTimer]; int32_t m_LastUpdate; int32_t & m_NextTimer; TimerType m_Current; bool m_inFixTimer; CRegisters & m_Reg; + RomMemoryHandler & m_RomMemoryHandler; AudioInterfaceHandler & m_AudioInterface; }; diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index 9d8f462a9..3ae3d898d 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -36,7 +36,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR m_Recomp(nullptr), m_InReset(false), m_NextTimer(0), - m_SystemTimer(m_Reg, m_MMU_VM.AudioInterface(), m_NextTimer), + m_SystemTimer(*this), m_bCleanFrameBox(true), m_RspBroke(true), m_DMAUsed(false), diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index b85bfb048..1be2ca228 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -11381,10 +11381,29 @@ void CX86RecompilerOps::SW_Register(CX86Ops::x86Reg Reg, uint32_t VAddr) m_Assembler.MoveX86regToVariable(Reg, PAddr + g_MMU->Rdram(), VarName); break; default: - m_CodeBlock.Log(" should be moving %s in to %08X ?", CX86Ops::x86_Name(Reg), VAddr); - if (BreakOnUnhandledMemory()) + if (PAddr >= 0x10000000 && PAddr < 0x20000000) { - g_Notify->BreakPoint(__FILE__, __LINE__); + m_RegWorkingSet.BeforeCallDirect(); + m_Assembler.PushImm32(0xFFFFFFFF); + m_Assembler.Push(Reg); + m_Assembler.PushImm32(PAddr); +#ifdef _MSC_VER + m_Assembler.MoveConstToX86reg((uint32_t)(MemoryHandler *)&g_MMU->m_RomMemoryHandler, CX86Ops::x86_ECX); + m_Assembler.Call_Direct((void *)((long**)(MemoryHandler *)&g_MMU->m_RomMemoryHandler)[0][1], "RomMemoryHandler::Write32"); +#else + m_Assembler.PushImm32((uint32_t)&g_MMU->m_RomMemoryHandler); + m_Assembler.Call_Direct(AddressOf(&RomMemoryHandler::Write32), "RomMemoryHandler::Write32"); + m_Assembler.AddConstToX86Reg(CX86Ops::x86_ESP, 16); +#endif + m_RegWorkingSet.AfterCallDirect(); + } + else + { + m_CodeBlock.Log(" should be moving %s in to %08X ?", CX86Ops::x86_Name(Reg), VAddr); + if (BreakOnUnhandledMemory()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } } } }