Core: pause on panic handler option

This commit is contained in:
dreamsyntax 2022-04-17 00:15:12 -07:00
parent 23902f99ae
commit 78c6819f5e
11 changed files with 41 additions and 1 deletions

View File

@ -168,6 +168,7 @@ const Info<bool> MAIN_WIIMOTE_ENABLE_SPEAKER{{System::Main, "Core", "WiimoteEnab
const Info<bool> MAIN_CONNECT_WIIMOTES_FOR_CONTROLLER_INTERFACE{ const Info<bool> MAIN_CONNECT_WIIMOTES_FOR_CONTROLLER_INTERFACE{
{System::Main, "Core", "WiimoteControllerInterface"}, false}; {System::Main, "Core", "WiimoteControllerInterface"}, false};
const Info<bool> MAIN_MMU{{System::Main, "Core", "MMU"}, false}; const Info<bool> MAIN_MMU{{System::Main, "Core", "MMU"}, false};
const Info<bool> MAIN_PAUSE_ON_PANIC{{System::Main, "Core", "PauseOnPanic"}, false};
const Info<int> MAIN_BB_DUMP_PORT{{System::Main, "Core", "BBDumpPort"}, -1}; const Info<int> MAIN_BB_DUMP_PORT{{System::Main, "Core", "BBDumpPort"}, -1};
const Info<bool> MAIN_SYNC_GPU{{System::Main, "Core", "SyncGPU"}, false}; const Info<bool> MAIN_SYNC_GPU{{System::Main, "Core", "SyncGPU"}, false};
const Info<int> MAIN_SYNC_GPU_MAX_DISTANCE{{System::Main, "Core", "SyncGpuMaxDistance"}, 200000}; const Info<int> MAIN_SYNC_GPU_MAX_DISTANCE{{System::Main, "Core", "SyncGpuMaxDistance"}, 200000};

View File

@ -98,6 +98,7 @@ extern const Info<bool> MAIN_WIIMOTE_CONTINUOUS_SCANNING;
extern const Info<bool> MAIN_WIIMOTE_ENABLE_SPEAKER; extern const Info<bool> MAIN_WIIMOTE_ENABLE_SPEAKER;
extern const Info<bool> MAIN_CONNECT_WIIMOTES_FOR_CONTROLLER_INTERFACE; extern const Info<bool> MAIN_CONNECT_WIIMOTES_FOR_CONTROLLER_INTERFACE;
extern const Info<bool> MAIN_MMU; extern const Info<bool> MAIN_MMU;
extern const Info<bool> MAIN_PAUSE_ON_PANIC;
extern const Info<int> MAIN_BB_DUMP_PORT; extern const Info<int> MAIN_BB_DUMP_PORT;
extern const Info<bool> MAIN_SYNC_GPU; extern const Info<bool> MAIN_SYNC_GPU;
extern const Info<int> MAIN_SYNC_GPU_MAX_DISTANCE; extern const Info<int> MAIN_SYNC_GPU_MAX_DISTANCE;

View File

@ -124,6 +124,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
&Config::GetInfoForSIDevice(3).GetLocation(), &Config::GetInfoForSIDevice(3).GetLocation(),
&Config::MAIN_CPU_THREAD.GetLocation(), &Config::MAIN_CPU_THREAD.GetLocation(),
&Config::MAIN_MMU.GetLocation(), &Config::MAIN_MMU.GetLocation(),
&Config::MAIN_PAUSE_ON_PANIC.GetLocation(),
&Config::MAIN_BB_DUMP_PORT.GetLocation(), &Config::MAIN_BB_DUMP_PORT.GetLocation(),
&Config::MAIN_SYNC_GPU.GetLocation(), &Config::MAIN_SYNC_GPU.GetLocation(),
&Config::MAIN_SYNC_GPU_MAX_DISTANCE.GetLocation(), &Config::MAIN_SYNC_GPU_MAX_DISTANCE.GetLocation(),

View File

@ -24,6 +24,7 @@
#include "Core/PowerPC/MMU.h" #include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PPCTables.h" #include "Core/PowerPC/PPCTables.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
namespace namespace
{ {
@ -341,6 +342,8 @@ void Interpreter::unknown_instruction(UGeckoInstruction inst)
ASSERT_MSG(POWERPC, 0, ASSERT_MSG(POWERPC, 0,
"\nIntCPU: Unknown instruction {:08x} at PC = {:08x} last_PC = {:08x} LR = {:08x}\n", "\nIntCPU: Unknown instruction {:08x} at PC = {:08x} last_PC = {:08x} LR = {:08x}\n",
inst.hex, PC, last_pc, LR); inst.hex, PC, last_pc, LR);
if (Core::System::GetInstance().IsPauseOnPanicMode())
CPU::Break();
} }
void Interpreter::ClearCache() void Interpreter::ClearCache()

View File

@ -57,6 +57,8 @@ void JitBase::RefreshConfig()
m_accurate_nans = Config::Get(Config::MAIN_ACCURATE_NANS); m_accurate_nans = Config::Get(Config::MAIN_ACCURATE_NANS);
m_fastmem_enabled = Config::Get(Config::MAIN_FASTMEM); m_fastmem_enabled = Config::Get(Config::MAIN_FASTMEM);
m_mmu_enabled = Core::System::GetInstance().IsMMUMode(); m_mmu_enabled = Core::System::GetInstance().IsMMUMode();
m_pause_on_panic_enabled = Core::System::GetInstance().IsPauseOnPanicMode();
analyzer.SetDebuggingEnabled(m_enable_debugging); analyzer.SetDebuggingEnabled(m_enable_debugging);
analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH)); analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH));
analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions); analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions);
@ -82,7 +84,7 @@ void JitBase::UpdateMemoryAndExceptionOptions()
{ {
bool any_watchpoints = PowerPC::memchecks.HasAny(); bool any_watchpoints = PowerPC::memchecks.HasAny();
jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (MSR.DR || !any_watchpoints); jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (MSR.DR || !any_watchpoints);
jo.memcheck = m_mmu_enabled || any_watchpoints; jo.memcheck = m_mmu_enabled || m_pause_on_panic_enabled || any_watchpoints;
jo.fp_exceptions = m_enable_float_exceptions; jo.fp_exceptions = m_enable_float_exceptions;
jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions; jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions;
} }

View File

@ -134,6 +134,7 @@ protected:
bool m_accurate_nans = false; bool m_accurate_nans = false;
bool m_fastmem_enabled = false; bool m_fastmem_enabled = false;
bool m_mmu_enabled = false; bool m_mmu_enabled = false;
bool m_pause_on_panic_enabled = false;
void RefreshConfig(); void RefreshConfig();

View File

@ -244,6 +244,11 @@ static T ReadFromHardware(u32 em_address)
} }
PanicAlertFmt("Unable to resolve read address {:x} PC {:x}", em_address, PC); PanicAlertFmt("Unable to resolve read address {:x} PC {:x}", em_address, PC);
if (Core::System::GetInstance().IsPauseOnPanicMode())
{
CPU::Break();
ppcState.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
}
return 0; return 0;
} }
@ -406,6 +411,11 @@ static void WriteToHardware(u32 em_address, const u32 data, const u32 size)
} }
PanicAlertFmt("Unable to resolve write address {:x} PC {:x}", em_address, PC); PanicAlertFmt("Unable to resolve write address {:x} PC {:x}", em_address, PC);
if (Core::System::GetInstance().IsPauseOnPanicMode())
{
CPU::Break();
ppcState.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
}
} }
// ===================== // =====================
@ -1148,6 +1158,11 @@ static void GenerateDSIException(u32 effective_address, bool write)
{ {
PanicAlertFmt("Invalid {} {:#010x}, PC = {:#010x}", write ? "write to" : "read from", PanicAlertFmt("Invalid {} {:#010x}, PC = {:#010x}", write ? "write to" : "read from",
effective_address, PC); effective_address, PC);
if (Core::System::GetInstance().IsPauseOnPanicMode())
{
CPU::Break();
ppcState.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
}
return; return;
} }

View File

@ -27,6 +27,7 @@ void System::Initialize()
{ {
m_separate_cpu_and_gpu_threads = Config::Get(Config::MAIN_CPU_THREAD); m_separate_cpu_and_gpu_threads = Config::Get(Config::MAIN_CPU_THREAD);
m_mmu_enabled = Config::Get(Config::MAIN_MMU); m_mmu_enabled = Config::Get(Config::MAIN_MMU);
m_pause_on_panic_enabled = Config::Get(Config::MAIN_PAUSE_ON_PANIC);
} }
SoundStream* System::GetSoundStream() const SoundStream* System::GetSoundStream() const

View File

@ -32,6 +32,7 @@ public:
bool IsDualCoreMode() const { return m_separate_cpu_and_gpu_threads; } bool IsDualCoreMode() const { return m_separate_cpu_and_gpu_threads; }
bool IsMMUMode() const { return m_mmu_enabled; } bool IsMMUMode() const { return m_mmu_enabled; }
bool IsPauseOnPanicMode() const { return m_pause_on_panic_enabled; }
SoundStream* GetSoundStream() const; SoundStream* GetSoundStream() const;
void SetSoundStream(std::unique_ptr<SoundStream> sound_stream); void SetSoundStream(std::unique_ptr<SoundStream> sound_stream);
@ -48,5 +49,6 @@ private:
bool m_separate_cpu_and_gpu_threads = false; bool m_separate_cpu_and_gpu_threads = false;
bool m_mmu_enabled = false; bool m_mmu_enabled = false;
bool m_pause_on_panic_enabled = false;
}; };
} // namespace Core } // namespace Core

View File

@ -68,6 +68,12 @@ void AdvancedPane::CreateLayout()
"Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = Fast)")); "Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = Fast)"));
cpu_options_group_layout->addWidget(m_enable_mmu_checkbox); cpu_options_group_layout->addWidget(m_enable_mmu_checkbox);
m_pause_on_panic_checkbox = new QCheckBox(tr("Pause on Panic"));
m_pause_on_panic_checkbox->setToolTip(
tr("Pauses the emulation if a Read/Write or Unknown Instruction panic occurs.\nEnabling will "
"affect performance.\nThe performance impact is the same as having Enable MMU on."));
cpu_options_group_layout->addWidget(m_pause_on_panic_checkbox);
auto* clock_override = new QGroupBox(tr("Clock Override")); auto* clock_override = new QGroupBox(tr("Clock Override"));
auto* clock_override_layout = new QVBoxLayout(); auto* clock_override_layout = new QVBoxLayout();
clock_override->setLayout(clock_override_layout); clock_override->setLayout(clock_override_layout);
@ -180,6 +186,9 @@ void AdvancedPane::ConnectLayout()
connect(m_enable_mmu_checkbox, &QCheckBox::toggled, this, connect(m_enable_mmu_checkbox, &QCheckBox::toggled, this,
[](bool checked) { Config::SetBaseOrCurrent(Config::MAIN_MMU, checked); }); [](bool checked) { Config::SetBaseOrCurrent(Config::MAIN_MMU, checked); });
connect(m_pause_on_panic_checkbox, &QCheckBox::toggled, this,
[](bool checked) { Config::SetBaseOrCurrent(Config::MAIN_PAUSE_ON_PANIC, checked); });
m_cpu_clock_override_checkbox->setChecked(Config::Get(Config::MAIN_OVERCLOCK_ENABLE)); m_cpu_clock_override_checkbox->setChecked(Config::Get(Config::MAIN_OVERCLOCK_ENABLE));
connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) { connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) {
Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK_ENABLE, enable_clock_override); Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK_ENABLE, enable_clock_override);
@ -246,6 +255,9 @@ void AdvancedPane::Update()
m_enable_mmu_checkbox->setChecked(Config::Get(Config::MAIN_MMU)); m_enable_mmu_checkbox->setChecked(Config::Get(Config::MAIN_MMU));
m_enable_mmu_checkbox->setEnabled(!running); m_enable_mmu_checkbox->setEnabled(!running);
m_pause_on_panic_checkbox->setChecked(Config::Get(Config::MAIN_PAUSE_ON_PANIC));
m_pause_on_panic_checkbox->setEnabled(!running);
QFont bf = font(); QFont bf = font();
bf.setBold(Config::GetActiveLayerForConfig(Config::MAIN_OVERCLOCK_ENABLE) != bf.setBold(Config::GetActiveLayerForConfig(Config::MAIN_OVERCLOCK_ENABLE) !=
Config::LayerType::Base); Config::LayerType::Base);

View File

@ -32,6 +32,7 @@ private:
QComboBox* m_cpu_emulation_engine_combobox; QComboBox* m_cpu_emulation_engine_combobox;
QCheckBox* m_enable_mmu_checkbox; QCheckBox* m_enable_mmu_checkbox;
QCheckBox* m_pause_on_panic_checkbox;
QCheckBox* m_cpu_clock_override_checkbox; QCheckBox* m_cpu_clock_override_checkbox;
QSlider* m_cpu_clock_override_slider; QSlider* m_cpu_clock_override_slider;
QLabel* m_cpu_clock_override_slider_label; QLabel* m_cpu_clock_override_slider_label;