1
0
mirror of https://github.com/lefticus/6502-cpp.git synced 2024-12-22 01:30:03 +00:00

Add xor AX,AX trick, rts support

This commit is contained in:
Jason Turner 2016-07-07 14:58:39 -06:00
parent 04e0a8dbc9
commit 76bb4371a7

View File

@ -69,7 +69,8 @@ struct mos6502 : ASMLine
beq, beq,
jmp, jmp,
adc, adc,
sbc sbc,
rts
}; };
static bool get_is_branch(const OpCode o) { static bool get_is_branch(const OpCode o) {
@ -90,6 +91,7 @@ struct mos6502 : ASMLine
case OpCode::jmp: case OpCode::jmp:
case OpCode::adc: case OpCode::adc:
case OpCode::sbc: case OpCode::sbc:
case OpCode::rts:
case OpCode::unknown: case OpCode::unknown:
break; break;
} }
@ -114,6 +116,7 @@ struct mos6502 : ASMLine
case OpCode::beq: case OpCode::beq:
case OpCode::adc: case OpCode::adc:
case OpCode::sbc: case OpCode::sbc:
case OpCode::rts:
case OpCode::unknown: case OpCode::unknown:
break; break;
} }
@ -169,6 +172,8 @@ struct mos6502 : ASMLine
return "adc"; return "adc";
case OpCode::sbc: case OpCode::sbc:
return "sbc"; return "sbc";
case OpCode::rts:
return "rts";
case OpCode::unknown: case OpCode::unknown:
return ""; return "";
}; };
@ -291,6 +296,9 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
{ {
switch(op) switch(op)
{ {
case i386::OpCode::ret:
instructions.emplace_back(mos6502::OpCode::rts);
break;
case i386::OpCode::movb: case i386::OpCode::movb:
if (o1.type == Operand::Type::literal && o2.type == Operand::Type::literal) { if (o1.type == Operand::Type::literal && o2.type == Operand::Type::literal) {
instructions.emplace_back(mos6502::OpCode::ldy, Operand(o1.type, "#" + o1.value)); instructions.emplace_back(mos6502::OpCode::ldy, Operand(o1.type, "#" + o1.value));
@ -350,6 +358,9 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
case i386::OpCode::xorl: case i386::OpCode::xorl:
if (o1.type == Operand::Type::literal && o2.type == Operand::Type::reg && o2.reg_num == 1) { if (o1.type == Operand::Type::literal && o2.type == Operand::Type::reg && o2.reg_num == 1) {
instructions.emplace_back(mos6502::OpCode::eor, Operand(o1.type, "#" + o1.value)); instructions.emplace_back(mos6502::OpCode::eor, Operand(o1.type, "#" + o1.value));
} else if (o1.type == Operand::Type::reg && o2.reg_num == 1 && o2.type == Operand::Type::reg && o2.reg_num == 1) {
// cheater shortcut on x86 to 0 out a register
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, "$00"));
} else if (o1.type == Operand::Type::literal && o2.type == Operand::Type::reg && o2.reg_num == 4) { } else if (o1.type == Operand::Type::literal && o2.type == Operand::Type::reg && o2.reg_num == 4) {
instructions.emplace_back(mos6502::OpCode::pha); // transfer memory through A register, pushing and popping around it instructions.emplace_back(mos6502::OpCode::pha); // transfer memory through A register, pushing and popping around it
instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, "$00")); instructions.emplace_back(mos6502::OpCode::lda, Operand(Operand::Type::literal, "$00"));
@ -454,6 +465,26 @@ void to_mos6502(const i386 &i, std::vector<mos6502> &instructions)
} }
} }
bool optimize(std::vector<mos6502> &instructions)
{
if (instructions.size() < 2) {
return false;
}
for (size_t op = 0; op < instructions.size() - 1; ++op)
{
if (instructions[op].opcode == mos6502::OpCode::pla
&& instructions[op+1].opcode == mos6502::OpCode::pha)
{
instructions.erase(std::next(std::begin(instructions), op), std::next(std::begin(instructions), op+2));
return true;
}
}
return false;
}
bool fix_overwritten_flags(std::vector<mos6502> &instructions) bool fix_overwritten_flags(std::vector<mos6502> &instructions)
{ {
if (instructions.size() < 3) { if (instructions.size() < 3) {
@ -629,6 +660,11 @@ int main()
// do it however many times it takes // do it however many times it takes
} }
while (optimize(new_instructions))
{
// do it however many times it takes
}
for (const auto i : new_instructions) for (const auto i : new_instructions)
{ {