added disasembly and better demo program
This commit is contained in:
parent
280a3b62fc
commit
ad3078ba48
3 changed files with 651 additions and 105 deletions
|
|
@ -3,6 +3,7 @@
|
|||
#include "MachineController.h"
|
||||
#include "../../include/machine.h"
|
||||
#include "../../include/instructions.h"
|
||||
#include "../../include/opcode.h"
|
||||
|
||||
#include <QIntValidator>
|
||||
#include <QLineEdit>
|
||||
|
|
@ -77,12 +78,26 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
connect(ui->MemoryDec256Btn, &QPushButton::clicked, this, &MainWindow::onMemoryDec256);
|
||||
connect(ui->MemoryDec4096Btn, &QPushButton::clicked, this, &MainWindow::onMemoryDec4096);
|
||||
connect(ui->MemoryDec65536Btn, &QPushButton::clicked, this, &MainWindow::onMemoryDec65536);
|
||||
connect(ui->MemoryGoToStart_2, &QPushButton::clicked, this, &MainWindow::onMemoryGoToStart);
|
||||
connect(ui->MemoryGoToEnd, &QPushButton::clicked, this, &MainWindow::onMemoryGoToEnd);
|
||||
|
||||
connect(ui->DisasmInc256Btn, &QPushButton::clicked, this, &MainWindow::onDisassemblyInc);
|
||||
connect(ui->DisasmInc4096Btn, &QPushButton::clicked, this, &MainWindow::onDisassemblyInc16);
|
||||
connect(ui->DisasmInc65536Btn, &QPushButton::clicked, this, &MainWindow::onDisassemblyInc256);
|
||||
connect(ui->DisasmDec256Btn, &QPushButton::clicked, this, &MainWindow::onDisassemblyDec);
|
||||
connect(ui->DisasmDec4096Btn, &QPushButton::clicked, this, &MainWindow::onDisassemblyDec16);
|
||||
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);
|
||||
|
||||
setupMemoryDisplay();
|
||||
setupDisassemblyDisplay();
|
||||
loadDemoProgram();
|
||||
|
||||
updateRegisterDisplays();
|
||||
updateMemoryDisplay();
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
|
|
@ -375,55 +390,117 @@ void MainWindow::loadDemoProgram()
|
|||
// 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);
|
||||
qDebug() << "Loading SIC/XE Demo Program: Array Sum with Indirect Addressing";
|
||||
|
||||
// Memory layout
|
||||
const int ARRAY_ADDR = 0x100; // Array of 3 numbers
|
||||
const int PTR_ADDR = 0x200; // Pointer to array
|
||||
const int SUM_ADDR = 0x300; // Result storage
|
||||
const int COUNTER_ADDR = 0x310; // Loop counter
|
||||
|
||||
// Initialize array with values: 10, 20, 30
|
||||
m_machine->setWord(ARRAY_ADDR, 10);
|
||||
m_machine->setWord(ARRAY_ADDR + 3, 20);
|
||||
m_machine->setWord(ARRAY_ADDR + 6, 30);
|
||||
|
||||
// Initialize pointer to point to array
|
||||
m_machine->setWord(PTR_ADDR, ARRAY_ADDR);
|
||||
|
||||
// Initialize counter to 3
|
||||
m_machine->setWord(COUNTER_ADDR, 3);
|
||||
|
||||
// Initialize sum to 0
|
||||
m_machine->setWord(SUM_ADDR, 0);
|
||||
|
||||
int addr = 0x00;
|
||||
|
||||
// Program: Sum array elements using indirect addressing
|
||||
// 0x00: LDA #0 ; Initialize accumulator to 0
|
||||
m_machine->setByte(addr++, 0x01); // LDA with immediate (n=0,i=1)
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
|
||||
// 0x03: STA SUM_ADDR ; Store 0 in SUM
|
||||
m_machine->setByte(addr++, 0x0F); // STA
|
||||
m_machine->setByte(addr++, (SUM_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, SUM_ADDR & 0xFF);
|
||||
|
||||
// 0x06: LDX #0 ; Initialize index to 0
|
||||
m_machine->setByte(addr++, 0x05); // LDX with immediate
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
|
||||
// LOOP (0x09):
|
||||
const int LOOP_START = addr;
|
||||
|
||||
// 0x09: LDA @PTR_ADDR ; Load value indirectly through pointer
|
||||
m_machine->setByte(addr++, 0x02); // LDA with indirect (n=1,i=0)
|
||||
m_machine->setByte(addr++, (PTR_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, PTR_ADDR & 0xFF);
|
||||
|
||||
// 0x0C: ADD SUM_ADDR ; Add to sum
|
||||
m_machine->setByte(addr++, 0x1B); // ADD
|
||||
m_machine->setByte(addr++, (SUM_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, SUM_ADDR & 0xFF);
|
||||
|
||||
// 0x0F: STA SUM_ADDR ; Store result back
|
||||
m_machine->setByte(addr++, 0x0F); // STA
|
||||
m_machine->setByte(addr++, (SUM_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, SUM_ADDR & 0xFF);
|
||||
|
||||
// 0x12: LDA PTR_ADDR ; Load current pointer value
|
||||
m_machine->setByte(addr++, 0x03); // LDA
|
||||
m_machine->setByte(addr++, (PTR_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, PTR_ADDR & 0xFF);
|
||||
|
||||
// 0x15: ADD #3 ; Add 3 to move to next array element
|
||||
m_machine->setByte(addr++, 0x19); // ADD with immediate
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
m_machine->setByte(addr++, 0x03);
|
||||
|
||||
// 0x18: STA PTR_ADDR ; Store updated pointer
|
||||
m_machine->setByte(addr++, 0x0F); // STA
|
||||
m_machine->setByte(addr++, (PTR_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, PTR_ADDR & 0xFF);
|
||||
|
||||
// 0x1B: LDA COUNTER_ADDR ; Load counter
|
||||
m_machine->setByte(addr++, 0x03); // LDA
|
||||
m_machine->setByte(addr++, (COUNTER_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, COUNTER_ADDR & 0xFF);
|
||||
|
||||
// 0x1E: ADD #-1 ; Decrement counter (add -1)
|
||||
m_machine->setByte(addr++, 0x19); // ADD with immediate
|
||||
m_machine->setByte(addr++, 0x0F); // -1 in 12-bit two's complement
|
||||
m_machine->setByte(addr++, 0xFF);
|
||||
|
||||
// 0x21: STA COUNTER_ADDR ; Store counter
|
||||
m_machine->setByte(addr++, 0x0F); // STA
|
||||
m_machine->setByte(addr++, (COUNTER_ADDR >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, COUNTER_ADDR & 0xFF);
|
||||
|
||||
// 0x24: COMP #0 ; Compare with 0
|
||||
m_machine->setByte(addr++, 0x29); // COMP with immediate
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
|
||||
// 0x27: JGT LOOP ; Jump if greater than 0
|
||||
m_machine->setByte(addr++, 0x37); // JGT
|
||||
m_machine->setByte(addr++, (LOOP_START >> 8) & 0xFF);
|
||||
m_machine->setByte(addr++, LOOP_START & 0xFF);
|
||||
|
||||
// 0x2A: J 0x2A ; Infinite loop (halt)
|
||||
m_machine->setByte(addr++, 0x3F); // J
|
||||
m_machine->setByte(addr++, 0x00);
|
||||
m_machine->setByte(addr++, 0x2A);
|
||||
|
||||
// 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.";
|
||||
qDebug() << "Program loaded:";
|
||||
qDebug() << " Array at 0x" << QString::number(ARRAY_ADDR, 16).toUpper() << " = [10, 20, 30]";
|
||||
qDebug() << " Pointer at 0x" << QString::number(PTR_ADDR, 16).toUpper();
|
||||
qDebug() << " Sum will be stored at 0x" << QString::number(SUM_ADDR, 16).toUpper();
|
||||
qDebug() << " Expected result: 60 (0x3C)";
|
||||
}
|
||||
|
||||
void MainWindow::setupMemoryDisplay()
|
||||
|
|
@ -486,6 +563,285 @@ void MainWindow::onMemoryDec65536()
|
|||
updateMemoryDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onMemoryGoToStart()
|
||||
{
|
||||
m_memoryOffset = 0;
|
||||
updateMemoryDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onMemoryGoToEnd()
|
||||
{
|
||||
m_memoryOffset = 1048576 - 256;
|
||||
updateMemoryDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::setupDisassemblyDisplay()
|
||||
{
|
||||
ui->MemorygroupBox_3->setTitle("Disassembly");
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyInc()
|
||||
{
|
||||
// Move forward by 1 instruction
|
||||
auto instr = disassembleAt(m_disassemblyOffset);
|
||||
m_disassemblyOffset += instr.size;
|
||||
if (m_disassemblyOffset > 1048576 - 16) {
|
||||
m_disassemblyOffset = 1048576 - 16;
|
||||
}
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyInc16()
|
||||
{
|
||||
// Move forward by 16 instructions
|
||||
for (int i = 0; i < 16 && m_disassemblyOffset < 1048576 - 16; i++) {
|
||||
auto instr = disassembleAt(m_disassemblyOffset);
|
||||
m_disassemblyOffset += instr.size;
|
||||
}
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyInc256()
|
||||
{
|
||||
// Move forward by 256 instructions
|
||||
for (int i = 0; i < 256 && m_disassemblyOffset < 1048576 - 16; i++) {
|
||||
auto instr = disassembleAt(m_disassemblyOffset);
|
||||
m_disassemblyOffset += instr.size;
|
||||
}
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyDec()
|
||||
{
|
||||
// Move back by trying to find previous instruction (assume max 4 bytes)
|
||||
m_disassemblyOffset = std::max(0, m_disassemblyOffset - 4);
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyDec16()
|
||||
{
|
||||
// Move back by approximately 16 instructions (16*3 = 48 bytes avg)
|
||||
m_disassemblyOffset = std::max(0, m_disassemblyOffset - 48);
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyDec256()
|
||||
{
|
||||
// Move back by approximately 256 instructions (256*3 = 768 bytes avg)
|
||||
m_disassemblyOffset = std::max(0, m_disassemblyOffset - 768);
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyGoToStart()
|
||||
{
|
||||
m_disassemblyOffset = 0;
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
void MainWindow::onDisassemblyGoToEnd()
|
||||
{
|
||||
m_disassemblyOffset = std::max(0, 1048576 - 1024);
|
||||
updateDisassemblyDisplay();
|
||||
}
|
||||
|
||||
MainWindow::DisassembledInstruction MainWindow::disassembleAt(int address)
|
||||
{
|
||||
DisassembledInstruction result;
|
||||
result.address = address;
|
||||
result.size = 1;
|
||||
result.mnemonic = "???";
|
||||
result.operand = "";
|
||||
result.effectiveAddr = -1;
|
||||
result.isImmediate = false;
|
||||
result.isIndirect = false;
|
||||
|
||||
if (address >= 1048576) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int byte1 = m_machine->getByte(address);
|
||||
int opcode = byte1 & 0xFC; // Mask off lower 2 bits (n, i flags)
|
||||
|
||||
if (opcode >= 0xff || instructions[opcode].type == InstructionType::INVALID) {
|
||||
result.mnemonic = QString("BYTE 0x%1").arg(byte1, 2, 16, QChar('0')).toUpper();
|
||||
return result;
|
||||
}
|
||||
|
||||
result.mnemonic = QString(instructions[opcode].name);
|
||||
|
||||
switch (instructions[opcode].type) {
|
||||
case InstructionType::TYPE1:
|
||||
result.size = 1;
|
||||
break;
|
||||
|
||||
case InstructionType::TYPE2: {
|
||||
result.size = 2;
|
||||
if (address + 1 < 1048576) {
|
||||
int byte2 = m_machine->getByte(address + 1);
|
||||
int r1 = (byte2 >> 4) & 0xF;
|
||||
int r2 = byte2 & 0xF;
|
||||
|
||||
const char* regNames[] = {"A", "X", "L", "B", "S", "T", "F", "?", "PC", "SW"};
|
||||
QString reg1Str = (r1 < 10) ? regNames[r1] : "?";
|
||||
QString reg2Str = (r2 < 10) ? regNames[r2] : "?";
|
||||
|
||||
result.operand = QString("%1, %2").arg(reg1Str).arg(reg2Str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case InstructionType::TYPE3_4: {
|
||||
if (address + 2 >= 1048576) {
|
||||
result.size = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
int byte2 = m_machine->getByte(address + 1);
|
||||
int byte3 = m_machine->getByte(address + 2);
|
||||
|
||||
int ni = (byte1 >> 0) & 0x3;
|
||||
int x = (byte2 >> 7) & 0x1;
|
||||
int b = (byte2 >> 6) & 0x1;
|
||||
int p = (byte2 >> 5) & 0x1;
|
||||
int e = (byte2 >> 4) & 0x1;
|
||||
|
||||
if (e) {
|
||||
// Format 4 - add + prefix to mnemonic
|
||||
result.mnemonic = "+" + result.mnemonic;
|
||||
result.size = 4;
|
||||
if (address + 3 < 1048576) {
|
||||
int byte4 = m_machine->getByte(address + 3);
|
||||
int addr = ((byte2 & 0xF) << 16) | (byte3 << 8) | byte4;
|
||||
|
||||
result.isImmediate = (ni == 0x1);
|
||||
result.isIndirect = (ni == 0x2);
|
||||
|
||||
if (!result.isImmediate) {
|
||||
result.effectiveAddr = addr;
|
||||
}
|
||||
|
||||
QString prefix = "";
|
||||
if (ni == 0x1) prefix = "#"; // Immediate
|
||||
else if (ni == 0x2) prefix = "@"; // Indirect
|
||||
|
||||
result.operand = QString("%1%2").arg(prefix).arg(addr, 5, 16, QChar('0')).toUpper();
|
||||
if (x) result.operand += ",X";
|
||||
}
|
||||
} else {
|
||||
result.size = 3;
|
||||
int disp = ((byte2 & 0xF) << 8) | byte3;
|
||||
|
||||
if (disp & 0x800) {
|
||||
disp |= 0xFFFFF000;
|
||||
}
|
||||
|
||||
result.isImmediate = (ni == 0x1);
|
||||
result.isIndirect = (ni == 0x2);
|
||||
|
||||
QString prefix = "";
|
||||
if (ni == 0x1) prefix = "#"; // Immediate
|
||||
else if (ni == 0x2) prefix = "@"; // Indirect
|
||||
|
||||
if (ni == 0x1 && !p && !b) {
|
||||
result.operand = QString("#%1").arg(disp & 0xFFF);
|
||||
} else {
|
||||
// Calculate effective address for display
|
||||
int ea = disp;
|
||||
QString addrMode = "";
|
||||
|
||||
if (p) {
|
||||
ea += m_machine->getPC();
|
||||
addrMode = " (PC)";
|
||||
} else if (b) {
|
||||
ea += m_machine->getB();
|
||||
addrMode = " (B)";
|
||||
}
|
||||
|
||||
if (!result.isImmediate && !x) {
|
||||
result.effectiveAddr = ea & 0xFFFFF;
|
||||
}
|
||||
|
||||
result.operand = QString("%1%2%3").arg(prefix).arg(ea & 0xFFFFF, 4, 16, QChar('0')).toUpper().arg(addrMode);
|
||||
if (x) result.operand += ",X";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void MainWindow::updateDisassemblyDisplay()
|
||||
{
|
||||
if (!m_machine) return;
|
||||
|
||||
QWidget* container = new QWidget();
|
||||
QVBoxLayout* layout = new QVBoxLayout(container);
|
||||
layout->setSpacing(1);
|
||||
layout->setContentsMargins(5, 5, 5, 5);
|
||||
|
||||
QFont monoFont("Courier New");
|
||||
monoFont.setPointSize(9);
|
||||
|
||||
// Header
|
||||
QString headerText = QString("Address Mnemonic Operand *var **var");
|
||||
QLabel* header = new QLabel(headerText);
|
||||
QFont headerFont = monoFont;
|
||||
headerFont.setBold(true);
|
||||
header->setFont(headerFont);
|
||||
layout->addWidget(header);
|
||||
|
||||
int pc = m_machine->getPC();
|
||||
int currentAddr = m_disassemblyOffset;
|
||||
|
||||
// Disassemble up to 255 instructions
|
||||
for (int i = 0; i < 255 && currentAddr < 1048576; i++) {
|
||||
auto instr = disassembleAt(currentAddr);
|
||||
|
||||
QString varCol = "";
|
||||
QString varVar = "";
|
||||
|
||||
// *var column - show value at effective address (if not immediate)
|
||||
if (instr.effectiveAddr >= 0 && instr.effectiveAddr < 1048576) {
|
||||
int value = m_machine->getWord(instr.effectiveAddr);
|
||||
varCol = QString("0x%1").arg(value & 0xFFFFFF, 6, 16, QChar('0')).toUpper();
|
||||
|
||||
// **var column - if indirect (@), dereference again
|
||||
if (instr.isIndirect && value >= 0 && value < 1048576) {
|
||||
int derefValue = m_machine->getWord(value);
|
||||
varVar = QString("0x%1").arg(derefValue & 0xFFFFFF, 6, 16, QChar('0')).toUpper();
|
||||
}
|
||||
}
|
||||
|
||||
QString line = QString("0x%1 %2 %3 %4 %5")
|
||||
.arg(instr.address, 5, 16, QChar('0')).toUpper()
|
||||
.arg(instr.mnemonic, -9)
|
||||
.arg(instr.operand, -14)
|
||||
.arg(varCol, -9)
|
||||
.arg(varVar, -9);
|
||||
|
||||
QLabel* instrLine = new QLabel(line);
|
||||
instrLine->setFont(monoFont);
|
||||
|
||||
// Highlight current PC
|
||||
if (pc == instr.address) {
|
||||
instrLine->setStyleSheet("background-color: #FFFF99; font-weight: bold;");
|
||||
}
|
||||
|
||||
layout->addWidget(instrLine);
|
||||
currentAddr += instr.size;
|
||||
}
|
||||
|
||||
layout->addStretch();
|
||||
container->setLayout(layout);
|
||||
|
||||
ui->DisasemblyScrollArea->setWidget(container);
|
||||
}
|
||||
|
||||
void MainWindow::updateMemoryDisplay()
|
||||
{
|
||||
if (!m_machine) return;
|
||||
|
|
@ -501,7 +857,7 @@ void MainWindow::updateMemoryDisplay()
|
|||
monoFont.setPointSize(9);
|
||||
|
||||
// Header with current offset range
|
||||
QString headerText = QString("Address Hex Value Char [0x%1 - 0x%2]")
|
||||
QString headerText = QString("Address Hex Value Char [0x%1 - 0x%2]")
|
||||
.arg(m_memoryOffset, 5, 16, QChar('0')).toUpper()
|
||||
.arg(m_memoryOffset + 255, 5, 16, QChar('0')).toUpper();
|
||||
QLabel* header = new QLabel(headerText);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public:
|
|||
private slots:
|
||||
void updateRegisterDisplays();
|
||||
void updateMemoryDisplay();
|
||||
void updateDisassemblyDisplay();
|
||||
void onRegisterFieldChanged();
|
||||
void onMemoryInc256();
|
||||
void onMemoryInc4096();
|
||||
|
|
@ -39,12 +40,23 @@ private slots:
|
|||
void onMemoryDec256();
|
||||
void onMemoryDec4096();
|
||||
void onMemoryDec65536();
|
||||
void onMemoryGoToStart();
|
||||
void onMemoryGoToEnd();
|
||||
void onDisassemblyInc();
|
||||
void onDisassemblyInc16();
|
||||
void onDisassemblyInc256();
|
||||
void onDisassemblyDec();
|
||||
void onDisassemblyDec16();
|
||||
void onDisassemblyDec256();
|
||||
void onDisassemblyGoToStart();
|
||||
void onDisassemblyGoToEnd();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
std::shared_ptr<Machine> m_machine;
|
||||
std::unique_ptr<MachineController> m_controller;
|
||||
int m_memoryOffset = 0;
|
||||
int m_disassemblyOffset = 0;
|
||||
|
||||
void connectRegisterFields();
|
||||
void updateSingleRegisterDisplay(const QString& fieldName, int value);
|
||||
|
|
@ -53,6 +65,18 @@ private:
|
|||
void handleFloatRegisterFieldChanged(QLineEdit* field, const QString& objectName);
|
||||
void loadDemoProgram();
|
||||
void setupMemoryDisplay();
|
||||
void setupDisassemblyDisplay();
|
||||
|
||||
struct DisassembledInstruction {
|
||||
int address;
|
||||
int size;
|
||||
QString mnemonic;
|
||||
QString operand;
|
||||
int effectiveAddr;
|
||||
bool isImmediate;
|
||||
bool isIndirect;
|
||||
};
|
||||
DisassembledInstruction disassembleAt(int address);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1137</width>
|
||||
<width>1172</width>
|
||||
<height>649</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>431</width>
|
||||
<height>601</height>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>280</y>
|
||||
<y>80</y>
|
||||
<width>431</width>
|
||||
<height>321</height>
|
||||
</rect>
|
||||
|
|
@ -48,8 +48,8 @@
|
|||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>41</y>
|
||||
<x>10</x>
|
||||
<y>40</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -150,8 +150,8 @@
|
|||
<widget class="QLabel" name="label_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>71</y>
|
||||
<x>10</x>
|
||||
<y>70</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -198,8 +198,8 @@
|
|||
<widget class="QLabel" name="label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>101</y>
|
||||
<x>10</x>
|
||||
<y>100</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -246,8 +246,8 @@
|
|||
<widget class="QLabel" name="label_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>131</y>
|
||||
<x>10</x>
|
||||
<y>130</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -294,8 +294,8 @@
|
|||
<widget class="QLabel" name="label_8">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>161</y>
|
||||
<x>10</x>
|
||||
<y>160</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -352,8 +352,8 @@
|
|||
<widget class="QLabel" name="label_9">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>191</y>
|
||||
<x>10</x>
|
||||
<y>190</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -380,8 +380,8 @@
|
|||
<widget class="QLabel" name="label_10">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>221</y>
|
||||
<x>10</x>
|
||||
<y>220</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -428,8 +428,8 @@
|
|||
<widget class="QLabel" name="label_11">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>250</y>
|
||||
<x>10</x>
|
||||
<y>249</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -476,8 +476,8 @@
|
|||
<widget class="QLabel" name="label_12">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>281</y>
|
||||
<x>10</x>
|
||||
<y>280</y>
|
||||
<width>57</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
|
@ -528,7 +528,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>431</width>
|
||||
<height>161</height>
|
||||
<height>81</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
|
|
@ -537,8 +537,8 @@
|
|||
<widget class="QPushButton" name="StartBtn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>70</y>
|
||||
<x>30</x>
|
||||
<y>40</y>
|
||||
<width>80</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
|
@ -550,8 +550,8 @@
|
|||
<widget class="QPushButton" name="StopBtn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>70</y>
|
||||
<x>170</x>
|
||||
<y>40</y>
|
||||
<width>80</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
|
@ -563,8 +563,8 @@
|
|||
<widget class="QPushButton" name="StepBtn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>70</y>
|
||||
<x>310</x>
|
||||
<y>40</y>
|
||||
<width>80</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
|
@ -578,9 +578,9 @@
|
|||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>430</x>
|
||||
<x>450</x>
|
||||
<y>0</y>
|
||||
<width>711</width>
|
||||
<width>721</width>
|
||||
<height>601</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
@ -590,11 +590,11 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>711</width>
|
||||
<height>251</height>
|
||||
<height>291</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>GroupBox</string>
|
||||
<string>Memory</string>
|
||||
</property>
|
||||
<widget class="QScrollArea" name="MemoryScrollArea">
|
||||
<property name="geometry">
|
||||
|
|
@ -602,7 +602,7 @@
|
|||
<x>0</x>
|
||||
<y>20</y>
|
||||
<width>711</width>
|
||||
<height>171</height>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
|
|
@ -614,7 +614,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>709</width>
|
||||
<height>169</height>
|
||||
<height>219</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -622,79 +622,245 @@
|
|||
<widget class="QPushButton" name="MemoryInc4096Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>460</x>
|
||||
<y>200</y>
|
||||
<width>121</width>
|
||||
<x>450</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>>> M[+0x01000]</string>
|
||||
<string>>></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryInc256Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>360</x>
|
||||
<y>200</y>
|
||||
<width>101</width>
|
||||
<x>370</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>> M[+0x00100]</string>
|
||||
<string>></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryInc65536Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>580</x>
|
||||
<y>200</y>
|
||||
<width>121</width>
|
||||
<x>530</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>>>> M[+0x10000]</string>
|
||||
<string>>>></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryDec256Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>250</x>
|
||||
<y>200</y>
|
||||
<width>101</width>
|
||||
<x>290</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>< M[-0x00100]</string>
|
||||
<string><</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryDec4096Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>200</y>
|
||||
<width>121</width>
|
||||
<x>210</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><< M[-0x01000]</string>
|
||||
<string><<</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryDec65536Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>200</y>
|
||||
<width>121</width>
|
||||
<x>130</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><<< M[-0x10000]</string>
|
||||
<string><<<</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryGoToStart_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>O</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="MemoryGoToEnd">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>610</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>|</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="MemorygroupBox_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>300</y>
|
||||
<width>711</width>
|
||||
<height>301</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Disasembly</string>
|
||||
</property>
|
||||
<widget class="QScrollArea" name="DisasemblyScrollArea">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>20</y>
|
||||
<width>711</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>709</width>
|
||||
<height>219</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmInc4096Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>440</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>>></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmInc256Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>360</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmInc65536Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>520</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>>>></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmDec256Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>280</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmDec4096Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><<</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmDec65536Btn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><<<</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmGoToStart">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>O</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DisasmGoToEnd">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>600</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>|</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
@ -705,7 +871,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1137</width>
|
||||
<width>1172</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue