Replace logger with basic disassembly in APU debugger (& fixing Absolute By X Address operand?)

This commit is contained in:
Melefo
2021-04-01 14:20:02 +02:00
parent 044aae174d
commit 06cdafbf16
7 changed files with 543 additions and 308 deletions

View File

@@ -191,7 +191,7 @@ namespace ComSquare::APU
int APU::_executeInstruction()
{
uint8_t opcode = this->_internalRead(this->_internalRegisters.pc++);
uint8_t opcode = this->_getImmediateData();
switch (opcode) {
case 0x00:

View File

@@ -65,8 +65,12 @@ namespace ComSquare::APU
uint24_t APU::_getAbsoluteByXAddr()
{
uint24_t addr1 = this->_getImmediateData() + this->_internalRegisters.x;
uint24_t addr2 = this->_getImmediateData() + this->_internalRegisters.x++;
uint24_t addr1 = this->_getImmediateData();
uint24_t addr2 = this->_getImmediateData();
uint24_t full = (addr2 << 8) | addr1;
addr1 = this->_internalRead(full + this->_internalRegisters.x);
addr2 = this->_internalRead(full + this->_internalRegisters.x + 1);
return (addr2 << 8u) | addr1;
}

View File

@@ -23,6 +23,11 @@ namespace ComSquare::Debugger
this->_ui.setupUi(this->_window);
QMainWindow::connect(this->_ui.resumeButton, &QPushButton::clicked, this, &APUDebug::pause);
QMainWindow::connect(this->_ui.stepButton, &QPushButton::clicked, this, &APUDebug::step);
this->_ui.logger->setRowCount(0x20);
this->_ui.logger->setColumnCount(3);
this->_ui.logger->horizontalHeader()->setHidden(true);
this->_ui.logger->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
this->_ui.logger->setShowGrid(false);
this->_window->show();
this->_updatePanel();
}
@@ -82,7 +87,14 @@ namespace ComSquare::Debugger
this->_ui.yIndexLineEdit->setText(Utility::to_hex(this->_internalRegisters.y).c_str());
this->_ui.accumlatorLineEdit->setText(Utility::to_hex(this->_internalRegisters.a).c_str());
this->_ui.programCounterLineEdit->setText(Utility::to_hex(this->_internalRegisters.pc).c_str());
this->_ui.programStatusWordLineEdit->setText(this->_getPSWString().c_str());
this->_ui.bFlagCheckBox->setChecked(this->_internalRegisters.b);
this->_ui.nFlagCheckBox->setChecked(this->_internalRegisters.n);
this->_ui.pFlagCheckBox->setChecked(this->_internalRegisters.p);
this->_ui.hFlagCheckBox->setChecked(this->_internalRegisters.h);
this->_ui.vFlagCheckBox->setChecked(this->_internalRegisters.v);
this->_ui.iFlagCheckBox->setChecked(this->_internalRegisters.i);
this->_ui.zFlagCheckBox->setChecked(this->_internalRegisters.z);
this->_ui.cFlagCheckBox->setChecked(this->_internalRegisters.c);
auto voices = this->_dsp.getVoices();
auto master = this->_dsp.getMaster();
@@ -235,256 +247,94 @@ namespace ComSquare::Debugger
this->_ui.EchocheckBox_8->setChecked(voices[7].eon);
this->_ui.SampleEndcheckBox_8->setChecked(voices[7].endx);
this->_ui.PitchModulationcheckBox_8->setChecked(voices[7].pmon);
this->_updateLogger();
}
std::string APUDebug::_getPSWString()
void APUDebug::_updateLogger()
{
std::string str;
str += this->_internalRegisters.n ? 'n' : '-';
str += this->_internalRegisters.v ? 'v' : '-';
str += this->_internalRegisters.p ? 'p' : '-';
str += this->_internalRegisters.b ? 'b' : '-';
str += this->_internalRegisters.h ? 'h' : '-';
str += this->_internalRegisters.i ? 'i' : '-';
str += this->_internalRegisters.z ? 'z' : '-';
str += this->_internalRegisters.c ? 'c' : '-';
return str;
}
QStringList labels = QStringList();
uint16_t offset = 0;
std::string APUDebug::_getInstructionString()
{
uint8_t opcode = this->_internalRead(this->_internalRegisters.pc);
for (uint16_t i = 0; i < 0x20; i++)
{
auto pc = this->_internalRegisters.pc;
auto instruction = this->_getInstruction();
std::string operand;
switch (opcode) {
case 0x00:
return "NOP";
case 0x10:
return "BPL";
case 0x20:
return "CLRP";
case 0x30:
return "BMI";
case 0x40:
return "SETP";
case 0x50:
return "BVC";
case 0x60:
return "CLRC";
case 0x70:
return "BVS";
case 0x80:
return "SETC";
case 0x90:
return "BCC";
case 0xA0:
return "EI";
case 0xB0:
return "BCS";
case 0xC0:
return "DI";
case 0xD0:
return "BNE";
case 0xE0:
return "CLRV";
case 0xF0:
return "BEQ";
case 0x01:
case 0x11:
case 0x21:
case 0x31:
case 0x41:
case 0x51:
case 0x61:
case 0x71:
case 0x81:
case 0x91:
case 0xA1:
case 0xB1:
case 0xC1:
case 0xD1:
case 0xE1:
case 0xF1:
return "TCALL";
case 0x02:
case 0x22:
case 0x42:
case 0x62:
case 0x82:
case 0xA2:
case 0xC2:
case 0xE2:
return "SET1";
case 0x12:
case 0x32:
case 0x52:
case 0x72:
case 0x92:
case 0xB2:
case 0xD2:
case 0xF2:
return "CLR1";
case 0x03:
case 0x13:
case 0x23:
case 0x33:
case 0x43:
case 0x53:
case 0x63:
case 0x73:
case 0x83:
case 0x93:
case 0xA3:
case 0xB3:
case 0xC3:
case 0xD3:
case 0xE3:
case 0xF3:
return "BBC";
case 0x04 ... 0x09:
case 0x14 ... 0x19:
return "OR";
case 0x24 ... 0x29:
case 0x34 ... 0x39:
return "AND";
case 0x44 ... 0x49:
case 0x54 ... 0x59:
return "EOR";
case 0x64 ... 0x69:
case 0x74 ... 0x79:
case 0xC8:
case 0xAD:
case 0x1E:
case 0x3E:
case 0x5E:
case 0x7E:
return "CMP";
case 0x84 ... 0x89:
case 0x94 ... 0x99:
return "ADC";
case 0xA4 ... 0xA9:
case 0xB4 ... 0xB9:
return "SBC";
case 0xC4 ... 0xC7:
case 0xCB ... 0xCD:
case 0xD4 ... 0xD9:
case 0xE4 ... 0xE9:
case 0xEB ... 0xEC:
case 0xF4 ... 0xFB:
case 0xDB:
case 0xC9:
case 0x5D:
case 0x7D:
case 0x8D:
case 0x9D:
case 0xBD:
case 0xDD:
case 0xFD:
case 0x8F:
case 0xAF:
case 0xBF:
return "MOV";
case 0x0A:
case 0x2A:
return "OR1";
case 0x1A:
return "DECW";
case 0x3A:
return "INCW";
case 0x4A:
case 0x6A:
return "AND1";
case 0x5A:
return "CMPW";
case 0x7A:
return "ADDW";
case 0x8A:
return "EOR1";
case 0x9A:
return "SUBW";
case 0xAA:
case 0xCA:
return "MOV1";
case 0xBA:
case 0xDA:
return "MOVW";
case 0xEA:
return "NOT1";
case 0x0B ... 0x0C:
case 0x1B ... 0x1C:
return "ASL";
case 0x2B ... 0x2C:
case 0x3B ... 0x3C:
return "ROL";
case 0x4B ... 0x4C:
case 0x5B ... 0x5C:
return "LSR";
case 0x6B ... 0x6C:
case 0x7B ... 0x7C:
return "ROR";
case 0x8B ... 0x8C:
case 0x9B ... 0x9C:
case 0xDC:
case 0x1D:
return "DEC";
case 0xAB ... 0xAC:
case 0xBB ... 0xBC:
case 0xFC:
case 0x3D:
return "INC";
case 0x0D:
case 0x2D:
case 0x4D:
case 0x6D:
return "PUSH";
case 0xED:
return "NOTC";
case 0x0E:
return "TSET1";
case 0x2E:
case 0xDE:
return "CBNE";
case 0x4E:
return "TCLR1";
case 0x6E:
case 0xFE:
return "DBNZ";
case 0x8E:
case 0xAE:
case 0xCE:
case 0xEE:
return "POP";
case 0x9E:
return "DIV";
case 0xBE:
return "DAS";
case 0x0F:
return "BRK";
case 0x1F:
case 0x5F:
return "JMP";
case 0x2F:
return "BRA";
case 0x3F:
return "CALL";
case 0x4F:
return "PCALL";
case 0x6F:
return "RET";
case 0x7F:
return "RETI";
case 0x9F:
return "XCN";
case 0xCF:
return "MUL";
case 0xDF:
return "DAA";
case 0xEF:
return "SLEEP";
case 0xFF:
return "STOP";
default:
return "Unknown";
this->_ui.logger->setItem(i, 0, new QTableWidgetItem(instruction.name.c_str()));
operand = this->_getOperand(std::get<0>(instruction.operands));
this->_ui.logger->setItem(i, 1, new QTableWidgetItem(operand.c_str()));
if (operand.empty())
this->_ui.logger->item(i, 1)->setData(Qt::BackgroundRole, QColor(220, 220, 220));
operand = this->_getOperand(std::get<1>(instruction.operands));
this->_ui.logger->setItem(i, 2, new QTableWidgetItem(operand.c_str()));
if (operand.empty())
this->_ui.logger->item(i, 2)->setData(Qt::BackgroundRole, QColor(220, 220, 220));
labels.append(Utility::to_hex(pc).c_str());
offset += instruction.size;
}
this->_ui.logger->setVerticalHeaderLabels(labels);
for (int i = 0; i < 3; i++)
this->_ui.logger->item(0, i)->setData(Qt::BackgroundRole, QColor(200, 255, 148));
this->_internalRegisters.pc -= offset;
}
std::string APUDebug::_getOperand(Operand ope)
{
switch (ope) {
case None:
return "";
case A:
return Utility::to_hex(this->_internalRegisters.a);
case X:
return Utility::to_hex(this->_internalRegisters.x);
case Y:
return Utility::to_hex(this->_internalRegisters.y);
case SP:
return Utility::to_hex(this->_internalRegisters.sp);
case PSW:
return Utility::to_hex(this->_internalRegisters.psw);
case ImmediateData:
return Utility::to_hex(this->_getImmediateData());
case IndexXAddr:
return Utility::to_hex(this->_getIndexXAddr());
case IndexYAddr:
return Utility::to_hex(this->_getIndexYAddr());
case AbsoluteAddr:
return Utility::to_hex(this->_getAbsoluteAddr());
case AbsoluteBit: {
auto pair = this->_getAbsoluteBit();
return Utility::to_hex(std::get<0>(pair)) + Utility::to_hex(std::get<1>(pair));
}
case AbsoluteAddrByX:
return Utility::to_hex(this->_getAbsoluteAddrByX());
case AbsoluteAddrByY:
return Utility::to_hex(this->_getAbsoluteAddrByY());
case AbsoluteByXAddr:
return Utility::to_hex(this->_getAbsoluteByXAddr());
case AbsoluteDirectByXAddr:
return Utility::to_hex(this->_getAbsoluteDirectByXAddr());
case AbsoluteDirectAddrByY:
return Utility::to_hex(this->_getAbsoluteDirectAddrByY());
case DirectAddr:
return Utility::to_hex(this->_getDirectAddr());
case DirectAddrByX:
return Utility::to_hex(this->_getDirectAddrByX());
case DirectAddrByY:
return Utility::to_hex(this->_getDirectAddrByY());
}
return "UNKNOWN";
}
Instruction &APUDebug::_getInstruction()
{
uint8_t opcode = this->_getImmediateData();
return this->_instructions[opcode];
}
int APUDebug::_executeInstruction()
@@ -497,7 +347,6 @@ namespace ComSquare::Debugger
this->_isStepping = false;
this->_isPaused = true;
}
this->_ui.logger->append(APUDebug::_getInstructionString().c_str());
cycles = APU::_executeInstruction();
this->_updatePanel();
return cycles;
@@ -511,7 +360,7 @@ namespace ComSquare::Debugger
APU::update(cycles);
} catch (InvalidOpcode &e) {
this->pause();
this->_ui.logger->append(e.what());
//this->_ui.logger->append(e.what());
}
}

View File

@@ -11,8 +11,301 @@
namespace ComSquare::Debugger
{
class APUDebug : public APU::APU, public QObject {
//! @brief List of all types of operands used by the instructions
enum Operand
{
None,
A,
X,
Y,
SP,
PSW,
ImmediateData,
IndexXAddr,
IndexYAddr,
AbsoluteBit,
AbsoluteAddr,
AbsoluteAddrByX,
AbsoluteAddrByY,
AbsoluteByXAddr,
AbsoluteDirectByXAddr,
AbsoluteDirectAddrByY,
DirectAddr,
DirectAddrByX,
DirectAddrByY
};
//! @brief Small structure to store some values on the instructions
struct Instruction
{
std::string name;
int size;
std::tuple<Operand, Operand> operands;
};
class APUDebug : public APU::APU, public QObject
{
private:
//! @brief List of instructions and their information
std::array<Instruction, 0x100> _instructions {{
{"NOP", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"OR", 2, {DirectAddr, None}},
{"OR", 3, {AbsoluteAddr, None}},
{"OR", 1, {IndexXAddr, None}},
{"OR", 2, {AbsoluteDirectByXAddr, None}},
{"OR", 2, {ImmediateData, None}},
{"OR", 3, {DirectAddr, DirectAddr}},
{"OR1", 3, {AbsoluteBit, None}},
{"ASL", 2, {DirectAddr, None}},
{"ASL", 3, {AbsoluteAddr, None}},
{"PUSH", 1, {PSW, None}},
{"TSET1", 3, {AbsoluteAddr, None}},
{"BRK", 1, {None, None}},
{"BPL", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"OR", 2, {DirectAddrByX, None}},
{"OR", 3, {AbsoluteAddrByX, None}},
{"OR", 3, {AbsoluteAddrByY, None}},
{"OR", 2, {AbsoluteDirectAddrByY, None}},
{"OR", 3, {DirectAddr, ImmediateData}},
{"OR", 1, {IndexYAddr, IndexYAddr}},
{"DECW", 2, {DirectAddr, None}},
{"ASL", 2, {DirectAddrByX, None}},
{"ASL", 1, {A, None}},
{"DEC", 1, {X, None}},
{"CMP", 3, {X, AbsoluteAddr}},
{"JMP", 3, {AbsoluteByXAddr, None}},
{"CLRP", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"AND", 2, {DirectAddr, None}},
{"AND", 3, {AbsoluteAddr, None}},
{"AND", 1, {IndexXAddr, None}},
{"AND", 2, {AbsoluteDirectByXAddr, None}},
{"AND", 2, {ImmediateData, None}},
{"AND", 3, {DirectAddr, DirectAddr}},
{"OR1", 3, {AbsoluteBit, None}},
{"ROL", 2, {DirectAddr, None}},
{"ROL", 3, {AbsoluteAddr, None}},
{"PUSH", 1, {A, None}},
{"CBNE", 3, {ImmediateData, ImmediateData}},
{"BRA", 2, {ImmediateData, None}},
{"BMI", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"AND", 2, {DirectAddrByX, None}},
{"AND", 3, {AbsoluteAddrByX, None}},
{"AND", 3, {AbsoluteAddrByY, None}},
{"AND", 2, {AbsoluteDirectAddrByY, None}},
{"AND", 3, {DirectAddr, ImmediateData}},
{"AND", 1, {IndexXAddr, IndexYAddr}},
{"INCW", 2, {DirectAddr, None}},
{"ROL", 2, {AbsoluteAddrByX, None}},
{"ROL", 1, {A, None}},
{"INC", 1, {X, None}},
{"CMP", 2, {X, DirectAddr}},
{"CALL", 3, {AbsoluteAddr, None}},
{"SETP", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"EOR", 2, {DirectAddr, None}},
{"EOR", 3, {AbsoluteAddr, None}},
{"EOR", 1, {IndexXAddr, None}},
{"EOR", 2, {AbsoluteDirectByXAddr, None}},
{"EOR", 2, {ImmediateData, None}},
{"EOR", 3, {DirectAddr, DirectAddr}},
{"AND1", 3, {AbsoluteBit, None}},
{"LSR", 2, {DirectAddr, None}},
{"LSR", 3, {AbsoluteAddr, None}},
{"PUSH", 1, {X, None}},
{"TCLR1", 3, {AbsoluteAddr, None}},
{"PCALL", 3, {None, None}},
{"BVC", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"EOR", 2, {DirectAddrByX, None}},
{"EOR", 3, {AbsoluteAddrByX, None}},
{"EOR", 3, {AbsoluteAddrByY, None}},
{"EOR", 2, {AbsoluteDirectAddrByY, None}},
{"EOR", 3, {DirectAddr, ImmediateData}},
{"EOR", 1, {IndexXAddr, IndexYAddr}},
{"CMPW", 2, {DirectAddr, None}},
{"LSR", 2, {DirectAddrByX, None}},
{"LSR", 1, {A, None}},
{"MOV", 1, {A, X}},
{"CMP", 3, {Y, AbsoluteAddr}},
{"JMP", 3, {AbsoluteAddr, None}},
{"CLRC", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"CMP", 2, {A, DirectAddr}},
{"CMP", 3, {A, AbsoluteAddr}},
{"CMP", 1, {A, IndexXAddr,}},
{"CMP", 2, {A, AbsoluteDirectByXAddr}},
{"CMP", 2, {A, ImmediateData}},
{"CMP", 3, {DirectAddr, DirectAddr}},
{"AND1", 3, {AbsoluteBit, None}},
{"ROR", 2, {DirectAddr , None}},
{"ROR", 3, {AbsoluteAddr, None}},
{"PUSH", 1, {Y, None}},
{"DBNZ", 3, {ImmediateData, None}},
{"RET", 1, {None, None}},
{"BVS", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"CMP", 2, {A, DirectAddrByX}},
{"CMP", 3, {A, AbsoluteAddrByX}},
{"CMP", 3, {A, AbsoluteAddrByY}},
{"CMP", 2, {A, AbsoluteDirectAddrByY}},
{"CMP", 3, {DirectAddr, ImmediateData}},
{"CMP", 1, {IndexXAddr, IndexYAddr}},
{"ADDW", 2, {DirectAddr, None}},
{"ROR", 2, {DirectAddrByX, None}},
{"ROR", 1, {A, None}},
{"MOV", 1, {X, A}},
{"CMP", 3, {Y, DirectAddr}},
{"RETI", 1, {None, None}},
{"SETC", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"ADC", 2, {DirectAddr, None}},
{"ADC", 3, {AbsoluteAddr, None}},
{"ADC", 1, {IndexXAddr, None}},
{"ADC", 2, {AbsoluteDirectByXAddr, None}},
{"ADC", 2, {ImmediateData, None}},
{"ADC", 3, {DirectAddr, DirectAddr}},
{"EOR1", 3, {AbsoluteBit, None}},
{"DEC", 2, {DirectAddr, None}},
{"DEC", 3, {AbsoluteAddr, None}},
{"MOV", 2, {ImmediateData, Y}},
{"POP", 1, {PSW, None}},
{"MOV", 3, {DirectAddr, ImmediateData}},
{"BCC", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"ADC", 2, {DirectAddrByX, None}},
{"ADC", 3, {AbsoluteAddrByX, None}},
{"ADC", 3, {AbsoluteAddrByY, None}},
{"ADC", 2, {AbsoluteDirectAddrByY, None}},
{"ADC", 3, {DirectAddr, ImmediateData}},
{"ADC", 1, {IndexXAddr, IndexYAddr}},
{"SUBW", 2, {DirectAddr, None}},
{"DEC", 2, {DirectAddrByX, None}},
{"DEC", 1, {A, None}},
{"MOV", 1, {SP, X}},
{"DIV", 1, {None, None}},
{"XCN", 1, {None, None}},
{"EI", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"SBC", 2, {DirectAddr, None}},
{"SBC", 3, {AbsoluteAddr, None}},
{"SBC", 1, {IndexXAddr, None}},
{"SBC", 2, {AbsoluteDirectByXAddr, None}},
{"SBC", 2, {ImmediateData, None}},
{"SBC", 3, {DirectAddr, DirectAddr}},
{"MOV1", 3, {AbsoluteBit, None}},
{"INC", 2, {DirectAddr, None}},
{"INC", 3, {AbsoluteAddr, None}},
{"CMP", 2, {Y, ImmediateData}},
{"POP", 1, {A, None}},
{"MOV", 1, {A, IndexXAddr}},
{"BCS", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"SBC", 2, {DirectAddrByX, None}},
{"SBC", 3, {AbsoluteAddrByX, None}},
{"SBC", 3, {AbsoluteAddrByY, None}},
{"SBC", 2, {AbsoluteDirectAddrByY, None}},
{"SBC", 2, {DirectAddr, ImmediateData}},
{"SBC", 1, {IndexXAddr, IndexYAddr}},
{"MOVW", 2, {DirectAddr, None}},
{"INC", 2, {DirectAddrByX, None}},
{"INC", 1, {A, None}},
{"MOV", 1, {X, SP}},
{"DAS", 1, {None, None}},
{"MOV", 1, {IndexXAddr, A}},
{"DI", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"MOV", 2, {A, DirectAddr}},
{"MOV", 3, {A, AbsoluteAddr}},
{"MOV", 1, {A, IndexXAddr}},
{"MOV", 2, {A, AbsoluteDirectByXAddr}},
{"CMP", 2, {X, ImmediateData}},
{"MOV", 3, {X, AbsoluteAddr}},
{"MOV1", 3, {AbsoluteBit, None}},
{"MOV", 2, {Y, DirectAddr}},
{"MOV", 3, {Y, AbsoluteAddr}},
{"MOV", 2, {ImmediateData, X}},
{"POP", 1, {X, None}},
{"MUL", 1, {None, None}},
{"BNE", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"MOV", 2, {A, DirectAddrByX}},
{"MOV", 3, {A, AbsoluteAddrByX}},
{"MOV", 3, {A, AbsoluteAddrByY}},
{"MOV", 2, {A, AbsoluteDirectAddrByY}},
{"MOV", 2, {X, DirectAddr}},
{"MOV", 2, {X, DirectAddrByY}},
{"MOVW", 2, {DirectAddr, None}},
{"MOV", 2, {Y, DirectAddrByX}},
{"DEC", 1, {Y, None}},
{"MOV", 1, {Y, A}},
{"CBNE", 3, {DirectAddrByX, ImmediateData}},
{"DAA", 1, {None, None}},
{"CLRV", 1, {None, None}},
{"TCALL", 1, {None, None}},
{"SET1", 2, {DirectAddr, None}},
{"BBS", 3, {DirectAddr, ImmediateData}},
{"MOV", 2, {DirectAddr, A}},
{"MOV", 3, {AbsoluteAddrByX, A}},
{"MOV", 1, {IndexXAddr, A}},
{"MOV", 2, {AbsoluteDirectByXAddr, A}},
{"MOV", 2, {ImmediateData, A}},
{"MOV", 3, {AbsoluteAddr, X}},
{"NOT1", 3, {AbsoluteBit, None}},
{"MOV", 2, {DirectAddr, Y}},
{"MOV", 3, {AbsoluteAddr, Y}},
{"NOTC", 1, {None, None}},
{"POP", 1, {Y, None}},
{"SLEEP", 1, {None, None}},
{"BEQ", 2, {ImmediateData, None}},
{"TCALL", 1, {None, None}},
{"CLR1", 2, {DirectAddr, None}},
{"BBC", 3, {DirectAddr, ImmediateData}},
{"MOV", 2, {DirectAddrByX, A}},
{"MOV", 3, {AbsoluteAddrByX, A}},
{"MOV", 3, {AbsoluteAddrByY, A}},
{"MOV", 2, {AbsoluteDirectAddrByY, A}},
{"MOV", 2, {DirectAddr, X}},
{"MOV", 2, {DirectAddrByY, X}},
{"MOV", 3, {DirectAddr, DirectAddr}},
{"MOV", 2, {DirectAddrByX, Y}},
{"INC", 1, {Y, None}},
{"MOV", 1, {A, Y}},
{"DBNZ", 3, {ImmediateData, None}},
{"STOP", 1, {None, None}}
}};
//! @brief The QT window for this debugger.
ClosableWindow<APUDebug> *_window;
@@ -30,14 +323,18 @@ namespace ComSquare::Debugger
//! @brief Update the debugger panel values
void _updatePanel();
//! @brief Convert CPU APU flags to a string.
std::string _getPSWString();
//! @brief Updates the object that serves as the disassembly
void _updateLogger();
//! @brief Replace original _executeInstruction to write to the logger.
int _executeInstruction() override;
//! @brief return the mnemonic of the current instruction done.
std::string _getInstructionString();
//! @brief Retrieves the instruction from the SP location
Instruction &_getInstruction();
//! @brief Returns an operand in text format
std::string _getOperand(Operand ope);
public slots:
//! @brief Pause/Resume the APU.
void pause();
@@ -55,7 +352,6 @@ namespace ComSquare::Debugger
//! @brief Override the apu's update to disable debugging.
void update(unsigned cycles) override;
//! @brief Return true if the CPU is overloaded with debugging features.
bool isDebugger() const override;

View File

@@ -736,6 +736,8 @@ Test(ProgramFlow, JMP)
cr_assert_eq(apu->_internalRegisters.pc, 61455);
apu->_internalRegisters.pc = 0x32;
apu->_internalRegisters.x = 0b000000001;
apu->_internalWrite(0b1111000000001111 + 1, 0b00010000);
apu->_internalWrite(0b1111000000001111 + 2, 0b11110001);
result = apu->JMP(apu->_getAbsoluteByXAddr(), true);
cr_assert_eq(result, 6);
cr_assert_eq(apu->_internalRegisters.pc, 61712);

View File

@@ -94,7 +94,8 @@ Test(apu_get, absolutebyx)
apu->_internalRegisters.x = 10;
apu->_internalWrite(0x32, 0b00001111);
apu->_internalWrite(0x33, 0b11110000);
cr_assert_eq(apu->_getAbsoluteByXAddr(), 64025);
apu->_internalWrite(0b1111000000001111 + 10, 255);
cr_assert_eq(apu->_getAbsoluteByXAddr(), 255);
}
Test(apu_get, absoluteaddrbyx)

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>740</width>
<height>868</height>
<width>483</width>
<height>673</height>
</rect>
</property>
<property name="windowTitle">
@@ -31,7 +31,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="APU">
<attribute name="title">
@@ -329,23 +329,70 @@
<string>CPU</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="0">
<widget class="QTextBrowser" name="logger"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="loggerLabel">
<property name="text">
<string>Instructions History</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<item row="5" column="0">
<widget class="QTableWidget" name="logger"/>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_15">
<item row="0" column="7">
<widget class="QLineEdit" name="accumlatorLineEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="stackPointerLabel">
<property name="text">
<string>SP</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="accumlatorLabel">
<property name="text">
<string>A</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="xIndexLabel">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLineEdit" name="yIndexLineEdit"/>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="xIndexLineEdit"/>
</item>
<item row="0" column="4">
<widget class="QLabel" name="yIndexLabel">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="stackPointerLineEdit"/>
</item>
<item row="0" column="9">
<widget class="QLineEdit" name="programCounterLineEdit"/>
</item>
<item row="0" column="8">
<widget class="QLabel" name="programCounterLabel">
<property name="text">
<string>PC</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="resumeButton">
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="text">
<string>Resume</string>
</property>
@@ -368,70 +415,106 @@
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_15">
<item row="0" column="0">
<widget class="QLabel" name="stackPointerLabel">
<item row="2" column="0">
<layout class="QGridLayout" name="gridLayout_16">
<item row="1" column="3">
<widget class="QCheckBox" name="bFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Stack Pointer</string>
<string>B</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="programStatusWordLineEdit"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="yIndexLineEdit"/>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="programCounterLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="xIndexLabel">
<item row="1" column="2">
<widget class="QCheckBox" name="pFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>X Index</string>
<string>P</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="accumlatorLabel">
<item row="1" column="6">
<widget class="QCheckBox" name="zFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Accumlator</string>
<string>Z</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="stackPointerLineEdit"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="accumlatorLineEdit"/>
<item row="1" column="7">
<widget class="QCheckBox" name="cFlagCheckBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="xIndexLineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="yIndexLabel">
<widget class="QCheckBox" name="vFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Y Index</string>
<string>V</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="programCounterLabel">
<item row="1" column="4">
<widget class="QCheckBox" name="hFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Program Counter</string>
<string>H</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="programStatusWordLabel">
<item row="1" column="5">
<widget class="QCheckBox" name="iFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Program Status Word</string>
<string>I</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="nFlagCheckBox">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>N</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="loggerLabel">
<property name="text">
<string>Instructions History</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="DSP">