From 598865d216158b4f9c37a3836297081e07cea547 Mon Sep 17 00:00:00 2001 From: zanostro Date: Mon, 17 Nov 2025 13:45:03 +0100 Subject: [PATCH] added loading --- simulator_SIC_XE/include/file_reader.h | 1 + simulator_SIC_XE/include/loader.h | 3 + simulator_SIC_XE/src/file_reader.cpp | 1 + simulator_SIC_XE/src/loader.cpp | 82 +++++++++++++++++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/simulator_SIC_XE/include/file_reader.h b/simulator_SIC_XE/include/file_reader.h index e2da87a..87b8a17 100644 --- a/simulator_SIC_XE/include/file_reader.h +++ b/simulator_SIC_XE/include/file_reader.h @@ -11,6 +11,7 @@ public: ~FileReader() override; int readByte() override; + bool readBytes(uint8_t* buf, size_t len) override; std::string readString(size_t len) override; std::string readLine() override; diff --git a/simulator_SIC_XE/include/loader.h b/simulator_SIC_XE/include/loader.h index c4d75e3..16ffa45 100644 --- a/simulator_SIC_XE/include/loader.h +++ b/simulator_SIC_XE/include/loader.h @@ -51,6 +51,9 @@ private : string _filename; shared_ptr _file_reader; HeaderMetadata readHeader(); + TextRecord readTextRecord(); + EndRecord readEndRecord(); + bool load_into_memory(int start_address, const std::vector& data); }; diff --git a/simulator_SIC_XE/src/file_reader.cpp b/simulator_SIC_XE/src/file_reader.cpp index 0ace74b..2a800cc 100644 --- a/simulator_SIC_XE/src/file_reader.cpp +++ b/simulator_SIC_XE/src/file_reader.cpp @@ -12,6 +12,7 @@ int FileReader::readByte() { return static_cast(c); } + bool FileReader::readBytes(uint8_t* buf, size_t len) { in.read(reinterpret_cast(buf), static_cast(len)); return static_cast(in.gcount()) == len; diff --git a/simulator_SIC_XE/src/loader.cpp b/simulator_SIC_XE/src/loader.cpp index 0626ac6..df459fa 100644 --- a/simulator_SIC_XE/src/loader.cpp +++ b/simulator_SIC_XE/src/loader.cpp @@ -1,5 +1,7 @@ #include "loader.h" #include "file_reader.h" +#include "machine.h" +#include "constants.h" Loader::~Loader() { @@ -11,8 +13,28 @@ Loader::~Loader() void Loader::load() { + HeaderMetadata header = readHeader(); - + while(true) { + RecordType type = parseRecordType(static_cast(_file_reader->readByte())); + switch (type) { + case RecordType::TEXT: { + TextRecord textRecord = readTextRecord(); + if (!load_into_memory(textRecord.start_address, textRecord.data)) { + throw std::runtime_error("Failed to load text record into memory"); + } + break; + } + case RecordType::END: { + EndRecord endRecord = readEndRecord(); + _machine->setPC(endRecord.execution_start_address); + return; // Loading complete + } + case RecordType::UNKNOWN: + default: + throw std::runtime_error("Unknown record type encountered"); + } + } } Loader::RecordType Loader::parseRecordType(char c) @@ -32,4 +54,62 @@ Loader::HeaderMetadata Loader::readHeader() throw std::runtime_error("Expected HEADER record"); } HeaderMetadata header; + // Read program name (6 bytes) + header.program_name = _file_reader->readString(6); + // Read start address (6 hex digits) + header.start_address = std::stoi(_file_reader->readString(6), nullptr, 16); + // Read length (6 hex digits) + header.length = std::stoi(_file_reader->readString(6), nullptr, 16); + // consume newline + _file_reader->readLine(); + return header; +} + +Loader::TextRecord Loader::readTextRecord() +{ + TextRecord record; + // Assume 'T' has already been read + record.start_address = std::stoi(_file_reader->readString(6), nullptr, 16); + // Read length (1 byte, 2 hex digits) + int length = std::stoi(_file_reader->readString(2), nullptr, 16); + + // Read data bytes + record.data.resize(length); + + + for(int i = 0; i < length; ++i) { + unsigned char buffer[2]; + _file_reader->readBytes(buffer, 2); + record.data[i] = static_cast(std::stoi(std::string(reinterpret_cast(buffer), 2), nullptr, 16)); + } + // consume newline + _file_reader->readLine(); + +} + +Loader::EndRecord Loader::readEndRecord() +{ + EndRecord record; + // Assume 'E' has already been read + std::string addrStr = _file_reader->readString(6); + if (!addrStr.empty()) { + record.execution_start_address = std::stoi(addrStr, nullptr, 16); + } else { + record.execution_start_address = 0; // default start address + } + // consume newline + _file_reader->readLine(); + return record; +} + +bool Loader::load_into_memory(int start_address, const std::vector &data) +{ + for(size_t i = 0; i < data.size(); ++i) { + int addr = start_address + static_cast(i); + if (addr < 0 || addr >= MEMORY_SIZE) { // 24-bit address space + return false; // Address out of bounds + } + _machine->setByte(addr, data[i]); + } + return true; }