Reconcile debugger and save state stuff into a single implementation.

Fixes #497 and fixes #496.
Still rough edges, but at least less duplication.
This commit is contained in:
Ben Vanik
2016-01-18 11:48:21 -08:00
parent ca135eb0e7
commit 6777ce6668
51 changed files with 1687 additions and 2250 deletions

View File

@@ -48,11 +48,6 @@ Emulator::Emulator(const std::wstring& command_line)
Emulator::~Emulator() {
// Note that we delete things in the reverse order they were initialized.
if (debugger_) {
// Kill the debugger first, so that we don't have it messing with things.
debugger_->StopSession();
}
// Give the systems time to shutdown before we delete them.
if (graphics_system_) {
graphics_system_->Shutdown();
@@ -70,8 +65,6 @@ Emulator::~Emulator() {
processor_.reset();
debugger_.reset();
export_resolver_.reset();
ExceptionHandler::Uninstall(Emulator::ExceptionCallbackThunk, this);
@@ -110,17 +103,9 @@ X_STATUS Emulator::Setup(
// Shared export resolver used to attach and query for HLE exports.
export_resolver_ = std::make_unique<xe::cpu::ExportResolver>();
if (FLAGS_debug) {
// Debugger first, as other parts hook into it.
debugger_.reset(new debug::Debugger(this));
// Create debugger first. Other types hook up to it.
debugger_->StartSession();
}
// Initialize the CPU.
processor_ = std::make_unique<xe::cpu::Processor>(
this, memory_.get(), export_resolver_.get(), debugger_.get());
processor_ = std::make_unique<xe::cpu::Processor>(memory_.get(),
export_resolver_.get());
if (!processor_->Setup()) {
return X_STATUS_UNSUCCESSFUL;
}
@@ -361,6 +346,7 @@ bool Emulator::SaveToFile(const std::wstring& path) {
// It's important we don't hold the global lock here! XThreads need to step
// forward (possibly through guarded regions) without worry!
processor_->Save(&stream);
graphics_system_->Save(&stream);
audio_system_->Save(&stream);
kernel_state_->Save(&stream);
@@ -390,6 +376,10 @@ bool Emulator::RestoreFromFile(const std::wstring& path) {
return false;
}
if (!processor_->Restore(&stream)) {
XELOGE("Could not restore processor!");
return false;
}
if (!graphics_system_->Restore(&stream)) {
XELOGE("Could not restore graphics system!");
return false;
@@ -435,15 +425,14 @@ bool Emulator::ExceptionCallback(Exception* ex) {
auto code_base = code_cache->base_address();
auto code_end = code_base + code_cache->total_size();
if (!debugger() ||
(!debugger()->is_attached() && debugging::IsDebuggerAttached())) {
if (!processor()->is_debugger_attached() && debugging::IsDebuggerAttached()) {
// If Xenia's debugger isn't attached but another one is, pass it to that
// debugger.
return false;
} else if (debugger() && debugger()->is_attached()) {
} else if (processor()->is_debugger_attached()) {
// Let the debugger handle this exception. It may decide to continue past it
// (if it was a stepping breakpoint, etc).
return debugger()->OnUnhandledException(ex);
return processor()->OnUnhandledException(ex);
}
if (!(ex->pc() >= code_base && ex->pc() < code_end)) {