first gui

This commit is contained in:
zanostro 2025-11-13 22:44:11 +01:00
parent 42737c0a66
commit c918993060
6 changed files with 1027 additions and 33 deletions

View file

@ -1,14 +1,414 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "MachineController.h"
#include "../../include/machine.h"
#include "../../include/instructions.h"
#include <QIntValidator>
#include <QLineEdit>
#include <QDebug>
#include <QRegularExpressionValidator>
#include <QDoubleValidator>
#include <QPushButton>
#include <cstdint>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui(new Ui::MainWindow),
m_machine(std::make_shared<Machine>()),
m_controller(std::make_unique<MachineController>(m_machine, this))
{
ui->setupUi(this);
ui->regA_dec_field->setValidator(new QIntValidator(-8388608, 8388607, this));
ui->regB_dec_field->setValidator(new QIntValidator(-8388608, 8388607, this));
ui->regS_dec_field->setValidator(new QIntValidator(-8388608, 8388607, this));
ui->regT_dec_field->setValidator(new QIntValidator(-8388608, 8388607, this));
ui->regX_dec_field->setValidator(new QIntValidator(-8388608, 8388607, this));
// unsigned 24 bit
ui->regL_dec_field->setValidator(new QIntValidator(0, 16777215, this));
ui->regPC_dec_field->setValidator(new QIntValidator(0, 16777215, this));
ui->regSW_dec_field->setValidator(new QIntValidator(0, 16777215, this));
// float
ui->regF_dec_field->setValidator(new QDoubleValidator(-3.402823e38, 3.402823e38, 6, this));
QRegularExpressionValidator* hexValidator = new QRegularExpressionValidator(QRegularExpression("^(0x)?[0-9A-Fa-f]{1,6}$"), this);
ui->regA_hex_field->setValidator(hexValidator);
ui->regB_hex_field->setValidator(hexValidator);
ui->regX_hex_field->setValidator(hexValidator);
ui->regS_hex_field->setValidator(hexValidator);
ui->regT_hex_field->setValidator(hexValidator);
ui->regL_hex_field->setValidator(hexValidator);
ui->regPC_hex_field->setValidator(hexValidator);
ui->regSW_hex_field->setValidator(hexValidator);
QRegularExpressionValidator* binValidator = new QRegularExpressionValidator(QRegularExpression("^[01]{1,24}$"), this);
ui->regA_bin_field->setValidator(binValidator);
ui->regB_bin_field->setValidator(binValidator);
ui->regX_bin_field->setValidator(binValidator);
ui->regS_bin_field->setValidator(binValidator);
ui->regT_bin_field->setValidator(binValidator);
ui->regL_bin_field->setValidator(binValidator);
ui->regPC_bin_field->setValidator(binValidator);
ui->regSW_bin_field->setValidator(binValidator);
QRegularExpressionValidator* floatHexValidator = new QRegularExpressionValidator(QRegularExpression("^(0x)?[0-9A-Fa-f]{1,12}$"), this);
ui->regF_hex_field->setValidator(floatHexValidator);
QRegularExpressionValidator* floatBinValidator = new QRegularExpressionValidator(QRegularExpression("^[01]{1,48}$"), this);
ui->regF_bin_field->setValidator(floatBinValidator);
connect(m_controller.get(), &MachineController::tick, this, &MainWindow::updateRegisterDisplays);
connectRegisterFields();
connect(ui->StartBtn, &QPushButton::clicked, this, &MainWindow::startExecution);
connect(ui->StopBtn, &QPushButton::clicked, this, &MainWindow::stopExecution);
connect(ui->StepBtn, &QPushButton::clicked, this, &MainWindow::stepExecution);
loadDemoProgram();
updateRegisterDisplays();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::updateRegisterDisplays()
{
if (!m_machine) return;
// Update all register display formats (decimal, hex, binary)
updateAllFormatsForRegister("regA", m_machine->getA());
updateAllFormatsForRegister("regB", m_machine->getB());
updateAllFormatsForRegister("regX", m_machine->getX());
updateAllFormatsForRegister("regS", m_machine->getS());
updateAllFormatsForRegister("regT", m_machine->getT());
updateAllFormatsForRegister("regL", m_machine->getL());
updateAllFormatsForRegister("regPC", m_machine->getPC());
updateAllFormatsForRegister("regSW", m_machine->getSW());
updateFloatRegisterFormats("regF", m_machine->getF());
}
void MainWindow::updateSingleRegisterDisplay(const QString& fieldName, int value)
{
QLineEdit* field = findChild<QLineEdit*>(fieldName);
if (field) {
// Only update if the field doesn't have focus (to avoid interfering with user input)
if (!field->hasFocus()) {
field->setText(QString::number(value));
}
}
}
void MainWindow::updateAllFormatsForRegister(const QString& regPrefix, int value)
{
// Update decimal field
QLineEdit* decField = findChild<QLineEdit*>(regPrefix + "_dec_field");
if (decField && !decField->hasFocus()) {
decField->setText(QString::number(value));
}
// Update hex field
QLineEdit* hexField = findChild<QLineEdit*>(regPrefix + "_hex_field");
if (hexField && !hexField->hasFocus()) {
// Convert to 24-bit representation, handle negative numbers
unsigned int unsignedValue = static_cast<unsigned int>(value) & 0xFFFFFF;
hexField->setText(QString("0x%1").arg(unsignedValue, 6, 16, QChar('0')).toUpper());
}
// Update binary field
QLineEdit* binField = findChild<QLineEdit*>(regPrefix + "_bin_field");
if (binField && !binField->hasFocus()) {
// Convert to 24-bit binary representation
unsigned int unsignedValue = static_cast<unsigned int>(value) & 0xFFFFFF;
QString binaryStr = QString::number(unsignedValue, 2);
// Pad to 24 bits
binaryStr = binaryStr.rightJustified(24, '0');
binField->setText(binaryStr);
}
}
void MainWindow::updateFloatRegisterFormats(const QString& regPrefix, double value)
{
// Update decimal field
QLineEdit* decField = findChild<QLineEdit*>(regPrefix + "_dec_field");
if (decField && !decField->hasFocus()) {
decField->setText(QString::number(value, 'g', 10));
}
// Update hex field (48-bit float representation)
QLineEdit* hexField = findChild<QLineEdit*>(regPrefix + "_hex_field");
if (hexField && !hexField->hasFocus()) {
// Convert double to 48-bit hex representation
// For SIC/XE, we need to convert to the 48-bit float format
uint64_t* intPtr = reinterpret_cast<uint64_t*>(&value);
uint64_t bits48 = (*intPtr) & 0xFFFFFFFFFFFFULL; // Mask to 48 bits
hexField->setText(QString("0x%1").arg(bits48, 12, 16, QChar('0')).toUpper());
}
// Update binary field (48-bit float representation)
QLineEdit* binField = findChild<QLineEdit*>(regPrefix + "_bin_field");
if (binField && !binField->hasFocus()) {
// Convert double to 48-bit binary representation
uint64_t* intPtr = reinterpret_cast<uint64_t*>(&value);
uint64_t bits48 = (*intPtr) & 0xFFFFFFFFFFFFULL; // Mask to 48 bits
QString binaryStr = QString::number(bits48, 2);
// Pad to 48 bits
binaryStr = binaryStr.rightJustified(48, '0');
binField->setText(binaryStr);
}
}
void MainWindow::connectRegisterFields()
{
// Connect decimal register fields to update machine registers when changed
connect(ui->regA_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regB_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regX_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regS_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regT_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regL_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regPC_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regSW_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
connect(ui->regF_dec_field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
// Connect hex register fields
QLineEdit* hexFields[] = {
ui->regA_hex_field, ui->regB_hex_field, ui->regX_hex_field,
ui->regS_hex_field, ui->regT_hex_field, ui->regL_hex_field,
ui->regPC_hex_field, ui->regSW_hex_field, ui->regF_hex_field
};
for (auto* field : hexFields) {
if (field) {
connect(field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
}
}
// Connect binary register fields
QLineEdit* binFields[] = {
ui->regA_bin_field, ui->regB_bin_field, ui->regX_bin_field,
ui->regS_bin_field, ui->regT_bin_field, ui->regL_bin_field,
ui->regPC_bin_field, ui->regSW_bin_field, ui->regF_bin_field
};
for (auto* field : binFields) {
if (field) {
connect(field, &QLineEdit::editingFinished, this, &MainWindow::onRegisterFieldChanged);
}
}
}
void MainWindow::onRegisterFieldChanged()
{
if (!m_machine) return;
QLineEdit* field = qobject_cast<QLineEdit*>(sender());
if (!field) return;
QString objectName = field->objectName();
QString regName = objectName.split('_')[0];
if (regName == "regF") {
handleFloatRegisterFieldChanged(field, objectName);
return;
}
// Handle integer registers
int value = 0;
bool ok = false;
// Parse value based on field type
if (objectName.contains("_dec_field")) {
value = field->text().toInt(&ok);
} else if (objectName.contains("_hex_field")) {
QString hexText = field->text();
// Remove 0x prefix if present
if (hexText.startsWith("0x", Qt::CaseInsensitive)) {
hexText = hexText.mid(2);
}
value = hexText.toInt(&ok, 16);
if (ok && (regName == "regA" || regName == "regB" || regName == "regX" ||
regName == "regS" || regName == "regT")) {
if (value > 0x7FFFFF) {
value = value - 0x1000000;
}
}
} else if (objectName.contains("_bin_field")) {
value = field->text().toInt(&ok, 2);
if (ok && (regName == "regA" || regName == "regB" || regName == "regX" ||
regName == "regS" || regName == "regT")) {
if (value > 0x7FFFFF) {
value = value - 0x1000000;
}
}
}
if (!ok) {
updateRegisterDisplays();
return;
}
if (regName == "regA") {
m_machine->setA(value);
updateAllFormatsForRegister("regA", m_machine->getA());
} else if (regName == "regB") {
m_machine->setB(value);
updateAllFormatsForRegister("regB", m_machine->getB());
} else if (regName == "regX") {
m_machine->setX(value);
updateAllFormatsForRegister("regX", m_machine->getX());
} else if (regName == "regS") {
m_machine->setS(value);
updateAllFormatsForRegister("regS", m_machine->getS());
} else if (regName == "regT") {
m_machine->setT(value);
updateAllFormatsForRegister("regT", m_machine->getT());
} else if (regName == "regL") {
m_machine->setL(value);
updateAllFormatsForRegister("regL", m_machine->getL());
} else if (regName == "regPC") {
m_machine->setPC(value);
updateAllFormatsForRegister("regPC", m_machine->getPC());
} else if (regName == "regSW") {
m_machine->setSW(value);
updateAllFormatsForRegister("regSW", m_machine->getSW());
}
}
void MainWindow::handleFloatRegisterFieldChanged(QLineEdit* field, const QString& objectName)
{
double value = 0.0;
bool ok = false;
if (objectName.contains("_dec_field")) {
value = field->text().toDouble(&ok);
} else if (objectName.contains("_hex_field")) {
QString hexText = field->text();
if (hexText.startsWith("0x", Qt::CaseInsensitive)) {
hexText = hexText.mid(2);
}
uint64_t intValue = hexText.toULongLong(&ok, 16);
if (ok) {
intValue &= 0xFFFFFFFFFFFFULL;
double* floatPtr = reinterpret_cast<double*>(&intValue);
value = *floatPtr;
}
} else if (objectName.contains("_bin_field")) {
uint64_t intValue = field->text().toULongLong(&ok, 2);
if (ok) {
intValue &= 0xFFFFFFFFFFFFULL;
double* floatPtr = reinterpret_cast<double*>(&intValue);
value = *floatPtr;
}
}
if (!ok) {
updateRegisterDisplays();
return;
}
m_machine->setF(value);
updateFloatRegisterFormats("regF", m_machine->getF());
}
void MainWindow::setTestRegisterValues()
{
if (!m_machine) return;
// Set some test values to demonstrate the register updating
m_machine->setA(12345); // Decimal: 12345, Hex: 0x003039, Binary: 000000011000000111001
m_machine->setB(-1000); // Negative value to test signed representation
m_machine->setX(0xABCDEF); // Hex value to test various formats
m_machine->setS(255); // Simple power of 2 minus 1
m_machine->setT(0x7FFFFF); // Maximum positive 24-bit value
// Update all displays
updateRegisterDisplays();
}
void MainWindow::startExecution()
{
if (m_controller) {
m_controller->start();
}
}
void MainWindow::stopExecution()
{
if (m_controller) {
m_controller->stop();
}
}
void MainWindow::stepExecution()
{
if (m_controller) {
m_controller->step();
}
}
void MainWindow::loadDemoProgram()
{
if (!m_machine) return;
// Load the instruction set first
loadInstructionSet();
qDebug() << "Loading SIC/XE Demo Program: Accumulator Loop";
const int TEMP_ADDR = 0x50;
const int LOOP_ADDR = 0x03;
// clear TEMP
m_machine->setByte(TEMP_ADDR, 0);
// Program (addresses):
// 0x00 LDA #1
// 0x03 LDB TEMP
// 0x06 ADDR A,B
// 0x08 RMO B,A
// 0x0A STA TEMP
// 0x0D J LOOP
// LDA #1
m_machine->setByte(0x00, 0x01);
m_machine->setByte(0x01, 0x00);
m_machine->setByte(0x02, 0x01);
// LDB TEMP
m_machine->setByte(0x03, 0x6B);
m_machine->setByte(0x04, 0x00);
m_machine->setByte(0x05, TEMP_ADDR);
// ADDR A,B
m_machine->setByte(0x06, 0x90);
m_machine->setByte(0x07, 0x03);
// RMO B,A
m_machine->setByte(0x08, 0xAC);
m_machine->setByte(0x09, 0x30);
// STA TEMP
m_machine->setByte(0x0A, 0x0F);
m_machine->setByte(0x0B, 0x00);
m_machine->setByte(0x0C, TEMP_ADDR);
// J LOOP
m_machine->setByte(0x0D, 0x3F);
m_machine->setByte(0x0E, 0x00);
m_machine->setByte(0x0F, LOOP_ADDR);
// Set PC to start of program
m_machine->setPC(0x00);
qDebug() << "Program loaded. TEMP at 0x" << QString::number(TEMP_ADDR, 16).toUpper();
qDebug() << "PC set to 0x00. Ready to execute.";
}

View file

@ -2,6 +2,11 @@
#define MAINWINDOW_H
#include <QMainWindow>
#include <memory>
class MachineController;
class Machine;
class QLineEdit;
namespace Ui {
class MainWindow;
@ -14,9 +19,31 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
std::shared_ptr<Machine> machine() const { return m_machine; }
MachineController* controller() const { return m_controller.get(); }
void startExecution();
void stopExecution();
void stepExecution();
void setTestRegisterValues();
private slots:
void updateRegisterDisplays();
void onRegisterFieldChanged();
private:
Ui::MainWindow *ui;
std::shared_ptr<Machine> m_machine;
std::unique_ptr<MachineController> m_controller;
void connectRegisterFields();
void updateSingleRegisterDisplay(const QString& fieldName, int value);
void updateAllFormatsForRegister(const QString& regPrefix, int value);
void updateFloatRegisterFormats(const QString& regPrefix, double value);
void handleFloatRegisterFieldChanged(QLineEdit* field, const QString& objectName);
void loadDemoProgram();
};
#endif // MAINWINDOW_H

View file

@ -19,17 +19,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>231</width>
<height>601</height>
</rect>
</property>
</widget>
<widget class="QWidget" name="widget_2" native="true">
<property name="geometry">
<rect>
<x>230</x>
<y>0</y>
<width>891</width>
<width>431</width>
<height>601</height>
</rect>
</property>
@ -37,34 +27,563 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>881</width>
<height>181</height>
<y>280</y>
<width>431</width>
<height>321</height>
</rect>
</property>
<property name="title">
<string>Register values</string>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<widget class="QLineEdit" name="regA_bin_field">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>881</width>
<height>161</height>
<x>70</x>
<y>40</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>41</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg A</string>
</property>
</widget>
<widget class="QLineEdit" name="regA_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>40</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regA_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>40</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>110</x>
<y>20</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Bin</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>230</x>
<y>20</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Hex</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>350</x>
<y>20</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Dec</string>
</property>
</widget>
<widget class="QLineEdit" name="regB_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>70</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>20</x>
<y>71</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg B</string>
</property>
</widget>
<widget class="QLineEdit" name="regB_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>70</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regB_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>70</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regX_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>100</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>20</x>
<y>101</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg X</string>
</property>
</widget>
<widget class="QLineEdit" name="regX_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>100</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regX_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>100</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regS_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>130</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>20</x>
<y>131</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg S</string>
</property>
</widget>
<widget class="QLineEdit" name="regS_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>130</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regS_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>130</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regT_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>160</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>20</x>
<y>161</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg T</string>
</property>
</widget>
<widget class="QLineEdit" name="regT_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>160</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regT_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>160</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regL_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>190</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regL_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>190</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_9">
<property name="geometry">
<rect>
<x>20</x>
<y>191</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg L</string>
</property>
</widget>
<widget class="QLineEdit" name="regL_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>190</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_10">
<property name="geometry">
<rect>
<x>20</x>
<y>221</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg PC</string>
</property>
</widget>
<widget class="QLineEdit" name="regPC_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>220</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regPC_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>220</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regPC_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>220</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_11">
<property name="geometry">
<rect>
<x>20</x>
<y>250</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg SW</string>
</property>
</widget>
<widget class="QLineEdit" name="regSW_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>249</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regSW_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>249</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regSW_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>249</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_12">
<property name="geometry">
<rect>
<x>20</x>
<y>281</y>
<width>57</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Reg L</string>
</property>
</widget>
<widget class="QLineEdit" name="regF_dec_field">
<property name="geometry">
<rect>
<x>310</x>
<y>280</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regF_bin_field">
<property name="geometry">
<rect>
<x>70</x>
<y>280</y>
<width>113</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="regF_hex_field">
<property name="geometry">
<rect>
<x>190</x>
<y>280</y>
<width>113</width>
<height>23</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>161</height>
</rect>
</property>
<property name="title">
<string>Control</string>
</property>
<widget class="QPushButton" name="StartBtn">
<property name="geometry">
<rect>
<x>40</x>
<y>70</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QPushButton" name="StopBtn">
<property name="geometry">
<rect>
<x>180</x>
<y>70</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Stop</string>
</property>
</widget>
<widget class="QPushButton" name="StepBtn">
<property name="geometry">
<rect>
<x>320</x>
<y>70</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Step</string>
</property>
</widget>
</widget>
</widget>
<widget class="QWidget" name="widget_2" native="true">
<property name="geometry">
<rect>
<x>430</x>
<y>0</y>
<width>711</width>
<height>601</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">

View file

@ -3,6 +3,8 @@
#include "constants.h"
#include <cmath>
// ==============================
// SIC/XE Utility Functions
// ==============================
@ -77,4 +79,17 @@ inline int getCC(int sw) {
return sw & CC_MASK;
}
inline double normaliseFloat(double value)
{
if (value == 0.0 )return 0.0;
if (!std::isfinite(value)) return value;
double mantissa = value;
while (std::fabs(mantissa) >= 10.0) mantissa /= 10.0;
while (std::fabs(mantissa) < 1.0) mantissa *= 10.0;
return mantissa;
}
#endif // UTILS_H

View file

@ -73,6 +73,11 @@ void float_handler(Machine &m)
m.setF(static_cast<double>(m.getA()));
}
void norm_handler(Machine &m)
{
m.setF(normaliseFloat(m.getF()));
}
void addr_handler(Machine &m, int r1, int r2)
{
m.setReg(r2, m.getReg(r1) + m.getReg(r2));
@ -303,6 +308,14 @@ void or_handler(Machine &m, int ea, AddressingMode mode)
m.setA(m.getA() | val);
}
void rd_handler(Machine &m, int ea, AddressingMode mode)
{
int deviceNum = resolveWordOperand(m, ea, mode);
Device& device = m.getDevice(deviceNum);
// Load byte into rightmost byte of A register
m.setA((m.getA() & 0xFFFF00) | device.read());
}
void rsub_handler(Machine &m, int ea, AddressingMode mode)
{
m.setPC(m.getL());
@ -372,6 +385,18 @@ void subf_handler(Machine &m, int ea, AddressingMode mode)
m.setF(m.getF() - val);
}
void td_handler(Machine &m, int ea, AddressingMode mode)
{
int deviceNum = resolveWordOperand(m, ea, mode);
Device& device = m.getDevice(deviceNum);
// Test device and set SW accordingly
if (device.test()) {
m.setSW(setCC(m.getSW(), CC_EQ));
} else {
m.setSW(setCC(m.getSW(), CC_LT));
}
}
void tix_handler(Machine &m, int ea, AddressingMode mode)
{
m.setX(m.getX() + 1);
@ -379,3 +404,11 @@ void tix_handler(Machine &m, int ea, AddressingMode mode)
int memVal = resolveWordOperand(m, ea, mode);
m.setSW(sic_comp(valX, memVal, m.getSW()));
}
void wd_handler(Machine &m, int ea, AddressingMode mode)
{
int deviceNum = resolveWordOperand(m, ea, mode);
Device& device = m.getDevice(deviceNum);
// Write rightmost byte of A register to device
device.write(static_cast<unsigned char>(m.getA() & 0xFF));
}

View file

@ -38,9 +38,9 @@ void loadInstructionSet()
instructions[MUL] = {"MUL", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(mul_handler)};
instructions[MULF] = {"MULF", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(mulf_handler)};
instructions[MULR] = {"MULR", InstructionType::TYPE2, reinterpret_cast<RawHandler>(mulr_handler)};
instructions[NORM] = {"NORM", InstructionType::TYPE1, nullptr};
instructions[NORM] = {"NORM", InstructionType::TYPE1, reinterpret_cast<RawHandler>(norm_handler)};
instructions[OR] = {"OR", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(or_handler)};
instructions[RD] = {"RD", InstructionType::TYPE3_4, nullptr};
instructions[RD] = {"RD", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(rd_handler)};
instructions[RMO] = {"RMO", InstructionType::TYPE2, reinterpret_cast<RawHandler>(rmo_handler)};
instructions[RSUB] = {"RSUB", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(rsub_handler)};
instructions[SHIFTL] = {"SHIFTL", InstructionType::TYPE2, reinterpret_cast<RawHandler>(shiftl_handler)};
@ -62,10 +62,10 @@ void loadInstructionSet()
instructions[SUBR] = {"SUBR", InstructionType::TYPE2, reinterpret_cast<RawHandler>(subr_handler)};
instructions[SVC] = {"SVC", InstructionType::TYPE2, reinterpret_cast<RawHandler>(svc_handler)};
instructions[TIXR] = {"TIXR", InstructionType::TYPE2, reinterpret_cast<RawHandler>(tixr_handler)};
instructions[TD] = {"TD", InstructionType::TYPE3_4, nullptr};
instructions[TD] = {"TD", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(td_handler)};
instructions[TIX] = {"TIX", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(tix_handler)};
instructions[TIO] = {"TIO", InstructionType::TYPE1, nullptr};
instructions[WD] = {"WD", InstructionType::TYPE3_4, nullptr};
instructions[WD] = {"WD", InstructionType::TYPE3_4, reinterpret_cast<RawHandler>(wd_handler)};
// Mark uninitialized opcodes as INVALID
for (int i = 0; i < 0xff; ++i) {