mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-06 11:22:27 +00:00
Merging origin/master
This commit is contained in:
@@ -535,7 +535,7 @@ namespace ComSquare::Debugger
|
||||
this->_snes.disableAPUDebugging();
|
||||
}
|
||||
|
||||
bool APUDebug::isDebugger()
|
||||
bool APUDebug::isDebugger() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace ComSquare::Debugger
|
||||
|
||||
|
||||
//! @brief Return true if the CPU is overloaded with debugging features.
|
||||
bool isDebugger() override;
|
||||
bool isDebugger() const override;
|
||||
|
||||
//! @brief Focus the debugger's window.
|
||||
void focus();
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <QtEvents>
|
||||
#include <QPainter>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace ComSquare::CPU;
|
||||
|
||||
@@ -58,7 +60,7 @@ namespace ComSquare::Debugger
|
||||
this->_updateDisassembly(this->_registers.pac, 0);
|
||||
}
|
||||
|
||||
bool CPUDebug::isDebugger()
|
||||
bool CPUDebug::isDebugger() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -79,6 +81,10 @@ namespace ComSquare::Debugger
|
||||
try {
|
||||
unsigned cycles = 0;
|
||||
|
||||
for (auto &channel : this->_dmaChannels)
|
||||
if (channel.enabled)
|
||||
cycles += channel.run(INT_MAX);
|
||||
|
||||
if (this->_isPaused)
|
||||
return 0xFF;
|
||||
if (this->_isStepping) {
|
||||
@@ -129,11 +135,22 @@ namespace ComSquare::Debugger
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CPUDebug::pause()
|
||||
void CPUDebug::showError(const DebuggableError &error)
|
||||
{
|
||||
QMessageBox msg;
|
||||
msg.setIcon(QMessageBox::Critical);
|
||||
msg.setText("Invalid rom action");
|
||||
msg.setInformativeText(error.what());
|
||||
msg.exec();
|
||||
}
|
||||
|
||||
void CPUDebug::pause(bool forcePause)
|
||||
{
|
||||
if (forcePause && this->_isPaused)
|
||||
return;
|
||||
this->_isPaused = !this->_isPaused;
|
||||
if (this->_isPaused)
|
||||
this->_ui.actionPause->setText("Resume");
|
||||
this->_ui.actionPause->setText("Continue");
|
||||
else
|
||||
this->_ui.actionPause->setText("Pause");
|
||||
this->_updateDisassembly(this->_registers.pac);
|
||||
@@ -383,7 +400,9 @@ QSize RowPainter::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) co
|
||||
return QSize();
|
||||
}
|
||||
|
||||
StackModel::StackModel(std::shared_ptr<ComSquare::Memory::MemoryBus> bus, ComSquare::Debugger::CPUDebug &cpu) : _bus(bus), _cpu(cpu) { }
|
||||
StackModel::StackModel(std::shared_ptr<ComSquare::Memory::MemoryBus> bus, ComSquare::Debugger::CPUDebug &cpu)
|
||||
: _bus(std::move(bus)), _cpu(cpu)
|
||||
{ }
|
||||
|
||||
void StackModel::setMemoryBus(std::shared_ptr<ComSquare::Memory::MemoryBus> bus)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "../../CPU/CPU.hpp"
|
||||
#include "../../Renderer/SFRenderer.hpp"
|
||||
#include "../../SNES.hpp"
|
||||
#include "../../../ui/ui_cpu.h"
|
||||
#include "../../../ui/ui_cpuView.h"
|
||||
#include "../ClosableWindow.hpp"
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
@@ -248,8 +248,10 @@ namespace ComSquare::Debugger
|
||||
std::string _getAbsoluteIndirectLongValue(uint24_t pc);
|
||||
|
||||
public:
|
||||
//! @brief Show an error dialog related to an exception.
|
||||
void showError(const DebuggableError &error);
|
||||
//! @brief Pause/Resume the CPU.
|
||||
void pause();
|
||||
void pause(bool forcePause = false);
|
||||
//! @brief Step - Execute a single instruction.
|
||||
void step();
|
||||
//! @brief Next - Continue running instructions until the next line is reached.
|
||||
@@ -281,7 +283,7 @@ namespace ComSquare::Debugger
|
||||
~CPUDebug() override = default;
|
||||
|
||||
//! @brief Return true if the CPU is overloaded with debugging features.
|
||||
bool isDebugger() override;
|
||||
bool isDebugger() const override;
|
||||
|
||||
//! @brief Focus the debugger's window.
|
||||
void focus();
|
||||
|
||||
@@ -251,7 +251,7 @@ namespace ComSquare::Debugger
|
||||
|
||||
std::string CPUDebug::_getAbsoluteIndirectValue(uint24_t pc)
|
||||
{
|
||||
uint24_t value = this->_bus->read(pc) + (this->_bus->read(pc + 1, true) << 8u);
|
||||
uint24_t value = this->_bus->read(pc, true) + (this->_bus->read(pc + 1, true) << 8u);
|
||||
return "(" + Utility::to_hex(value, Utility::HexString::AsmPrefix) + ")";
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ namespace ComSquare::Debugger
|
||||
|
||||
std::string CPUDebug::_getAbsoluteIndirectIndexedByXValue(uint24_t pc)
|
||||
{
|
||||
uint24_t value = this->_bus->read(pc) + (this->_bus->read(pc + 1, true) << 8u);
|
||||
uint24_t value = this->_bus->read(pc, true) + (this->_bus->read(pc + 1, true) << 8u);
|
||||
return "(" + Utility::to_hex(value, Utility::HexString::AsmPrefix) + ", x)";
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,13 @@ namespace ComSquare::Debugger
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t MemoryBusDebug::read(uint24_t addr)
|
||||
{
|
||||
if (this->forceSilence)
|
||||
return MemoryBus::read(addr);
|
||||
return this->read(addr, false);
|
||||
}
|
||||
|
||||
uint8_t MemoryBusDebug::read(uint24_t addr, bool silence)
|
||||
{
|
||||
if (!silence && !this->forceSilence) {
|
||||
@@ -155,11 +162,11 @@ namespace ComSquare::Debugger
|
||||
if (!accessor) {
|
||||
this->_model.log(BusLog(true, addr, accessor, this->_openBus, this->_openBus));
|
||||
} else {
|
||||
uint8_t value = accessor->read(addr - accessor->getStart());
|
||||
uint8_t value = accessor->read(accessor->getRelativeAddress(addr));
|
||||
this->_model.log(BusLog(false, addr, accessor, value, value));
|
||||
}
|
||||
}
|
||||
return MemoryBus::read(addr);
|
||||
return MemoryBus::read(addr, silence);
|
||||
}
|
||||
|
||||
void MemoryBusDebug::write(uint24_t addr, uint8_t data)
|
||||
@@ -168,7 +175,7 @@ namespace ComSquare::Debugger
|
||||
std::optional<uint8_t> value = std::nullopt;
|
||||
try {
|
||||
if (accessor)
|
||||
value = accessor->read(addr - accessor->getStart());
|
||||
value = accessor->read(accessor->getRelativeAddress(addr));
|
||||
} catch (InvalidAddress &) {
|
||||
value = std::nullopt;
|
||||
}
|
||||
@@ -177,7 +184,7 @@ namespace ComSquare::Debugger
|
||||
MemoryBus::write(addr, data);
|
||||
}
|
||||
|
||||
BusLog::BusLog(bool _write, uint24_t _addr, std::shared_ptr<Memory::AMemory> &_accessor, std::optional<uint8_t> _oldData, uint8_t _newData) :
|
||||
BusLog::BusLog(bool _write, uint24_t _addr, std::shared_ptr<Memory::IMemory> &_accessor, std::optional<uint8_t> _oldData, uint8_t _newData) :
|
||||
write(_write), addr(_addr), accessor(std::move(_accessor)), oldData(_oldData), newData(_newData)
|
||||
{}
|
||||
}
|
||||
@@ -206,8 +213,10 @@ QVariant BusLogModel::data(const QModelIndex &index, int role) const
|
||||
return QString(ComSquare::Utility::to_hex(log.addr).c_str());
|
||||
case 2:
|
||||
return QString(log.accessor ? log.accessor->getName().c_str() : "Bus");
|
||||
case 3:
|
||||
return QString(log.accessor ? log.accessor->getValueName(log.addr - log.accessor->getStart()).c_str() : "Open bus");
|
||||
case 3: {
|
||||
uint24_t addr = log.accessor->getRelativeAddress(log.addr);
|
||||
return QString(log.accessor ? log.accessor->getValueName(addr).c_str() : "Open bus");
|
||||
}
|
||||
case 4:
|
||||
if (!log.oldData)
|
||||
return QString("???");
|
||||
|
||||
@@ -17,13 +17,13 @@ namespace ComSquare::Debugger
|
||||
struct BusLog {
|
||||
BusLog(bool write,
|
||||
uint24_t addr,
|
||||
std::shared_ptr<Memory::AMemory> &accessor,
|
||||
std::shared_ptr<Memory::IMemory> &accessor,
|
||||
std::optional<uint8_t> oldData,
|
||||
uint8_t newData);
|
||||
|
||||
bool write;
|
||||
uint24_t addr;
|
||||
std::shared_ptr<Memory::AMemory> accessor;
|
||||
std::shared_ptr<Memory::IMemory> accessor;
|
||||
std::optional<uint8_t> oldData;
|
||||
uint8_t newData;
|
||||
};
|
||||
@@ -127,7 +127,12 @@ namespace ComSquare::Debugger
|
||||
//! @brief Read data at a global address and log it to the debugger.
|
||||
//! @param addr The address to read from.
|
||||
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
|
||||
uint8_t read(uint24_t addr, bool silence = false) override;
|
||||
uint8_t read(uint24_t addr) override;
|
||||
|
||||
//! @brief Read data at a global address and log it to the debugger.
|
||||
//! @param addr The address to read from.
|
||||
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
|
||||
uint8_t read(uint24_t addr, bool silence) override;
|
||||
|
||||
//! @brief Write a data to a global address and log it to the debugger.
|
||||
//! @param addr The address to write to.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <cmath>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
#include <QMessageBox>
|
||||
#include "MemoryViewer.hpp"
|
||||
#include "../SNES.hpp"
|
||||
#include "../Memory/MemoryShadow.hpp"
|
||||
@@ -35,7 +36,7 @@ QVariant MemoryViewerModel::data(const QModelIndex &index, int role) const
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
char buf[3];
|
||||
snprintf(buf, 3, "%02X", this->_memory->read_internal((index.row() << 4u) + index.column()));
|
||||
snprintf(buf, 3, "%02X", this->_memory->read((index.row() << 4u) + index.column()));
|
||||
return QString(buf);
|
||||
}
|
||||
|
||||
@@ -147,33 +148,48 @@ namespace ComSquare::Debugger
|
||||
if (dialogUI.checkBox->isChecked()) {
|
||||
try {
|
||||
value = this->switchToAddrTab(value);
|
||||
} catch (InvalidAddress &) {}
|
||||
} catch (const InvalidAddress &) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText("This address is not mapped. Reading it will result in OpenBus.");
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
QModelIndex index = this->_ui.tableView->model()->index(value >> 4, value & 0x0000000F);
|
||||
QModelIndex index = this->_ui.tableView->model()->index(value >> 4, value & 0x0F);
|
||||
this->_ui.tableView->scrollTo(index);
|
||||
this->_ui.tableView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
|
||||
this->_ui.tableView->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
unsigned MemoryViewer::switchToAddrTab(uint24_t addr)
|
||||
{
|
||||
std::shared_ptr<Memory::AMemory> accessor = this->_bus.getAccessor(addr);
|
||||
std::shared_ptr<Memory::IMemory> accessor = this->_bus.getAccessor(addr);
|
||||
if (!accessor)
|
||||
throw InvalidAddress("Memory viewer switch to address", addr);
|
||||
Memory::AMemory *ptr;
|
||||
if (accessor->isMirror())
|
||||
ptr = accessor->getMirrored().get();
|
||||
else
|
||||
ptr = accessor.get();
|
||||
|
||||
if (ptr == this->_snes.wram.get())
|
||||
switch (accessor->getComponent()) {
|
||||
case WRam:
|
||||
this->_ui.tabs->setCurrentIndex(0);
|
||||
else if (ptr == this->_snes.sram.get())
|
||||
break;
|
||||
case SRam:
|
||||
this->_ui.tabs->setCurrentIndex(1);
|
||||
else if (ptr == this->_snes.cartridge.get())
|
||||
break;
|
||||
case Rom:
|
||||
this->_ui.tabs->setCurrentIndex(2);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
throw InvalidAddress("Memory viewer switch to address", addr);
|
||||
return addr - accessor->getStart();
|
||||
}
|
||||
addr = accessor->getRelativeAddress(addr);
|
||||
if (addr > accessor->getSize()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText((std::string("The ") + accessor->getName() + " is too small to contain this address.").c_str());
|
||||
msgBox.exec();
|
||||
return 0;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
void MemoryViewer::focus()
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
//
|
||||
// Created by anonymus-raccoon on 5/28/20.
|
||||
//
|
||||
|
||||
#include "RegisterViewer.hpp"
|
||||
#include "../SNES.hpp"
|
||||
#include "../Utility/Utility.hpp"
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
{
|
||||
RegisterViewer::RegisterViewer(SNES &snes)
|
||||
: _window(new ClosableWindow<RegisterViewer>(*this, &RegisterViewer::disableDebugger)),
|
||||
_ui(),
|
||||
_snes(snes)
|
||||
{
|
||||
this->_window->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
this->_window->setAttribute(Qt::WA_QuitOnClose, false);
|
||||
this->_window->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
this->_ui.setupUi(this->_window);
|
||||
this->_setupUi();
|
||||
this->_window->show();
|
||||
}
|
||||
|
||||
void RegisterViewer::_setupUi()
|
||||
{
|
||||
this->_models.clear();
|
||||
|
||||
std::array<QTableView *, 8> channels = {
|
||||
this->_ui.dmaChannel1,
|
||||
this->_ui.dmaChannel2,
|
||||
this->_ui.dmaChannel3,
|
||||
this->_ui.dmaChannel4,
|
||||
this->_ui.dmaChannel5,
|
||||
this->_ui.dmaChannel6,
|
||||
this->_ui.dmaChannel7,
|
||||
this->_ui.dmaChannel8
|
||||
};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
RegistersViewerModel *model = new RegistersViewerModel(this->_snes);
|
||||
model->addRegister(Register(0x420B, std::string(":") + std::to_string(i), "Enabled", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i].enabled;
|
||||
}, nullptr, Boolean));
|
||||
model->addRegister(Register(0x4302 + (i << 4u), "-4", "A address", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i]._aAddress.raw;
|
||||
}, nullptr, TwentyFourBits));
|
||||
model->addRegister(Register(0x4301 + (i << 4u), "", "B address", [i](SNES &snes) {
|
||||
return 0x2100 | snes.cpu->_dmaChannels[i]._port;
|
||||
}, nullptr, SixteenBits));
|
||||
model->addRegister(Register(0x4305 + (i << 4u), "-6", "Count", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i]._count.raw;
|
||||
}, nullptr, SixteenBits));
|
||||
model->addRegister(Register(0x4300 + (i << 4u), ":7", "B To A", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i]._controlRegister.direction;
|
||||
}, nullptr, Boolean));
|
||||
model->addRegister(Register(0x4300 + (i << 4u), ":3", "Fixed", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i]._controlRegister.fixed;
|
||||
}, nullptr, Boolean));
|
||||
model->addRegister(Register(0x4300 + (i << 4u), ":4", "Decrement", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i]._controlRegister.increment;
|
||||
}, nullptr, Boolean));
|
||||
model->addRegister(Register(0x4300 + (i << 4u), ":0-2", "Mode", [i](SNES &snes) {
|
||||
return snes.cpu->_dmaChannels[i]._controlRegister.increment;
|
||||
}, nullptr, EightBits));
|
||||
channels[i]->setModel(model);
|
||||
this->_models.push_back(model);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterViewer::focus()
|
||||
{
|
||||
this->_window->activateWindow();
|
||||
}
|
||||
|
||||
void RegisterViewer::disableDebugger()
|
||||
{
|
||||
this->_snes.disableRegisterDebugging();
|
||||
}
|
||||
|
||||
RegisterViewer::~RegisterViewer()
|
||||
{
|
||||
for (auto &model : this->_models)
|
||||
delete model;
|
||||
}
|
||||
|
||||
Register::Register(uint24_t addr,
|
||||
const std::string &usedBits,
|
||||
const std::string ®Name,
|
||||
const std::function<unsigned int(SNES &)> &getValue,
|
||||
const std::function<void(SNES &, unsigned int)> &setValue,
|
||||
RegisterType regType)
|
||||
: address(addr),
|
||||
bits(usedBits),
|
||||
name(regName),
|
||||
get(getValue),
|
||||
set(setValue),
|
||||
type(regType) {}
|
||||
}
|
||||
|
||||
using namespace ComSquare;
|
||||
using namespace ComSquare::Debugger;
|
||||
|
||||
RegistersViewerModel::RegistersViewerModel(SNES &snes, QObject *parent) : QAbstractTableModel(parent), _snes(snes) { }
|
||||
|
||||
|
||||
void RegistersViewerModel::addRegister(Register reg)
|
||||
{
|
||||
int row = this->_registers.size();
|
||||
this->beginInsertRows(QModelIndex(), row, row);
|
||||
this->_registers.push_back(reg);
|
||||
this->insertRow(row);
|
||||
this->endInsertRows();
|
||||
}
|
||||
|
||||
int RegistersViewerModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return this->_registers.size();
|
||||
}
|
||||
|
||||
int RegistersViewerModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
QVariant RegistersViewerModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Register reg = this->_registers[index.row()];
|
||||
|
||||
if (role == Qt::CheckStateRole && reg.type == Boolean && index.column() == 2)
|
||||
return reg.get(this->_snes) ? Qt::Checked : Qt::Unchecked;
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
return QString((Utility::to_hex(reg.address) + reg.bits).c_str());
|
||||
case 1:
|
||||
return QString(reg.name.c_str());
|
||||
case 2:
|
||||
switch (reg.type) {
|
||||
case Boolean:
|
||||
return QString(reg.get(this->_snes) ? "True" : "False");
|
||||
case EightBits:
|
||||
return QString(Utility::to_hex(static_cast<uint8_t>(reg.get(this->_snes))).c_str());
|
||||
case SixteenBits:
|
||||
return QString(Utility::to_hex(static_cast<uint16_t>(reg.get(this->_snes))).c_str());
|
||||
case TwentyFourBits:
|
||||
return QString(Utility::to_hex(static_cast<uint24_t>(reg.get(this->_snes))).c_str());
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant RegistersViewerModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Vertical || role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
switch (section) {
|
||||
case 0:
|
||||
return QString("Address");
|
||||
case 1:
|
||||
return QString("Name");
|
||||
case 2:
|
||||
return QString("Value");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// Created by anonymus-raccoon on 5/28/20.
|
||||
//
|
||||
|
||||
#ifndef COMSQUARE_REGISTERVIEWER_HPP
|
||||
#define COMSQUARE_REGISTERVIEWER_HPP
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include "ClosableWindow.hpp"
|
||||
#include "../../ui/ui_registersView.h"
|
||||
#include "../Models/Int24.hpp"
|
||||
#include "../Memory/MemoryBus.hpp"
|
||||
|
||||
namespace ComSquare::Debugger
|
||||
{
|
||||
struct Register;
|
||||
}
|
||||
|
||||
class RegistersViewerModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
//! @brief The list of registers to display / update.
|
||||
std::vector<ComSquare::Debugger::Register> _registers;
|
||||
//! @brief Reference to the snes to get information from registers.
|
||||
ComSquare::SNES &_snes;
|
||||
public:
|
||||
//! @brief Add a register.
|
||||
void addRegister(ComSquare::Debugger::Register reg);
|
||||
|
||||
RegistersViewerModel(ComSquare::SNES &snes, QObject *parent = nullptr);
|
||||
RegistersViewerModel(const RegistersViewerModel &) = delete;
|
||||
const RegistersViewerModel &operator=(const RegistersViewerModel &) = delete;
|
||||
~RegistersViewerModel() override = default;
|
||||
|
||||
//! @brief The number of row the table has.
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
//! @brief The number of column the table has.
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
//! @brief Return a data representing the table cell.
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
//! @brief Override the headers to use hex values.
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
};
|
||||
|
||||
|
||||
namespace ComSquare
|
||||
{
|
||||
class SNES;
|
||||
|
||||
namespace Debugger
|
||||
{
|
||||
class RegisterViewer : public QObject {
|
||||
private:
|
||||
//! @brief The QT window for this debugger.
|
||||
ClosableWindow<RegisterViewer> *_window;
|
||||
//! @brief A widget that contain the whole UI.
|
||||
Ui::RegistersView _ui;
|
||||
//! @brief The list of models used by different panels.
|
||||
std::vector<RegistersViewerModel *> _models;
|
||||
|
||||
//! @brief The snes instance to read/write to.
|
||||
SNES &_snes;
|
||||
|
||||
//! @brief Set models to the different tables and initialize them.
|
||||
void _setupUi();
|
||||
public:
|
||||
//! @brief Called when the window is closed. Turn off the debugger.
|
||||
void disableDebugger();
|
||||
|
||||
explicit RegisterViewer(SNES &snes);
|
||||
RegisterViewer(
|
||||
const RegisterViewer &) = delete;
|
||||
RegisterViewer &operator=(const RegisterViewer &) = delete;
|
||||
~RegisterViewer();
|
||||
|
||||
//! @brief Focus the debugger's window.
|
||||
void focus();
|
||||
};
|
||||
|
||||
//! @brief The types of registers
|
||||
enum RegisterType {
|
||||
//! @brief This type display a checkbox
|
||||
Boolean,
|
||||
//! @brief A 8 bits hexadecimal value.
|
||||
EightBits,
|
||||
//! @brief A 16 bits hexadecimal value.
|
||||
SixteenBits,
|
||||
//! @brief A 24 bits hexadecimal value.
|
||||
TwentyFourBits
|
||||
};
|
||||
|
||||
//! @brief Struct containing information about a register.
|
||||
struct Register {
|
||||
Register(uint24_t addr,
|
||||
const std::string &usedBits,
|
||||
const std::string ®Name,
|
||||
const std::function<unsigned int(SNES &)> &getValue,
|
||||
const std::function<void(SNES &, unsigned int)> &setValue,
|
||||
RegisterType regType);
|
||||
|
||||
//! @brief Where this register is located on the bus.
|
||||
uint24_t address;
|
||||
//! @brief Specify witch bits are concerned if not all bytes are concerned.
|
||||
std::string bits;
|
||||
//! @brief The name of this register.
|
||||
std::string name;
|
||||
//! @brief How to get this value.
|
||||
std::function<unsigned(SNES &)> get;
|
||||
//! @brief How to set this value.
|
||||
std::function<void(SNES &, unsigned)> set;
|
||||
//! @brief How this value should be displayed/asked for input.
|
||||
RegisterType type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //COMSQUARE_REGISTERVIEWER_HPP
|
||||
Reference in New Issue
Block a user