mirror of
https://github.com/tdinucci/6502-emulator.git
synced 2024-11-27 02:49:50 +00:00
Finish bitwise operations
This commit is contained in:
parent
2bc37b1b61
commit
6411d74583
@ -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));
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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{}));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user