Also, "Go to" button added.
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFont>
+#include <QInputDialog>
+#include <QStringList>
#include "QtBoiDisassemblyWindow.h"
#include "../common/toString.h"
browser->setOpenLinks(false);
browser->setFont(QFont("courier"));
browser->setFocusPolicy(Qt::NoFocus);
- browser->setMinimumSize(500,500);
+ browser->setMinimumSize(700,500);
connect(browser, SIGNAL(anchorClicked(const QUrl&)), this, SIGNAL(anchorClicked(const QUrl &)));
forwardButton = new QPushButton("Forward", this);
forwardButton->setEnabled(false);
forwardButton->setFocusPolicy(Qt::NoFocus);
+ gotoButton = new QPushButton("Go to...", this);
+ gotoButton->setFocusPolicy(Qt::NoFocus);
+ gotoButton->setEnabled(false);
connect(backButton, SIGNAL(clicked()), this, SLOT(historyBack()));
connect(forwardButton, SIGNAL(clicked()), this, SLOT(historyForward()));
+ connect(gotoButton, SIGNAL(clicked()), this, SLOT(onGotoButton()));
//backButton->setIcon(QIcon("../icons/go-next.svg"));
//forwardButton->setIcon(QIcon("../icons/go-previous.svg"));
QHBoxLayout *buttons = new QHBoxLayout();
buttons->addWidget(backButton);
buttons->addWidget(forwardButton);
+ buttons->addWidget(gotoButton);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(browser);
result += toString(addr);
result += "\">";
if (tags->value(addr) != "")
- result += tags->value(addr).toStdString();
+ result += tags->value(addr).split("#").at(0).toStdString();
else
result += toStringHex(addr, 4);
result += "</a>";
str << "<html><head><title>Disassembly</title></head><body>";
str << "<table cellpadding=0 cellspacing=0>";
- str << "<tr bgcolor=#c0ffc0><td width=25%>Labels</td><td> BP </td><td width=15%>Addr</td><td width=15%>Opcodes</td><td>Instruction</td></tr>";
+ str << "<tr bgcolor=#c0ffc0><td width=25%>Labels</td><td> BP </td><td> Addr </td>"
+ "<td> Opcodes </td><td>Instruction</td><td>Comments</td></tr>";
bool hilightBG=true;
}
}
+ QStringList tag_comment = tags->value(pos, "#").split("#");
+ QString tag = tag_comment.at(0);
+ QString comment = tag_comment.at(1);
+
Instruction ins(gb->disassemble_opcode(pos));
str << "<tr bgcolor=" << (isBP? "#ff0000" : (pos == gb->regs.PC ? "#ffc0c0" : (hilightBG ? "#d0d0d0" : "#ffffff"))) << ">" <<
- "<td>" << tags->value(pos).toStdString() << "</td>" <<
+ "<td>" << tag.toStdString() << (tag=="" ? "" : ":")<<" </td>" <<
"<td> <a href=\"togglebp:" << std::dec << pos << "\">"<< (isBP? "#" : " ") <<"</a> </font></td>" <<
- "<td><a href=\"newtag:" << std::dec << pos << "\">0x" << std::hex << std::setw(4) << std::setfill('0') <<
- pos << "</a></td><td>";
+ "<td><a href=\"tag:" << std::dec << pos << "\">0x" << std::hex << std::setw(4) << std::setfill('0') <<
+ pos << "</a> </td><td>";
for (int i=0; i<ins.length; i++)
str << std::setw(2) << int(gb->memory.read(pos+i)) << " ";
- str << "</td><td>";
+ str << " </td><td>";
- str << insToHtml(ins) << "</td></tr>";
+ str << insToHtml(ins) << " </td>";
+ str << "<td>" << "<a href=\"comment:" << std::dec << pos << "\">#</a> "<< comment.toStdString() << " </td></tr>";
pos += ins.length;
hilightBG = !hilightBG;
gotoAddress(currentAddress);
}
+void QtBoiDisassemblyWindow::ready()
+{
+ gotoPC();
+ gotoButton->setEnabled(true);
+}
+
+
void QtBoiDisassemblyWindow::historyBack()
{
if (historyPosition >= 1)
gotoAddress(history[historyPosition+1]);
}
+void QtBoiDisassemblyWindow::onGotoButton()
+{
+ QString s = QInputDialog::getText(this, tr("Go to address"), tr("Enter the address to disassemble"));
+ gotoAddress(s.toUInt(0,0));
+}
class QtBoiDisassemblyWindow: public QWidget
{
- Q_OBJECT
+ Q_OBJECT
- public:
- QtBoiDisassemblyWindow(QWidget *parent, GameBoy *gb, QHash<u32, QString> *tags);
- ~QtBoiDisassemblyWindow();
+ public:
+ QtBoiDisassemblyWindow(QWidget *parent, GameBoy *gb, QHash<u32, QString> *tags);
+ ~QtBoiDisassemblyWindow();
- void gotoAddress(u16 addr);
- void gotoPC();
+ void gotoAddress(u16 addr);
+ void gotoPC();
void refresh();
+ void ready();
- public slots:
- void historyBack();
+ public slots:
+ void historyBack();
void historyForward();
+ void onGotoButton();
- signals:
- void anchorClicked(const QUrl & link);
+ signals:
+ void anchorClicked(const QUrl & link);
- private:
- std::string insToHtml(const Instruction &ins);
- std::string operandToHtml(const Instruction::Operand &ins);
- std::string htmlLinkMem(u32 addr);
+ private:
+ std::string insToHtml(const Instruction &ins);
+ std::string operandToHtml(const Instruction::Operand &ins);
+ std::string htmlLinkMem(u32 addr);
- QTextBrowser *browser;
- QPushButton *backButton, *forwardButton;
-
- GameBoy *gb;
- QString romTitle;
- QHash<u32, QString> *tags;
- QList<u32> history;
- int historyPosition;
-
- u16 currentAddress;
+ QTextBrowser *browser;
+ QPushButton *backButton, *forwardButton, *gotoButton;
+ GameBoy *gb;
+ QString romTitle;
+ QHash<u32, QString> *tags;
+ QList<u32> history;
+ int historyPosition;
+ u16 currentAddress;
};
toolbar->addAction(emulatorCont);
toolbar->addAction(emulatorPause);
toolbar->addAction(emulatorReset);
+ toolbar->addAction(emulatorStep);
}
void QtBoiMainWindow::onLoadROM()
{
- saveTags();
+ saveTags();
- QString filename = QFileDialog::getOpenFileName(this, tr("Load ROM"), "../roms", tr("GameBoy ROMs (*.gb *.gbc)"));
- if (filename == "") return;
+ QString filename = QFileDialog::getOpenFileName(this, tr("Load ROM"), "../roms", tr("GameBoy ROMs (*.gb *.gbc)"));
+ if (filename == "") return;
- emuThread->loadROM(filename);
-
- char title[12];
- memcpy(title, emuThread->gb.rom->header.new_title, 11);
- title[11]='\0';
- romTitle=QString(title);
- loadTags();
+ emuThread->loadROM(filename);
+
+ char title[12];
+ memcpy(title, emuThread->gb.rom->header.new_title, 11);
+ title[11]='\0';
+ romTitle=QString(title);
+ loadTags();
- statusbar->showMessage(tr("Loaded ROM ")+filename+" ["+romTitle+"]");
+ statusbar->showMessage(tr("Loaded ROM ")+filename+" ["+romTitle+"]");
+ disassembly->ready();
}
void QtBoiMainWindow::onDisassemblyAnchorClicked(const QUrl& url)
{
- std::cout << url.toString().toStdString() << std::endl;
+ //std::cout << url.toString().toStdString() << std::endl;
if (url.scheme() == "gotoaddr") {
u32 addr = url.path().toUInt();
disassembly->gotoAddress(addr);
}
- else if (url.scheme() == "newtag") {
+ else if (url.scheme() == "tag") {
u32 addr = url.path().toUInt();
- QString tag = QInputDialog::getText(this, tr("Create new tag"), tr("Enter the tag for the selected address"),
- QLineEdit::Normal, tags[addr]);
-
- tags[addr] = tag;
+ QStringList tag_comment = tags.value(addr,"#").split("#");
+ QString tag = tag_comment.at(0);
+ QString comment = tag_comment.at(1);
+ tag = QInputDialog::getText(this, tr("Edit tag"), tr("Enter the tag for the selected address"),
+ QLineEdit::Normal, tag);
+ tags[addr] = tag+"#"+comment;
disassembly->refresh();
}
else if (url.scheme() == "togglebp") {
}
if (!bpFound) {
emuThread->gb.set_breakpoint(addr);
- std::cout << "bp set at 0x" << std::hex << addr << std::endl;
+ //std::cout << "bp set at 0x" << std::hex << addr << std::endl;
}
disassembly->refresh();
status->update();
}
+ else if (url.scheme() == "comment") {
+ u32 addr = url.path().toUInt();
+ QStringList tag_comment = tags.value(addr,"#").split("#");
+ QString tag = tag_comment.at(0);
+ QString comment = tag_comment.at(1);
+ comment = QInputDialog::getText(this, tr("Edit comment"), tr("Enter the comment for the selected address"),
+ QLineEdit::Normal, comment);
+ tags[addr] = tag+"#"+comment;
+ disassembly->refresh();
+ }
}
void QtBoiMainWindow::onRedraw(const uchar *buffer)