More Qt changes for debugger
This commit is contained in:
		
							parent
							
								
									564e3f5032
								
							
						
					
					
						commit
						1c7120b3aa
					
				| @ -14,7 +14,7 @@ | |||||||
| #define APP_TITLE       APP_NAME " " APP_VERSION | #define APP_TITLE       APP_NAME " " APP_VERSION | ||||||
| #define COPYRIGHT       "Copyright (C) 2013-2014 Citra Team" | #define COPYRIGHT       "Copyright (C) 2013-2014 Citra Team" | ||||||
| 
 | 
 | ||||||
| EmuThread::EmuThread(GRenderWindow* render_window) : exec_cpu_step(false), cpu_running(true), render_window(render_window) | EmuThread::EmuThread(GRenderWindow* render_window) : exec_cpu_step(false), cpu_running(false), render_window(render_window) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -25,61 +25,23 @@ void EmuThread::SetFilename(const char* filename) | |||||||
| 
 | 
 | ||||||
| void EmuThread::run() | void EmuThread::run() | ||||||
| { | { | ||||||
| 	//u32 tight_loop;
 |  | ||||||
| 
 |  | ||||||
|     NOTICE_LOG(MASTER_LOG, APP_NAME " starting...\n"); |  | ||||||
| 
 |  | ||||||
|     if (Core::Init(/*render_window*/)) { |  | ||||||
| 		ERROR_LOG(MASTER_LOG, "core initialization failed, exiting..."); |  | ||||||
|         Core::Stop(); |  | ||||||
|         exit(1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 	// Load a game or die...
 |  | ||||||
| 	std::string boot_filename = filename; |  | ||||||
| 	std::string error_str; |  | ||||||
| 	bool res = Loader::LoadFile(boot_filename, &error_str); |  | ||||||
| 
 |  | ||||||
| 	if (!res) { |  | ||||||
| 		ERROR_LOG(BOOT, "Failed to load ROM: %s", error_str.c_str()); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Core::Start(); //autoboot for now
 | 	Core::Start(); //autoboot for now
 | ||||||
| 
 | 
 | ||||||
| 	for (int tight_loop = 0; tight_loop < 10000; ++tight_loop) { |     while (true) | ||||||
| 		Core::SingleStep(); |     { | ||||||
| 	} |         for (int tight_loop = 0; tight_loop < 10000; ++tight_loop) | ||||||
| 	/*
 |         { | ||||||
|     while(core::SYS_DIE != core::g_state)  |             if (cpu_running || exec_cpu_step) | ||||||
| 	{ |             { | ||||||
|         if (core::SYS_RUNNING == core::g_state)  |                 if (exec_cpu_step) | ||||||
| 		{ |                     exec_cpu_step = false; | ||||||
|             if(!cpu->is_on)  | 
 | ||||||
| 			{ |                 Core::SingleStep(); | ||||||
| 				cpu->Start(); // Initialize and start CPU.
 |                 emit CPUStepped(); | ||||||
|             } |             } | ||||||
| 			else  |  | ||||||
| 			{ |  | ||||||
|                 for(tight_loop = 0; tight_loop < 10000; ++tight_loop)  |  | ||||||
| 				{ |  | ||||||
|                     if (!cpu_running) |  | ||||||
|                     { |  | ||||||
|                         emit CPUStepped(); |  | ||||||
|                         exec_cpu_step = false; |  | ||||||
|                         cpu->step = true; |  | ||||||
|                         while (!exec_cpu_step && !cpu_running && core::SYS_DIE != core::g_state); |  | ||||||
|                     } |  | ||||||
|                     cpu->execStep(); |  | ||||||
|                     cpu->step = false; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }  |  | ||||||
| 		else if (core::SYS_HALTED == core::g_state)  |  | ||||||
| 		{ |  | ||||||
|             core::Stop(); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 	*/ | 
 | ||||||
|     Core::Stop(); |     Core::Stop(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -40,6 +40,14 @@ public: | |||||||
|      */ |      */ | ||||||
|     void SetCpuRunning(bool running) { cpu_running = running; } |     void SetCpuRunning(bool running) { cpu_running = running; } | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |     * Allow the CPU to continue processing instructions without interruption | ||||||
|  |     * | ||||||
|  |     * @note This function is thread-safe | ||||||
|  |     */ | ||||||
|  |     bool IsCpuRunning() { return cpu_running; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| public slots: | public slots: | ||||||
|     /**
 |     /**
 | ||||||
|      * Stop emulation and wait for the thread to finish. |      * Stop emulation and wait for the thread to finish. | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #include "cpu_regs.hxx" | #include "cpu_regs.hxx" | ||||||
| 
 | 
 | ||||||
| //#include "powerpc/cpu_core_regs.h"
 | #include "core.h" | ||||||
|  | #include "arm/armdefs.h" | ||||||
| 
 | 
 | ||||||
| GARM11RegsView::GARM11RegsView(QWidget* parent) : QDockWidget(parent) | GARM11RegsView::GARM11RegsView(QWidget* parent) : QDockWidget(parent) | ||||||
| { | { | ||||||
| @ -8,57 +9,54 @@ GARM11RegsView::GARM11RegsView(QWidget* parent) : QDockWidget(parent) | |||||||
| 
 | 
 | ||||||
|     tree = cpu_regs_ui.treeWidget; |     tree = cpu_regs_ui.treeWidget; | ||||||
|     tree->addTopLevelItem(registers = new QTreeWidgetItem(QStringList("Registers"))); |     tree->addTopLevelItem(registers = new QTreeWidgetItem(QStringList("Registers"))); | ||||||
| 	tree->addTopLevelItem(CSPR = new QTreeWidgetItem(QStringList("CSPR"))); |     tree->addTopLevelItem(CSPR = new QTreeWidgetItem(QStringList("CSPR"))); | ||||||
| 
 | 
 | ||||||
| 	//const Qt::ItemFlags child_flags = Qt::ItemIsEditable | Qt::ItemIsEnabled;
 |     registers->setExpanded(true); | ||||||
| 	//registers->setFlags(child_flags);
 |     CSPR->setExpanded(true); | ||||||
| 	//CSPR->setFlags(child_flags);
 |  | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i < 16; ++i) |     for (int i = 0; i < 16; ++i) | ||||||
|     { |     { | ||||||
| 		QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString("R[%1]").arg(i, 2, 10, QLatin1Char('0')))); |         QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString("R[%1]").arg(i, 2, 10, QLatin1Char('0')))); | ||||||
|         //child->setFlags(child_flags);
 |  | ||||||
|         registers->addChild(child); |         registers->addChild(child); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("M"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("M"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("T"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("T"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("F"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("F"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("I"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("I"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("A"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("A"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("E"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("E"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("IT"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("IT"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("GE"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("GE"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("DNM"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("DNM"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("J"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("J"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("Q"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("Q"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("V"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("V"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("C"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("C"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("Z"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("Z"))); | ||||||
| 	CSPR->addChild(new QTreeWidgetItem(QStringList("N"))); |     CSPR->addChild(new QTreeWidgetItem(QStringList("N"))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GARM11RegsView::OnCPUStepped() | void GARM11RegsView::OnCPUStepped() | ||||||
| { | { | ||||||
| 	//TODO (Vail) replace values
 |     ARMul_State* state = Core::GetState(); | ||||||
| 	int value = 0; |     for (int i = 0; i < 16; ++i) | ||||||
| 	for (int i = 0; i < 16; ++i) |         registers->child(i)->setText(1, QString("0x%1").arg(state->Reg[i], 8, 16, QLatin1Char('0'))); | ||||||
| 		registers->child(i)->setText(1, QString("0x%1").arg(i, 8, 16, QLatin1Char('0'))); |  | ||||||
| 
 | 
 | ||||||
| 	CSPR->child(0)->setText(1, QString("%1").arg(value)); |     CSPR->setText(1, QString("0x%1").arg(state->Cpsr, 8, 16, QLatin1Char('0'))); | ||||||
| 	CSPR->child(1)->setText(1, QString("%1").arg(value)); |     CSPR->child(0)->setText(1, QString("b%1").arg(state->Cpsr & 0x1F, 5, 2, QLatin1Char('0'))); // M - Mode
 | ||||||
| 	CSPR->child(2)->setText(1, QString("%1").arg(value)); |     CSPR->child(1)->setText(1, QString("%1").arg((state->Cpsr >> 5) & 0x1));	// T - State
 | ||||||
| 	CSPR->child(3)->setText(1, QString("%1").arg(value)); |     CSPR->child(2)->setText(1, QString("%1").arg((state->Cpsr >> 6) & 0x1));	// F - FIQ disable
 | ||||||
| 	CSPR->child(4)->setText(1, QString("%1").arg(value)); |     CSPR->child(3)->setText(1, QString("%1").arg((state->Cpsr >> 7) & 0x1));	// I - IRQ disable
 | ||||||
| 	CSPR->child(5)->setText(1, QString("%1").arg(value)); |     CSPR->child(4)->setText(1, QString("%1").arg((state->Cpsr >> 8) & 0x1));	// A - Imprecise abort
 | ||||||
| 	CSPR->child(6)->setText(1, QString("%1").arg(value)); |     CSPR->child(5)->setText(1, QString("%1").arg((state->Cpsr >> 9) & 0x1));	// E - Data endianess
 | ||||||
| 	CSPR->child(7)->setText(1, QString("%1").arg(value)); |     CSPR->child(6)->setText(1, QString("%1").arg((state->Cpsr >> 10) & 0x3F));	// IT - If-Then state (DNM)
 | ||||||
| 	CSPR->child(8)->setText(1, QString("%1").arg(value)); |     CSPR->child(7)->setText(1, QString("%1").arg((state->Cpsr >> 16) & 0xF));	// GE - Greater-than-or-Equal
 | ||||||
| 	CSPR->child(9)->setText(1, QString("%1").arg(value)); |     CSPR->child(8)->setText(1, QString("%1").arg((state->Cpsr >> 20) & 0xF));	// DNM - Do not modify
 | ||||||
| 	CSPR->child(10)->setText(1, QString("%1").arg(value)); |     CSPR->child(9)->setText(1, QString("%1").arg((state->Cpsr >> 24) & 0x1));	// J - Java state
 | ||||||
| 	CSPR->child(11)->setText(1, QString("%1").arg(value)); |     CSPR->child(10)->setText(1, QString("%1").arg((state->Cpsr >> 27) & 0x1));	// Q - Sticky overflow
 | ||||||
| 	CSPR->child(12)->setText(1, QString("%1").arg(value)); |     CSPR->child(11)->setText(1, QString("%1").arg((state->Cpsr >> 28) & 0x1));	// V - Overflow
 | ||||||
| 	CSPR->child(13)->setText(1, QString("%1").arg(value)); |     CSPR->child(12)->setText(1, QString("%1").arg((state->Cpsr >> 29) & 0x1));	// C - Carry/Borrow/Extend
 | ||||||
| 	CSPR->child(14)->setText(1, QString("%1").arg(value)); |     CSPR->child(13)->setText(1, QString("%1").arg((state->Cpsr >> 30) & 0x1));	// Z - Zero
 | ||||||
| 	CSPR->child(15)->setText(1, QString("%1").arg(value)); |     CSPR->child(14)->setText(1, QString("%1").arg((state->Cpsr >> 31) & 0x1));	// N - Negative/Less than
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,12 +8,11 @@ | |||||||
| #include "common.h" | #include "common.h" | ||||||
| #include "mem_map.h" | #include "mem_map.h" | ||||||
| 
 | 
 | ||||||
|  | #include "core.h" | ||||||
| #include "break_points.h" | #include "break_points.h" | ||||||
| //#include "powerpc/cpu_core_regs.h"
 | #include "arm/armdefs.h" | ||||||
| #include "arm/disassembler/arm_disasm.h" | #include "arm/disassembler/arm_disasm.h" | ||||||
| 
 | 
 | ||||||
| //#include "powerpc/interpreter/cpu_int.h"
 |  | ||||||
| 
 |  | ||||||
| GDisAsmView::GDisAsmView(QWidget* parent, EmuThread& emu_thread) : QDockWidget(parent), base_addr(0), emu_thread(emu_thread) | GDisAsmView::GDisAsmView(QWidget* parent, EmuThread& emu_thread) : QDockWidget(parent), base_addr(0), emu_thread(emu_thread) | ||||||
| { | { | ||||||
|     disasm_ui.setupUi(this); |     disasm_ui.setupUi(this); | ||||||
| @ -21,49 +20,82 @@ GDisAsmView::GDisAsmView(QWidget* parent, EmuThread& emu_thread) : QDockWidget(p | |||||||
| 	breakpoints = new BreakPoints(); | 	breakpoints = new BreakPoints(); | ||||||
| 
 | 
 | ||||||
|     model = new QStandardItemModel(this); |     model = new QStandardItemModel(this); | ||||||
|     model->setColumnCount(3); |     model->setColumnCount(2); | ||||||
|     disasm_ui.treeView->setModel(model); |     disasm_ui.treeView->setModel(model); | ||||||
| 
 | 
 | ||||||
|  |     RegisterHotkey("Disassembler", "Start/Stop", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut); | ||||||
|     RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut); |     RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut); | ||||||
|     RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut); |     RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut); | ||||||
| //    RegisterHotkey("Disassembler", "Pause", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut);
 |  | ||||||
|     RegisterHotkey("Disassembler", "Continue", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut); |  | ||||||
|     RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), Qt::ApplicationShortcut); |     RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), Qt::ApplicationShortcut); | ||||||
| 
 | 
 | ||||||
|     connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), this, SLOT(OnSetBreakpoint())); |     connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), this, SLOT(OnSetBreakpoint())); | ||||||
|     connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep())); |     connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep())); | ||||||
|     connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause())); |     connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause())); | ||||||
|     connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue())); |     connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue())); | ||||||
|  | 
 | ||||||
|  |     connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this, SLOT(OnToggleStartStop())); | ||||||
|     connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep())); |     connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep())); | ||||||
|     connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, SLOT(OnStepInto())); |     connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, SLOT(OnStepInto())); | ||||||
| //    connect(GetHotkey("Disassembler", "Pause", this), SIGNAL(activated()), this, SLOT(OnPause()));
 |  | ||||||
|     connect(GetHotkey("Disassembler", "Continue", this), SIGNAL(activated()), this, SLOT(OnContinue())); |  | ||||||
|     connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), this, SLOT(OnSetBreakpoint())); |     connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), this, SLOT(OnSetBreakpoint())); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void GDisAsmView::Init() | ||||||
|  | { | ||||||
|  |     ARMul_State* state = Core::GetState(); | ||||||
|  |     Arm* disasm = new Arm(); | ||||||
|  | 
 | ||||||
|  |     base_addr = state->pc; | ||||||
|  |     unsigned int curInstAddr = base_addr; | ||||||
|  |     char result[255]; | ||||||
|  | 
 | ||||||
|  |     for (int i = 0; i < 10000; i++) // fixed for now
 | ||||||
|  |     { | ||||||
|  |         disasm->disasm(curInstAddr, Memory::Read32(curInstAddr), result); | ||||||
|  |         model->setItem(i, 0, new QStandardItem(QString("0x%1").arg((uint)(curInstAddr), 8, 16, QLatin1Char('0')))); | ||||||
|  |         model->setItem(i, 1, new QStandardItem(QString(result))); | ||||||
|  |         curInstAddr += 4; | ||||||
|  |     } | ||||||
|  |     disasm_ui.treeView->resizeColumnToContents(0); | ||||||
|  |     disasm_ui.treeView->resizeColumnToContents(1); | ||||||
|  |      | ||||||
|  |     QModelIndex model_index = model->index(0, 0); | ||||||
|  |     disasm_ui.treeView->scrollTo(model_index); | ||||||
|  |     disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void GDisAsmView::OnSetBreakpoint() | void GDisAsmView::OnSetBreakpoint() | ||||||
| { | { | ||||||
| 	if (SelectedRow() == -1) |     int selected_row = SelectedRow(); | ||||||
|  | 
 | ||||||
|  |     if (selected_row == -1) | ||||||
|         return; |         return; | ||||||
| 	 | 	 | ||||||
|     u32 address = base_addr + 4 * SelectedRow(); |     u32 address = base_addr + (selected_row * 4); | ||||||
|     if (breakpoints->IsAddressBreakPoint(address)) |     if (breakpoints->IsAddressBreakPoint(address)) | ||||||
|     { |     { | ||||||
| 		breakpoints->Remove(address); | 		breakpoints->Remove(address); | ||||||
|         model->item(SelectedRow(), 0)->setBackground(QBrush()); |         model->item(selected_row, 0)->setBackground(QBrush()); | ||||||
|         model->item(SelectedRow(), 1)->setBackground(QBrush()); |         model->item(selected_row, 1)->setBackground(QBrush()); | ||||||
|         model->item(SelectedRow(), 2)->setBackground(QBrush()); |  | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         breakpoints->Add(address); |         breakpoints->Add(address); | ||||||
|         model->item(SelectedRow(), 0)->setBackground(Qt::red); |         model->item(selected_row, 0)->setBackground(QBrush(QColor(0xFF, 0x99, 0x99))); | ||||||
|         model->item(SelectedRow(), 1)->setBackground(Qt::red); |         model->item(selected_row, 1)->setBackground(QBrush(QColor(0xFF, 0x99, 0x99))); | ||||||
|         model->item(SelectedRow(), 2)->setBackground(Qt::red); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void GDisAsmView::OnContinue() | ||||||
|  | { | ||||||
|  |     emu_thread.SetCpuRunning(true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void GDisAsmView::OnStep() | void GDisAsmView::OnStep() | ||||||
|  | { | ||||||
|  |     OnStepInto(); // change later
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void GDisAsmView::OnStepInto() | ||||||
| { | { | ||||||
|     emu_thread.SetCpuRunning(false); |     emu_thread.SetCpuRunning(false); | ||||||
|     emu_thread.ExecStep(); |     emu_thread.ExecStep(); | ||||||
| @ -74,64 +106,24 @@ void GDisAsmView::OnPause() | |||||||
|     emu_thread.SetCpuRunning(false); |     emu_thread.SetCpuRunning(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GDisAsmView::OnContinue() | void GDisAsmView::OnToggleStartStop() | ||||||
| { | { | ||||||
|     emu_thread.SetCpuRunning(true); |     emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GDisAsmView::OnCPUStepped() | void GDisAsmView::OnCPUStepped() | ||||||
| { | { | ||||||
| 	/*
 |     ARMword next_instr = Core::GetState()->pc; | ||||||
| 	base_addr = ireg.PC - 52; | 
 | ||||||
|     unsigned int curInstAddr = base_addr; |     if (breakpoints->IsAddressBreakPoint(next_instr)) | ||||||
|     int  counter = 0; |  | ||||||
|     QModelIndex cur_instr_index; |  | ||||||
|     model->setRowCount(100); |  | ||||||
|     while(true) |  | ||||||
|     { |     { | ||||||
|         u32 opcode = *(u32*)(&Mem_RAM[curInstAddr & RAM_MASK]); |         emu_thread.SetCpuRunning(false); | ||||||
| 
 |  | ||||||
|         char out1[64]; |  | ||||||
|         char out2[128]; |  | ||||||
|         u32 out3 = 0; |  | ||||||
|         memset(out1, 0, sizeof(out1)); |  | ||||||
|         memset(out2, 0, sizeof(out2)); |  | ||||||
| 
 |  | ||||||
|         // NOTE: out3 (nextInstAddr) seems to be bugged, better don't use it...
 |  | ||||||
|         DisassembleGekko(out1, out2, opcode, curInstAddr, &out3); |  | ||||||
|         model->setItem(counter, 0, new QStandardItem(QString("0x%1").arg((uint)curInstAddr, 8, 16, QLatin1Char('0')))); |  | ||||||
|         model->setItem(counter, 1, new QStandardItem(QString(out1))); |  | ||||||
|         model->setItem(counter, 2, new QStandardItem(QString(out2))); |  | ||||||
| 
 |  | ||||||
|         if (ireg.PC == curInstAddr) |  | ||||||
|         { |  | ||||||
|             model->item(counter, 0)->setBackground(Qt::yellow); |  | ||||||
|             model->item(counter, 1)->setBackground(Qt::yellow); |  | ||||||
|             model->item(counter, 2)->setBackground(Qt::yellow); |  | ||||||
|             cur_instr_index = model->index(counter, 0); |  | ||||||
|         } |  | ||||||
|         else if (Debugger::IsBreakpoint(curInstAddr)) |  | ||||||
|         { |  | ||||||
|             model->item(counter, 0)->setBackground(Qt::red); |  | ||||||
|             model->item(counter, 1)->setBackground(Qt::red); |  | ||||||
|             model->item(counter, 2)->setBackground(Qt::red); |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             model->item(counter, 0)->setBackground(QBrush()); |  | ||||||
|             model->item(counter, 1)->setBackground(QBrush()); |  | ||||||
|             model->item(counter, 2)->setBackground(QBrush()); |  | ||||||
|         } |  | ||||||
|         curInstAddr += 4; |  | ||||||
| 
 |  | ||||||
|         ++counter; |  | ||||||
|         if (counter >= 100) break; |  | ||||||
|     } |     } | ||||||
|     disasm_ui.treeView->resizeColumnToContents(0); | 
 | ||||||
|     disasm_ui.treeView->resizeColumnToContents(1); |     unsigned int index = (next_instr - base_addr) / 4; | ||||||
|     disasm_ui.treeView->resizeColumnToContents(2); |     QModelIndex model_index = model->index(index, 0); | ||||||
|     disasm_ui.treeView->scrollTo(cur_instr_index); // QAbstractItemView::PositionAtCenter?
 |     disasm_ui.treeView->scrollTo(model_index); | ||||||
| 	*/ |     disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int GDisAsmView::SelectedRow() | int GDisAsmView::SelectedRow() | ||||||
|  | |||||||
| @ -15,11 +15,15 @@ class GDisAsmView : public QDockWidget | |||||||
| public: | public: | ||||||
|     GDisAsmView(QWidget* parent, EmuThread& emu_thread); |     GDisAsmView(QWidget* parent, EmuThread& emu_thread); | ||||||
| 
 | 
 | ||||||
|  |     void Init(); | ||||||
|  | 
 | ||||||
| public slots: | public slots: | ||||||
|     void OnSetBreakpoint(); |     void OnSetBreakpoint(); | ||||||
|     void OnStep(); |  | ||||||
|     void OnPause(); |  | ||||||
|     void OnContinue(); |     void OnContinue(); | ||||||
|  |     void OnStep(); | ||||||
|  |     void OnStepInto(); | ||||||
|  |     void OnPause(); | ||||||
|  |     void OnToggleStartStop(); | ||||||
| 
 | 
 | ||||||
|     void OnCPUStepped(); |     void OnCPUStepped(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,6 +19,8 @@ | |||||||
| #include "callstack.hxx" | #include "callstack.hxx" | ||||||
| #include "ramview.hxx" | #include "ramview.hxx" | ||||||
| 
 | 
 | ||||||
|  | #include "system.h" | ||||||
|  | #include "loader.h" | ||||||
| #include "core.h" | #include "core.h" | ||||||
| #include "version.h" | #include "version.h" | ||||||
| 
 | 
 | ||||||
| @ -31,11 +33,11 @@ GMainWindow::GMainWindow() | |||||||
|     render_window = new GRenderWindow; |     render_window = new GRenderWindow; | ||||||
|     render_window->hide(); |     render_window->hide(); | ||||||
| 
 | 
 | ||||||
|     GDisAsmView* disasm = new GDisAsmView(this, render_window->GetEmuThread()); |     disasm = new GDisAsmView(this, render_window->GetEmuThread()); | ||||||
|     addDockWidget(Qt::BottomDockWidgetArea, disasm); |     addDockWidget(Qt::BottomDockWidgetArea, disasm); | ||||||
|     disasm->hide(); |     disasm->hide(); | ||||||
| 
 | 
 | ||||||
|     GARM11RegsView* arm_regs = new GARM11RegsView(this); |     arm_regs = new GARM11RegsView(this); | ||||||
|     addDockWidget(Qt::RightDockWidgetArea, arm_regs); |     addDockWidget(Qt::RightDockWidgetArea, arm_regs); | ||||||
|     arm_regs->hide(); |     arm_regs->hide(); | ||||||
| 
 | 
 | ||||||
| @ -75,8 +77,6 @@ GMainWindow::GMainWindow() | |||||||
|     // 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()), disasm, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); |     connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), disasm, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); | ||||||
|     connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), arm_regs, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); |     connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), arm_regs, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); | ||||||
| 	//connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), ram_edit, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
 |  | ||||||
| 	//connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), callstack, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
 |  | ||||||
| 
 | 
 | ||||||
|     // Setup hotkeys
 |     // Setup hotkeys
 | ||||||
|     RegisterHotkey("Main Window", "Load Image", QKeySequence::Open); |     RegisterHotkey("Main Window", "Load Image", QKeySequence::Open); | ||||||
| @ -87,6 +87,8 @@ GMainWindow::GMainWindow() | |||||||
|     connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame())); |     connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame())); | ||||||
| 
 | 
 | ||||||
|     show(); |     show(); | ||||||
|  | 
 | ||||||
|  |     System::Init(render_window); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GMainWindow::~GMainWindow() | GMainWindow::~GMainWindow() | ||||||
| @ -100,6 +102,27 @@ void GMainWindow::BootGame(const char* filename) | |||||||
| { | { | ||||||
|     render_window->DoneCurrent(); // make sure EmuThread can access GL context
 |     render_window->DoneCurrent(); // make sure EmuThread can access GL context
 | ||||||
|     render_window->GetEmuThread().SetFilename(filename); |     render_window->GetEmuThread().SetFilename(filename); | ||||||
|  |      | ||||||
|  |     NOTICE_LOG(MASTER_LOG, "citra starting...\n"); | ||||||
|  | 
 | ||||||
|  |     if (Core::Init(/*render_window*/)) { | ||||||
|  |         ERROR_LOG(MASTER_LOG, "core initialization failed, exiting..."); | ||||||
|  |         Core::Stop(); | ||||||
|  |         exit(1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Load a game or die...
 | ||||||
|  |     std::string boot_filename = filename; | ||||||
|  |     std::string error_str; | ||||||
|  |     bool res = Loader::LoadFile(boot_filename, &error_str); | ||||||
|  | 
 | ||||||
|  |     if (!res) { | ||||||
|  |         ERROR_LOG(BOOT, "Failed to load ROM: %s", error_str.c_str()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     disasm->Init(); | ||||||
|  |     arm_regs->OnCPUStepped(); | ||||||
|  | 
 | ||||||
|     render_window->GetEmuThread().start(); |     render_window->GetEmuThread().start(); | ||||||
| 
 | 
 | ||||||
|     SetupEmuWindowMode(); |     SetupEmuWindowMode(); | ||||||
| @ -115,14 +138,30 @@ void GMainWindow::OnMenuLoadELF() | |||||||
| 
 | 
 | ||||||
| void GMainWindow::OnStartGame() | void GMainWindow::OnStartGame() | ||||||
| { | { | ||||||
|  |     render_window->show(); | ||||||
|  |     render_window->GetEmuThread().SetCpuRunning(true); | ||||||
|  | 
 | ||||||
|  |     ui.action_Start->setEnabled(false); | ||||||
|  |     ui.action_Pause->setEnabled(true); | ||||||
|  |     ui.action_Stop->setEnabled(true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnPauseGame() | void GMainWindow::OnPauseGame() | ||||||
| { | { | ||||||
|  |     render_window->GetEmuThread().SetCpuRunning(false); | ||||||
|  | 
 | ||||||
|  |     ui.action_Start->setEnabled(true); | ||||||
|  |     ui.action_Pause->setEnabled(false); | ||||||
|  |     ui.action_Stop->setEnabled(true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnStopGame() | void GMainWindow::OnStopGame() | ||||||
| { | { | ||||||
|  |     render_window->GetEmuThread().SetCpuRunning(false); | ||||||
|  | 
 | ||||||
|  |     ui.action_Start->setEnabled(true); | ||||||
|  |     ui.action_Pause->setEnabled(false); | ||||||
|  |     ui.action_Stop->setEnabled(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnOpenHotkeysDialog() | void GMainWindow::OnOpenHotkeysDialog() | ||||||
| @ -134,8 +173,8 @@ void GMainWindow::OnOpenHotkeysDialog() | |||||||
| 
 | 
 | ||||||
| void GMainWindow::SetupEmuWindowMode() | void GMainWindow::SetupEmuWindowMode() | ||||||
| { | { | ||||||
|     if (!render_window->GetEmuThread().isRunning()) |     //if (!render_window->GetEmuThread().isRunning())
 | ||||||
|         return; |     //    return;
 | ||||||
| 
 | 
 | ||||||
|     bool enable = ui.action_Single_Window_Mode->isChecked(); |     bool enable = ui.action_Single_Window_Mode->isChecked(); | ||||||
|     if (enable && render_window->parent() == NULL) // switch to single window mode
 |     if (enable && render_window->parent() == NULL) // switch to single window mode
 | ||||||
|  | |||||||
| @ -7,6 +7,8 @@ | |||||||
| 
 | 
 | ||||||
| class GImageInfo; | class GImageInfo; | ||||||
| class GRenderWindow; | class GRenderWindow; | ||||||
|  | class GDisAsmView; | ||||||
|  | class GARM11RegsView; | ||||||
| 
 | 
 | ||||||
| class GMainWindow : public QMainWindow | class GMainWindow : public QMainWindow | ||||||
| { | { | ||||||
| @ -42,6 +44,8 @@ private: | |||||||
|     Ui::MainWindow ui; |     Ui::MainWindow ui; | ||||||
| 
 | 
 | ||||||
|     GRenderWindow* render_window; |     GRenderWindow* render_window; | ||||||
|  |     GDisAsmView* disasm; | ||||||
|  |     GARM11RegsView* arm_regs; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // _CITRA_QT_MAIN_HXX_
 | #endif // _CITRA_QT_MAIN_HXX_
 | ||||||
|  | |||||||
| @ -87,14 +87,6 @@ | |||||||
|     <string>&Start</string> |     <string>&Start</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="action_Stop"> |  | ||||||
|    <property name="enabled"> |  | ||||||
|     <bool>false</bool> |  | ||||||
|    </property> |  | ||||||
|    <property name="text"> |  | ||||||
|     <string>&Stop</string> |  | ||||||
|    </property> |  | ||||||
|   </action> |  | ||||||
|   <action name="action_Pause"> |   <action name="action_Pause"> | ||||||
|    <property name="enabled"> |    <property name="enabled"> | ||||||
|     <bool>false</bool> |     <bool>false</bool> | ||||||
| @ -102,11 +94,16 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>&Pause</string> |     <string>&Pause</string> | ||||||
|    </property> |    </property> | ||||||
|    <property name="visible"> |  | ||||||
|     <bool>false</bool> |  | ||||||
|    </property> |  | ||||||
|   </action> |   </action> | ||||||
|   <action name="action_About"> |    <action name="action_Stop"> | ||||||
|  |      <property name="enabled"> | ||||||
|  |        <bool>false</bool> | ||||||
|  |      </property> | ||||||
|  |      <property name="text"> | ||||||
|  |        <string>&Stop</string> | ||||||
|  |      </property> | ||||||
|  |    </action> | ||||||
|  |    <action name="action_About"> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>About Citra</string> |     <string>About Citra</string> | ||||||
|    </property> |    </property> | ||||||
|  | |||||||
| @ -29,8 +29,8 @@ public: | |||||||
|     QAction *action_load_elf; |     QAction *action_load_elf; | ||||||
|     QAction *action_Exit; |     QAction *action_Exit; | ||||||
|     QAction *action_Start; |     QAction *action_Start; | ||||||
|     QAction *action_Stop; |  | ||||||
|     QAction *action_Pause; |     QAction *action_Pause; | ||||||
|  |     QAction *action_Stop; | ||||||
|     QAction *action_About; |     QAction *action_About; | ||||||
|     QAction *action_Single_Window_Mode; |     QAction *action_Single_Window_Mode; | ||||||
|     QAction *action_Hotkeys; |     QAction *action_Hotkeys; | ||||||
| @ -60,13 +60,12 @@ public: | |||||||
|         action_Exit->setObjectName(QString::fromUtf8("action_Exit")); |         action_Exit->setObjectName(QString::fromUtf8("action_Exit")); | ||||||
|         action_Start = new QAction(MainWindow); |         action_Start = new QAction(MainWindow); | ||||||
|         action_Start->setObjectName(QString::fromUtf8("action_Start")); |         action_Start->setObjectName(QString::fromUtf8("action_Start")); | ||||||
|         action_Stop = new QAction(MainWindow); |  | ||||||
|         action_Stop->setObjectName(QString::fromUtf8("action_Stop")); |  | ||||||
|         action_Stop->setEnabled(false); |  | ||||||
|         action_Pause = new QAction(MainWindow); |         action_Pause = new QAction(MainWindow); | ||||||
|         action_Pause->setObjectName(QString::fromUtf8("action_Pause")); |         action_Pause->setObjectName(QString::fromUtf8("action_Pause")); | ||||||
|         action_Pause->setEnabled(false); |         action_Pause->setEnabled(false); | ||||||
|         action_Pause->setVisible(false); |         action_Stop = new QAction(MainWindow); | ||||||
|  |         action_Stop->setObjectName(QString::fromUtf8("action_Stop")); | ||||||
|  |         action_Stop->setEnabled(false); | ||||||
|         action_About = new QAction(MainWindow); |         action_About = new QAction(MainWindow); | ||||||
|         action_About->setObjectName(QString::fromUtf8("action_About")); |         action_About->setObjectName(QString::fromUtf8("action_About")); | ||||||
|         action_Single_Window_Mode = new QAction(MainWindow); |         action_Single_Window_Mode = new QAction(MainWindow); | ||||||
| @ -126,8 +125,8 @@ public: | |||||||
|         action_load_elf->setText(QApplication::translate("MainWindow", "Load ELF ...", 0, QApplication::UnicodeUTF8)); |         action_load_elf->setText(QApplication::translate("MainWindow", "Load ELF ...", 0, QApplication::UnicodeUTF8)); | ||||||
|         action_Exit->setText(QApplication::translate("MainWindow", "E&xit", 0, QApplication::UnicodeUTF8)); |         action_Exit->setText(QApplication::translate("MainWindow", "E&xit", 0, QApplication::UnicodeUTF8)); | ||||||
|         action_Start->setText(QApplication::translate("MainWindow", "&Start", 0, QApplication::UnicodeUTF8)); |         action_Start->setText(QApplication::translate("MainWindow", "&Start", 0, QApplication::UnicodeUTF8)); | ||||||
|         action_Stop->setText(QApplication::translate("MainWindow", "&Stop", 0, QApplication::UnicodeUTF8)); |  | ||||||
|         action_Pause->setText(QApplication::translate("MainWindow", "&Pause", 0, QApplication::UnicodeUTF8)); |         action_Pause->setText(QApplication::translate("MainWindow", "&Pause", 0, QApplication::UnicodeUTF8)); | ||||||
|  |         action_Stop->setText(QApplication::translate("MainWindow", "&Stop", 0, QApplication::UnicodeUTF8)); | ||||||
|         action_About->setText(QApplication::translate("MainWindow", "About Citra", 0, QApplication::UnicodeUTF8)); |         action_About->setText(QApplication::translate("MainWindow", "About Citra", 0, QApplication::UnicodeUTF8)); | ||||||
|         action_Single_Window_Mode->setText(QApplication::translate("MainWindow", "Single Window Mode", 0, QApplication::UnicodeUTF8)); |         action_Single_Window_Mode->setText(QApplication::translate("MainWindow", "Single Window Mode", 0, QApplication::UnicodeUTF8)); | ||||||
|         action_Hotkeys->setText(QApplication::translate("MainWindow", "Configure &Hotkeys ...", 0, QApplication::UnicodeUTF8)); |         action_Hotkeys->setText(QApplication::translate("MainWindow", "Configure &Hotkeys ...", 0, QApplication::UnicodeUTF8)); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Mathieu Vaillancourt
						Mathieu Vaillancourt