#include "debug_wnd.h"
CDebugWnd::CDebugWnd(nes_emu_t* nes, QWidget* parent)
: QWidget(parent)
{
QGridLayout* mainLayout;
QGroupBox* controlBox;
QGridLayout* controlLayout;
QPushButton* startBtn;
QPushButton* stepBtn;
QPushButton* stopBtn;
QPushButton* resetBtn;
setFixedSize(712, 388);
mainLayout = new QGridLayout();
/* Controls */
controlBox = new QGroupBox("Controls");
controlBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
startBtn = new QPushButton("Start", this);
stepBtn = new QPushButton("Step", this);
stopBtn = new QPushButton("Stop", this);
resetBtn = new QPushButton("Reset", this);
startBtn->setDisabled(true);
stopBtn->setDisabled(true);
this->connect(startBtn, SIGNAL(clicked()), this, SLOT(startEmulation()));
this->connect(stepBtn, SIGNAL(clicked()), this, SLOT(stepEmulation()));
this->connect(stopBtn, SIGNAL(clicked()), this, SLOT(stopEmulation()));
this->connect(resetBtn, SIGNAL(clicked()), this, SLOT(resetEmulation()));
controlLayout = new QGridLayout();
controlLayout->addWidget(startBtn, 0, 0);
controlLayout->addWidget(stepBtn, 0, 1);
controlLayout->addWidget(stopBtn, 0, 2);
controlLayout->addWidget(resetBtn, 1, 0, 1, 3);
controlBox->setLayout(controlLayout);
/* Controls */
/* Dissassembly */
disassemblyBox = new QTextEdit();
disassemblyBox->setFont(QFont("Courier New", 10, QFont::Normal));
/* Dissassembly */
mainLayout->addWidget(controlBox, 0, 0);
mainLayout->addWidget(disassemblyBox, 0, 1, 2, 1);
this->setLayout(mainLayout);
this->nes = nes;
nes_load_rom(this->nes);
}
void CDebugWnd::startEmulation(void)
{
/* TODO: Add logic. */
}
void CDebugWnd::stepEmulation(void)
{
nes_step(this->nes);
this->updateDisassembly();
}
void CDebugWnd::stopEmulation(void)
{
/* TODO: Add logic. */
}
void CDebugWnd::resetEmulation(void)
{
nes_reset(this->nes);
}
void CDebugWnd::updateDisassembly(void)
{
int t, u, pc;
char buffer[2048] = {0};
cpu6502_t* cpu = nes_get_cpu(this->nes);
mapper_t* mapper = nes_get_mapper(this->nes);
t = 0;
pc = cpu_get_pc(cpu);
do {
opcode_t op = cpu_get_op(cpu, pc);
sprintf(buffer, "%s$%04X", buffer, pc);
/* Raw memory */
sprintf(buffer, "%s:%02X", buffer, mapper_read(mapper, pc));
for (u = pc + 1; u < (pc + op.size); u++) {
sprintf(buffer, "%s %02X", buffer, mapper_read(mapper, u));
}
/* Raw memory */
/* Disassembly */
sprintf(buffer, "%s\t%s", buffer, op.inst_name);
switch (op.addr_mode) {
case ADDRMODE_ZP: {
int val = mapper_read(mapper, mapper_read(mapper, pc + 1));
sprintf(buffer, "%s $%02X = #$%02X", buffer, mapper_read(mapper, pc + 1), val);
break;
}
case ADDRMODE_REL: {
int val = mapper_read(mapper, pc + 1);
if (val < 0x80) {
val += pc;
}
else {
val += pc - 0xFF;
}
val++;
sprintf(buffer, "%s $%04X", buffer, val);
break;
}
case ADDRMODE_ABS: {
int val = mapper_read(mapper, mapper_read16(mapper, pc + 1));
sprintf(buffer, "%s $%04X = #$%02X", buffer, mapper_read16(mapper, pc + 1), val);
break;
}
case ADDRMODE_ACC: {
sprintf(buffer, "%s A = #$%02X", buffer, cpu_get_a(cpu));
break;
}
case ADDRMODE_IMM: {
sprintf(buffer, "%s #$%02X", buffer, mapper_read(mapper, pc + 1));
break;
}
case ADDRMODE_ZPX: {
int val = (mapper_read(mapper, pc + 1) + cpu_get_x(cpu)) & 0xFF;
sprintf(buffer, "%s $%02X,X @ $%04X = #$%02X", buffer, mapper_read(mapper, pc + 1), val, mapper_read(mapper, val));
break;
}
case ADDRMODE_ZPY: {
int val = (mapper_read(mapper, pc + 1) + cpu_get_y(cpu)) & 0xFF;
sprintf(buffer, "%s $%02X,Y @ $%04X = #$%02X", buffer, mapper_read(mapper, pc + 1), val, mapper_read(mapper, val));
break;
}
case ADDRMODE_ABSX: {
int val = mapper_read16(mapper, pc + 1) + cpu_get_x(cpu);
sprintf(buffer, "%s $%04X,X @ $%04X = #$%02X", buffer, mapper_read16(mapper, pc + 1), val, mapper_read(mapper, val));
break;
}
case ADDRMODE_ABSY: {
int val = mapper_read16(mapper, pc + 1) + cpu_get_y(cpu);
sprintf(buffer, "%s $%04X,Y @ $%04X = #$%02X", buffer, mapper_read16(mapper, pc + 1), val, mapper_read(mapper, val));
break;
}
case ADDRMODE_PREIDXIND: {
sprintf(buffer, "%s ($%02X,X)", buffer, mapper_read(mapper, pc + 1));
break;
}
case ADDRMODE_POSTIDXIND: {
sprintf(buffer, "%s ($%02X),Y", buffer, mapper_read(mapper, pc + 1));
break;
}
case ADDRMODE_INDABS: {
int addr = mapper_read16(mapper, mapper_read16(mapper, pc + 1));
sprintf(buffer, "%s ($%04X) @ $%04X = #$%02X", buffer, mapper_read16(mapper, pc + 1), addr, mapper_read(mapper, addr));
break;
}
default: {
sprintf(buffer, "%s", buffer);
break;
}
}
/* Disassembly */
sprintf(buffer, "%s\r\n", buffer);
pc += op.size;
} while(t++ < 20);
disassemblyBox->setText(buffer);
}