From 23c1007aa04322def05cf80a37e8c2ff0b98d0d9 Mon Sep 17 00:00:00 2001 From: Azimer Date: Tue, 17 Oct 2017 21:38:38 -0500 Subject: [PATCH 1/4] Randomize PI and SI DMA timing This should help with randomization while FAT is on. --- Source/Project64-core/3rdParty/Random.cpp | 48 +++++++++++++++++++ Source/Project64-core/3rdParty/Random.h | 31 ++++++++++++ Source/Project64-core/N64System/Mips/Dma.cpp | 8 ++-- .../Project64-core/N64System/Mips/PifRam.cpp | 9 ++-- Source/Project64-core/N64System/N64Class.cpp | 3 ++ Source/Project64-core/N64System/N64Class.h | 2 + .../Project64-core/N64System/SystemGlobals.h | 5 +- Source/Project64-core/Project64-core.vcxproj | 2 + .../Project64-core.vcxproj.filters | 6 +++ 9 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 Source/Project64-core/3rdParty/Random.cpp create mode 100644 Source/Project64-core/3rdParty/Random.h diff --git a/Source/Project64-core/3rdParty/Random.cpp b/Source/Project64-core/3rdParty/Random.cpp new file mode 100644 index 000000000..3209cf6db --- /dev/null +++ b/Source/Project64-core/3rdParty/Random.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2017 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +/* + * Implements the CRandom class. + * + * This class implements the Lehmer Random Number Generator. + * + */ + +#include "Random.h" +#include + +CRandom::CRandom() +{ + state = (uint32_t)time(NULL); +} + +CRandom::CRandom(uint32_t seed_value) +{ + state = seed_value; +} + +uint32_t randomizer(uint32_t val) +{ + return ((uint64_t)val * 279470273UL) % 4294967291UL; +} + +uint32_t CRandom::next() +{ + state = randomizer(state); + return state; +} + +void CRandom::seed(uint32_t seed_value) +{ + if (seed_value == 0) + state == 1; + else + state = seed_value; +} diff --git a/Source/Project64-core/3rdParty/Random.h b/Source/Project64-core/3rdParty/Random.h new file mode 100644 index 000000000..439f06a7f --- /dev/null +++ b/Source/Project64-core/3rdParty/Random.h @@ -0,0 +1,31 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2017 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +/* + * Defines the CRandom class. + * + * This class implements the Lehmer Random Number Generator. + * + */ + +#include + +class CRandom +{ +public: + CRandom(); + CRandom(uint32_t seed_value); + uint32_t next(); + void seed(uint32_t seed_value); + +protected: + uint32_t randomizer(uint32_t val); + uint32_t state; +}; diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index abfa03ab3..b5eb0ad54 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -458,9 +458,11 @@ void CDMA::PI_DMA_WRITE() { g_Recompiler->ClearRecompCode_Phys(g_Reg->PI_DRAM_ADDR_REG, g_Reg->PI_WR_LEN_REG, CRecompiler::Remove_DMA); } - g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; - g_Reg->MI_INTR_REG |= MI_INTR_PI; - g_Reg->CheckInterrupts(); + g_SystemTimer->SetTimer(g_SystemTimer->PiTimer, PI_WR_LEN_REG/8 + (g_Random->next() % 0x40), false); + + //g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + //g_Reg->MI_INTR_REG |= MI_INTR_PI; + //g_Reg->CheckInterrupts(); //ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9) + 50); //ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN_REG * 8.9)); return; diff --git a/Source/Project64-core/N64System/Mips/PifRam.cpp b/Source/Project64-core/N64System/Mips/PifRam.cpp index 8b4ba49d7..9583070f4 100644 --- a/Source/Project64-core/N64System/Mips/PifRam.cpp +++ b/Source/Project64-core/N64System/Mips/PifRam.cpp @@ -358,13 +358,14 @@ void CPifRam::SI_DMA_READ() if (g_System->bDelaySI()) { - g_SystemTimer->SetTimer(CSystemTimer::SiTimer, 0x900, false); + g_SystemTimer->SetTimer(CSystemTimer::SiTimer, 0x900 + (g_Random->next() % 0x40), false); } else { - g_Reg->MI_INTR_REG |= MI_INTR_SI; - g_Reg->SI_STATUS_REG |= SI_STATUS_INTERRUPT; - g_Reg->CheckInterrupts(); + g_SystemTimer->SetTimer(CSystemTimer::SiTimer, g_Random->next() % 0x40, false); + //g_Reg->MI_INTR_REG |= MI_INTR_SI; + //g_Reg->SI_STATUS_REG |= SI_STATUS_INTERRUPT; + //g_Reg->CheckInterrupts(); } } diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index 2f56f5221..ac275402d 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -716,6 +716,7 @@ void CN64System::Reset(bool bInitReg, bool ClearMenory) m_SyncCPU->Reset(bInitReg, ClearMenory); } g_Settings->SaveBool(GameRunning_InReset, true); + WriteTrace(TraceN64System, TraceDebug, "Done"); } @@ -763,6 +764,7 @@ bool CN64System::SetActiveSystem(bool bActive) R4300iOp::m_TestTimer = m_TestTimer; R4300iOp::m_NextInstruction = m_NextInstruction; R4300iOp::m_JumpToLocation = m_JumpToLocation; + g_Random = &m_Random; } else { @@ -782,6 +784,7 @@ bool CN64System::SetActiveSystem(bool bActive) g_Plugins = m_Plugins; g_TLBLoadAddress = NULL; g_TLBStoreAddress = NULL; + g_Random = NULL; } } diff --git a/Source/Project64-core/N64System/N64Class.h b/Source/Project64-core/N64System/N64Class.h index 63d04d1b7..c4326b01c 100644 --- a/Source/Project64-core/N64System/N64Class.h +++ b/Source/Project64-core/N64System/N64Class.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "Mips/TLBClass.h" #include "CheatClass.h" @@ -164,6 +165,7 @@ private: uint32_t m_SyncCount; bool m_SyncCpu; bool m_CheatsSlectionChanged; + CRandom m_Random; //When Syncing cores this is the PC where it last Sync'ed correctly uint32_t m_LastSuccessSyncPC[10]; diff --git a/Source/Project64-core/N64System/SystemGlobals.h b/Source/Project64-core/N64System/SystemGlobals.h index 3ebbff683..b1bfd0521 100644 --- a/Source/Project64-core/N64System/SystemGlobals.h +++ b/Source/Project64-core/N64System/SystemGlobals.h @@ -62,4 +62,7 @@ extern CDebugger * g_Debugger; extern uint8_t ** g_RecompPos; class CMempak; -extern CMempak * g_Mempak; \ No newline at end of file +extern CMempak * g_Mempak; + +class CRandom; +extern CRandom * g_Random; diff --git a/Source/Project64-core/Project64-core.vcxproj b/Source/Project64-core/Project64-core.vcxproj index 412d6fedc..9cbfef092 100644 --- a/Source/Project64-core/Project64-core.vcxproj +++ b/Source/Project64-core/Project64-core.vcxproj @@ -35,6 +35,7 @@ NotUsing + @@ -126,6 +127,7 @@ + diff --git a/Source/Project64-core/Project64-core.vcxproj.filters b/Source/Project64-core/Project64-core.vcxproj.filters index f3f9f6b9b..44f537ba3 100644 --- a/Source/Project64-core/Project64-core.vcxproj.filters +++ b/Source/Project64-core/Project64-core.vcxproj.filters @@ -339,6 +339,9 @@ Source Files\N64 System\Recompiler\Arm + + Source Files\3rd Party + @@ -659,6 +662,9 @@ Header Files + + Header Files\3rd Party + From 1b8d0324175a2e7a4ab17655c7771c8f82c6b069 Mon Sep 17 00:00:00 2001 From: Azimer Date: Tue, 17 Oct 2017 22:52:07 -0500 Subject: [PATCH 2/4] Bug fixes and requests * Moved to CRandom to Common lib * Initialized CRandom with a time seed in CN64System constructor * Added CRandom::state getters and setters to support saved states --- Source/Common/Common.vcxproj | 2 ++ Source/Common/Common.vcxproj.filters | 6 ++++++ .../3rdParty => Common}/Random.cpp | 20 ++++++++++++------- .../3rdParty => Common}/Random.h | 5 +++-- Source/Project64-core/N64System/N64Class.cpp | 3 ++- Source/Project64-core/N64System/N64Class.h | 2 +- .../N64System/SystemGlobals.cpp | 1 + Source/Project64-core/Project64-core.vcxproj | 2 -- .../Project64-core.vcxproj.filters | 6 ------ 9 files changed, 28 insertions(+), 19 deletions(-) rename Source/{Project64-core/3rdParty => Common}/Random.cpp (79%) rename Source/{Project64-core/3rdParty => Common}/Random.h (93%) diff --git a/Source/Common/Common.vcxproj b/Source/Common/Common.vcxproj index 4ce014430..e8ba6cbe8 100644 --- a/Source/Common/Common.vcxproj +++ b/Source/Common/Common.vcxproj @@ -43,6 +43,7 @@ + Create @@ -64,6 +65,7 @@ + diff --git a/Source/Common/Common.vcxproj.filters b/Source/Common/Common.vcxproj.filters index 437d0328f..69caab164 100644 --- a/Source/Common/Common.vcxproj.filters +++ b/Source/Common/Common.vcxproj.filters @@ -62,6 +62,9 @@ Source Files + + Source Files + @@ -124,5 +127,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/Source/Project64-core/3rdParty/Random.cpp b/Source/Common/Random.cpp similarity index 79% rename from Source/Project64-core/3rdParty/Random.cpp rename to Source/Common/Random.cpp index 3209cf6db..a46f8887c 100644 --- a/Source/Project64-core/3rdParty/Random.cpp +++ b/Source/Common/Random.cpp @@ -15,6 +15,7 @@ * */ +#include "stdafx.h" #include "Random.h" #include @@ -23,12 +24,12 @@ CRandom::CRandom() state = (uint32_t)time(NULL); } -CRandom::CRandom(uint32_t seed_value) +CRandom::CRandom(uint32_t state_value) { - state = seed_value; + state = state_value; } -uint32_t randomizer(uint32_t val) +uint32_t CRandom::randomizer(uint32_t val) { return ((uint64_t)val * 279470273UL) % 4294967291UL; } @@ -39,10 +40,15 @@ uint32_t CRandom::next() return state; } -void CRandom::seed(uint32_t seed_value) +void CRandom::set_state(uint32_t state_value) { - if (seed_value == 0) - state == 1; + if (state_value == 0) + state = 1; else - state = seed_value; + state = state_value; +} + +uint32_t CRandom::get_state() +{ + return state; } diff --git a/Source/Project64-core/3rdParty/Random.h b/Source/Common/Random.h similarity index 93% rename from Source/Project64-core/3rdParty/Random.h rename to Source/Common/Random.h index 439f06a7f..1a599a47c 100644 --- a/Source/Project64-core/3rdParty/Random.h +++ b/Source/Common/Random.h @@ -14,7 +14,7 @@ * This class implements the Lehmer Random Number Generator. * */ - +#pragma once #include class CRandom @@ -23,7 +23,8 @@ public: CRandom(); CRandom(uint32_t seed_value); uint32_t next(); - void seed(uint32_t seed_value); + uint32_t get_state(); + void set_state(uint32_t state_value); protected: uint32_t randomizer(uint32_t val); diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index ac275402d..c2d649ee9 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -57,7 +57,8 @@ CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) m_thread(NULL), m_hPauseEvent(true), m_CheatsSlectionChanged(false), - m_SyncCpu(SyncSystem) + m_SyncCpu(SyncSystem), + m_Random((uint32_t)time(NULL)) { WriteTrace(TraceN64System, TraceDebug, "Start"); memset(m_LastSuccessSyncPC, 0, sizeof(m_LastSuccessSyncPC)); diff --git a/Source/Project64-core/N64System/N64Class.h b/Source/Project64-core/N64System/N64Class.h index c4326b01c..85ae9796c 100644 --- a/Source/Project64-core/N64System/N64Class.h +++ b/Source/Project64-core/N64System/N64Class.h @@ -10,6 +10,7 @@ ****************************************************************************/ #pragma once +#include #include #include #include @@ -23,7 +24,6 @@ #include #include #include -#include #include "Mips/TLBClass.h" #include "CheatClass.h" diff --git a/Source/Project64-core/N64System/SystemGlobals.cpp b/Source/Project64-core/N64System/SystemGlobals.cpp index d6e058b1c..84552337b 100644 --- a/Source/Project64-core/N64System/SystemGlobals.cpp +++ b/Source/Project64-core/N64System/SystemGlobals.cpp @@ -32,5 +32,6 @@ uint32_t * g_TLBStoreAddress = NULL; CDebugger * g_Debugger = NULL; uint8_t ** g_RecompPos = NULL; CMempak * g_Mempak = NULL; +CRandom * g_Random = NULL; int * g_NextTimer; \ No newline at end of file diff --git a/Source/Project64-core/Project64-core.vcxproj b/Source/Project64-core/Project64-core.vcxproj index 9cbfef092..412d6fedc 100644 --- a/Source/Project64-core/Project64-core.vcxproj +++ b/Source/Project64-core/Project64-core.vcxproj @@ -35,7 +35,6 @@ NotUsing - @@ -127,7 +126,6 @@ - diff --git a/Source/Project64-core/Project64-core.vcxproj.filters b/Source/Project64-core/Project64-core.vcxproj.filters index 44f537ba3..f3f9f6b9b 100644 --- a/Source/Project64-core/Project64-core.vcxproj.filters +++ b/Source/Project64-core/Project64-core.vcxproj.filters @@ -339,9 +339,6 @@ Source Files\N64 System\Recompiler\Arm - - Source Files\3rd Party - @@ -662,9 +659,6 @@ Header Files - - Header Files\3rd Party - From 958f11cc6dbc66fc49182b86c24b9649eef21ce4 Mon Sep 17 00:00:00 2001 From: Azimer Date: Wed, 18 Oct 2017 00:05:38 -0500 Subject: [PATCH 3/4] Fixed random state with SyncCPU --- Source/Project64-core/N64System/N64Class.cpp | 8 ++++---- Source/Project64-core/N64System/N64Class.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index c2d649ee9..d3190edfc 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -30,7 +30,7 @@ #pragma warning(disable:4355) // Disable 'this' : used in base member initializer list -CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) : +CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesReadOnly, bool SyncSystem) : CSystemEvents(this, Plugins), m_EndEmulation(false), m_SaveUsing((SAVE_CHIP_TYPE)g_Settings->LoadDword(Game_SaveChip)), @@ -58,7 +58,7 @@ CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) m_hPauseEvent(true), m_CheatsSlectionChanged(false), m_SyncCpu(SyncSystem), - m_Random((uint32_t)time(NULL)) + m_Random(randomizer_seed) { WriteTrace(TraceN64System, TraceDebug, "Start"); memset(m_LastSuccessSyncPC, 0, sizeof(m_LastSuccessSyncPC)); @@ -111,7 +111,7 @@ CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) g_Plugins->CopyPlugins(g_Settings->LoadStringVal(Directory_PluginSync)); m_SyncPlugins = new CPlugins(Directory_PluginSync, true); m_SyncPlugins->SetRenderWindows(g_Plugins->SyncWindow(), NULL); - m_SyncCPU = new CN64System(m_SyncPlugins, true, true); + m_SyncCPU = new CN64System(m_SyncPlugins, randomizer_seed, true, true); } Reset(true, true); @@ -360,7 +360,7 @@ bool CN64System::RunFileImage(const char * FileLoc) void CN64System::RunLoadedImage(void) { WriteTrace(TraceN64System, TraceDebug, "Start"); - g_BaseSystem = new CN64System(g_Plugins, false, false); + g_BaseSystem = new CN64System(g_Plugins, (uint32_t)time(NULL), false, false); if (g_BaseSystem) { g_BaseSystem->StartEmulation(true); diff --git a/Source/Project64-core/N64System/N64Class.h b/Source/Project64-core/N64System/N64Class.h index 85ae9796c..909cc0732 100644 --- a/Source/Project64-core/N64System/N64Class.h +++ b/Source/Project64-core/N64System/N64Class.h @@ -49,7 +49,7 @@ class CN64System : protected CDebugSettings { public: - CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem); + CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesReadOnly, bool SyncSystem); virtual ~CN64System(void); CCheats m_Cheats; From 44f8a82c875246656364c1b40c25816bf19578bb Mon Sep 17 00:00:00 2001 From: Azimer Date: Wed, 18 Oct 2017 00:16:30 -0500 Subject: [PATCH 4/4] Prefix m_ in CRandom class --- Source/Common/Random.cpp | 14 +++++++------- Source/Common/Random.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Common/Random.cpp b/Source/Common/Random.cpp index a46f8887c..54bc07126 100644 --- a/Source/Common/Random.cpp +++ b/Source/Common/Random.cpp @@ -21,12 +21,12 @@ CRandom::CRandom() { - state = (uint32_t)time(NULL); + m_state = (uint32_t)time(NULL); } CRandom::CRandom(uint32_t state_value) { - state = state_value; + m_state = state_value; } uint32_t CRandom::randomizer(uint32_t val) @@ -36,19 +36,19 @@ uint32_t CRandom::randomizer(uint32_t val) uint32_t CRandom::next() { - state = randomizer(state); - return state; + m_state = randomizer(m_state); + return m_state; } void CRandom::set_state(uint32_t state_value) { if (state_value == 0) - state = 1; + m_state = 1; else - state = state_value; + m_state = state_value; } uint32_t CRandom::get_state() { - return state; + return m_state; } diff --git a/Source/Common/Random.h b/Source/Common/Random.h index 1a599a47c..aeb33536a 100644 --- a/Source/Common/Random.h +++ b/Source/Common/Random.h @@ -28,5 +28,5 @@ public: protected: uint32_t randomizer(uint32_t val); - uint32_t state; + uint32_t m_state; };