137 lines
4 KiB
C++
137 lines
4 KiB
C++
#include "DisassemblyLoader.hpp"
|
|
|
|
#include <ostd/io/File.hpp>
|
|
#include <ostd/io/FileSystem.hpp>
|
|
#include <ostd/io/Memory.hpp>
|
|
#include <ostd/io/Serial.hpp>
|
|
|
|
#include <algorithm>
|
|
#include <ostd/string/String.hpp>
|
|
|
|
namespace dragon
|
|
{
|
|
const DisassemblyTable DisassemblyTable::DefaultObject;
|
|
|
|
void DisassemblyTable::init(const ostd::String& filePath)
|
|
{
|
|
ostd::ByteStream stream;
|
|
if (!ostd::Memory::loadByteStreamFromFile(filePath, stream))
|
|
{
|
|
m_initialized = false;
|
|
return;
|
|
}
|
|
load_data(stream);
|
|
}
|
|
|
|
void DisassemblyTable::load_data(ostd::ByteStream& stream)
|
|
{
|
|
constexpr int32_t MODE_CODE = 0, MODE_DATA = 1, MODE_LABELS = 2;
|
|
int32_t mode = MODE_CODE;
|
|
ostd::serial::SerialIO serializer(stream, ostd::serial::SerialIO::tEndianness::BigEndian);
|
|
ostd::StreamIndex addr = 0;
|
|
int32_t line_addr = 0;
|
|
int16_t data_size = 1;
|
|
int8_t line_code_char = 0;
|
|
ostd::String header_string = "";
|
|
serializer.r_NullTerminatedString(0, header_string);
|
|
if (header_string != "{ DRAGON_DEBUG_DISASSEMBLY }") return;
|
|
addr += (header_string.len() + 1) * ostd::tTypeSize::BYTE;
|
|
while (addr < serializer.size())
|
|
{
|
|
serializer.r_DWord(addr, line_addr);
|
|
addr += ostd::tTypeSize::DWORD;
|
|
serializer.r_Word(addr, data_size);
|
|
addr += ostd::tTypeSize::WORD;
|
|
ostd::String code_line = "";
|
|
serializer.r_NullTerminatedString(addr, code_line);
|
|
addr += (code_line.len() + 1) * ostd::tTypeSize::BYTE;
|
|
if (code_line == "{ DATA }")
|
|
{
|
|
mode = MODE_DATA;
|
|
continue;
|
|
}
|
|
else if (code_line == "{ LABELS }")
|
|
{
|
|
mode = MODE_LABELS;
|
|
continue;
|
|
}
|
|
else if (code_line == "[----------DATA_SECTION----------]")
|
|
{
|
|
continue; //TODO: Store addresses for various data sections
|
|
}
|
|
|
|
code::Assembler::tDisassemblyLine line;
|
|
line.addr = line_addr;
|
|
line.code = code_line;
|
|
line.size = data_size;
|
|
if (mode == MODE_CODE)
|
|
{
|
|
ostd::String codeEdit(line.code);
|
|
codeEdit.trim();
|
|
if (codeEdit.contains(" "))
|
|
{
|
|
ostd::String part1 = codeEdit.new_substr(0, codeEdit.indexOf(" "));
|
|
ostd::String part2 = codeEdit.new_substr(codeEdit.indexOf(" ") + 1);
|
|
part1.trim();
|
|
part2.trim();
|
|
int32_t opCodeLen = 10;
|
|
if (part1.len() < opCodeLen)
|
|
{
|
|
codeEdit = part1 + ostd::String::duplicateChar(' ', opCodeLen - part1.len()) + part2;
|
|
line.code = codeEdit;
|
|
}
|
|
}
|
|
m_code.push_back(line);
|
|
}
|
|
else if (mode == MODE_DATA)
|
|
m_data.push_back(line);
|
|
else if (mode == MODE_LABELS)
|
|
m_labels.push_back(line);
|
|
}
|
|
m_initialized = true;
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyLoader::loadDirectory(const ostd::String& directoryPath)
|
|
{
|
|
auto list = ostd::FileSystem::listFilesInDirectory(directoryPath);
|
|
for (auto& path : list)
|
|
loadFile(path.string());
|
|
}
|
|
|
|
const DisassemblyTable& DisassemblyLoader::loadFile(const ostd::String& filePath)
|
|
{
|
|
DisassemblyTable table(filePath);
|
|
if (!table.isInitialized()) return DisassemblyTable::DefaultObject; //TODO: Error
|
|
m_tables.push_back(table);
|
|
return m_tables[m_tables.size() - 1];
|
|
}
|
|
|
|
std::vector<code::Assembler::tDisassemblyLine> DisassemblyLoader::getCodeTable(void)
|
|
{
|
|
std::vector<code::Assembler::tDisassemblyLine> fullTable;
|
|
for (auto& table : m_tables)
|
|
fullTable.insert(fullTable.end(), table.getCodeTable().begin(), table.getCodeTable().end());
|
|
std::sort(fullTable.begin(), fullTable.end());
|
|
return fullTable;
|
|
}
|
|
|
|
std::vector<code::Assembler::tDisassemblyLine> DisassemblyLoader::getDataTable(void)
|
|
{
|
|
std::vector<code::Assembler::tDisassemblyLine> fullTable;
|
|
for (auto& table : m_tables)
|
|
fullTable.insert(fullTable.end(), table.getDataTable().begin(), table.getDataTable().end());
|
|
std::sort(fullTable.begin(), fullTable.end());
|
|
return fullTable;
|
|
}
|
|
|
|
std::vector<code::Assembler::tDisassemblyLine> DisassemblyLoader::getLabelTable(void)
|
|
{
|
|
std::vector<code::Assembler::tDisassemblyLine> fullTable;
|
|
for (auto& table : m_tables)
|
|
fullTable.insert(fullTable.end(), table.getLabelTable().begin(), table.getLabelTable().end());
|
|
std::sort(fullTable.begin(), fullTable.end());
|
|
return fullTable;
|
|
}
|
|
}
|