Core: Add rom write decay and some code clean up

This commit is contained in:
zilmar 2022-08-22 12:47:44 +09:30
parent 4b0966a264
commit 9b16d29792
9 changed files with 81 additions and 48 deletions

View File

@ -3,12 +3,12 @@
#include <Project64-core/N64System/N64Types.h>
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);

View File

@ -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;

View File

@ -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;

View File

@ -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&);

View File

@ -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();

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <Project64-core/N64System/N64System.h>
#include <Project64-core/N64System/Mips/SystemTiming.h>
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Mips/Register.h>
@ -7,13 +8,15 @@
#include <Project64-core/N64System/MemoryHandler/AudioInterfaceHandler.h>
#include <Project64-core/3rdParty/zip.h>
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);
}

View File

@ -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;
};

View File

@ -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),

View File

@ -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__);
}
}
}
}