spo/ass2/simulator/mainwindow.cpp
2025-12-10 17:57:28 +01:00

176 lines
6 KiB
C++

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QAction *actionLoad = new QAction(tr("Load"), this);
ui->menuLoad->addAction(actionLoad);
executorThread = new QThread(this);
executor.moveToThread(executorThread);
connect(this, &MainWindow::startExecutor, &executor, &Executor::start);
connect(this, &MainWindow::stopExecutor, &executor, &Executor::stop);
connect(this, &MainWindow::stepExecutor, &executor, &Executor::step);
executorThread->start();
connect(&executor, &Executor::updateRequested, this, &MainWindow::updateUI);
connect(&executor, &Executor::signalStarted, this, &MainWindow::setStatusLightRunning);
connect(&executor, &Executor::signalStopped, this, &MainWindow::setStatusLightStopped);
connect(&executor, &Executor::signalEnded, this, &MainWindow::setStatusLightEnded);
connect(actionLoad, &QAction::triggered, this, &MainWindow::onLoadTriggered);
connect(ui->runButton, &QPushButton::clicked, this, &MainWindow::on_runButton_clicked);
connect(ui->stepButton, &QPushButton::clicked, this, &MainWindow::on_stepButton_clicked);
updateUI();
ui->statusLight->setFixedSize(16,16);
ui->statusLight->setStyleSheet("background-color: green; border-radius: 8px;");
// nastavi tabelo
const int columns = 16;
int memSize = machine.getMemSize(); // ali fiksno (npr. 1000000), če še ni naloženo
int rows = (memSize + columns - 1) / columns;
ui->tableWidget->setColumnCount(columns);
ui->tableWidget->setRowCount(rows);
// Nastavi naslove stolpcev
QStringList headers;
for (int c = 0; c < columns; ++c) {
headers << QString("%1").arg(c, 2, 16, QChar('0')).toUpper();
}
ui->tableWidget->setHorizontalHeaderLabels(headers);
// Nastavi naslove vrstic v heks formatu
QStringList verticalHeaders;
for (int r = 0; r < rows; ++r) {
verticalHeaders << QString("%1").arg(r * columns, 4, 16, QChar('0')).toUpper();
}
ui->tableWidget->setVerticalHeaderLabels(verticalHeaders);
// Nastavi fiksno širino stolpcev (ali prilagodi po potrebi)
int columnWidth = 30;
for (int c = 0; c < columns; ++c) {
ui->tableWidget->setColumnWidth(c, columnWidth);
}
// Nastavi politiko velikosti
ui->tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
MainWindow::~MainWindow()
{
executorThread->quit();
executorThread->wait();
delete ui;
}
void populateMemoryTable(QTableWidget* tableWidget, Machine& machine) {
const int columns = 16;
int memSize = machine.getMemSize();
for (int r = 0; r < tableWidget->rowCount(); ++r) {
for (int c = 0; c < columns; ++c) {
int addr = r * columns + c;
if (addr < memSize) {
unsigned char val = machine.readByte(addr);
QString hexVal = QString("%1").arg(val, 2, 16, QChar('0')).toUpper();
// Posodobi ali ustvari nov element
if (tableWidget->item(r, c)) {
tableWidget->item(r, c)->setText(hexVal);
} else {
tableWidget->setItem(r, c, new QTableWidgetItem(hexVal));
}
}
}
}
}
void MainWindow::updateRegisters()
{
ui->labelA->setText(QString("0x%1").arg(machine.getA(), 6, 16, QChar('0')).toUpper());
ui->labelX->setText(QString("0x%1").arg(machine.getX(), 6, 16, QChar('0')).toUpper());
ui->labelL->setText(QString("0x%1").arg(machine.getL(), 6, 16, QChar('0')).toUpper());
ui->labelB->setText(QString("0x%1").arg(machine.getB(), 6, 16, QChar('0')).toUpper());
ui->labelS->setText(QString("0x%1").arg(machine.getS(), 6, 16, QChar('0')).toUpper());
ui->labelT->setText(QString("0x%1").arg(machine.getT(), 6, 16, QChar('0')).toUpper());
ui->labelPC->setText(QString("0x%1").arg(machine.getPC(), 6, 16, QChar('0')).toUpper());
ui->labelSW->setText(QString("0x%1").arg(machine.getSW(), 6, 16, QChar('0')).toUpper());
// F je float/double register
ui->labelF->setText(QString::number(machine.getF()));
}
void MainWindow::updateUI()
{
updateRegisters();
populateMemoryTable(ui->tableWidget, machine);
}
void MainWindow::onLoadTriggered() {
machine.resetRegisters();
machine.resetMemory();
executor.resetProgram();
updateUI();
QString filename = QFileDialog::getOpenFileName(this, tr("Open Object File"), "", tr("Object Files (*.obj)"));
if (!filename.isEmpty()) {
bool ok = loader.loadObj(machine, filename.toStdString());
if (!ok) {
QMessageBox::warning(this, tr("Error"), tr("Failed to load file"));
}
}
populateMemoryTable(ui->tableWidget, machine);
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
ui->tableWidget->horizontalHeader()->setDefaultSectionSize(30);
}
void MainWindow::on_readButton_clicked()
{
bool ok;
unsigned int addr = ui->addressLineEdit->text().toUInt(&ok);
if (!ok) {
QMessageBox::warning(this, "Napaka", "Neveljaven naslov!");
return;
}
try {
unsigned char val = machine.readByte(addr);
ui->valueLabel->setText(QString::number(val));
} catch (const std::out_of_range &e) {
QMessageBox::warning(this, "Napaka", "Naslov je izven meje pomnilnika!");
}
}
void MainWindow::on_runButton_clicked()
{
emit startExecutor();
}
void MainWindow::on_stepButton_clicked()
{
emit stepExecutor();
}
void MainWindow::on_stopButton_clicked()
{
emit stopExecutor();
}
void MainWindow::setStatusLightRunning() {
ui->statusLight->setStyleSheet("background-color: green; border-radius: 8px;");
}
void MainWindow::setStatusLightStopped() {
ui->statusLight->setStyleSheet("background-color: yellow; border-radius: 8px;");
}
void MainWindow::setStatusLightEnded() {
ui->statusLight->setStyleSheet("background-color: black; border-radius: 8px;");
}