mirror of
https://github.com/lefticus/6502-cpp.git
synced 2025-05-17 06:38:19 +00:00
Implement some more instructions, and fix typos.
Implement 16-bit shrl (new instruction). Implement movl with a 16-bit literal value. Add the 6502 ROR instruction.
This commit is contained in:
parent
88d197e0d7
commit
4ed4e6a94c
39
src/main.cpp
39
src/main.cpp
@ -112,6 +112,7 @@ struct mos6502 : ASMLine
|
|||||||
php,
|
php,
|
||||||
plp,
|
plp,
|
||||||
lsr,
|
lsr,
|
||||||
|
ror,
|
||||||
AND,
|
AND,
|
||||||
inc,
|
inc,
|
||||||
dec,
|
dec,
|
||||||
@ -148,6 +149,7 @@ struct mos6502 : ASMLine
|
|||||||
case OpCode::php:
|
case OpCode::php:
|
||||||
case OpCode::plp:
|
case OpCode::plp:
|
||||||
case OpCode::lsr:
|
case OpCode::lsr:
|
||||||
|
case OpCode::ror:
|
||||||
case OpCode::AND:
|
case OpCode::AND:
|
||||||
case OpCode::inc:
|
case OpCode::inc:
|
||||||
case OpCode::dec:
|
case OpCode::dec:
|
||||||
@ -184,6 +186,7 @@ struct mos6502 : ASMLine
|
|||||||
case OpCode::php:
|
case OpCode::php:
|
||||||
case OpCode::plp:
|
case OpCode::plp:
|
||||||
case OpCode::lsr:
|
case OpCode::lsr:
|
||||||
|
case OpCode::ror:
|
||||||
case OpCode::AND:
|
case OpCode::AND:
|
||||||
case OpCode::inc:
|
case OpCode::inc:
|
||||||
case OpCode::dec:
|
case OpCode::dec:
|
||||||
@ -248,6 +251,8 @@ struct mos6502 : ASMLine
|
|||||||
return "plp";
|
return "plp";
|
||||||
case OpCode::lsr:
|
case OpCode::lsr:
|
||||||
return "lsr";
|
return "lsr";
|
||||||
|
case OpCode::ror:
|
||||||
|
return "ror";
|
||||||
case OpCode::AND:
|
case OpCode::AND:
|
||||||
return "and";
|
return "and";
|
||||||
case OpCode::inc:
|
case OpCode::inc:
|
||||||
@ -318,6 +323,7 @@ struct i386 : ASMLine
|
|||||||
movzbl,
|
movzbl,
|
||||||
movzwl,
|
movzwl,
|
||||||
shrb,
|
shrb,
|
||||||
|
shrl,
|
||||||
xorl,
|
xorl,
|
||||||
andl,
|
andl,
|
||||||
andb,
|
andb,
|
||||||
@ -363,6 +369,7 @@ struct i386 : ASMLine
|
|||||||
if (o == "movzwl") return OpCode::movzwl;
|
if (o == "movzwl") return OpCode::movzwl;
|
||||||
if (o == "movzbl") return OpCode::movzbl;
|
if (o == "movzbl") return OpCode::movzbl;
|
||||||
if (o == "shrb") return OpCode::shrb;
|
if (o == "shrb") return OpCode::shrb;
|
||||||
|
if (o == "shrl") return OpCode::shrl;
|
||||||
if (o == "xorl") return OpCode::xorl;
|
if (o == "xorl") return OpCode::xorl;
|
||||||
if (o == "andl") return OpCode::andl;
|
if (o == "andl") return OpCode::andl;
|
||||||
if (o == "ret") return OpCode::ret;
|
if (o == "ret") return OpCode::ret;
|
||||||
@ -475,6 +482,11 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
|||||||
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num));
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num));
|
||||||
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num, 1));
|
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num, 1));
|
||||||
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num, 1));
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num, 1));
|
||||||
|
} else if (o1.type == Operand::Type::literal && o2.type == Operand::Type::reg) {
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(o1.type, "#<" + o1.value));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lda, Operand(o1.type, "#>" + o1.value));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num, 1));
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Cannot translate movl instruction");
|
throw std::runtime_error("Cannot translate movl instruction");
|
||||||
}
|
}
|
||||||
@ -486,7 +498,7 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
|||||||
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num));
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num));
|
||||||
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num, 1));
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num, 1));
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Cannot translate movl instruction");
|
throw std::runtime_error("Cannot translate xorl instruction");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case i386::OpCode::movb:
|
case i386::OpCode::movb:
|
||||||
@ -550,6 +562,25 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
|||||||
throw std::runtime_error("Cannot translate shrb instruction");
|
throw std::runtime_error("Cannot translate shrb instruction");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case i386::OpCode::shrl:
|
||||||
|
if (o1.type == Operand::Type::reg || o2.type == Operand::Type::reg) {
|
||||||
|
const auto do_shift = [&instructions](const int reg_num) {
|
||||||
|
instructions.emplace_back(mos6502::OpCode::lsr, get_register(reg_num, 1));
|
||||||
|
instructions.emplace_back(mos6502::OpCode::ror, get_register(reg_num));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (o1.type == Operand::Type::literal) {
|
||||||
|
const auto count = parse_8bit_literal(o1.value);
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
do_shift(o2.reg_num);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
do_shift(o1.reg_num);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Cannot translate shrl instruction");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case i386::OpCode::testb:
|
case i386::OpCode::testb:
|
||||||
if (o1.type == Operand::Type::reg && o2.type == Operand::Type::reg && o1.reg_num == o2.reg_num) {
|
if (o1.type == Operand::Type::reg && o2.type == Operand::Type::reg && o1.reg_num == o2.reg_num) {
|
||||||
// this just tests the register for 0
|
// this just tests the register for 0
|
||||||
@ -625,7 +656,7 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
|||||||
instructions.emplace_back(mos6502::OpCode::lda, get_register(o2.reg_num));
|
instructions.emplace_back(mos6502::OpCode::lda, get_register(o2.reg_num));
|
||||||
instructions.emplace_back(mos6502::OpCode::cmp, Operand(o1.type, fixup_8bit_literal(o1.value)));
|
instructions.emplace_back(mos6502::OpCode::cmp, Operand(o1.type, fixup_8bit_literal(o1.value)));
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Cannot translate cmb instruction");
|
throw std::runtime_error("Cannot translate cmpb instruction");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case i386::OpCode::andb:
|
case i386::OpCode::andb:
|
||||||
@ -684,7 +715,7 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
|||||||
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num, 1));
|
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num, 1));
|
||||||
instructions.emplace_back(mos6502::OpCode::pha);
|
instructions.emplace_back(mos6502::OpCode::pha);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Cannot translate sbb instruction");
|
throw std::runtime_error("Cannot translate pushl instruction");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -701,7 +732,7 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
|||||||
instructions.emplace_back(mos6502::OpCode::eor, Operand(Operand::Type::literal, "#$ff")); // invert the bits
|
instructions.emplace_back(mos6502::OpCode::eor, Operand(Operand::Type::literal, "#$ff")); // invert the bits
|
||||||
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num)); // place the value
|
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num)); // place the value
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Cannot translate sbb instruction");
|
throw std::runtime_error("Cannot translate sbbb instruction");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user