Merge pull request #10175 from dreamsyntax/pause-on-panic

Core/DolphinQt: Add Pause on Panic Option for DSI Exceptions and Unknown Instruction
This commit is contained in:
Admiral H. Curtiss 2022-09-24 20:28:09 +02:00 committed by GitHub
commit 63975556a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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{
{System::Main, "Core", "WiimoteControllerInterface"}, 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<bool> MAIN_SYNC_GPU{{System::Main, "Core", "SyncGPU"}, false};
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_CONNECT_WIIMOTES_FOR_CONTROLLER_INTERFACE;
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<bool> MAIN_SYNC_GPU;
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::MAIN_CPU_THREAD.GetLocation(),
&Config::MAIN_MMU.GetLocation(),
&Config::MAIN_PAUSE_ON_PANIC.GetLocation(),
&Config::MAIN_BB_DUMP_PORT.GetLocation(),
&Config::MAIN_SYNC_GPU.GetLocation(),
&Config::MAIN_SYNC_GPU_MAX_DISTANCE.GetLocation(),

View File

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

View File

@ -57,6 +57,8 @@ void JitBase::RefreshConfig()
m_accurate_nans = Config::Get(Config::MAIN_ACCURATE_NANS);
m_fastmem_enabled = Config::Get(Config::MAIN_FASTMEM);
m_mmu_enabled = Core::System::GetInstance().IsMMUMode();
m_pause_on_panic_enabled = Core::System::GetInstance().IsPauseOnPanicMode();
analyzer.SetDebuggingEnabled(m_enable_debugging);
analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH));
analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions);
@ -82,7 +84,7 @@ void JitBase::UpdateMemoryAndExceptionOptions()
{
bool any_watchpoints = PowerPC::memchecks.HasAny();
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.div_by_zero_exceptions = m_enable_div_by_zero_exceptions;
}

View File

@ -134,6 +134,7 @@ protected:
bool m_accurate_nans = false;
bool m_fastmem_enabled = false;
bool m_mmu_enabled = false;
bool m_pause_on_panic_enabled = false;
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);
if (Core::System::GetInstance().IsPauseOnPanicMode())
{
CPU::Break();
ppcState.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
}
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);
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",
effective_address, PC);
if (Core::System::GetInstance().IsPauseOnPanicMode())
{
CPU::Break();
ppcState.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
}
return;
}

View File

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

View File

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

View File

@ -68,6 +68,12 @@ void AdvancedPane::CreateLayout()
"Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = Fast)"));
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_layout = new QVBoxLayout();
clock_override->setLayout(clock_override_layout);
@ -180,6 +186,9 @@ void AdvancedPane::ConnectLayout()
connect(m_enable_mmu_checkbox, &QCheckBox::toggled, this,
[](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));
connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool 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->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();
bf.setBold(Config::GetActiveLayerForConfig(Config::MAIN_OVERCLOCK_ENABLE) !=
Config::LayerType::Base);

View File

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