Finish bitwise operations

This commit is contained in:
Tony Di Nucci 2019-04-21 00:18:15 +01:00
parent 2bc37b1b61
commit 6411d74583
3 changed files with 210 additions and 1 deletions

View File

@ -50,6 +50,12 @@ namespace emu_6502 {
handlers.insert({Op::ROL_ZPG_X, [this](Machine& machine) { rol_zpg_x(machine); }});
handlers.insert({Op::ROL_ABS, [this](Machine& machine) { rol_abs(machine); }});
handlers.insert({Op::ROL_ABS_X, [this](Machine& machine) { rol_abs_x(machine); }});
handlers.insert({Op::ROR_ACC, [this](Machine& machine) { ror_acc(machine); }});
handlers.insert({Op::ROR_ZPG, [this](Machine& machine) { ror_zpg(machine); }});
handlers.insert({Op::ROR_ZPG_X, [this](Machine& machine) { ror_zpg_x(machine); }});
handlers.insert({Op::ROR_ABS, [this](Machine& machine) { ror_abs(machine); }});
handlers.insert({Op::ROR_ABS_X, [this](Machine& machine) { ror_abs_x(machine); }});
}
void BitwiseOpcodeHandlerContainer::do_and(Machine& machine, uint8_t value) {
@ -311,4 +317,46 @@ namespace emu_6502 {
void BitwiseOpcodeHandlerContainer::rol_abs_x(Machine& machine) {
rol_at(machine, get_abs_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::ror_at(Machine& machine, uint16_t address) {
auto orig = machine.get_memory().get_at(address);
auto result = orig >> 1;
auto& ps = machine.get_cpu().get_ps();
if (ps.is_carry_set())
result += 0x80;
machine.get_memory().set_at(address, result);
ps.set_carry((orig & 1) == 1);
set_zero_and_neg_flags(ps, result);
}
void BitwiseOpcodeHandlerContainer::ror_acc(Machine& machine) {
auto orig = machine.get_cpu().get_a().get_value();
auto result = orig >> 1;
auto& ps = machine.get_cpu().get_ps();
if (ps.is_carry_set())
result += 0x80;
machine.get_cpu().get_a().set_value(result);
ps.set_carry((orig & 1) == 1);
set_zero_and_neg_flags(ps, result);
}
void BitwiseOpcodeHandlerContainer::ror_zpg(Machine& machine) {
ror_at(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::ror_zpg_x(Machine& machine) {
ror_at(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::ror_abs(Machine& machine) {
ror_at(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::ror_abs_x(Machine& machine) {
ror_at(machine, get_abs_x_address(machine));
}
}

View File

@ -120,7 +120,12 @@ namespace emu_6502 {
void rol_abs(Machine& machine);
void rol_abs_x(Machine& machine);
void ror_at(Machine& machine, uint16_t address);
void ror_acc(Machine& machine);
void ror_zpg(Machine& machine);
void ror_zpg_x(Machine& machine);
void ror_abs(Machine& machine);
void ror_abs_x(Machine& machine);
public:
BitwiseOpcodeHandlerContainer();

View File

@ -52,6 +52,12 @@ const uint8_t ROL_ZPG_X = 0x36;
const uint8_t ROL_ABS = 0x2E;
const uint8_t ROL_ABS_X = 0x3E;
const uint8_t ROR_ACC = 0x6A;
const uint8_t ROR_ZPG = 0x66;
const uint8_t ROR_ZPG_X = 0x76;
const uint8_t ROR_ABS = 0x6E;
const uint8_t ROR_ABS_X = 0x7E;
TEST(LoadOpcodeHandlerContainer, AND_IMM) {
auto machine = create_machine({AND_IMM, 0x23});
machine->get_cpu().get_a().set_value(0x13);
@ -783,3 +789,153 @@ TEST(LoadOpcodeHandlerContainer, ROL_ZPG_ZeroFlag) {
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROL_ZPG_X) {
auto machine = create_machine({ROL_ZPG_X, 0x10});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x15, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x15));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ABS) {
auto machine = create_machine({ROL_ABS, 0x10, 0x11});
machine->get_memory().set_at(0x1110, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x1110));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ABS_X) {
auto machine = create_machine({ROL_ABS_X, 0x10, 0x11});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x1115, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x1115));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROR_ACC) {
auto machine = create_machine({ROR_ACC});
machine->get_cpu().get_a().set_value(0x08);
machine->execute();
ASSERT_EQ(0x4, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROR_ACC_OldCarry) {
auto machine = create_machine({ROR_ACC});
machine->get_cpu().get_ps().set_carry(true);
machine->get_cpu().get_a().set_value(0x08);
machine->execute();
ASSERT_EQ(0x84, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROR_ACC_NegativeAndCarryFlag) {
auto machine = create_machine({ROR_ACC});
machine->get_cpu().get_ps().set_carry(true);
machine->get_cpu().get_a().set_value(0x09);
machine->execute();
ASSERT_EQ(0x84, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.carry = true;
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROR_ACC_ZeroFlag) {
auto machine = create_machine({ROR_ACC});
machine->get_cpu().get_a().set_value(0x01);
machine->execute();
ASSERT_EQ(0x0, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.carry = true;
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROR_ZPG) {
auto machine = create_machine({ROR_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x08);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x10));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROR_ZPG_OldCarry) {
auto machine = create_machine({ROR_ZPG, 0x10});
machine->get_cpu().get_ps().set_carry(true);
machine->get_memory().set_at(0x10, 0x08);
machine->execute();
ASSERT_EQ(0x84, machine->get_memory().get_at(0x10));
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROR_ZPG_NegativeAndCarryFlag) {
auto machine = create_machine({ROR_ZPG, 0x10});
machine->get_cpu().get_ps().set_carry(true);
machine->get_memory().set_at(0x10, 0x09);
machine->execute();
ASSERT_EQ(0x84, machine->get_memory().get_at(0x10));
RegisterFlagSet flags{};
flags.carry = true;
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROR_ZPG_ZeroFlag) {
auto machine = create_machine({ROR_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x01);
machine->execute();
ASSERT_EQ(0x0, machine->get_memory().get_at(0x10));
RegisterFlagSet flags{};
flags.carry = true;
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROR_ZPG_X) {
auto machine = create_machine({ROR_ZPG_X, 0x10});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x15, 0x08);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x15));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROR_ABS) {
auto machine = create_machine({ROR_ABS, 0x10, 0x75});
machine->get_memory().set_at(0x7510, 0x08);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x7510));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROR_ABS_X) {
auto machine = create_machine({ROR_ABS_X, 0x10, 0x75});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x7515, 0x08);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x7515));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}