mupen64plus-oldsvn/main/gui_qt4/debugger/debuggerwidget.cpp
2009-03-28 15:22:03 +00:00

162 lines
6.2 KiB
C++

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - debuggerwidget.cpp *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2009 olejl *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "debuggerwidget.h"
#include "hexspinboxdialog.h"
namespace debugger {
extern "C" {
#include "../../../debugger/debugger.h"
#include "../../../debugger/decoder.h"
}
}
namespace core {
extern "C" {
#include "../../version.h"
}
}
DebuggerWidget::DebuggerWidget(QWidget *parent) : QWidget(parent)
{
setupUi(this);
smDebugger = new QSignalMapper(this);
connect(pushStep, SIGNAL(clicked()), smDebugger, SLOT(map()));
connect(pushRun, SIGNAL(clicked()), smDebugger, SLOT(map()));
connect(pushTrace, SIGNAL(clicked()), smDebugger, SLOT(map()));
connect(pushBreak, SIGNAL(clicked()), smDebugger, SLOT(map()));
connect(pushGoto, SIGNAL(clicked()), smDebugger, SLOT(map()));
smDebugger->setMapping(pushStep, "Step");
smDebugger->setMapping(pushRun, "Run");
smDebugger->setMapping(pushTrace, "Trace");
smDebugger->setMapping(pushBreak, "Break");
smDebugger->setMapping(pushGoto, "Goto");
connect(smDebugger, SIGNAL(mapped(const QString &)), this, SLOT(clicked(const QString &)));
smNavigate = new QSignalMapper(this);
connect(pushReduce1000, SIGNAL(clicked()), smNavigate, SLOT(map()));
connect(pushReduce100, SIGNAL(clicked()), smNavigate, SLOT(map()));
connect(pushReduce10, SIGNAL(clicked()), smNavigate, SLOT(map()));
connect(pushIncrease1000, SIGNAL(clicked()), smNavigate, SLOT(map()));
connect(pushIncrease100, SIGNAL(clicked()), smNavigate, SLOT(map()));
connect(pushIncrease10, SIGNAL(clicked()), smNavigate, SLOT(map()));
smNavigate->setMapping(pushReduce1000, -0x1000);
smNavigate->setMapping(pushReduce100, -0x100);
smNavigate->setMapping(pushReduce10, -0x10);
smNavigate->setMapping(pushIncrease1000, 0x1000);
smNavigate->setMapping(pushIncrease100, 0x100);
smNavigate->setMapping(pushIncrease10, 0x10);
connect(smNavigate, SIGNAL(mapped(const int)), this, SLOT(clicked(const int)));
setWindowTitle(tr("Mupen64Plus Debugger - %1").arg(PLUGIN_VERSION));
treeDisasm->setEditTriggers(QAbstractItemView::AllEditTriggers);
QStringList headerList;
headerList << tr("Address") << tr("Opcode") << tr("Args");
treeDisasm->setHeaderLabels(headerList);
color_PC = QColor(Qt::red);
color_BP = QColor(Qt::blue);
}
void DebuggerWidget::update_desasm( unsigned int pc )
{
current_pc = pc;
update(current_pc);
}
void DebuggerWidget::update( unsigned int pc )
{
char opcode[64];
char args[128];
unsigned int instr;
unsigned int tmp_pc;
treeDisasm->clear();
items.clear();
focused_pc = pc;
for (int i = -4; i < 28; i++) {
tmp_pc = pc + (i * 4);
if((debugger::get_memory_flags(tmp_pc) & MEM_FLAG_READABLE) != 0) {
instr = debugger::read_memory_32(tmp_pc);
debugger::r4300_decode_op(instr, opcode, args, tmp_pc );
} else {
strcpy( opcode, "X+X+X+X");
sprintf( args, "UNREADABLE (%d)",debugger::get_memory_type(tmp_pc));
}
QTreeWidgetItem *item=new QTreeWidgetItem(0);
item->setText(0,"0x" + QString::number(tmp_pc,16).toUpper());
item->setText(1,opcode);
item->setText(2,args);
item->setFlags(Qt::ItemIsEnabled);
if (tmp_pc==current_pc) {
item->setBackgroundColor(0, color_PC);
item->setBackgroundColor(1, color_PC);
item->setBackgroundColor(2, color_PC);
}
if(debugger::check_breakpoints(tmp_pc) != -1) {
item->setBackgroundColor(0, color_BP);
item->setBackgroundColor(1, color_BP);
item->setBackgroundColor(2, color_BP);
}
items.append(item);
}
treeDisasm->insertTopLevelItems(0,items);
treeDisasm->setItemSelected(items[4], true);
treeDisasm->show();
items.clear();
}
void DebuggerWidget::clicked(int value)
{
DebuggerWidget::update( focused_pc + value );
}
void DebuggerWidget::clicked(const QString text)
{
if (text == "Step") {
if(debugger::run == EmulatorStop) {
debugger::debugger_step();
}
} else if (text == "Run") {
int oldrun = debugger::run;
debugger::run = EmulatorRun;
if(oldrun == EmulatorStop) {
debugger::debugger_step();
}
} else if (text == "Break") {
debugger::run = EmulatorStop;
} else if (text == "Goto") {
HexSpinBoxDialog *d = new HexSpinBoxDialog(&focused_pc);
if (d->exec()) {
DebuggerWidget::update( focused_pc );
}
} else if (text == "Trace") {
int oldrun = debugger::run;
debugger::run = EmulatorTrace;
if(oldrun == EmulatorStop) {
debugger::debugger_step();
}
}
}