mirror of
https://github.com/lefticus/6502-cpp.git
synced 2025-02-06 14:30:11 +00:00
Implement a bunch more instructions
This commit is contained in:
parent
f79a189a12
commit
d2241528e5
@ -17,6 +17,15 @@ struct C64 : Personality
|
|||||||
new_instructions.emplace_back(ASMLine::Type::Directive, ".byt $0B,$08,$0A,$00,$9E,$32,$30,$36,$31,$00,$00,$00");
|
new_instructions.emplace_back(ASMLine::Type::Directive, ".byt $0B,$08,$0A,$00,$9E,$32,$30,$36,$31,$00,$00,$00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string_view stack_low_address() const override
|
||||||
|
{
|
||||||
|
return "$02";
|
||||||
|
}
|
||||||
|
[[nodiscard]] std::string_view stack_high_address() const override
|
||||||
|
{
|
||||||
|
return "$03";
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] Operand get_register(const int reg_num) const override
|
[[nodiscard]] Operand get_register(const int reg_num) const override
|
||||||
{
|
{
|
||||||
switch (reg_num) {
|
switch (reg_num) {
|
||||||
|
@ -9,6 +9,8 @@ class Personality
|
|||||||
public:
|
public:
|
||||||
virtual void insert_autostart_sequence(std::vector<mos6502> &new_instructions) const = 0;
|
virtual void insert_autostart_sequence(std::vector<mos6502> &new_instructions) const = 0;
|
||||||
[[nodiscard]] virtual Operand get_register(const int reg_num) const = 0;
|
[[nodiscard]] virtual Operand get_register(const int reg_num) const = 0;
|
||||||
|
[[nodiscard]] virtual std::string_view stack_low_address() const = 0;
|
||||||
|
[[nodiscard]] virtual std::string_view stack_high_address() const= 0;
|
||||||
|
|
||||||
virtual ~Personality() = default;
|
virtual ~Personality() = default;
|
||||||
Personality(const Personality &) = delete;
|
Personality(const Personality &) = delete;
|
||||||
|
157
src/6502-c++.cpp
157
src/6502-c++.cpp
@ -9,17 +9,25 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <charconv>
|
||||||
|
|
||||||
#include "../include/assembly.hpp"
|
#include "../include/assembly.hpp"
|
||||||
#include "../include/6502.hpp"
|
#include "../include/6502.hpp"
|
||||||
#include "../include/optimizer.hpp"
|
#include "../include/optimizer.hpp"
|
||||||
#include "../include/personalities/c64.hpp"
|
#include "../include/personalities/c64.hpp"
|
||||||
|
|
||||||
int parse_8bit_literal(const std::string &s)
|
|
||||||
{
|
int to_int(const std::string_view sv) {
|
||||||
return std::stoi(std::string(std::next(std::begin(s)), std::end(s)));
|
int result{};
|
||||||
|
std::from_chars(sv.begin(), sv.end(), result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_8bit_literal(const std::string_view s)
|
||||||
|
{
|
||||||
|
return to_int(s.substr(1));
|
||||||
|
}
|
||||||
|
|
||||||
std::string_view strip_lo_hi(std::string_view s)
|
std::string_view strip_lo_hi(std::string_view s)
|
||||||
{
|
{
|
||||||
@ -66,6 +74,7 @@ struct AVR : ASMLine
|
|||||||
unknown,
|
unknown,
|
||||||
|
|
||||||
adc,
|
adc,
|
||||||
|
adiw,
|
||||||
add,
|
add,
|
||||||
andi,
|
andi,
|
||||||
|
|
||||||
@ -76,6 +85,7 @@ struct AVR : ASMLine
|
|||||||
|
|
||||||
clr,
|
clr,
|
||||||
com,
|
com,
|
||||||
|
cp,
|
||||||
cpc,
|
cpc,
|
||||||
cpi,
|
cpi,
|
||||||
cpse,
|
cpse,
|
||||||
@ -83,7 +93,10 @@ struct AVR : ASMLine
|
|||||||
|
|
||||||
eor,
|
eor,
|
||||||
|
|
||||||
|
in,
|
||||||
|
|
||||||
ld,
|
ld,
|
||||||
|
ldd,
|
||||||
ldi,
|
ldi,
|
||||||
lds,
|
lds,
|
||||||
lsl,
|
lsl,
|
||||||
@ -99,12 +112,15 @@ struct AVR : ASMLine
|
|||||||
rjmp,
|
rjmp,
|
||||||
rol,
|
rol,
|
||||||
|
|
||||||
|
sbc,
|
||||||
sbci,
|
sbci,
|
||||||
sbiw,
|
sbiw,
|
||||||
sbrc,
|
sbrc,
|
||||||
sbrs,
|
sbrs,
|
||||||
st,
|
st,
|
||||||
|
std,
|
||||||
sts,
|
sts,
|
||||||
|
sub,
|
||||||
subi,
|
subi,
|
||||||
swap,
|
swap,
|
||||||
};
|
};
|
||||||
@ -124,9 +140,13 @@ struct AVR : ASMLine
|
|||||||
if (o == "rol") { return OpCode::rol; }
|
if (o == "rol") { return OpCode::rol; }
|
||||||
if (o == "rcall") { return OpCode::rcall; }
|
if (o == "rcall") { return OpCode::rcall; }
|
||||||
if (o == "ld") { return OpCode::ld; }
|
if (o == "ld") { return OpCode::ld; }
|
||||||
|
if (o == "sub") { return OpCode::subi; }
|
||||||
if (o == "subi") { return OpCode::subi; }
|
if (o == "subi") { return OpCode::subi; }
|
||||||
|
if (o == "sbc") { return OpCode::sbci; }
|
||||||
if (o == "sbci") { return OpCode::sbci; }
|
if (o == "sbci") { return OpCode::sbci; }
|
||||||
if (o == "st") { return OpCode::st; }
|
if (o == "st") { return OpCode::st; }
|
||||||
|
if (o == "std") { return OpCode::std; }
|
||||||
|
if (o == "ldd") { return OpCode::ldd; }
|
||||||
if (o == "lds") { return OpCode::lds; }
|
if (o == "lds") { return OpCode::lds; }
|
||||||
if (o == "lsr") { return OpCode::lsr; }
|
if (o == "lsr") { return OpCode::lsr; }
|
||||||
if (o == "andi") { return OpCode::andi; }
|
if (o == "andi") { return OpCode::andi; }
|
||||||
@ -136,6 +156,7 @@ struct AVR : ASMLine
|
|||||||
if (o == "sbrs") { return OpCode::sbrs; }
|
if (o == "sbrs") { return OpCode::sbrs; }
|
||||||
if (o == "brne") { return OpCode::brne; }
|
if (o == "brne") { return OpCode::brne; }
|
||||||
if (o == "dec") { return OpCode::dec; }
|
if (o == "dec") { return OpCode::dec; }
|
||||||
|
if (o == "adiw") { return OpCode::adiw; }
|
||||||
if (o == "sbiw") { return OpCode::sbiw; }
|
if (o == "sbiw") { return OpCode::sbiw; }
|
||||||
if (o == "push") { return OpCode::push; }
|
if (o == "push") { return OpCode::push; }
|
||||||
if (o == "pop") { return OpCode::pop; }
|
if (o == "pop") { return OpCode::pop; }
|
||||||
@ -148,11 +169,13 @@ struct AVR : ASMLine
|
|||||||
if (o == "add") { return OpCode::add; }
|
if (o == "add") { return OpCode::add; }
|
||||||
if (o == "adc") { return OpCode::adc; }
|
if (o == "adc") { return OpCode::adc; }
|
||||||
if (o == "cpc") { return OpCode::cpc; }
|
if (o == "cpc") { return OpCode::cpc; }
|
||||||
|
if (o == "cp") { return OpCode::cp; }
|
||||||
if (o == "brsh") { return OpCode::brsh; }
|
if (o == "brsh") { return OpCode::brsh; }
|
||||||
if (o == "breq") { return OpCode::breq; }
|
if (o == "breq") { return OpCode::breq; }
|
||||||
|
if (o == "in") { return OpCode::in; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::runtime_error(fmt::format("Unknown opcode: {}"));
|
throw std::runtime_error(fmt::format("Unknown opcode: {}", o));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_register_number(const char reg_name)
|
static int get_register_number(const char reg_name)
|
||||||
@ -177,7 +200,7 @@ struct AVR : ASMLine
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o[0] == 'r' && o.size() > 1) {
|
if (o[0] == 'r' && o.size() > 1) {
|
||||||
return Operand(Operand::Type::reg, atoi(&o[1]));
|
return Operand(Operand::Type::reg, to_int(o.substr(1)));
|
||||||
} else {
|
} else {
|
||||||
return Operand(Operand::Type::literal, std::string{ o });
|
return Operand(Operand::Type::literal, std::string{ o });
|
||||||
}
|
}
|
||||||
@ -196,17 +219,17 @@ struct AVR : ASMLine
|
|||||||
Operand operand2;
|
Operand operand2;
|
||||||
};
|
};
|
||||||
|
|
||||||
void indirect_load(std::vector<mos6502> &instructions, const std::string &from_address_low_byte, const std::string &to_address)
|
void indirect_load(std::vector<mos6502> &instructions, const std::string &from_address_low_byte, const std::string &to_address, const int offset = 0)
|
||||||
{
|
{
|
||||||
instructions.emplace_back(mos6502::OpCode::ldy, Operand(Operand::Type::literal, "#0"));
|
instructions.emplace_back(mos6502::OpCode::ldy, Operand(Operand::Type::literal, fmt::format("#{}", offset)));
|
||||||
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, "(" + from_address_low_byte + "), Y"));
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, "(" + from_address_low_byte + "), Y"));
|
||||||
instructions.emplace_back(mos6502::OpCode::sta, Operand(Operand::Type::literal, to_address));
|
instructions.emplace_back(mos6502::OpCode::sta, Operand(Operand::Type::literal, to_address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void indirect_store(std::vector<mos6502> &instructions, const std::string &from_address, const std::string &to_address_low_byte)
|
void indirect_store(std::vector<mos6502> &instructions, const std::string &from_address, const std::string &to_address_low_byte, const int offset = 0)
|
||||||
{
|
{
|
||||||
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, from_address));
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, from_address));
|
||||||
instructions.emplace_back(mos6502::OpCode::ldy, Operand(Operand::Type::literal, "#0"));
|
instructions.emplace_back(mos6502::OpCode::ldy, Operand(Operand::Type::literal, fmt::format("#{}", offset)));
|
||||||
instructions.emplace_back(mos6502::OpCode::sta, Operand(Operand::Type::literal, "(" + to_address_low_byte + "), Y"));
|
instructions.emplace_back(mos6502::OpCode::sta, Operand(Operand::Type::literal, "(" + to_address_low_byte + "), Y"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +255,19 @@ void fixup_16_bit_N_Z_flags(std::vector<mos6502> &instructions)
|
|||||||
instructions.emplace_back(ASMLine::Type::Directive, "; END remove if next is lda");
|
instructions.emplace_back(ASMLine::Type::Directive, "; END remove if next is lda");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_16_bit(const Personality &personality, std::vector<mos6502> &instructions, int reg, const std::uint16_t value)
|
||||||
|
{
|
||||||
|
//instructions.emplace_back(mos6502::OpCode::sta, Operand(Operand::Type::literal, address_low_byte));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::clc);
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(reg));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::adc, Operand(Operand::Type::literal, "#" + std::to_string((value & 0xFFu))));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(reg));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(reg + 1));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::adc, Operand(Operand::Type::literal, "#" + std::to_string((value >> 8u) & 0xFFu)));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(reg + 1));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::tax);
|
||||||
|
fixup_16_bit_N_Z_flags(instructions);
|
||||||
|
}
|
||||||
|
|
||||||
void subtract_16_bit(const Personality &personality, std::vector<mos6502> &instructions, int reg, const std::uint16_t value)
|
void subtract_16_bit(const Personality &personality, std::vector<mos6502> &instructions, int reg, const std::uint16_t value)
|
||||||
{
|
{
|
||||||
@ -312,7 +348,34 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
increment_16_bit(personality, instructions, AVR::get_register_number(o2.value[0]));
|
increment_16_bit(personality, instructions, AVR::get_register_number(o2.value[0]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Unhandled ld to non-Z");
|
throw std::runtime_error("Unknown ld indexing");
|
||||||
|
}
|
||||||
|
case AVR::OpCode::ldd: {
|
||||||
|
indirect_load(instructions, personality.get_register(AVR::get_register_number(o2.value[0])).value, personality.get_register(o1_reg_num).value, to_int(o2.value.substr(1)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case AVR::OpCode::std: {
|
||||||
|
indirect_store(instructions, personality.get_register(o2_reg_num).value, personality.get_register(AVR::get_register_number(o1.value[0])).value, to_int(o2.value.substr(1)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case AVR::OpCode::sub: {
|
||||||
|
// we want to utilize the carry flag, however it was set previously
|
||||||
|
// (it's really a borrow flag on the 6502)
|
||||||
|
instructions.emplace_back(mos6502::OpCode::clc);
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sbc, personality.get_register(o1_reg_num));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(o1_reg_num));
|
||||||
|
fixup_16_bit_N_Z_flags(instructions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case AVR::OpCode::sbc: {
|
||||||
|
// we want to utilize the carry flag, however it was set previously
|
||||||
|
// (it's really a borrow flag on the 6502)
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sbc, personality.get_register(o1_reg_num));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(o1_reg_num));
|
||||||
|
fixup_16_bit_N_Z_flags(instructions);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case AVR::OpCode::sbci: {
|
case AVR::OpCode::sbci: {
|
||||||
// we want to utilize the carry flag, however it was set previously
|
// we want to utilize the carry flag, however it was set previously
|
||||||
@ -388,7 +451,7 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case AVR::OpCode::sbrc: {
|
case AVR::OpCode::sbrc: {
|
||||||
instructions.emplace_back(mos6502::OpCode::lda, Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (atoi(o2.value.c_str()))))));
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (to_int(o2.value))))));
|
||||||
instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num));
|
instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num));
|
||||||
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size());
|
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size());
|
||||||
instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name));
|
instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name));
|
||||||
@ -396,7 +459,7 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case AVR::OpCode::sbrs: {
|
case AVR::OpCode::sbrs: {
|
||||||
instructions.emplace_back(mos6502::OpCode::lda, Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (atoi(o2.value.c_str()))))));
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (to_int(o2.value.c_str()))))));
|
||||||
instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num));
|
instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num));
|
||||||
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size());
|
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size());
|
||||||
instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, new_label_name));
|
instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, new_label_name));
|
||||||
@ -418,7 +481,12 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
}
|
}
|
||||||
|
|
||||||
case AVR::OpCode::sbiw: {
|
case AVR::OpCode::sbiw: {
|
||||||
subtract_16_bit(personality, instructions, o1_reg_num, static_cast<std::uint16_t>(std::stoi(o2.value)));
|
subtract_16_bit(personality, instructions, o1_reg_num, static_cast<std::uint16_t>(to_int(o2.value)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case AVR::OpCode::adiw: {
|
||||||
|
add_16_bit(personality, instructions, o1_reg_num, static_cast<std::uint16_t>(to_int(o2.value)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +565,12 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(o1_reg_num));
|
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(o1_reg_num));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case AVR::OpCode::cp: {
|
||||||
|
// note that this will leave the C flag in the 6502 borrow state, not normal carry state
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::cmp, personality.get_register(o2_reg_num));
|
||||||
|
return;
|
||||||
|
}
|
||||||
case AVR::OpCode::cpc: {
|
case AVR::OpCode::cpc: {
|
||||||
// this instruction seems to need to be used in the case after a sbc operation, where the
|
// this instruction seems to need to be used in the case after a sbc operation, where the
|
||||||
// carry flag is set to the appropriate borrow state, so I'm going to not invert
|
// carry flag is set to the appropriate borrow state, so I'm going to not invert
|
||||||
@ -522,6 +595,22 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AVR::OpCode::in: {
|
||||||
|
if (o2.value == "__SP_L__") {
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, std::string{personality.stack_low_address()}));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, o1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o2.value == "__SP_H__") {
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, std::string{ personality.stack_high_address() }));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, o1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Could not translate unknown 'in' instruction");
|
||||||
|
}
|
||||||
|
|
||||||
case AVR::OpCode::breq: {
|
case AVR::OpCode::breq: {
|
||||||
instructions.emplace_back(mos6502::OpCode::beq, o1);
|
instructions.emplace_back(mos6502::OpCode::beq, o1);
|
||||||
return;
|
return;
|
||||||
@ -534,33 +623,6 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
|
|||||||
throw std::runtime_error("Could not translate unhandled instruction");
|
throw std::runtime_error("Could not translate unhandled instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class LogLevel {
|
|
||||||
Warning,
|
|
||||||
Error
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string to_string(const LogLevel ll)
|
|
||||||
{
|
|
||||||
switch (ll) {
|
|
||||||
case LogLevel::Warning:
|
|
||||||
return "warning";
|
|
||||||
case LogLevel::Error:
|
|
||||||
return "error";
|
|
||||||
}
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void log(LogLevel ll, const AVR &i, const std::string &message)
|
|
||||||
{
|
|
||||||
std::cerr << to_string(ll) << ": " << i.line_num << ": " << message << ": `" << i.line_text << "`\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void log(LogLevel ll, const std::size_t line_no, const std::string &line, const std::string &message)
|
|
||||||
{
|
|
||||||
std::cerr << to_string(ll) << ": " << line_no << ": " << message << ": `" << line << "`\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void to_mos6502(const Personality &personality, const AVR &from_instruction, std::vector<mos6502> &instructions)
|
void to_mos6502(const Personality &personality, const AVR &from_instruction, std::vector<mos6502> &instructions)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -606,7 +668,7 @@ void to_mos6502(const Personality &personality, const AVR &from_instruction, std
|
|||||||
translate_instruction(personality, instructions, from_instruction.opcode, from_instruction.operand1, from_instruction.operand2);
|
translate_instruction(personality, instructions, from_instruction.opcode, from_instruction.operand1, from_instruction.operand2);
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
instructions.emplace_back(ASMLine::Type::Directive, "; Unhandled opcode: '" + from_instruction.text + "' " + e.what());
|
instructions.emplace_back(ASMLine::Type::Directive, "; Unhandled opcode: '" + from_instruction.text + "' " + e.what());
|
||||||
log(LogLevel::Error, from_instruction, e.what());
|
spdlog::error("[{}]: Unhandled instruction: '{}': {}", from_instruction.line_num, from_instruction.line_text, e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto text = from_instruction.line_text;
|
auto text = from_instruction.line_text;
|
||||||
@ -619,7 +681,7 @@ void to_mos6502(const Personality &personality, const AVR &from_instruction, std
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
log(LogLevel::Error, from_instruction, e.what());
|
spdlog::error("[{}]: Unhandled instruction: '{}': {}", from_instruction.line_num, from_instruction.line_text, e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,7 +799,7 @@ void run(const Personality &personality, std::istream &input)
|
|||||||
// skip empty lines
|
// skip empty lines
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
log(LogLevel::Error, lineno, line, e.what());
|
spdlog::error("[{}]: parse exception with '{}': {}", lineno, line, e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
++lineno;
|
++lineno;
|
||||||
@ -789,7 +851,12 @@ void run(const Personality &personality, std::istream &input)
|
|||||||
if (i.text == "0") {
|
if (i.text == "0") {
|
||||||
i.text = "-memcpy_0";
|
i.text = "-memcpy_0";
|
||||||
} else {
|
} else {
|
||||||
i.text = new_labels.at(i.text);
|
try {
|
||||||
|
i.text = new_labels.at(i.text);
|
||||||
|
} catch (...) {
|
||||||
|
spdlog::error("Error looking up label name: '{}'", i.text);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user