mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-06 03:12:19 +00:00
Finishing lazy disassembly updating and adding an auto scroll to the row
This commit is contained in:
@@ -29,7 +29,7 @@ namespace ComSquare::Debugger
|
|||||||
|
|
||||||
this->_ui.setupUi(this->_window);
|
this->_ui.setupUi(this->_window);
|
||||||
|
|
||||||
this->disassembledInstructions = this->_disassemble(this->_registers.pac, 0x7FFF);
|
this->_updateDisassembly(0xFFFF - this->_registers.pc); //Parse the first page of the ROM (the code can't reach the second page without a jump).
|
||||||
this->_ui.disassembly->setModel(&this->_model);
|
this->_ui.disassembly->setModel(&this->_model);
|
||||||
this->_ui.disassembly->horizontalHeader()->setStretchLastSection(true);
|
this->_ui.disassembly->horizontalHeader()->setStretchLastSection(true);
|
||||||
this->_ui.disassembly->resizeColumnsToContents();
|
this->_ui.disassembly->resizeColumnsToContents();
|
||||||
@@ -60,7 +60,7 @@ namespace ComSquare::Debugger
|
|||||||
return 0xFF;
|
return 0xFF;
|
||||||
if (this->_isStepping) {
|
if (this->_isStepping) {
|
||||||
unsigned ret = this->_executeInstruction(this->readPC());
|
unsigned ret = this->_executeInstruction(this->readPC());
|
||||||
this->_ui.disassembly->viewport()->repaint();
|
this->_updateDisassembly();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return CPU::update();
|
return CPU::update();
|
||||||
@@ -81,7 +81,7 @@ namespace ComSquare::Debugger
|
|||||||
this->_isPaused = true;
|
this->_isPaused = true;
|
||||||
}
|
}
|
||||||
uint24_t pc = (this->_registers.pbr << 16u) | (this->_registers.pc - 1u);
|
uint24_t pc = (this->_registers.pbr << 16u) | (this->_registers.pc - 1u);
|
||||||
DisassemblyContext ctx = {this->_registers.p.m, this->_registers.p.x_b};
|
DisassemblyContext ctx = this->_getDisassemblyContext();
|
||||||
DisassembledInstruction instruction = this->_parseInstruction(pc, ctx);
|
DisassembledInstruction instruction = this->_parseInstruction(pc, ctx);
|
||||||
this->_ui.logger->append((instruction.toString() + " - " + Utility::to_hex(opcode)).c_str());
|
this->_ui.logger->append((instruction.toString() + " - " + Utility::to_hex(opcode)).c_str());
|
||||||
unsigned ret = CPU::_executeInstruction(opcode);
|
unsigned ret = CPU::_executeInstruction(opcode);
|
||||||
@@ -96,10 +96,7 @@ namespace ComSquare::Debugger
|
|||||||
this->_ui.actionPause->setText("Resume");
|
this->_ui.actionPause->setText("Resume");
|
||||||
else
|
else
|
||||||
this->_ui.actionPause->setText("Pause");
|
this->_ui.actionPause->setText("Pause");
|
||||||
// TODO reload the disassembly from this point to update items that may be false up to this point
|
this->_updateDisassembly();
|
||||||
// TODO highlight the current line.
|
|
||||||
//this->disassembledInstructions. //= this->_disassemble(0x808000, 0x7FFF);
|
|
||||||
this->_ui.disassembly->viewport()->repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUDebug::step()
|
void CPUDebug::step()
|
||||||
@@ -152,11 +149,37 @@ namespace ComSquare::Debugger
|
|||||||
this->_ui.logger->clear();
|
this->_ui.logger->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DisassembledInstruction> CPUDebug::_disassemble(uint24_t pc, uint24_t length)
|
void CPUDebug::_updateDisassembly(uint24_t refreshSize)
|
||||||
|
{
|
||||||
|
auto first = std::find_if(this->disassembledInstructions.begin(), this->disassembledInstructions.end(), [this](DisassembledInstruction &i) {
|
||||||
|
return i.address >= this->_registers.pac;
|
||||||
|
});
|
||||||
|
auto end = std::find_if(this->disassembledInstructions.begin(), this->disassembledInstructions.end(),[this, refreshSize](DisassembledInstruction &i) {
|
||||||
|
return i.address >= this->_registers.pac + refreshSize;
|
||||||
|
});
|
||||||
|
this->disassembledInstructions.erase(first, end);
|
||||||
|
|
||||||
|
auto next = std::find_if(this->disassembledInstructions.begin(), this->disassembledInstructions.end(), [this](DisassembledInstruction &i) {
|
||||||
|
return i.address >= this->_registers.pac;
|
||||||
|
});
|
||||||
|
int row = next - this->disassembledInstructions.begin();
|
||||||
|
DisassemblyContext ctx = this->_getDisassemblyContext();
|
||||||
|
std::vector<DisassembledInstruction> nextInstructions = this->_disassemble(this->_registers.pac, refreshSize, ctx);
|
||||||
|
this->disassembledInstructions.insert(next, nextInstructions.begin(), nextInstructions.end());
|
||||||
|
if (this->_ui.disassembly->rowAt(0) > row || this->_ui.disassembly->rowAt(this->_ui.disassembly->height()) < row)
|
||||||
|
this->_ui.disassembly->scrollTo(this->_model.index(row, 0), QAbstractItemView::PositionAtCenter);
|
||||||
|
this->_ui.disassembly->viewport()->repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
DisassemblyContext CPUDebug::_getDisassemblyContext()
|
||||||
|
{
|
||||||
|
return {this->_registers.p.m, this->_registers.p.x_b, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DisassembledInstruction> CPUDebug::_disassemble(uint24_t pc, uint24_t length, DisassemblyContext &ctx)
|
||||||
{
|
{
|
||||||
std::vector<DisassembledInstruction> map;
|
std::vector<DisassembledInstruction> map;
|
||||||
uint24_t endAddr = pc + length;
|
uint24_t endAddr = pc + length;
|
||||||
DisassemblyContext ctx;
|
|
||||||
|
|
||||||
while (pc < endAddr) {
|
while (pc < endAddr) {
|
||||||
DisassembledInstruction instruction = this->_parseInstruction(pc, ctx);
|
DisassembledInstruction instruction = this->_parseInstruction(pc, ctx);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public:
|
|||||||
class RowPainter : public QStyledItemDelegate {
|
class RowPainter : public QStyledItemDelegate {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
|
//! @brief The CPU to get PC and breakpoints from.
|
||||||
ComSquare::Debugger::CPUDebug &_cpu;
|
ComSquare::Debugger::CPUDebug &_cpu;
|
||||||
public:
|
public:
|
||||||
explicit RowPainter(ComSquare::Debugger::CPUDebug &cpu, QObject *parent = nullptr);
|
explicit RowPainter(ComSquare::Debugger::CPUDebug &cpu, QObject *parent = nullptr);
|
||||||
@@ -102,8 +103,13 @@ namespace ComSquare::Debugger
|
|||||||
SNES &_snes;
|
SNES &_snes;
|
||||||
//! @brief Reimplement the basic instruction execution method to log instructions inside the logger view.
|
//! @brief Reimplement the basic instruction execution method to log instructions inside the logger view.
|
||||||
unsigned _executeInstruction(uint8_t opcode) override;
|
unsigned _executeInstruction(uint8_t opcode) override;
|
||||||
|
//! @brief Return a disassembly context representing the current state of the processor.
|
||||||
|
DisassemblyContext _getDisassemblyContext();
|
||||||
//! @brief Disassemble part of the memory (using the bus) and parse it to a map of address and disassembled instruction.
|
//! @brief Disassemble part of the memory (using the bus) and parse it to a map of address and disassembled instruction.
|
||||||
std::vector<DisassembledInstruction> _disassemble(uint24_t startAddr, uint24_t size);
|
//! @param ctx The initial context of the processor before the disassembly begin.
|
||||||
|
std::vector<DisassembledInstruction> _disassemble(uint24_t startAddr, uint24_t size, DisassemblyContext &ctx);
|
||||||
|
//! @brief Update disassembly with the new state of the processor.
|
||||||
|
void _updateDisassembly(uint24_t refreshSize = 0xFF);
|
||||||
//! @brief Parse the instruction at the program counter given to have human readable information.
|
//! @brief Parse the instruction at the program counter given to have human readable information.
|
||||||
DisassembledInstruction _parseInstruction(uint24_t pc, DisassemblyContext &ctx);
|
DisassembledInstruction _parseInstruction(uint24_t pc, DisassemblyContext &ctx);
|
||||||
//! @brief Get the parameter of the instruction as an hexadecimal string.
|
//! @brief Get the parameter of the instruction as an hexadecimal string.
|
||||||
@@ -116,8 +122,6 @@ namespace ComSquare::Debugger
|
|||||||
//! @brief Return a printable string corresponding to the value of a 8 or 16 bits immediate addressing mode.
|
//! @brief Return a printable string corresponding to the value of a 8 or 16 bits immediate addressing mode.
|
||||||
//! @param dual Set this to true if the instruction take 16bits and not 8. (used for the immediate by a when the flag m is not set or the immediate by x if the flag x is not set).
|
//! @param dual Set this to true if the instruction take 16bits and not 8. (used for the immediate by a when the flag m is not set or the immediate by x if the flag x is not set).
|
||||||
std::string _getImmediateValue(uint24_t pc, bool dual);
|
std::string _getImmediateValue(uint24_t pc, bool dual);
|
||||||
//! @brief Return a printable string corresponding to the value of a 16bits immediate addressing mode.
|
|
||||||
std::string _getImmediateValue16Bits(uint24_t pc);
|
|
||||||
//! @brief Return a printable string corresponding to the value of a direct addressing mode.
|
//! @brief Return a printable string corresponding to the value of a direct addressing mode.
|
||||||
std::string _getDirectValue(uint24_t pc);
|
std::string _getDirectValue(uint24_t pc);
|
||||||
//! @brief Return a printable string corresponding to the value of an absolute addressing mode.
|
//! @brief Return a printable string corresponding to the value of an absolute addressing mode.
|
||||||
|
|||||||
Reference in New Issue
Block a user