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_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 }},
|
||||||
|
@ -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
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 <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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user