Merge pull request #437 from Kingcom/DebugMode

Replace OnCpuStepped signal
This commit is contained in:
Tony Wasserka 2015-01-11 21:28:18 +01:00
commit f1080de47d
9 changed files with 60 additions and 15 deletions

View file

@ -40,18 +40,35 @@ void EmuThread::SetFilename(std::string filename)
void EmuThread::run()
{
stop_run = false;
// holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the
// next execution step
bool was_active = false;
while (!stop_run)
{
if (cpu_running)
{
if (!was_active)
emit DebugModeLeft();
Core::RunLoop();
was_active = cpu_running || exec_cpu_step;
if (!was_active)
emit DebugModeEntered();
}
else if (exec_cpu_step)
{
if (!was_active)
emit DebugModeLeft();
exec_cpu_step = false;
Core::SingleStep();
emit CPUStepped();
emit DebugModeEntered();
yieldCurrentThread();
was_active = false;
}
}
render_window->moveContext();

View file

@ -81,12 +81,18 @@ private:
signals:
/**
* Emitted when CPU when we've finished processing a single Gekko instruction
* Emitted when the CPU has halted execution
*
* @warning This will only be emitted when the CPU is not running (SetCpuRunning(false))
* @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns)
*/
void CPUStepped();
void DebugModeEntered();
/**
* Emitted right before the CPU continues execution
*
* @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns)
*/
void DebugModeLeft();
};
class GRenderWindow : public QWidget, public EmuWindow

View file

@ -25,7 +25,7 @@ CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent)
ui.treeView->setModel(callstack_model);
}
void CallstackWidget::OnCPUStepped()
void CallstackWidget::OnDebugModeEntered()
{
ARM_Disasm* disasm = new ARM_Disasm();
ARM_Interface* app_core = Core::g_app_core;
@ -71,3 +71,8 @@ void CallstackWidget::OnCPUStepped()
}
}
}
void CallstackWidget::OnDebugModeLeft()
{
}

View file

@ -15,7 +15,8 @@ public:
CallstackWidget(QWidget* parent = 0);
public slots:
void OnCPUStepped();
void OnDebugModeEntered();
void OnDebugModeLeft();
private:
Ui::CallStack ui;

View file

@ -235,7 +235,7 @@ void DisassemblerWidget::OnToggleStartStop()
emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning());
}
void DisassemblerWidget::OnCPUStepped()
void DisassemblerWidget::OnDebugModeEntered()
{
ARMword next_instr = Core::g_app_core->GetPC();
@ -252,6 +252,11 @@ void DisassemblerWidget::OnCPUStepped()
disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
}
void DisassemblerWidget::OnDebugModeLeft()
{
}
int DisassemblerWidget::SelectedRow()
{
QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex();

View file

@ -61,7 +61,8 @@ public slots:
void OnPause();
void OnToggleStartStop();
void OnCPUStepped();
void OnDebugModeEntered();
void OnDebugModeLeft();
private:
// returns -1 if no row is selected

View file

@ -41,7 +41,7 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent)
CSPR->addChild(new QTreeWidgetItem(QStringList("N")));
}
void RegistersWidget::OnCPUStepped()
void RegistersWidget::OnDebugModeEntered()
{
ARM_Interface* app_core = Core::g_app_core;
@ -65,3 +65,8 @@ void RegistersWidget::OnCPUStepped()
CSPR->child(13)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 30) & 0x1)); // Z - Zero
CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than
}
void RegistersWidget::OnDebugModeLeft()
{
}

View file

@ -17,7 +17,8 @@ public:
RegistersWidget(QWidget* parent = NULL);
public slots:
void OnCPUStepped();
void OnDebugModeEntered();
void OnDebugModeLeft();
private:
Ui::ARMRegisters cpu_regs_ui;

View file

@ -124,9 +124,13 @@ GMainWindow::GMainWindow()
connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues
connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), disasmWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), registersWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), callstackWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), registersWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), callstackWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeLeft()), disasmWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection);
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection);
// Setup hotkeys
RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
@ -167,8 +171,8 @@ void GMainWindow::BootGame(std::string filename)
}
disasmWidget->Init();
registersWidget->OnCPUStepped();
callstackWidget->OnCPUStepped();
registersWidget->OnDebugModeEntered();
callstackWidget->OnDebugModeEntered();
render_window->GetEmuThread().SetFilename(filename);
render_window->GetEmuThread().start();