added loading
This commit is contained in:
parent
598865d216
commit
7b79c35f63
8 changed files with 84 additions and 14 deletions
|
|
@ -46,3 +46,15 @@ message(STATUS "Output directory: ${OUTPUT_DIR}")
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/gui/qt/CMakeLists.txt")
|
if(EXISTS "${CMAKE_SOURCE_DIR}/gui/qt/CMakeLists.txt")
|
||||||
add_subdirectory(gui/qt)
|
add_subdirectory(gui/qt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Copy resources directory (if present) to target/res so build output includes them
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/res")
|
||||||
|
add_custom_target(copy_resources
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/target/res
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/res ${CMAKE_SOURCE_DIR}/target/res
|
||||||
|
COMMENT "Copying resources from res/ to target/res/"
|
||||||
|
)
|
||||||
|
if(TARGET simulator_exec)
|
||||||
|
add_dependencies(simulator_exec copy_resources)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ build: configure
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
@echo "Running primary target..."
|
@echo "Running primary target..."
|
||||||
# Prefer GUI if available, otherwise fall back to console executable
|
# Prefer GUI if avail able, otherwise fall back to console executable
|
||||||
@if [ -x "$(GUI_TARGET)" ]; then \
|
@if [ -x "$(GUI_TARGET)" ]; then \
|
||||||
echo "Launching GUI: $(GUI_TARGET)"; \
|
echo "Launching GUI: $(GUI_TARGET)"; \
|
||||||
sh -c 'nohup env QT_QPA_PLATFORM=xcb ./$(GUI_TARGET) >/dev/null 2>&1 & echo $! > "$(BUILD_DIR)/simulator_qt.pid"'; \
|
sh -c 'nohup env QT_QPA_PLATFORM=xcb ./$(GUI_TARGET) >/dev/null 2>&1 & echo $! > "$(BUILD_DIR)/simulator_qt.pid"'; \
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
#include "../../include/machine.h"
|
#include "../../include/machine.h"
|
||||||
#include "../../include/instructions.h"
|
#include "../../include/instructions.h"
|
||||||
#include "../../include/opcode.h"
|
#include "../../include/opcode.h"
|
||||||
|
#include "../../include/constants.h"
|
||||||
|
#include "../../../include/loader.h"
|
||||||
|
|
||||||
#include <QIntValidator>
|
#include <QIntValidator>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
|
@ -16,6 +18,10 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
|
|
||||||
|
class Loader;
|
||||||
|
|
||||||
|
std::shared_ptr<Loader> g_loader;
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow),
|
ui(new Ui::MainWindow),
|
||||||
|
|
@ -93,7 +99,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
|
||||||
setupMemoryDisplay();
|
setupMemoryDisplay();
|
||||||
setupDisassemblyDisplay();
|
setupDisassemblyDisplay();
|
||||||
loadDemoProgram();
|
//loadDemoProgram();
|
||||||
|
g_loader = std::make_shared<Loader>(machine(), std::string(PATH_RESOURCES) + "demo_program.obj");
|
||||||
|
g_loader->load();
|
||||||
|
|
||||||
updateRegisterDisplays();
|
updateRegisterDisplays();
|
||||||
updateMemoryDisplay();
|
updateMemoryDisplay();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONSTANTS_H
|
#ifndef CONSTANTS_H
|
||||||
#define CONSTANTS_H
|
#define CONSTANTS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
// ==============================
|
// ==============================
|
||||||
// SIC/XE Architecture Constants
|
// SIC/XE Architecture Constants
|
||||||
// ==============================
|
// ==============================
|
||||||
|
|
@ -39,5 +40,13 @@ constexpr int BIT_E_MASK = 0x10; // mask for e bit in F4 and F3 instructions
|
||||||
constexpr bool USE_EXTENDED_MODE = true;
|
constexpr bool USE_EXTENDED_MODE = true;
|
||||||
constexpr int VECTOR_REG_SIZE = 4;
|
constexpr int VECTOR_REG_SIZE = 4;
|
||||||
|
|
||||||
|
/* if structure is
|
||||||
|
/target/
|
||||||
|
|-> bin/simulator_exec
|
||||||
|
|-> res/
|
||||||
|
*/
|
||||||
|
// When running from project root (./target/bin/simulator_exec), resources are in ./target/res/
|
||||||
|
constexpr char PATH_RESOURCES[] = "./target/res/";
|
||||||
|
constexpr bool FILE_CONTAINS_WHITE_SPACES = true;
|
||||||
|
|
||||||
#endif // CONSTANTS_H
|
#endif // CONSTANTS_H
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "file_reader.h"
|
#include "file_reader.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
class Machine;
|
class Machine;
|
||||||
|
|
||||||
|
|
@ -16,6 +17,9 @@ class Loader {
|
||||||
public:
|
public:
|
||||||
Loader( shared_ptr<Machine> machine, string filename) : _machine(machine), _filename(filename) {
|
Loader( shared_ptr<Machine> machine, string filename) : _machine(machine), _filename(filename) {
|
||||||
_file_reader = std::make_shared<FileReader>(filename, std::ios::in);
|
_file_reader = std::make_shared<FileReader>(filename, std::ios::in);
|
||||||
|
if (!_file_reader->good()) {
|
||||||
|
throw std::runtime_error("Loader: failed to open file: " + filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~Loader();
|
~Loader();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "file_reader.h"
|
#include "file_reader.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
Loader::~Loader()
|
Loader::~Loader()
|
||||||
{
|
{
|
||||||
|
|
@ -49,15 +50,22 @@ Loader::RecordType Loader::parseRecordType(char c)
|
||||||
|
|
||||||
Loader::HeaderMetadata Loader::readHeader()
|
Loader::HeaderMetadata Loader::readHeader()
|
||||||
{
|
{
|
||||||
|
|
||||||
RecordType type = parseRecordType(static_cast<char>(_file_reader->readByte()));
|
RecordType type = parseRecordType(static_cast<char>(_file_reader->readByte()));
|
||||||
if (type != RecordType::HEADER) {
|
if (type != RecordType::HEADER) {
|
||||||
throw std::runtime_error("Expected HEADER record");
|
throw std::runtime_error("Expected HEADER record");
|
||||||
}
|
}
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
|
|
||||||
HeaderMetadata header;
|
HeaderMetadata header;
|
||||||
// Read program name (6 bytes)
|
// Read program name (6 bytes)
|
||||||
header.program_name = _file_reader->readString(6);
|
header.program_name = _file_reader->readString(6);
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
|
|
||||||
// Read start address (6 hex digits)
|
// Read start address (6 hex digits)
|
||||||
header.start_address = std::stoi(_file_reader->readString(6), nullptr, 16);
|
header.start_address = std::stoi(_file_reader->readString(6), nullptr, 16);
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
|
|
||||||
// Read length (6 hex digits)
|
// Read length (6 hex digits)
|
||||||
header.length = std::stoi(_file_reader->readString(6), nullptr, 16);
|
header.length = std::stoi(_file_reader->readString(6), nullptr, 16);
|
||||||
// consume newline
|
// consume newline
|
||||||
|
|
@ -67,35 +75,40 @@ Loader::HeaderMetadata Loader::readHeader()
|
||||||
|
|
||||||
Loader::TextRecord Loader::readTextRecord()
|
Loader::TextRecord Loader::readTextRecord()
|
||||||
{
|
{
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
TextRecord record;
|
TextRecord record;
|
||||||
// Assume 'T' has already been read
|
// Assume 'T' has already been read
|
||||||
record.start_address = std::stoi(_file_reader->readString(6), nullptr, 16);
|
record.start_address = std::stoi(_file_reader->readString(6), nullptr, 16);
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
|
|
||||||
// Read length (1 byte, 2 hex digits)
|
// Read length (1 byte, 2 hex digits)
|
||||||
int length = std::stoi(_file_reader->readString(2), nullptr, 16);
|
int length = std::stoi(_file_reader->readString(2), nullptr, 16);
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
|
|
||||||
// Read data bytes
|
|
||||||
record.data.resize(length);
|
record.data.resize(length);
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < length; ++i) {
|
int index = 0;
|
||||||
unsigned char buffer[2];
|
string byteStr = _file_reader->readLine();
|
||||||
_file_reader->readBytes(buffer, 2);
|
// Remove spaces, newlines, and other whitespace characters
|
||||||
record.data[i] = static_cast<uint8_t>(std::stoi(std::string(reinterpret_cast<char*>(buffer), 2), nullptr, 16));
|
byteStr.erase(std::remove_if(byteStr.begin(), byteStr.end(), ::isspace), byteStr.end());
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
std::string byteHex = byteStr.substr(i * 2, 2);
|
||||||
|
record.data[i] = static_cast<uint8_t>(std::stoi(byteHex, nullptr, 16));
|
||||||
}
|
}
|
||||||
// consume newline
|
return record;
|
||||||
_file_reader->readLine();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::EndRecord Loader::readEndRecord()
|
Loader::EndRecord Loader::readEndRecord()
|
||||||
{
|
{
|
||||||
EndRecord record;
|
EndRecord record;
|
||||||
|
if(FILE_CONTAINS_WHITE_SPACES) _file_reader->readByte();
|
||||||
// Assume 'E' has already been read
|
// Assume 'E' has already been read
|
||||||
std::string addrStr = _file_reader->readString(6);
|
std::string addrStr = _file_reader->readString(6);
|
||||||
if (!addrStr.empty()) {
|
if (!addrStr.empty()) {
|
||||||
record.execution_start_address = std::stoi(addrStr, nullptr, 16);
|
record.execution_start_address = std::stoi(addrStr, nullptr, 16);
|
||||||
} else {
|
} else {
|
||||||
record.execution_start_address = 0; // default start address
|
record.execution_start_address = 0;
|
||||||
}
|
}
|
||||||
// consume newline
|
// consume newline
|
||||||
_file_reader->readLine();
|
_file_reader->readLine();
|
||||||
|
|
@ -106,8 +119,8 @@ bool Loader::load_into_memory(int start_address, const std::vector<uint8_t> &dat
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < data.size(); ++i) {
|
for(size_t i = 0; i < data.size(); ++i) {
|
||||||
int addr = start_address + static_cast<int>(i);
|
int addr = start_address + static_cast<int>(i);
|
||||||
if (addr < 0 || addr >= MEMORY_SIZE) { // 24-bit address space
|
if (addr < 0 || addr >= MEMORY_SIZE) {
|
||||||
return false; // Address out of bounds
|
return false;
|
||||||
}
|
}
|
||||||
_machine->setByte(addr, data[i]);
|
_machine->setByte(addr, data[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
#include "file_device.h"
|
#include "file_device.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
#include "instructions.h"
|
#include "instructions.h"
|
||||||
|
#include "constants.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
|
@ -17,6 +19,7 @@ struct VectorAddProgram {
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
loadInstructionSet();
|
loadInstructionSet();
|
||||||
Machine machine;
|
Machine machine;
|
||||||
cout << "SIC/XE Program: Accumulator Loop" << endl;
|
cout << "SIC/XE Program: Accumulator Loop" << endl;
|
||||||
|
|
@ -88,6 +91,20 @@ int main()
|
||||||
int val = machine.getWord(VR_ADDR + i * 3);
|
int val = machine.getWord(VR_ADDR + i * 3);
|
||||||
cout << val << (i + 1 < VECTOR_REG_SIZE ? ", " : "\n");
|
cout << val << (i + 1 < VECTOR_REG_SIZE ? ", " : "\n");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
loadInstructionSet();
|
||||||
|
std::shared_ptr<Machine> machine = std::make_shared<Machine>();
|
||||||
|
Loader loader(machine, std::string(PATH_RESOURCES) + "test.obj");
|
||||||
|
loader.load();
|
||||||
|
machine->execute();
|
||||||
|
machine->execute();
|
||||||
|
machine->execute();
|
||||||
|
machine->execute();
|
||||||
|
machine->execute();
|
||||||
|
machine->execute();
|
||||||
|
cout << "Register A after execution: " << machine->getA() << endl;
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
7
test.asm
Normal file
7
test.asm
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
test START 0
|
||||||
|
LDA #1
|
||||||
|
LDB #2
|
||||||
|
ADDR B, A
|
||||||
|
|
||||||
|
halt J halt
|
||||||
|
END test
|
||||||
Loading…
Add table
Add a link
Reference in a new issue