mirror of
https://github.com/zoriya/ComSquare.git
synced 2025-12-06 07:16:17 +00:00
Replace logger with basic disassembly in APU debugger (& fixing Absolute By X Address operand?)
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
185
ui/apuView.ui
185
ui/apuView.ui
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user