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:
parent
04e0a8dbc9
commit
76bb4371a7
38
src/main.cpp
38
src/main.cpp
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user