Merge pull request #437 from Kingcom/DebugMode
Replace OnCpuStepped signal
This commit is contained in:
commit
f1080de47d
|
@ -40,18 +40,35 @@ void EmuThread::SetFilename(std::string filename)
|
||||||
void EmuThread::run()
|
void EmuThread::run()
|
||||||
{
|
{
|
||||||
stop_run = false;
|
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)
|
while (!stop_run)
|
||||||
{
|
{
|
||||||
if (cpu_running)
|
if (cpu_running)
|
||||||
{
|
{
|
||||||
|
if (!was_active)
|
||||||
|
emit DebugModeLeft();
|
||||||
|
|
||||||
Core::RunLoop();
|
Core::RunLoop();
|
||||||
|
|
||||||
|
was_active = cpu_running || exec_cpu_step;
|
||||||
|
if (!was_active)
|
||||||
|
emit DebugModeEntered();
|
||||||
}
|
}
|
||||||
else if (exec_cpu_step)
|
else if (exec_cpu_step)
|
||||||
{
|
{
|
||||||
|
if (!was_active)
|
||||||
|
emit DebugModeLeft();
|
||||||
|
|
||||||
exec_cpu_step = false;
|
exec_cpu_step = false;
|
||||||
Core::SingleStep();
|
Core::SingleStep();
|
||||||
emit CPUStepped();
|
emit DebugModeEntered();
|
||||||
yieldCurrentThread();
|
yieldCurrentThread();
|
||||||
|
|
||||||
|
was_active = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render_window->moveContext();
|
render_window->moveContext();
|
||||||
|
|
|
@ -81,12 +81,18 @@ private:
|
||||||
|
|
||||||
signals:
|
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)
|
* @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
|
class GRenderWindow : public QWidget, public EmuWindow
|
||||||
|
|
|
@ -25,7 +25,7 @@ CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent)
|
||||||
ui.treeView->setModel(callstack_model);
|
ui.treeView->setModel(callstack_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallstackWidget::OnCPUStepped()
|
void CallstackWidget::OnDebugModeEntered()
|
||||||
{
|
{
|
||||||
ARM_Disasm* disasm = new ARM_Disasm();
|
ARM_Disasm* disasm = new ARM_Disasm();
|
||||||
ARM_Interface* app_core = Core::g_app_core;
|
ARM_Interface* app_core = Core::g_app_core;
|
||||||
|
@ -71,3 +71,8 @@ void CallstackWidget::OnCPUStepped()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallstackWidget::OnDebugModeLeft()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ public:
|
||||||
CallstackWidget(QWidget* parent = 0);
|
CallstackWidget(QWidget* parent = 0);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnCPUStepped();
|
void OnDebugModeEntered();
|
||||||
|
void OnDebugModeLeft();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::CallStack ui;
|
Ui::CallStack ui;
|
||||||
|
|
|
@ -235,7 +235,7 @@ void DisassemblerWidget::OnToggleStartStop()
|
||||||
emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning());
|
emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblerWidget::OnCPUStepped()
|
void DisassemblerWidget::OnDebugModeEntered()
|
||||||
{
|
{
|
||||||
ARMword next_instr = Core::g_app_core->GetPC();
|
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);
|
disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblerWidget::OnDebugModeLeft()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int DisassemblerWidget::SelectedRow()
|
int DisassemblerWidget::SelectedRow()
|
||||||
{
|
{
|
||||||
QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex();
|
QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex();
|
||||||
|
|
|
@ -61,7 +61,8 @@ public slots:
|
||||||
void OnPause();
|
void OnPause();
|
||||||
void OnToggleStartStop();
|
void OnToggleStartStop();
|
||||||
|
|
||||||
void OnCPUStepped();
|
void OnDebugModeEntered();
|
||||||
|
void OnDebugModeLeft();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// returns -1 if no row is selected
|
// returns -1 if no row is selected
|
||||||
|
|
|
@ -41,7 +41,7 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent)
|
||||||
CSPR->addChild(new QTreeWidgetItem(QStringList("N")));
|
CSPR->addChild(new QTreeWidgetItem(QStringList("N")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::OnCPUStepped()
|
void RegistersWidget::OnDebugModeEntered()
|
||||||
{
|
{
|
||||||
ARM_Interface* app_core = Core::g_app_core;
|
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(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
|
CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegistersWidget::OnDebugModeLeft()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ public:
|
||||||
RegistersWidget(QWidget* parent = NULL);
|
RegistersWidget(QWidget* parent = NULL);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnCPUStepped();
|
void OnDebugModeEntered();
|
||||||
|
void OnDebugModeLeft();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ARMRegisters cpu_regs_ui;
|
Ui::ARMRegisters cpu_regs_ui;
|
||||||
|
|
|
@ -124,9 +124,13 @@ GMainWindow::GMainWindow()
|
||||||
connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
|
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
|
// 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(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
|
||||||
connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), registersWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
|
connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), registersWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
|
||||||
connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), callstackWidget, SLOT(OnCPUStepped()), 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
|
// Setup hotkeys
|
||||||
RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
|
RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
|
||||||
|
@ -167,8 +171,8 @@ void GMainWindow::BootGame(std::string filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
disasmWidget->Init();
|
disasmWidget->Init();
|
||||||
registersWidget->OnCPUStepped();
|
registersWidget->OnDebugModeEntered();
|
||||||
callstackWidget->OnCPUStepped();
|
callstackWidget->OnDebugModeEntered();
|
||||||
|
|
||||||
render_window->GetEmuThread().SetFilename(filename);
|
render_window->GetEmuThread().SetFilename(filename);
|
||||||
render_window->GetEmuThread().start();
|
render_window->GetEmuThread().start();
|
||||||
|
|
Reference in New Issue