6502-cpp/include/6502.hpp

241 lines
4.8 KiB
C++

#ifndef INC_6502_CPP_6502_HPP
#define INC_6502_CPP_6502_HPP
#include "assembly.hpp"
struct mos6502 : ASMLine
{
enum class OpCode {
unknown,
adc,
AND,
asl,
bcc,
bcs,
beq,
bit,
bmi,
bne,
bpl,
cpy,
cmp,
clc,
dec,
eor,
inc,
jmp,
jsr,
lda,
ldy,
lsr,
ORA,
pha,
php,
pla,
plp,
rol,
ror,
rts,
sbc,
sec,
sta,
sty,
tax,
tay,
txa,
tya,
};
static bool get_is_branch(const OpCode o)
{
switch (o) {
case OpCode::beq:
case OpCode::bne:
case OpCode::bmi:
case OpCode::bpl:
case OpCode::bcc:
case OpCode::bcs:
return true;
case OpCode::adc:
case OpCode::AND:
case OpCode::asl:
case OpCode::bit:
case OpCode::cpy:
case OpCode::cmp:
case OpCode::clc:
case OpCode::dec:
case OpCode::eor:
case OpCode::inc:
case OpCode::jmp:
case OpCode::jsr:
case OpCode::lda:
case OpCode::ldy:
case OpCode::lsr:
case OpCode::ORA:
case OpCode::pha:
case OpCode::php:
case OpCode::pla:
case OpCode::plp:
case OpCode::rol:
case OpCode::ror:
case OpCode::rts:
case OpCode::sbc:
case OpCode::sec:
case OpCode::sta:
case OpCode::sty:
case OpCode::tax:
case OpCode::tay:
case OpCode::txa:
case OpCode::tya:
case OpCode::unknown:
break;
}
return false;
}
static bool get_is_comparison(const OpCode o)
{
switch (o) {
case OpCode::bit:
case OpCode::cmp:
case OpCode::cpy:
return true;
case OpCode::adc:
case OpCode::AND:
case OpCode::asl:
case OpCode::beq:
case OpCode::bne:
case OpCode::bmi:
case OpCode::bpl:
case OpCode::bcc:
case OpCode::bcs:
case OpCode::clc:
case OpCode::dec:
case OpCode::eor:
case OpCode::inc:
case OpCode::jmp:
case OpCode::jsr:
case OpCode::lda:
case OpCode::ldy:
case OpCode::lsr:
case OpCode::ORA:
case OpCode::pha:
case OpCode::php:
case OpCode::pla:
case OpCode::plp:
case OpCode::rol:
case OpCode::ror:
case OpCode::rts:
case OpCode::sbc:
case OpCode::sec:
case OpCode::sta:
case OpCode::sty:
case OpCode::tax:
case OpCode::tay:
case OpCode::txa:
case OpCode::tya:
case OpCode::unknown:
break;
}
return false;
}
explicit mos6502(const OpCode o)
: ASMLine(Type::Instruction, std::string{ to_string(o) }), opcode(o), is_branch(get_is_branch(o)), is_comparison(get_is_comparison(o))
{
}
mos6502(const Type t, std::string s)
: ASMLine(t, std::move(s))
{
}
mos6502(const OpCode o, Operand t_o)
: ASMLine(Type::Instruction, std::string{ to_string(o) }), opcode(o), op(std::move(t_o)), is_branch(get_is_branch(o)), is_comparison(get_is_comparison(o))
{
}
constexpr static std::string_view to_string(const OpCode o)
{
switch (o) {
case OpCode::lda: return "lda";
case OpCode::asl: return "asl";
case OpCode::rol: return "rol";
case OpCode::ldy: return "ldy";
case OpCode::tay: return "tay";
case OpCode::tya: return "tya";
case OpCode::tax: return "tax";
case OpCode::txa: return "txa";
case OpCode::cpy: return "cpy";
case OpCode::eor: return "eor";
case OpCode::sta: return "sta";
case OpCode::sty: return "sty";
case OpCode::pha: return "pha";
case OpCode::pla: return "pla";
case OpCode::php: return "php";
case OpCode::plp: return "plp";
case OpCode::lsr: return "lsr";
case OpCode::ror: return "ror";
case OpCode::AND: return "and";
case OpCode::inc: return "inc";
case OpCode::dec: return "dec";
case OpCode::ORA: return "ora";
case OpCode::cmp: return "cmp";
case OpCode::bne: return "bne";
case OpCode::bmi: return "bmi";
case OpCode::beq: return "beq";
case OpCode::jmp: return "jmp";
case OpCode::adc: return "adc";
case OpCode::sbc: return "sbc";
case OpCode::rts: return "rts";
case OpCode::clc: return "clc";
case OpCode::sec: return "sec";
case OpCode::bit: return "bit";
case OpCode::jsr: return "jsr";
case OpCode::bpl: return "bpl";
case OpCode::bcc: return "bcc";
case OpCode::bcs: return "bcs";
case OpCode::unknown: return "";
}
return "";
}
[[nodiscard]] std::string to_string() const
{
switch (type) {
case ASMLine::Type::Label:
return text;// + ':';
case ASMLine::Type::Directive:
case ASMLine::Type::Instruction: {
return fmt::format("\t{} {:15}; {}", text, op.value, comment);
}
}
throw std::runtime_error("Unable to render: " + text);
}
OpCode opcode = OpCode::unknown;
Operand op;
std::string comment;
bool is_branch = false;
bool is_comparison = false;
};
#endif//INC_6502_CPP_6502_HPP