add end_l/end_h

I don't remember why I did this.
This commit is contained in:
Zack Buhman 2023-06-15 17:02:04 +00:00
parent 0dda2ad13f
commit b5e460048d
5 changed files with 69 additions and 16 deletions

View File

@ -10,6 +10,8 @@ static bool is_uint8(ssize_t n) { return n >= 0 && n <= 255; }
static bool is_int8(ssize_t n) { return n >= -128 && n <= 127; } static bool is_int8(ssize_t n) { return n >= -128 && n <= 127; }
static bool is_imm8(ssize_t n) { return n >= -128 && n <= 255; }
static bool always_valid(ssize_t _) { return true; } static bool always_valid(ssize_t _) { return true; }
std::unordered_map<isa::mode, addressing_mode_t>& addressing_mode() { std::unordered_map<isa::mode, addressing_mode_t>& addressing_mode() {
@ -20,7 +22,7 @@ std::unordered_map<isa::mode, addressing_mode_t>& addressing_mode() {
{isa::mode::AIY, { .len = 2, .valid = is_uint16 }}, {isa::mode::AIY, { .len = 2, .valid = is_uint16 }},
{isa::mode::AI, { .len = 2, .valid = is_uint16 }}, {isa::mode::AI, { .len = 2, .valid = is_uint16 }},
{isa::mode::ACC, { .len = 0, .valid = always_valid }}, {isa::mode::ACC, { .len = 0, .valid = always_valid }},
{isa::mode::IMM, { .len = 1, .valid = is_uint8 }}, {isa::mode::IMM, { .len = 1, .valid = is_imm8 }},
{isa::mode::I, { .len = 0, .valid = always_valid }}, {isa::mode::I, { .len = 0, .valid = always_valid }},
{isa::mode::R, { .len = 1, .valid = is_int8 }}, {isa::mode::R, { .len = 1, .valid = is_int8 }},
{isa::mode::S, { .len = 0, .valid = always_valid }}, {isa::mode::S, { .len = 0, .valid = always_valid }},

View File

@ -36,6 +36,8 @@ namespace assembler {
size_t start_h; size_t start_h;
size_t size_l; size_t size_l;
size_t size_h; size_t size_h;
size_t end_l;
size_t end_h;
} symbol; } symbol;
size_t location; size_t location;
std::shared_ptr<std::string> buf; std::shared_ptr<std::string> buf;

29
link.py Normal file
View File

@ -0,0 +1,29 @@
import sys
assert len(sys.argv) > 2
mem = bytearray(2 ** 15)
with open(sys.argv[1], 'rb') as f:
l = f.read()
for i, a in enumerate(l):
mem[i + 0x4000] = a
# NMIB
mem[0xfffa - 0x8000] = 0x00
mem[0xfffb - 0x8000] = 0xc0
# RESB
mem[0xfffc - 0x8000] = 0x00
mem[0xfffd - 0x8000] = 0xc0
# IRQB
mem[0xfffe - 0x8000] = 0x02
mem[0xffff - 0x8000] = 0xc0
with open(sys.argv[2], 'wb') as f:
f.write(mem)

46
main.cc
View File

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include <memory> #include <memory>
#include <cstdio>
#include "assembler.hh" #include "assembler.hh"
#include "addressing_mode.hh" #include "addressing_mode.hh"
@ -13,9 +14,9 @@
using namespace std::literals; using namespace std::literals;
void serialize_program(const assembler::program_t& program, const assembler::symbol_table_t &symbol_table, std::ostream& out) bool serialize_program(const assembler::program_t& program, const assembler::symbol_table_t &symbol_table, std::ostream& out)
{ {
auto serialize_instruction = [&](assembler::instruction_t& ins) -> void { auto serialize_instruction = [&](assembler::instruction_t& ins) -> bool {
//std::cerr << "enc " << (int)ins.op << ' ' << (int)ins.mode << '\n'; //std::cerr << "enc " << (int)ins.op << ' ' << (int)ins.mode << '\n';
char buf[3]; char buf[3];
@ -24,15 +25,9 @@ void serialize_program(const assembler::program_t& program, const assembler::sym
std::cerr << ins.row << ": illegal op,mode: " std::cerr << ins.row << ": illegal op,mode: "
<< tostring::op().find(ins.op)->second << ' ' << tostring::op().find(ins.op)->second << ' '
<< tostring::mode().find(ins.mode)->second << '\n'; << tostring::mode().find(ins.mode)->second << '\n';
return; return false;
} }
/*
std::cerr << tostring::op().find(ins.op)->second << ' '
<< tostring::mode().find(ins.mode)->second << ' '
<< std::hex << (int)opcode_it->second << '\n';
*/
buf[0] = opcode_it->second; buf[0] = opcode_it->second;
auto am_it = addressing_mode().find(ins.mode); auto am_it = addressing_mode().find(ins.mode);
@ -67,7 +62,7 @@ void serialize_program(const assembler::program_t& program, const assembler::sym
size_t value = get_value(); size_t value = get_value();
if (!am_it->second.valid(value)) { if (!am_it->second.valid(value)) {
std::cerr << "overflow at " << ins.row << " value: " << value << '\n'; std::cerr << "overflow at " << ins.row << " value: " << value << '\n';
return; return false;
} }
//std::cerr << "value " << std::hex << value << ' ' << am_it->second.len << '\n'; //std::cerr << "value " << std::hex << value << ' ' << am_it->second.len << '\n';
@ -77,14 +72,28 @@ void serialize_program(const assembler::program_t& program, const assembler::sym
if (am_it->second.len >= 1) if (am_it->second.len >= 1)
buf[1] = (value >> 0) & 0xff; buf[1] = (value >> 0) & 0xff;
std::cerr << std::hex << ins.location << ' '
<< tostring::op().find(ins.op)->second << ' '
<< tostring::mode().find(ins.mode)->second << ' ';
if (am_it->second.len == 2)
std::cerr << std::hex << (value & 0xffff) << '\n';
else if (am_it->second.len == 1)
std::cerr << std::hex << (value & 0xff) << '\n';
else
std::cerr << '\n';
out.write(buf, 1 + am_it->second.len); out.write(buf, 1 + am_it->second.len);
return true;
}; };
for (auto prog_it = program.cbegin(); prog_it != program.cend(); prog_it++) { for (auto prog_it = program.cbegin(); prog_it != program.cend(); prog_it++) {
if (std::holds_alternative<assembler::instruction_t>(*prog_it)) { if (std::holds_alternative<assembler::instruction_t>(*prog_it)) {
auto ins = std::get<assembler::instruction_t>(*prog_it); auto ins = std::get<assembler::instruction_t>(*prog_it);
serialize_instruction(ins); auto ok = serialize_instruction(ins);
if (!ok)
return false;
} else if (std::holds_alternative<assembler::blob_t>(*prog_it)) { } else if (std::holds_alternative<assembler::blob_t>(*prog_it)) {
auto blob = std::get<assembler::blob_t>(*prog_it); auto blob = std::get<assembler::blob_t>(*prog_it);
out.write(blob.buf->data(), blob.buf->size()); out.write(blob.buf->data(), blob.buf->size());
@ -92,6 +101,8 @@ void serialize_program(const assembler::program_t& program, const assembler::sym
assert (false); assert (false);
} }
} }
return true;
} }
int main(int argc, char * argv[]) int main(int argc, char * argv[])
@ -128,7 +139,7 @@ int main(int argc, char * argv[])
ok = parser::parse(*buf, program, symbol_strings); ok = parser::parse(*buf, program, symbol_strings);
if (!ok) if (!ok)
return -1; return -1;
} else if (ext == ".bin"s) { } else if (ext == ".bin"s or ext == ".txt"s) {
std::string name = input_filename.substr(0, input_filename.size() - 4); std::string name = input_filename.substr(0, input_filename.size() - 4);
assembler::blob_t blob { assembler::blob_t blob {
.symbol = { .symbol = {
@ -137,6 +148,8 @@ int main(int argc, char * argv[])
.start_h = symbol::get(symbol_strings, "_bin_"s + name + "_start_h"s), .start_h = symbol::get(symbol_strings, "_bin_"s + name + "_start_h"s),
.size_l = symbol::get(symbol_strings, "_bin_"s + name + "_size_l"s), .size_l = symbol::get(symbol_strings, "_bin_"s + name + "_size_l"s),
.size_h = symbol::get(symbol_strings, "_bin_"s + name + "_size_h"s), .size_h = symbol::get(symbol_strings, "_bin_"s + name + "_size_h"s),
.end_l = symbol::get(symbol_strings, "_bin_"s + name + "_end_l"s),
.end_h = symbol::get(symbol_strings, "_bin_"s + name + "_end_h"s),
}, },
.location = 0xeeee, .location = 0xeeee,
.buf = std::move(buf), .buf = std::move(buf),
@ -159,14 +172,19 @@ int main(int argc, char * argv[])
std::cerr << "output: " << argv[argc - 1] << '\n'; std::cerr << "output: " << argv[argc - 1] << '\n';
std::string output_filename {argv[argc - 1]}; std::string output_filename {argv[argc - 1]};
std::ofstream out {output_filename, std::ios::binary}; std::ofstream out {output_filename + ".part", std::ios::binary};
if (!out.is_open()) { if (!out.is_open()) {
std::cerr << "failed to open " << output_filename << '\n'; std::cerr << "failed to open " << output_filename << '\n';
return -1; return -1;
} }
serialize_program(program, symbol_table, out); ok = serialize_program(program, symbol_table, out);
if (!ok) {
return -1;
}
out.close(); out.close();
std::rename((output_filename + ".part").data(), output_filename.data());
return 0; return 0;
} }

View File

@ -47,7 +47,9 @@ bool resolve(size_t link_location, assembler::program_t& program, assembler::sym
auto [_3, ok3] = symbol_table.insert({blob.symbol.start_h, (offset >> 8) & 0xff}); auto [_3, ok3] = symbol_table.insert({blob.symbol.start_h, (offset >> 8) & 0xff});
auto [_4, ok4] = symbol_table.insert({blob.symbol.size_l, (blob.buf->size() >> 0) & 0xff}); auto [_4, ok4] = symbol_table.insert({blob.symbol.size_l, (blob.buf->size() >> 0) & 0xff});
auto [_5, ok5] = symbol_table.insert({blob.symbol.size_h, (blob.buf->size() >> 8) & 0xff}); auto [_5, ok5] = symbol_table.insert({blob.symbol.size_h, (blob.buf->size() >> 8) & 0xff});
if (!ok1 || !ok2 || !ok3 || !ok4 || !ok5) { auto [_6, ok6] = symbol_table.insert({blob.symbol.end_l, ((offset + blob.buf->size() - 1) >> 0) & 0xff});
auto [_7, ok7] = symbol_table.insert({blob.symbol.end_h, ((offset + blob.buf->size() - 1) >> 8) & 0xff});
if (!ok1 || !ok2 || !ok3 || !ok4 || !ok5 || !ok6 || !ok7) {
std::cerr << "duplicate blob symbol\n"; std::cerr << "duplicate blob symbol\n";
return false; return false;
} }