From e6ca4b4568e311b47239bfe83de15ed9e91c57b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Fri, 15 Dec 2017 22:45:28 +0100 Subject: Implement few initial graphic elements --- qtmips_gui/coreview.cpp | 48 ++++++++++----------- qtmips_gui/coreview.h | 46 ++++++++------------ qtmips_gui/coreview/connection.cpp | 79 ++++++++++++++++++++++++++++++++++ qtmips_gui/coreview/connection.h | 60 ++++++++++++++++++++++++++ qtmips_gui/coreview/latch.cpp | 51 ++++++++++++++++++++++ qtmips_gui/coreview/latch.h | 45 +++++++++++++++++++ qtmips_gui/coreview/multiplexer.cpp | 79 ++++++++++++++++++++++++++++++++++ qtmips_gui/coreview/multiplexer.h | 41 ++++++++++++++++++ qtmips_gui/coreview/programcounter.cpp | 48 +++++++++++++++++++++ qtmips_gui/coreview/programcounter.h | 42 ++++++++++++++++++ qtmips_gui/mainwindow.cpp | 26 ++++++++--- qtmips_gui/qtmips_gui.pro | 12 +++++- qtmips_machine/qtmipsmachine.cpp | 17 +++++++- qtmips_machine/qtmipsmachine.h | 2 + qtmips_machine/registers.cpp | 3 ++ qtmips_machine/registers.h | 3 +- 16 files changed, 538 insertions(+), 64 deletions(-) create mode 100644 qtmips_gui/coreview/connection.cpp create mode 100644 qtmips_gui/coreview/connection.h create mode 100644 qtmips_gui/coreview/latch.cpp create mode 100644 qtmips_gui/coreview/latch.h create mode 100644 qtmips_gui/coreview/multiplexer.cpp create mode 100644 qtmips_gui/coreview/multiplexer.h create mode 100644 qtmips_gui/coreview/programcounter.cpp create mode 100644 qtmips_gui/coreview/programcounter.h diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp index 4d23bd8..660f78d 100644 --- a/qtmips_gui/coreview.cpp +++ b/qtmips_gui/coreview.cpp @@ -1,35 +1,35 @@ #include "coreview.h" -CoreView::CoreView(QWidget *parent) : QGraphicsView(parent) { +CoreView::CoreView(QWidget *parent, QtMipsMachine *machine) : QGraphicsView(parent) { + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); -} - -/* -CoreViewBlock::CoreViewBlock() { -} - -CoreViewLine::CoreViewLine() { - -} - -CoreViewLine::CoreViewLine(struct point start, struct point end, QList axis) { + this->machine = machine; + // Identification cross + scene.addLine(400, 0, 400, 800); + scene.addLine(0, 400, 800, 400); -} + pc = new coreview::ProgramCounter(machine); + pc_multiplexer = new coreview::Multiplexer(4); + testlatch = new coreview::Latch(machine, 300); -CoreViewLine::~CoreViewLine() { + pc2pc = new coreview::Connection(pc_multiplexer->connector_out(), pc->connector_in()); -} + scene.addItem(pc); + scene.addItem(pc_multiplexer); + scene.addItem(testlatch); + scene.addItem(pc2pc); -void CoreViewLine::set_start(struct point p) { + pc->setPos(100,100); + pc_multiplexer->setPos(60, 100); + pc_multiplexer->set(2); + setScene(&scene); + // TODO fitInView doesn't work as I want so reimplement or do something with it + //fitInView(0, 0, 201, 201, Qt::KeepAspectRatioByExpanding); } -void CoreViewLine::set_end(struct point p) { - +void CoreView::resizeEvent(QResizeEvent *event) { + // fitInView(0, 0, 201, 201, Qt::KeepAspectRatioByExpanding); } - -void CoreViewLine::set_axis(QList axs) { - -} - -*/ diff --git a/qtmips_gui/coreview.h b/qtmips_gui/coreview.h index a2772fb..fc69861 100644 --- a/qtmips_gui/coreview.h +++ b/qtmips_gui/coreview.h @@ -2,45 +2,33 @@ #define COREVIEW_H #include -#include -#include -#include "machineconfig.h" +#include +#include "qtmipsmachine.h" +#include "coreview/connection.h" +#include "coreview/programcounter.h" +#include "coreview/multiplexer.h" +#include "coreview/latch.h" class CoreView : public QGraphicsView { Q_OBJECT public: - CoreView(QWidget *parent); + CoreView(QWidget *parent, QtMipsMachine *machine); private: + void resizeEvent(QResizeEvent *event); -}; + QGraphicsScene scene; + QtMipsMachine *machine; -/* -class CoreViewBlock : public QGraphicsItem { - Q_OBJECT -public: - CoreViewBlock(); + coreview::ProgramCounter *pc; + coreview::Multiplexer *pc_multiplexer; + coreview::Connection *pc2pc; + coreview::Latch *testlatch; }; -class CoreViewLine : public QGraphicsItem { - Q_OBJECT -public: - struct point { - int x1, y1, x2, y2; - }; - - CoreViewLine(); - CoreViewLine(struct point start, struct point end, QList axis); - ~CoreViewLine(); +#else - void set_start(struct point); - void set_end(struct point); - void set_axis(QList); - -protected: - struct point start, end; - QList axis; -}; -*/ +class CoreView; +class CoreViewBlock; #endif // COREVIEW_H diff --git a/qtmips_gui/coreview/connection.cpp b/qtmips_gui/coreview/connection.cpp new file mode 100644 index 0000000..ebca519 --- /dev/null +++ b/qtmips_gui/coreview/connection.cpp @@ -0,0 +1,79 @@ +#include "connection.h" + +using namespace coreview; + +void Connector::setPos(qreal x, qreal y) { + qx = x; + qy = y; + emit updated(); +} + +qreal Connector::x() const { + return qx; +} + +qreal Connector::y() const { + return qy; +} + +QPointF Connector::point() const { + return QPointF(qx, qy); +} + +Connection::Connection(const Connector *a, const Connector *b) : QGraphicsObject(nullptr) { + connect(a, SIGNAL(updated()), this, SLOT(moved())); + connect(b, SIGNAL(updated()), this, SLOT(moved())); + this->a = a; + this->b = b; + update_pos(); +} + +void Connection::setHasText(bool has) { + if (has && value == nullptr) { + value = new QGraphicsSimpleTextItem(this); + value->setText(text); + } else if (!has && value != nullptr) { + delete value; + } + update_pos(); +} + +void Connection::setText(QString val) { + text = val; + if (value != nullptr) + value->setText(val); +} + +void Connection::moved() { + update_pos(); +} + +QRectF Connection::boundingRect() const { + QRectF rect; + for (int i = 0; i < (points.size() - 1); i++) { + qreal x = points[i].x(); + if (x > points[i+1].x()) + x = points[i+1].x(); + qreal y = points[i].y(); + if (y > points[i+1].y()) + y = points[i+1].y(); + // TODO pen width + rect.united(QRectF(x - 0.5, y - 0.5, fabs(points[i].x() - points[i+1].x()) + 1, fabs(points[i].y() - points[i+1].y()) + 1)); + } + //return rect; + return QRectF(0, 0, 300, 300); +} + +void Connection::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + for (int i = 0; i < (points.size() - 1); i++) + painter->drawLine(points[i], points[i+1]); + // TODO meaby use QPath instead? +} + +void Connection::update_pos() { + points.clear(); + points.append(a->point()); + points.append(b->point()); + // TODO more than one line + // TODO update position of value +} diff --git a/qtmips_gui/coreview/connection.h b/qtmips_gui/coreview/connection.h new file mode 100644 index 0000000..eda6afe --- /dev/null +++ b/qtmips_gui/coreview/connection.h @@ -0,0 +1,60 @@ +#ifndef CONNECTION_H +#define CONNECTION_H + +#include +#include +#include +#include "../coreview.h" + +namespace coreview { + +class Connector : public QObject { + Q_OBJECT +public: + void setPos(qreal x, qreal y); + qreal x() const; + qreal y() const; + QPointF point() const; + +signals: + void updated(); + +private: + qreal qx, qy; +}; + +class Connection : public QGraphicsObject { + Q_OBJECT +public: + Connection(const Connector *a, const Connector *b); + + void setHasText(bool has); + void setText(QString val); + +private slots: + void moved(); + +private: + QGraphicsSimpleTextItem *value; + QList points; + const Connector *a, *b; + QString text; + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + // TODO line width and possibly bus width + + void update_pos(); +}; + +} + +#else + +namespace coreview { + class Connector; + class Connection; +}; + +#endif // CONNECTION_H diff --git a/qtmips_gui/coreview/latch.cpp b/qtmips_gui/coreview/latch.cpp new file mode 100644 index 0000000..77bb317 --- /dev/null +++ b/qtmips_gui/coreview/latch.cpp @@ -0,0 +1,51 @@ +#include "latch.h" + +using namespace coreview; + +////////////////////// +#define WIDTH 10 +#define PENW 1 +////////////////////// + +Latch::Latch(QtMipsMachine *machine, qreal height) { + this->height = height; + connect(machine, SIGNAL(tick()), this, SLOT(tick())); +} + +QRectF Latch::boundingRect() const { + return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, height + PENW); +} + +void Latch::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + painter->drawRect(0, 0, WIDTH, height); + // Now tick rectangle + const QPointF tickPolygon[] = { + QPointF(0, 0), + QPointF(WIDTH/2, WIDTH/2), + QPointF(WIDTH, 0) + }; + painter->drawPolygon(tickPolygon, 3); +} + +void Latch::setPos(qreal x, qreal y) { + QGraphicsObject::setPos(x, y); + for (unsigned i = 0; i < connectors.size(); i++) { + connectors[i].in->setPos(x, y + connectors_off[i]); + connectors[i].out->setPos(x + WIDTH, y + connectors_off[i]); + } +} + +struct Latch::ConnectorPair Latch::new_connector(qreal cy) { + SANITY_ASSERT(cy < height, "Latch: Trying to create connector outside of latch height"); + ConnectorPair cp; + cp.in = new Connector(); + cp.out = new Connector(); + connectors.append(cp); + connectors_off.append(cy); + setPos(x(), y()); // Update connectors position + return cp; +} + +void Latch::tick() { + // TODO animate +} diff --git a/qtmips_gui/coreview/latch.h b/qtmips_gui/coreview/latch.h new file mode 100644 index 0000000..a8738b3 --- /dev/null +++ b/qtmips_gui/coreview/latch.h @@ -0,0 +1,45 @@ +#ifndef LATCH_H +#define LATCH_H + +#include +#include +#include "qtmipsexception.h" +#include "qtmipsmachine.h" +#include "../coreview.h" +#include "connection.h" + +namespace coreview { + +class Latch : public QGraphicsObject { + Q_OBJECT +public: + Latch(QtMipsMachine *machine, qreal height); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setPos(qreal x, qreal y); + + struct ConnectorPair { Connector *in, *out; }; + + struct ConnectorPair new_connector(qreal y); // Create new connectors pair that is given y from top of latch + +private slots: + void tick(); + +private: + qreal height; + QList connectors; + QList connectors_off; + +}; + +} + +#else + +namespace coreview { + class Latch; +}; + +#endif // LATCH_H diff --git a/qtmips_gui/coreview/multiplexer.cpp b/qtmips_gui/coreview/multiplexer.cpp new file mode 100644 index 0000000..57fa443 --- /dev/null +++ b/qtmips_gui/coreview/multiplexer.cpp @@ -0,0 +1,79 @@ +#include "multiplexer.h" + +using namespace coreview; + +////////////////////// +#define WIDTH 20 +#define HEIGHT 20 +#define PENW 1 +////////////////////// + +Multiplexer::Multiplexer(unsigned size) { + this->size = size; + seton = 0; + ctlfrom = false; + con_ctl = new Connector(); + con_out = new Connector(); + con_in = new Connector*[size]; + for (unsigned i = 0; i < size; i++) + con_in[i] = new Connector(); + setPos(x(), y()); // Set connectors possitions +} + +Multiplexer::~Multiplexer() { + delete con_ctl; + delete con_out; + for (unsigned i = 0; i < size; i++) + delete con_in[i]; + delete con_in; +} + +QRectF Multiplexer::boundingRect() const { + return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, (HEIGHT * size) + PENW); +} + +void Multiplexer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + // Draw pointing line first so it isn't over the border lines + painter->setPen(QColor(200, 200, 200)); + painter->drawLine(0, (HEIGHT / 2) + (seton * HEIGHT), WIDTH, (HEIGHT * size) / 2); + + painter->setPen(QColor()); + painter->drawLine(0, 0, 0, (HEIGHT * size)); // (|) + painter->drawLine(0, 0, WIDTH, WIDTH); // (\) + painter->drawLine(0, (HEIGHT * size), WIDTH, (HEIGHT * size) - WIDTH); // (/) + painter->drawLine(WIDTH, WIDTH, WIDTH, (HEIGHT * size) - WIDTH); // (|) +} + +void Multiplexer::setPos(qreal x, qreal y) { + QGraphicsItem::setPos(x, y); + if (ctlfrom) + con_ctl->setPos(x + (WIDTH / 2), y + (WIDTH / 2)); + else + con_ctl->setPos(x + (WIDTH / 2), y + (HEIGHT * size) - (WIDTH / 2)); + con_out->setPos(x + WIDTH, y + ((HEIGHT *size) / 2)); + for (unsigned i = 0; i < size; i++) + con_in[i]->setPos(x, y + (HEIGHT / 2) + (i * HEIGHT)); +} + +const Connector *Multiplexer::connector_ctl() const { + return con_ctl; +} + +const Connector *Multiplexer::connector_out() const { + return con_out; +} + +const Connector *Multiplexer::connector_in(unsigned i) const { + SANITY_ASSERT(i < size, "Multiplexer: requested out of range input connector"); + return con_in[i]; +} + +void Multiplexer::set(unsigned i) { + seton = i; + update(boundingRect()); +} + +void Multiplexer::setCtl(bool up) { + ctlfrom = up; + setPos(x(), y()); // Update connectors +} diff --git a/qtmips_gui/coreview/multiplexer.h b/qtmips_gui/coreview/multiplexer.h new file mode 100644 index 0000000..6aa11a6 --- /dev/null +++ b/qtmips_gui/coreview/multiplexer.h @@ -0,0 +1,41 @@ +#ifndef MULTIPLEXER_H +#define MULTIPLEXER_H + +#include +#include "qtmipsexception.h" +#include "../coreview.h" +#include "connection.h" + +namespace coreview { + +class Multiplexer : public QGraphicsItem { +public: + Multiplexer(unsigned size); + ~Multiplexer(); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setPos(qreal x, qreal y); + const Connector *connector_ctl() const; // Control input + const Connector *connector_out() const; // Output + const Connector *connector_in(unsigned i) const; // Inputs + + void set(unsigned i); // Set what value should be set as connected + void setCtl(bool up); // Set if control signal is from up or down (in default down) + +private: + bool ctlfrom; + unsigned size, seton; + Connector *con_ctl, *con_out, **con_in; +}; + +} + +#else + +namespace coreview { + class Multiplexer; +} + +#endif // MULTIPLEXER_H diff --git a/qtmips_gui/coreview/programcounter.cpp b/qtmips_gui/coreview/programcounter.cpp new file mode 100644 index 0000000..32c907c --- /dev/null +++ b/qtmips_gui/coreview/programcounter.cpp @@ -0,0 +1,48 @@ +#include "programcounter.h" + +using namespace coreview; + +////////////////////// +#define WIDTH 80 +#define HEIGHT 100 +#define PENW 1 +////////////////////// + +ProgramCounter::ProgramCounter(QtMipsMachine *machine) : QGraphicsObject(nullptr), value(this), name(this) { + value.setText(QString("0x") + QString::number(machine->registers()->read_pc(), 16)); + value.setPos(0, HEIGHT/2 - value.boundingRect().height()/2); + name.setText(QString("PC")); + name.setPos(WIDTH/2 - name.boundingRect().width()/2, 0); + + connect(machine->registers(), SIGNAL(pc_update(std::uint32_t)), this, SLOT(pc_update(std::uint32_t))); + + con_in = new Connector(); + con_out = new Connector(); + setPos(x(), y()); // To set initial connectors positions +} + +QRectF ProgramCounter::boundingRect() const { + return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, HEIGHT + PENW); +} + +void ProgramCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + painter->drawRect(0, 0, WIDTH, HEIGHT); +} + +void ProgramCounter::setPos(qreal x, qreal y) { + QGraphicsObject::setPos(x, y); + con_in->setPos(x, y + HEIGHT/2); + con_out->setPos(x + WIDTH, y + HEIGHT/2); +} + +const Connector *ProgramCounter::connector_in() const { + return con_in; +} + +const Connector *ProgramCounter::connector_out() const { + return con_out; +} + +void ProgramCounter::pc_update(std::uint32_t val) { + value.setText(QString("0x") + QString::number(val, 16)); +} diff --git a/qtmips_gui/coreview/programcounter.h b/qtmips_gui/coreview/programcounter.h new file mode 100644 index 0000000..98b161d --- /dev/null +++ b/qtmips_gui/coreview/programcounter.h @@ -0,0 +1,42 @@ +#ifndef PROGRAMCOUNTER_H +#define PROGRAMCOUNTER_H + +#include +#include +#include "qtmipsmachine.h" +#include "../coreview.h" +#include "connection.h" + +namespace coreview { + +class ProgramCounter : public QGraphicsObject { + Q_OBJECT +public: + ProgramCounter(QtMipsMachine *machine); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setPos(qreal x, qreal y); + const Connector *connector_in() const; + const Connector *connector_out() const; + +private slots: + void pc_update(std::uint32_t val); + +private: + QGraphicsSimpleTextItem value; + QGraphicsSimpleTextItem name; + + Connector *con_in, *con_out; +}; + +} + +#else + +namespace coreview { + class ProgramCounter; +}; + +#endif // PROGRAMCOUNTER_H diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp index ea48736..157baf4 100644 --- a/qtmips_gui/mainwindow.cpp +++ b/qtmips_gui/mainwindow.cpp @@ -18,11 +18,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { registers->hide(); // Connect signals from menu - QObject::connect(ui->actionExit, SIGNAL(triggered(bool)), this, SLOT(close())); - QObject::connect(ui->actionNew, SIGNAL(triggered(bool)), this, SLOT(new_machine())); - QObject::connect(ui->actionCache, SIGNAL(triggered(bool)), this, SLOT(show_cache_content())); - QObject::connect(ui->actionCache_statistics, SIGNAL(triggered(bool)), this, SLOT(show_cache_statictics())); - QObject::connect(ui->actionRegisters, SIGNAL(triggered(bool)), this, SLOT(show_registers())); + connect(ui->actionExit, SIGNAL(triggered(bool)), this, SLOT(close())); + connect(ui->actionNew, SIGNAL(triggered(bool)), this, SLOT(new_machine())); + connect(ui->actionCache, SIGNAL(triggered(bool)), this, SLOT(show_cache_content())); + connect(ui->actionCache_statistics, SIGNAL(triggered(bool)), this, SLOT(show_cache_statictics())); + connect(ui->actionRegisters, SIGNAL(triggered(bool)), this, SLOT(show_registers())); // Restore application state from settings restoreState(settings->value("windowState").toByteArray()); @@ -39,6 +39,8 @@ MainWindow::~MainWindow() { delete cache_statictics; delete registers; delete ui; + if (machine != nullptr) + delete machine; } void MainWindow::start() { @@ -50,9 +52,19 @@ void MainWindow::create_core(MachineConfig *config) { // Create machine machine = new QtMipsMachine(config); // Create machine view - coreview = new CoreView(this); + coreview = new CoreView(this, machine); this->setCentralWidget(coreview); - // TODO connect signals + + machine->set_speed(1000); // Set default speed to 1 sec + + // Connect machine signals + connect(ui->actionRun, SIGNAL(triggered(bool)), machine, SLOT(play())); + connect(ui->actionPause, SIGNAL(triggered(bool)), machine, SLOT(pause())); + connect(ui->actionStep, SIGNAL(triggered(bool)), machine, SLOT(step())); + connect(ui->actionRestart, SIGNAL(triggered(bool)), machine, SLOT(restart())); + + // Setup docks + registers->setup(machine); } void MainWindow::new_machine() { diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro index ee2bd6e..da91449 100644 --- a/qtmips_gui/qtmips_gui.pro +++ b/qtmips_gui/qtmips_gui.pro @@ -19,7 +19,11 @@ SOURCES += \ coreview.cpp \ registersdock.cpp \ cachestatistics.cpp \ - cachecontent.cpp + cachecontent.cpp \ + coreview/programcounter.cpp \ + coreview/multiplexer.cpp \ + coreview/connection.cpp \ + coreview/latch.cpp HEADERS += \ mainwindow.h \ @@ -27,7 +31,11 @@ HEADERS += \ coreview.h \ registersdock.h \ cachestatistics.h \ - cachecontent.h + cachecontent.h \ + coreview/programcounter.h \ + coreview/multiplexer.h \ + coreview/connection.h \ + coreview/latch.h FORMS += \ NewDialog.ui \ diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp index 7b44a7b..191a7c7 100644 --- a/qtmips_machine/qtmipsmachine.cpp +++ b/qtmips_machine/qtmipsmachine.cpp @@ -9,6 +9,7 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) { program.to_memory(mem); program_end = program.end(); + program_ended = false; MemoryAccess *coremem; switch (cc.cache()) { @@ -35,6 +36,8 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) { void QtMipsMachine::set_speed(unsigned val) { run_speed = val; + if (run_t->isActive()) + play(); } const Registers *QtMipsMachine::registers() { @@ -54,19 +57,31 @@ const Core *QtMipsMachine::core() { } void QtMipsMachine::play() { + if (program_ended) + return; run_t->start(run_speed); } void QtMipsMachine::pause() { + if (program_ended) + return; run_t->stop(); } void QtMipsMachine::step() { + if (program_ended) // Ignore if program ended + return; + emit tick(); cr->step(); - if (regs->read_pc() >= program_end) + if (regs->read_pc() >= program_end) { + program_ended = true; + run_t->stop(); emit program_exit(); + } } void QtMipsMachine::restart() { + if (!program_ended) + run_t->stop(); // Stop timer if program is still running // TODO } diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h index 829e571..c185f28 100644 --- a/qtmips_machine/qtmipsmachine.h +++ b/qtmips_machine/qtmipsmachine.h @@ -32,6 +32,7 @@ public slots: signals: void program_exit(); + void tick(); // Time tick private: Registers *regs; @@ -43,6 +44,7 @@ private: QTimer *run_t; std::uint32_t program_end; + bool program_ended; }; #endif // QTMIPSMACHINE_H diff --git a/qtmips_machine/registers.cpp b/qtmips_machine/registers.cpp index a18421e..b77b1b7 100644 --- a/qtmips_machine/registers.cpp +++ b/qtmips_machine/registers.cpp @@ -44,6 +44,7 @@ void Registers::pc_abs_jmp(std::uint32_t address) { if (address % 4) throw QTMIPS_EXCEPTION(UnalignedJump, "Trying to jump to unaligned address", QString::number(address, 16)); this->pc = address; + emit pc_update(this->pc); } void Registers::pc_abs_jmp_28(std::uint32_t address) { @@ -61,6 +62,7 @@ void Registers::write_gp(std::uint8_t i, std::uint32_t value) { SANITY_ASSERT(i < 32, QString("Trying to write to register ") + QString(i)); if (i == 0) // Skip write to $0 return; + emit gp_update(i, value); this->gp[i - 1] = value; } @@ -76,6 +78,7 @@ void Registers::write_hi_lo(bool hi, std::uint32_t value) { this->hi = value; else this->lo = value; + emit hi_lo_update(hi, value); } bool Registers::operator==(const Registers &c) const { diff --git a/qtmips_machine/registers.h b/qtmips_machine/registers.h index dd7e393..4a693db 100644 --- a/qtmips_machine/registers.h +++ b/qtmips_machine/registers.h @@ -26,7 +26,8 @@ public: signals: void pc_update(std::uint32_t val); - // TODO signals + void gp_update(std::uint8_t i, std::uint32_t val); + void hi_lo_update(bool hi, std::uint32_t val); private: std::uint32_t gp[31]; // general-purpose registers ($0 is intentionally skipped) -- cgit v1.2.3