diff --git a/simulator_SIC_XE/gui/qt/MachineController.cpp b/simulator_SIC_XE/gui/qt/MachineController.cpp index 9861e0c..0ea4178 100644 --- a/simulator_SIC_XE/gui/qt/MachineController.cpp +++ b/simulator_SIC_XE/gui/qt/MachineController.cpp @@ -42,13 +42,8 @@ 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 dcdb9bc..de0ca3c 100644 --- a/simulator_SIC_XE/gui/qt/mainwindow.cpp +++ b/simulator_SIC_XE/gui/qt/mainwindow.cpp @@ -17,9 +17,6 @@ #include #include #include -#include -#include -#include class Loader; @@ -72,8 +69,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->regF_bin_field->setValidator(floatBinValidator); - connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateRegisterDisplays, Qt::QueuedConnection); - connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateMemoryDisplay, Qt::QueuedConnection); + connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateRegisterDisplays); + connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateMemoryDisplay); connectRegisterFields(); @@ -98,16 +95,15 @@ 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, Qt::QueuedConnection); - - // Connect menu actions - connect(ui->actionLoad_Object_File, &QAction::triggered, this, &MainWindow::loadObjectFile); + connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateDisassemblyDisplay); setupMemoryDisplay(); setupDisassemblyDisplay(); loadInstructionSet(); - // Don't load any program by default - user will load via File menu + //loadDemoProgram(); + Loader loader(m_machine, std::string(PATH_RESOURCES) + "print.obj"); + loader.load(); updateRegisterDisplays(); updateMemoryDisplay(); @@ -699,18 +695,7 @@ MainWindow::DisassembledInstruction MainWindow::disassembleAt(int address) QString reg1Str = (r1 < 10) ? regNames[r1] : "?"; QString reg2Str = (r2 < 10) ? regNames[r2] : "?"; - // Check if this is a single-operand Format 2 instruction - QString mnem = result.mnemonic.toUpper(); - if (mnem == "CLEAR" || mnem == "TIXR") { - result.operand = reg1Str; - } else if (mnem == "SVC") { - result.operand = QString::number(r1); - } else if (mnem == "SHIFTL" || mnem == "SHIFTR") { - result.operand = QString("%1, %2").arg(reg1Str).arg(r2); - } else { - // Two register operands (ADDR, SUBR, COMPR, etc.) - result.operand = QString("%1, %2").arg(reg1Str).arg(reg2Str); - } + result.operand = QString("%1, %2").arg(reg1Str).arg(reg2Str); } break; } @@ -775,7 +760,7 @@ MainWindow::DisassembledInstruction MainWindow::disassembleAt(int address) QString addrMode = ""; if (p) { - ea += (address + 3); + ea += m_machine->getPC(); addrMode = " (PC)"; } else if (b) { ea += m_machine->getB(); @@ -864,13 +849,7 @@ void MainWindow::updateDisassemblyDisplay() layout->addStretch(); container->setLayout(layout); - // Save scroll position before updating - int scrollPos = ui->DisasemblyScrollArea->verticalScrollBar()->value(); - ui->DisasemblyScrollArea->setWidget(container); - - // Restore scroll position after updating - ui->DisasemblyScrollArea->verticalScrollBar()->setValue(scrollPos); } void MainWindow::updateMemoryDisplay() @@ -937,44 +916,5 @@ void MainWindow::updateMemoryDisplay() layout->addStretch(); container->setLayout(layout); - int scrollPos = ui->MemoryScrollArea->verticalScrollBar()->value(); - ui->MemoryScrollArea->setWidget(container); - - ui->MemoryScrollArea->verticalScrollBar()->setValue(scrollPos); -} - -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 caa9550..1e39a7d 100644 --- a/simulator_SIC_XE/gui/qt/mainwindow.h +++ b/simulator_SIC_XE/gui/qt/mainwindow.h @@ -50,7 +50,6 @@ 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 e9084bd..2fad622 100644 --- a/simulator_SIC_XE/gui/qt/mainwindow.ui +++ b/simulator_SIC_XE/gui/qt/mainwindow.ui @@ -866,18 +866,6 @@ - - - - toolBar - - - TopToolBarArea - - - false - - @@ -887,43 +875,8 @@ 20 - - - File - - - - - - Machine - - - - - - Help - - - - - - - - - Load Object File - - - - - Frequency - - - - - About - - + diff --git a/simulator_SIC_XE/include/file_device.h b/simulator_SIC_XE/include/file_device.h index 01b433c..a08e2ac 100644 --- a/simulator_SIC_XE/include/file_device.h +++ b/simulator_SIC_XE/include/file_device.h @@ -17,7 +17,6 @@ private: std::fstream fileStream; std::string filename; bool fileCreated; - std::streampos readPosition; }; #endif // FILE_DEVICE_H \ No newline at end of file diff --git a/simulator_SIC_XE/include/machine.h b/simulator_SIC_XE/include/machine.h index cd14f74..8e80669 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 speedHz) : Machine() { this->speedHz = speedHz; _instructionsTable = instructions; } + Machine(int speedkHz) : Machine() { this->speedkHz = speedkHz; _instructionsTable = instructions; } ~Machine(); int getA() const { return A; } @@ -84,13 +84,11 @@ public: // Execution and speed control int getSpeed() const; - void setSpeed(int Hz); + void setSpeed(int kHz); void start(); void stop(); void tick(); void halt(); - bool isStopped() const { return _stopped; } - void reset(); // error handling methods void notImplemented(string mnemonic); @@ -130,7 +128,7 @@ private: // Execution control std::atomic running{false}; - std::atomic speedHz{10}; // Default 10 Hz + std::atomic speedkHz{1}; // Default 1 kHz bool execF1(int opcode); bool execF2(int opcode, int operand); diff --git a/simulator_SIC_XE/src/file_device.cpp b/simulator_SIC_XE/src/file_device.cpp index 781a9b6..8ca554f 100644 --- a/simulator_SIC_XE/src/file_device.cpp +++ b/simulator_SIC_XE/src/file_device.cpp @@ -3,8 +3,9 @@ #include FileDevice::FileDevice(const std::string &filename) - : filename(filename), fileCreated(false), readPosition(0) + : filename(filename), fileCreated(false) { + // Don't create the file yet - wait until first write } FileDevice::~FileDevice() @@ -17,16 +18,9 @@ FileDevice::~FileDevice() void FileDevice::ensureFileOpen() { if (!fileStream.is_open()) { - // Check if file exists - std::ifstream checkFile(filename); - bool fileExists = checkFile.good(); - checkFile.close(); - - if (fileExists) { - fileStream.open(filename, std::ios::in | std::ios::out | std::ios::ate); - fileCreated = true; + if (fileCreated) { + fileStream.open(filename, std::ios::in | std::ios::out); } else { - // Create new file std::ofstream create(filename); if (!create) { throw std::runtime_error("Failed to create file: " + filename); @@ -47,11 +41,9 @@ unsigned char FileDevice::read() unsigned char value = 0; ensureFileOpen(); if (fileStream.is_open()) { - fileStream.seekg(readPosition); char ch; if (fileStream.get(ch)) { value = static_cast(ch); - readPosition = fileStream.tellg(); } } return value; @@ -61,7 +53,6 @@ void FileDevice::write(unsigned char value) { ensureFileOpen(); if (fileStream.is_open()) { - fileStream.seekp(0, std::ios::end); fileStream.put(static_cast(value)); fileStream.flush(); } diff --git a/simulator_SIC_XE/src/loader.cpp b/simulator_SIC_XE/src/loader.cpp index 8d3aa17..9b3d293 100644 --- a/simulator_SIC_XE/src/loader.cpp +++ b/simulator_SIC_XE/src/loader.cpp @@ -1,10 +1,8 @@ #include "loader.h" #include "file_reader.h" -#include "string_reader.h" #include "machine.h" #include "constants.h" #include -#include Loader::~Loader() { @@ -84,24 +82,20 @@ Loader::TextRecord Loader::readTextRecord() if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte(); // Read length (1 byte, 2 hex digits) - std::string lengthStr = _file_reader->readString(2); - int length = std::stoi(lengthStr, nullptr, 16); - - // Read the rest of the line (data bytes with spaces) - std::string dataLine = _file_reader->readLine(); - - // Remove all whitespace from the data line - dataLine.erase(std::remove_if(dataLine.begin(), dataLine.end(), ::isspace), dataLine.end()); - - // Now use StringReader to parse the hex bytes - StringReader stringReader(dataLine); + int length = std::stoi(_file_reader->readString(2), nullptr, 16); + if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte(); + record.data.resize(length); - + + int index = 0; + string byteStr = _file_reader->readLine(); + // Remove spaces, newlines, and other whitespace characters + byteStr.erase(std::remove_if(byteStr.begin(), byteStr.end(), ::isspace), byteStr.end()); + for (int i = 0; i < length; ++i) { - std::string byteHex = stringReader.readString(2); + std::string byteHex = byteStr.substr(i * 2, 2); record.data[i] = static_cast(std::stoi(byteHex, nullptr, 16)); } - return record; } diff --git a/simulator_SIC_XE/src/machine.cpp b/simulator_SIC_XE/src/machine.cpp index d8d0356..e15e6c1 100644 --- a/simulator_SIC_XE/src/machine.cpp +++ b/simulator_SIC_XE/src/machine.cpp @@ -14,17 +14,6 @@ string prefix = "Machine error: "; Machine::Machine() { - // Initialize registers and memory to zero - A = B = X = L = S = T = PC = SW = 0; - F = 0.0; - for (int i = 0; i < MEMORY_SIZE; i++) { - memory[i] = 0; - } - for (int i = 0; i < VECTOR_REG_SIZE; i++) { - VA[i] = VS[i] = VT[i] = 0; - } - _stopped = false; - devices.resize(NUM_DEVICES); // device 0: standard input devices[0] = make_shared(std::cin); @@ -56,12 +45,12 @@ Machine::~Machine() int Machine::getSpeed() const { - return speedHz.load(); + return speedkHz.load(); } -void Machine::setSpeed(int Hz) +void Machine::setSpeed(int kHz) { - speedHz.store(Hz); + speedkHz.store(kHz); } // TODO: implement errors @@ -149,10 +138,10 @@ void Machine::setVT(const int *values) void Machine::tick() { - const int speed = speedHz.load(); + const int speed = speedkHz.load(); if (speed <= 0) throw std::runtime_error("Invalid speed setting in Machine::tick"); - const auto delay = std::chrono::milliseconds(1000 / speed); + const auto delay = std::chrono::microseconds(1000 / speed); std::this_thread::sleep_for(delay); } @@ -161,27 +150,6 @@ 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) {