Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1329,13 +1329,13 @@ bool Assembler::parse(std::string_view source, std::string const& fname)
auto layoutOk = mach->layoutSections();

for (auto const& s : mach->getSections()) {
LOGD("%s : %x -> %x (%d) [%x]\n", s.name, s.start, s.start + s.size,
LOGD("%s : %x -> %x (%d) [%x]\n", s.name, s.start.value(), s.start.value() + s.size.value(),
s.data.size(), s.flags);

auto prefix = "section."s + std::string(s.name);

auto start = static_cast<Number>(s.start);
auto end = static_cast<Number>(s.start + s.data.size());
auto start = static_cast<Number>(s.start.value());
auto end = static_cast<Number>(s.start.value() + s.data.size());

syms.set(prefix + ".start", start);
syms.set(prefix + ".end", end);
Expand Down
10 changes: 10 additions & 0 deletions src/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <coreutils/file.h>
#include <fmt/format.h>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
Expand Down Expand Up @@ -111,6 +112,15 @@ inline std::string_view operator+(std::string_view sv, std::string_view n)

using Number = double;

template<typename T>
using Optional = std::optional<T>;
// TODO: register type for RTTI comparison (aka std::type_info)
// struct Optional : public std::optional<T> {
// Optional() : std::optional<T>() {
// // TODO: register type for RTTI comparison (aka std::typeinfo)
// }
// };

inline Num div(Num a, Num b)
{
DBZ(b.i());
Expand Down
87 changes: 47 additions & 40 deletions src/machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ Section& Machine::addSection(Section const& s)
section.flags |= SectionFlags::FixedSize;
}

if (start != -1) {
if (start.has_value()) {
section.start = start;
section.flags |= SectionFlags::FixedStart;
}

if (!in.empty()) {
auto& parent = getSection(in);
LOGD("Parent %s at %x/%x", parent.name, parent.start, parent.pc);
LOGD("Parent %s at %x/%x", parent.name, parent.start.value(), parent.pc.value());
Check(parent.data.empty(), "Parent section must contain no data");

if (section.parent.empty()) {
Expand All @@ -174,8 +174,8 @@ Section& Machine::addSection(Section const& s)
section.flags |= SectionFlags::ReadOnly;
}

if (section.start == -1) {
LOGD("Setting start to %x", parent.pc);
if (!section.start.has_value()) {
LOGD("Setting start to %x", parent.pc.value());
section.start = parent.pc;
}
}
Expand All @@ -184,7 +184,7 @@ Section& Machine::addSection(Section const& s)
section.pc = section.start;
}

Check(section.start != -1, "Section must have start");
Check(section.start.has_value(), "Section must have start");

return section;
}
Expand Down Expand Up @@ -226,20 +226,20 @@ int32_t Machine::layoutSection(int32_t start, Section& s)
LOGD("Layout %s", s.name);
if ((s.flags & FixedStart) == 0) {
if (s.start != start) {
LOGD("%s: %x differs from %x", s.name, s.start, start);
LOGD("%s: %x differs from %x", s.name, s.start.value(), start);
layoutOk = false;
}
s.start = start;
}

Check(s.start >= start,
fmt::format("Section {} starts at {:x} which is before {:x}", s.name,
s.start, start));
s.start.value(), start));

if (!s.data.empty()) {
Check(s.children.empty(), "Data section may not have children");
// Leaf / data section
return s.start + static_cast<int32_t>(s.data.size());
return s.start.value() + static_cast<int32_t>(s.data.size());
}

if (!s.children.empty()) {
Expand All @@ -250,12 +250,12 @@ int32_t Machine::layoutSection(int32_t start, Section& s)
}
// Unless fixed size, update size to total of its children
if ((s.flags & FixedSize) == 0) {
s.size = start - s.start;
s.size = start - s.start.value();
}
if (start - s.start > s.size) {
if (start - s.start.value() > s.size) {
throw machine_error(fmt::format("Section {} is too large", s.name));
}
return s.start + s.size;
return s.start.value() + s.size.value();
}

bool Machine::layoutSections()
Expand All @@ -265,8 +265,13 @@ bool Machine::layoutSections()
for (auto& s : sections) {
if (s.parent.empty()) {
// LOGI("Root %s at %x", s.name, s.start);
auto start = s.start;
layoutSection(start, s);
if (s.start.has_value()) {
auto start = s.start.value();
layoutSection(start, s);
} else {
LOGD(fmt::format("Start of section {} is undefined -> skipping layout", s.name));
layoutOk = false;
}
}
}
return layoutOk;
Expand All @@ -279,9 +284,9 @@ Error Machine::checkOverlap()
for (auto const& b : sections) {
if (&a != &b && !b.data.empty() &&
((b.flags & NoStorage) == 0)) {
auto as = a.start;
auto as = a.start.value();
auto ae = as + static_cast<int32_t>(a.data.size());
auto bs = b.start;
auto bs = b.start.value();
auto be = bs + static_cast<int32_t>(b.data.size());
if (as >= bs && as < be) {
return {2, 0,
Expand Down Expand Up @@ -353,7 +358,7 @@ uint32_t Machine::getPC() const
if (currentSection == nullptr) {
return 0;
}
return currentSection->pc;
return currentSection->pc.value();
}

// clang-format off
Expand Down Expand Up @@ -411,9 +416,9 @@ void Machine::writeCrt(utils::File const& outFile)
if (section.data.empty()) {
continue;
}
LOGI("Start %x", section.start);
auto bank = section.start >> 16;
auto start = section.start & 0xffff;
LOGI("Start %x", section.start.value());
auto bank = section.start.value() >> 16;
auto start = section.start.value() & 0xffff;
auto end = start + section.data.size();
// bank : 01a000,01c000,01e000
if (start < 0x8000 || end > 0xc000) {
Expand Down Expand Up @@ -493,8 +498,8 @@ void Machine::write(std::string_view name, OutFmt fmt)

utils::File outFile = createFile(name);

auto start = non_empty.front().start;
auto end = non_empty.back().start +
auto start = non_empty.front().start.value();
auto end = non_empty.back().start.value() +
static_cast<int32_t>(non_empty.back().data.size());

if (end <= start) {
Expand Down Expand Up @@ -535,8 +540,8 @@ void Machine::write(std::string_view name, OutFmt fmt)
}
if ((section.flags & WriteToDisk) != 0) {
auto of = createFile(section.name);
of.write<uint8_t>(section.start & 0xff);
of.write<uint8_t>(section.start >> 8);
of.write<uint8_t>(section.start.value() & 0xff);
of.write<uint8_t>(section.start.value() >> 8);
of.write(section.data);
of.close();
continue;
Expand All @@ -554,7 +559,7 @@ void Machine::write(std::string_view name, OutFmt fmt)
fmt::format("Section {} overlaps previous", section.name));
}

auto offset = section.start;
auto offset = section.start.value();

if (last_end >= 0) {
while (last_end < offset) {
Expand Down Expand Up @@ -613,12 +618,12 @@ std::pair<uint32_t, uint32_t> Machine::runSetup()
continue;
}
if (low == 0) {
low = section.start;
low = section.start.value();
}
high = section.start + section.data.size();
high = section.start.value() + section.data.size();
//LOGI("Writing '%s' to %x-%x", section.name, section.start,
// section.start + section.data.size());
machine->write_ram(section.start, section.data.data(),
machine->write_ram(section.start.value(), section.data.data(),
section.data.size());
}
}
Expand All @@ -628,18 +633,20 @@ std::pair<uint32_t, uint32_t> Machine::runSetup()

uint32_t Machine::writeByte(uint8_t b)
{
dis[currentSection->pc] = fmt::format("{:02x}", b);
auto& section_pc = currentSection->pc;
dis[section_pc.value()] = fmt::format("{:02x}", b);
currentSection->data.push_back(b);
currentSection->pc++;
return currentSection->pc;
section_pc.emplace(section_pc.value() + 1);
return section_pc.value();
}

uint32_t Machine::writeChar(uint8_t b)
{
dis[currentSection->pc] = fmt::format("{:02x}", b);
auto& section_pc = currentSection->pc;
dis[section_pc.value()] = fmt::format("{:02x}", b);
currentSection->data.push_back(b);
currentSection->pc++;
return currentSection->pc;
section_pc.emplace(section_pc.value() + 1);
return section_pc.value();
}

std::string Machine::disassemble(sixfive::Machine<EmuPolicy>& m, uint32_t* pc)
Expand Down Expand Up @@ -752,13 +759,13 @@ AsmResult Machine::assemble(Instruction const& instr)
arg.mode = it_op->mode;

if (arg.mode == Mode::REL) {
arg.val = arg.val - currentSection->pc - 2;
arg.val = arg.val - currentSection->pc.value() - 2;
}

if (arg.mode == Mode::ZP_REL) {
auto adr = arg.val & 0xffff;
auto val = (arg.val >> 16) & 0xff;
auto diff = adr - currentSection->pc - 2;
auto diff = adr - currentSection->pc.value() - 2;
arg.val = diff << 8 | val;
}

Expand All @@ -767,22 +774,22 @@ AsmResult Machine::assemble(Instruction const& instr)
auto& cs = *currentSection;
auto v = arg.val & (sz == 2 ? 0xff : 0xffff);
if (arg.mode == sixfive::Mode::REL) {
v = (static_cast<int8_t>(v)) + 2 + cs.pc;
v = (static_cast<int8_t>(v)) + 2 + cs.pc.value();
}

dis[cs.pc] = fmt::format(
dis[cs.pc.value()] = fmt::format(
"{} "s + modeTemplate.at(static_cast<int>(arg.mode)), it_ins->name, v);

cs.data.push_back(it_op->code);
if (sz > 1) {
cs.data.push_back(arg.val & 0xff);
dis.erase(cs.pc + 1);
dis.erase(cs.pc.value() + 1);
}
if (sz > 2) {
cs.data.push_back(arg.val >> 8);
dis.erase(cs.pc + 2);
dis.erase(cs.pc.value() + 2);
}
cs.pc += sz;
cs.pc.emplace(cs.pc.value() + sz);

if (arg.mode == Mode::REL && (arg.val > 127 || arg.val < -128)) {
return AsmResult::Truncated;
Expand Down
10 changes: 5 additions & 5 deletions src/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct Section
Section& addByte(uint8_t b)
{
data.push_back(b);
pc++;
pc = pc.value() + 1;
return *this;
}

Expand All @@ -98,15 +98,15 @@ struct Section

int32_t get_size() const
{
return size >= 0 ? size : (int32_t)data.size();
return size >= 0 ? size.value() : (int32_t)data.size();
}

std::string name;
std::string parent;
std::vector<std::string> children;
int32_t start = -1;
int32_t pc = -1;
int32_t size = -1;
Optional<int32_t> start;
Optional<int32_t> pc = -1;
Optional<int32_t> size = -1;
uint32_t flags{};
std::vector<uint8_t> data;
bool valid{true};
Expand Down
8 changes: 4 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ int main(int argc, char** argv)
int32_t start = 0x10000;
for (auto const& s : mach.getSections()) {
if (!s.data.empty() && (s.flags & NoStorage) == 0) {
emu.load(s.start, s.data);
emu.load(s.start.value(), s.data);
if (s.start < start) {
start = s.start;
start = s.start.value();
}
}
}
Expand Down Expand Up @@ -292,8 +292,8 @@ int main(int argc, char** argv)
mach.sortSectionsByStart();
for (auto const& section : mach.getSections()) {
if (!section.data.empty()) {
fmt::print("{:04x}-{:04x} {}\n", section.start,
section.start + section.data.size()-1, section.name);
fmt::print("{:04x}-{:04x} {}\n", section.start.value(),
section.start.value() + section.data.size()-1, section.name);
}
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,13 @@ void initMeta(Assembler& assem)
});

assem.registerMeta("ds", [&](Meta const& meta) {
auto& section_pc = mach.getCurrentSection().pc;
if (meta.args.empty()) {
mach.getCurrentSection().pc ++;
section_pc.emplace(section_pc.value() + 1);
return;
}
auto sz = number<int32_t>(meta.args[0]);
mach.getCurrentSection().pc += sz;
section_pc.emplace(section_pc.value() + sz);
});

assem.registerMeta("run", [&](Meta const& meta) {
Expand Down Expand Up @@ -420,8 +421,9 @@ void initMeta(Assembler& assem)
assem.evaluateBlock(meta.blocks[0]);

if (!section.parent.empty()) {
mach.getSection(section.parent).pc +=
static_cast<int32_t>(section.get_size() - sz);
auto& parent_section_pc = mach.getSection(section.parent).pc;
parent_section_pc.emplace(parent_section_pc.value() +
static_cast<int32_t>(section.get_size() - sz));
}

if ((section.flags & Backwards) != 0) {
Expand All @@ -445,8 +447,8 @@ void initMeta(Assembler& assem)
section.data = packed;
}
syms.set(p + ".data", section.data);
syms.set(p + ".start", section.start);
syms.set(p + ".pc", pc);
syms.set(p + ".start", section.start.value());
syms.set(p + ".pc", pc.value());
syms.set(p + ".size", section.data.size());
mach.popSection();
return;
Expand Down
4 changes: 4 additions & 0 deletions src/symbol_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ struct SymbolTable
template <typename T>
void set(std::string const& name, T const& val)
{
// TODO: cannot check on optional template types (check the ones we use explicitly)
static_assert(false == std::is_same_v<Optional<int32_t>, T>);
static_assert(false == std::is_same_v<Optional<Number>, T>);

if (!is_redefinable(name)) {
throw sym_error(fmt::format("Symbol '{}' already defined", name));
}
Expand Down