added loading
This commit is contained in:
parent
d438feb9ee
commit
598865d216
4 changed files with 86 additions and 1 deletions
|
|
@ -11,6 +11,7 @@ public:
|
||||||
~FileReader() override;
|
~FileReader() override;
|
||||||
|
|
||||||
int readByte() override;
|
int readByte() override;
|
||||||
|
|
||||||
bool readBytes(uint8_t* buf, size_t len) override;
|
bool readBytes(uint8_t* buf, size_t len) override;
|
||||||
std::string readString(size_t len) override;
|
std::string readString(size_t len) override;
|
||||||
std::string readLine() override;
|
std::string readLine() override;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,9 @@ private :
|
||||||
string _filename;
|
string _filename;
|
||||||
shared_ptr<FileReader> _file_reader;
|
shared_ptr<FileReader> _file_reader;
|
||||||
HeaderMetadata readHeader();
|
HeaderMetadata readHeader();
|
||||||
|
TextRecord readTextRecord();
|
||||||
|
EndRecord readEndRecord();
|
||||||
|
bool load_into_memory(int start_address, const std::vector<uint8_t>& data);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ int FileReader::readByte() {
|
||||||
return static_cast<unsigned char>(c);
|
return static_cast<unsigned char>(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FileReader::readBytes(uint8_t* buf, size_t len) {
|
bool FileReader::readBytes(uint8_t* buf, size_t len) {
|
||||||
in.read(reinterpret_cast<char*>(buf), static_cast<std::streamsize>(len));
|
in.read(reinterpret_cast<char*>(buf), static_cast<std::streamsize>(len));
|
||||||
return static_cast<size_t>(in.gcount()) == len;
|
return static_cast<size_t>(in.gcount()) == len;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "file_reader.h"
|
#include "file_reader.h"
|
||||||
|
#include "machine.h"
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
Loader::~Loader()
|
Loader::~Loader()
|
||||||
{
|
{
|
||||||
|
|
@ -11,8 +13,28 @@ Loader::~Loader()
|
||||||
|
|
||||||
void Loader::load()
|
void Loader::load()
|
||||||
{
|
{
|
||||||
|
HeaderMetadata header = readHeader();
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
RecordType type = parseRecordType(static_cast<char>(_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)
|
Loader::RecordType Loader::parseRecordType(char c)
|
||||||
|
|
@ -32,4 +54,62 @@ Loader::HeaderMetadata Loader::readHeader()
|
||||||
throw std::runtime_error("Expected HEADER record");
|
throw std::runtime_error("Expected HEADER record");
|
||||||
}
|
}
|
||||||
HeaderMetadata header;
|
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<uint8_t>(std::stoi(std::string(reinterpret_cast<char*>(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<uint8_t> &data)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < data.size(); ++i) {
|
||||||
|
int addr = start_address + static_cast<int>(i);
|
||||||
|
if (addr < 0 || addr >= MEMORY_SIZE) { // 24-bit address space
|
||||||
|
return false; // Address out of bounds
|
||||||
|
}
|
||||||
|
_machine->setByte(addr, data[i]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue