add end_l
/end_h
I don't remember why I did this.
This commit is contained in:
parent
0dda2ad13f
commit
b5e460048d
@ -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_imm8(ssize_t n) { return n >= -128 && n <= 255; }
|
||||
|
||||
static bool always_valid(ssize_t _) { return true; }
|
||||
|
||||
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::AI, { .len = 2, .valid = is_uint16 }},
|
||||
{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::R, { .len = 1, .valid = is_int8 }},
|
||||
{isa::mode::S, { .len = 0, .valid = always_valid }},
|
||||
|
@ -36,6 +36,8 @@ namespace assembler {
|
||||
size_t start_h;
|
||||
size_t size_l;
|
||||
size_t size_h;
|
||||
size_t end_l;
|
||||
size_t end_h;
|
||||
} symbol;
|
||||
size_t location;
|
||||
std::shared_ptr<std::string> buf;
|
||||
|
29
link.py
Normal file
29
link.py
Normal 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
46
main.cc
@ -3,6 +3,7 @@
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
|
||||
#include "assembler.hh"
|
||||
#include "addressing_mode.hh"
|
||||
@ -13,9 +14,9 @@
|
||||
|
||||
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';
|
||||
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: "
|
||||
<< tostring::op().find(ins.op)->second << ' '
|
||||
<< 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;
|
||||
|
||||
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();
|
||||
if (!am_it->second.valid(value)) {
|
||||
std::cerr << "overflow at " << ins.row << " value: " << value << '\n';
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//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)
|
||||
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);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
for (auto prog_it = program.cbegin(); prog_it != program.cend(); prog_it++) {
|
||||
if (std::holds_alternative<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)) {
|
||||
auto blob = std::get<assembler::blob_t>(*prog_it);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
@ -128,7 +139,7 @@ int main(int argc, char * argv[])
|
||||
ok = parser::parse(*buf, program, symbol_strings);
|
||||
if (!ok)
|
||||
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);
|
||||
assembler::blob_t blob {
|
||||
.symbol = {
|
||||
@ -137,6 +148,8 @@ int main(int argc, char * argv[])
|
||||
.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_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,
|
||||
.buf = std::move(buf),
|
||||
@ -159,14 +172,19 @@ int main(int argc, char * argv[])
|
||||
|
||||
std::cerr << "output: " << argv[argc - 1] << '\n';
|
||||
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()) {
|
||||
std::cerr << "failed to open " << output_filename << '\n';
|
||||
return -1;
|
||||
}
|
||||
|
||||
serialize_program(program, symbol_table, out);
|
||||
ok = serialize_program(program, symbol_table, out);
|
||||
if (!ok) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
out.close();
|
||||
std::rename((output_filename + ".part").data(), output_filename.data());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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 [_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});
|
||||
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";
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user