From d3ab78e76cc51b702fe87f215044ec00a05920a5 Mon Sep 17 00:00:00 2001 From: zanostro Date: Fri, 5 Dec 2025 19:00:11 +0100 Subject: [PATCH] ui changes --- simulator_SIC_XE/gui/qt/MachineController.cpp | 7 ++- simulator_SIC_XE/gui/qt/mainwindow.cpp | 52 ++++++++++++++++--- simulator_SIC_XE/gui/qt/mainwindow.h | 1 + simulator_SIC_XE/gui/qt/mainwindow.ui | 49 ++++++++++++++++- simulator_SIC_XE/include/machine.h | 8 +-- simulator_SIC_XE/src/machine.cpp | 31 +++++++++-- 6 files changed, 131 insertions(+), 17 deletions(-) diff --git a/simulator_SIC_XE/gui/qt/MachineController.cpp b/simulator_SIC_XE/gui/qt/MachineController.cpp index 0ea4178..9861e0c 100644 --- a/simulator_SIC_XE/gui/qt/MachineController.cpp +++ b/simulator_SIC_XE/gui/qt/MachineController.cpp @@ -42,8 +42,13 @@ void MachineController::runLoop() { try { if (m_machine) { m_machine->execute(); - m_machine->tick(); + m_machine->tick(); emit tick(); + + if (m_machine->isStopped()) { + m_running.store(false); + break; + } } } catch (const std::exception &e) { emit error(QString::fromStdString(e.what())); diff --git a/simulator_SIC_XE/gui/qt/mainwindow.cpp b/simulator_SIC_XE/gui/qt/mainwindow.cpp index de0ca3c..e2d4c61 100644 --- a/simulator_SIC_XE/gui/qt/mainwindow.cpp +++ b/simulator_SIC_XE/gui/qt/mainwindow.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include class Loader; @@ -69,8 +71,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->regF_bin_field->setValidator(floatBinValidator); - connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateRegisterDisplays); - connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateMemoryDisplay); + connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateRegisterDisplays, Qt::QueuedConnection); + connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateMemoryDisplay, Qt::QueuedConnection); connectRegisterFields(); @@ -95,15 +97,16 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->DisasmDec65536Btn, &QPushButton::clicked, this, &MainWindow::onDisassemblyDec256); connect(ui->DisasmGoToStart, &QPushButton::clicked, this, &MainWindow::onDisassemblyGoToStart); connect(ui->DisasmGoToEnd, &QPushButton::clicked, this, &MainWindow::onDisassemblyGoToEnd); - connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateDisassemblyDisplay); + connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateDisassemblyDisplay, Qt::QueuedConnection); + + // Connect menu actions + connect(ui->actionLoad_Object_File, &QAction::triggered, this, &MainWindow::loadObjectFile); setupMemoryDisplay(); setupDisassemblyDisplay(); loadInstructionSet(); - //loadDemoProgram(); - Loader loader(m_machine, std::string(PATH_RESOURCES) + "print.obj"); - loader.load(); + // Don't load any program by default - user will load via File menu updateRegisterDisplays(); updateMemoryDisplay(); @@ -760,7 +763,7 @@ MainWindow::DisassembledInstruction MainWindow::disassembleAt(int address) QString addrMode = ""; if (p) { - ea += m_machine->getPC(); + ea += (address + 3); addrMode = " (PC)"; } else if (b) { ea += m_machine->getB(); @@ -918,3 +921,38 @@ void MainWindow::updateMemoryDisplay() ui->MemoryScrollArea->setWidget(container); } + +void MainWindow::loadObjectFile() +{ + QString fileName = QFileDialog::getOpenFileName(this, + tr("Load Object File"), + QString(), + tr("Object Files (*.obj);;All Files (*)")); + + if (fileName.isEmpty()) { + return; + } + + try { + // Stop execution if running + m_controller->stop(); + + // Reset machine state + m_machine->reset(); + + // Load the object file + Loader loader(m_machine, fileName.toStdString()); + loader.load(); + + // Update displays + updateRegisterDisplays(); + updateMemoryDisplay(); + updateDisassemblyDisplay(); + + QMessageBox::information(this, tr("Success"), + tr("Object file loaded successfully")); + } catch (const std::exception &e) { + QMessageBox::critical(this, tr("Error"), + tr("Failed to load object file: %1").arg(e.what())); + } +} diff --git a/simulator_SIC_XE/gui/qt/mainwindow.h b/simulator_SIC_XE/gui/qt/mainwindow.h index 1e39a7d..caa9550 100644 --- a/simulator_SIC_XE/gui/qt/mainwindow.h +++ b/simulator_SIC_XE/gui/qt/mainwindow.h @@ -50,6 +50,7 @@ private slots: void onDisassemblyDec256(); void onDisassemblyGoToStart(); void onDisassemblyGoToEnd(); + void loadObjectFile(); private: Ui::MainWindow *ui; diff --git a/simulator_SIC_XE/gui/qt/mainwindow.ui b/simulator_SIC_XE/gui/qt/mainwindow.ui index 2fad622..e9084bd 100644 --- a/simulator_SIC_XE/gui/qt/mainwindow.ui +++ b/simulator_SIC_XE/gui/qt/mainwindow.ui @@ -866,6 +866,18 @@ + + + + toolBar + + + TopToolBarArea + + + false + + @@ -875,8 +887,43 @@ 20 + + + File + + + + + + Machine + + + + + + Help + + + + + + - + + + Load Object File + + + + + Frequency + + + + + About + + diff --git a/simulator_SIC_XE/include/machine.h b/simulator_SIC_XE/include/machine.h index 8e80669..cd14f74 100644 --- a/simulator_SIC_XE/include/machine.h +++ b/simulator_SIC_XE/include/machine.h @@ -26,7 +26,7 @@ using std::cout; class Machine { public: Machine(); - Machine(int speedkHz) : Machine() { this->speedkHz = speedkHz; _instructionsTable = instructions; } + Machine(int speedHz) : Machine() { this->speedHz = speedHz; _instructionsTable = instructions; } ~Machine(); int getA() const { return A; } @@ -84,11 +84,13 @@ public: // Execution and speed control int getSpeed() const; - void setSpeed(int kHz); + void setSpeed(int Hz); void start(); void stop(); void tick(); void halt(); + bool isStopped() const { return _stopped; } + void reset(); // error handling methods void notImplemented(string mnemonic); @@ -128,7 +130,7 @@ private: // Execution control std::atomic running{false}; - std::atomic speedkHz{1}; // Default 1 kHz + std::atomic speedHz{10}; // Default 10 Hz bool execF1(int opcode); bool execF2(int opcode, int operand); diff --git a/simulator_SIC_XE/src/machine.cpp b/simulator_SIC_XE/src/machine.cpp index e15e6c1..f71814d 100644 --- a/simulator_SIC_XE/src/machine.cpp +++ b/simulator_SIC_XE/src/machine.cpp @@ -45,12 +45,12 @@ Machine::~Machine() int Machine::getSpeed() const { - return speedkHz.load(); + return speedHz.load(); } -void Machine::setSpeed(int kHz) +void Machine::setSpeed(int Hz) { - speedkHz.store(kHz); + speedHz.store(Hz); } // TODO: implement errors @@ -138,10 +138,10 @@ void Machine::setVT(const int *values) void Machine::tick() { - const int speed = speedkHz.load(); + const int speed = speedHz.load(); if (speed <= 0) throw std::runtime_error("Invalid speed setting in Machine::tick"); - const auto delay = std::chrono::microseconds(1000 / speed); + const auto delay = std::chrono::milliseconds(1000 / speed); std::this_thread::sleep_for(delay); } @@ -150,6 +150,27 @@ void Machine::halt() _stopped = true; } +void Machine::reset() +{ + // Reset all registers + A = B = X = L = S = T = PC = SW = 0; + F = 0.0; + + // Clear memory + for (int i = 0; i < MEMORY_SIZE; i++) { + memory[i] = 0; + } + + // Reset execution state + _stopped = false; + running.store(false); + + // Reset vector registers + for (int i = 0; i < VECTOR_REG_SIZE; i++) { + VA[i] = VS[i] = VT[i] = 0; + } +} + int Machine::getReg(int regNum) const { switch (regNum) {