Most bitwise operations

This commit is contained in:
Tony Di Nucci 2019-04-20 23:58:03 +01:00
parent ade6eaec6d
commit 2bc37b1b61
9 changed files with 1247 additions and 14 deletions

View File

@ -0,0 +1,314 @@
#include "bitwise-opcode-handler-container.h"
#include "../../utils.h"
namespace emu_6502 {
BitwiseOpcodeHandlerContainer::BitwiseOpcodeHandlerContainer() {
handlers.insert({Op::AND_IMM, [this](Machine& machine) { and_imm(machine); }});
handlers.insert({Op::AND_ZPG, [this](Machine& machine) { and_zpg(machine); }});
handlers.insert({Op::AND_ZPG_X, [this](Machine& machine) { and_zpg_x(machine); }});
handlers.insert({Op::AND_ABS, [this](Machine& machine) { and_abs(machine); }});
handlers.insert({Op::AND_ABS_X, [this](Machine& machine) { and_abs_x(machine); }});
handlers.insert({Op::AND_ABS_Y, [this](Machine& machine) { and_abs_y(machine); }});
handlers.insert({Op::AND_IND_X, [this](Machine& machine) { and_ind_x(machine); }});
handlers.insert({Op::AND_IND_Y, [this](Machine& machine) { and_ind_y(machine); }});
handlers.insert({Op::ORA_IMM, [this](Machine& machine) { or_imm(machine); }});
handlers.insert({Op::ORA_ZPG, [this](Machine& machine) { or_zpg(machine); }});
handlers.insert({Op::ORA_ZPG_X, [this](Machine& machine) { or_zpg_x(machine); }});
handlers.insert({Op::ORA_ABS, [this](Machine& machine) { or_abs(machine); }});
handlers.insert({Op::ORA_ABS_X, [this](Machine& machine) { or_abs_x(machine); }});
handlers.insert({Op::ORA_ABS_Y, [this](Machine& machine) { or_abs_y(machine); }});
handlers.insert({Op::ORA_IND_X, [this](Machine& machine) { or_ind_x(machine); }});
handlers.insert({Op::ORA_IND_Y, [this](Machine& machine) { or_ind_y(machine); }});
handlers.insert({Op::EOR_IMM, [this](Machine& machine) { xor_imm(machine); }});
handlers.insert({Op::EOR_ZPG, [this](Machine& machine) { xor_zpg(machine); }});
handlers.insert({Op::EOR_ZPG_X, [this](Machine& machine) { xor_zpg_x(machine); }});
handlers.insert({Op::EOR_ABS, [this](Machine& machine) { xor_abs(machine); }});
handlers.insert({Op::EOR_ABS_X, [this](Machine& machine) { xor_abs_x(machine); }});
handlers.insert({Op::EOR_ABS_Y, [this](Machine& machine) { xor_abs_y(machine); }});
handlers.insert({Op::EOR_IND_X, [this](Machine& machine) { xor_ind_x(machine); }});
handlers.insert({Op::EOR_IND_Y, [this](Machine& machine) { xor_ind_y(machine); }});
handlers.insert({Op::BIT_ZPG, [this](Machine& machine) { bit_zpg(machine); }});
handlers.insert({Op::BIT_ABS, [this](Machine& machine) { bit_abs(machine); }});
handlers.insert({Op::ASL_ACC, [this](Machine& machine) { asl_acc(machine); }});
handlers.insert({Op::ASL_ZPG, [this](Machine& machine) { asl_zpg(machine); }});
handlers.insert({Op::ASL_ZPG_X, [this](Machine& machine) { asl_zpg_x(machine); }});
handlers.insert({Op::ASL_ABS, [this](Machine& machine) { asl_abs(machine); }});
handlers.insert({Op::ASL_ABS_X, [this](Machine& machine) { asl_abs_x(machine); }});
handlers.insert({Op::LSR_ACC, [this](Machine& machine) { lsr_acc(machine); }});
handlers.insert({Op::LSR_ZPG, [this](Machine& machine) { lsr_zpg(machine); }});
handlers.insert({Op::LSR_ZPG_X, [this](Machine& machine) { lsr_zpg_x(machine); }});
handlers.insert({Op::LSR_ABS, [this](Machine& machine) { lsr_abs(machine); }});
handlers.insert({Op::LSR_ABS_X, [this](Machine& machine) { lsr_abs_x(machine); }});
handlers.insert({Op::ROL_ACC, [this](Machine& machine) { rol_acc(machine); }});
handlers.insert({Op::ROL_ZPG, [this](Machine& machine) { rol_zpg(machine); }});
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); }});
}
void BitwiseOpcodeHandlerContainer::do_and(Machine& machine, uint8_t value) {
auto& cpu = machine.get_cpu();
auto result = cpu.get_a().get_value() & value;
cpu.get_a().set_value(result);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), result);
}
void BitwiseOpcodeHandlerContainer::do_and_with(Machine& machine, uint16_t address) {
do_and(machine, machine.get_memory().get_at(address));
}
void BitwiseOpcodeHandlerContainer::and_imm(Machine& machine) {
do_and(machine, machine.read_program_byte());
}
void BitwiseOpcodeHandlerContainer::and_zpg(Machine& machine) {
do_and_with(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::and_zpg_x(Machine& machine) {
do_and_with(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::and_abs(Machine& machine) {
do_and_with(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::and_abs_x(Machine& machine) {
do_and_with(machine, get_abs_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::and_abs_y(Machine& machine) {
do_and_with(machine, get_abs_y_address(machine));
}
void BitwiseOpcodeHandlerContainer::and_ind_x(Machine& machine) {
do_and_with(machine, get_ind_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::and_ind_y(Machine& machine) {
do_and_with(machine, get_ind_y_address(machine));
}
void BitwiseOpcodeHandlerContainer::do_or(Machine& machine, uint8_t value) {
auto& cpu = machine.get_cpu();
auto result = cpu.get_a().get_value() | value;
cpu.get_a().set_value(result);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), result);
}
void BitwiseOpcodeHandlerContainer::do_or_with(Machine& machine, uint16_t address) {
do_or(machine, machine.get_memory().get_at(address));
}
void BitwiseOpcodeHandlerContainer::or_imm(Machine& machine) {
do_or(machine, machine.read_program_byte());
}
void BitwiseOpcodeHandlerContainer::or_zpg(Machine& machine) {
do_or_with(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::or_zpg_x(Machine& machine) {
do_or_with(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::or_abs(Machine& machine) {
do_or_with(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::or_abs_x(Machine& machine) {
do_or_with(machine, get_abs_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::or_abs_y(Machine& machine) {
do_or_with(machine, get_abs_y_address(machine));
}
void BitwiseOpcodeHandlerContainer::or_ind_x(Machine& machine) {
do_or_with(machine, get_ind_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::or_ind_y(Machine& machine) {
do_or_with(machine, get_ind_y_address(machine));
}
void BitwiseOpcodeHandlerContainer::do_xor(Machine& machine, uint8_t value) {
auto& cpu = machine.get_cpu();
auto result = cpu.get_a().get_value() ^value;
cpu.get_a().set_value(result);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), result);
}
void BitwiseOpcodeHandlerContainer::do_xor_with(Machine& machine, uint16_t address) {
do_xor(machine, machine.get_memory().get_at(address));
}
void BitwiseOpcodeHandlerContainer::xor_imm(Machine& machine) {
do_xor(machine, machine.read_program_byte());
}
void BitwiseOpcodeHandlerContainer::xor_zpg(Machine& machine) {
do_xor_with(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::xor_zpg_x(Machine& machine) {
do_xor_with(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::xor_abs(Machine& machine) {
do_xor_with(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::xor_abs_x(Machine& machine) {
do_xor_with(machine, get_abs_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::xor_abs_y(Machine& machine) {
do_xor_with(machine, get_abs_y_address(machine));
}
void BitwiseOpcodeHandlerContainer::xor_ind_x(Machine& machine) {
do_xor_with(machine, get_ind_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::xor_ind_y(Machine& machine) {
do_xor_with(machine, get_ind_y_address(machine));
}
void BitwiseOpcodeHandlerContainer::bit(Machine& machine, uint16_t address) {
auto a = machine.get_cpu().get_a().get_value();
auto mem = machine.get_memory().get_at(address);
auto& ps = machine.get_cpu().get_ps();
ps.set_zero((a & mem) == 0);
ps.set_negative((mem & 0x80) == 0x80);
ps.set_overflow((mem & 0x40) == 0x40);
}
void BitwiseOpcodeHandlerContainer::bit_zpg(Machine& machine) {
bit(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::bit_abs(Machine& machine) {
bit(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::asl_at(Machine& machine, uint16_t address) {
uint16_t result = machine.get_memory().get_at(address) << 1;
machine.get_memory().set_at(address, result);
auto& ps = machine.get_cpu().get_ps();
ps.set_carry((result & 0x100) == 0x100);
set_zero_and_neg_flags(ps, result);
}
void BitwiseOpcodeHandlerContainer::asl_acc(Machine& machine) {
uint16_t result = machine.get_cpu().get_a().get_value() << 1;
machine.get_cpu().get_a().set_value(result);
auto& ps = machine.get_cpu().get_ps();
ps.set_carry((result & 0x100) == 0x100);
set_zero_and_neg_flags(ps, result);
}
void BitwiseOpcodeHandlerContainer::asl_zpg(Machine& machine) {
asl_at(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::asl_zpg_x(Machine& machine) {
asl_at(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::asl_abs(Machine& machine) {
asl_at(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::asl_abs_x(Machine& machine) {
asl_at(machine, get_abs_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::lsr_at(Machine& machine, uint16_t address) {
auto orig = machine.get_memory().get_at(address);
auto result = orig >> 1;
machine.get_memory().set_at(address, result);
auto& ps = machine.get_cpu().get_ps();
ps.set_carry((orig & 1) == 1);
ps.set_zero(result == 0);
}
void BitwiseOpcodeHandlerContainer::lsr_acc(Machine& machine) {
auto orig = machine.get_cpu().get_a().get_value();
auto result = orig >> 1;
machine.get_cpu().get_a().set_value(result);
auto& ps = machine.get_cpu().get_ps();
ps.set_carry((orig & 1) == 1);
ps.set_zero(result == 0);
}
void BitwiseOpcodeHandlerContainer::lsr_zpg(Machine& machine) {
lsr_at(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::lsr_zpg_x(Machine& machine) {
lsr_at(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::lsr_abs(Machine& machine) {
lsr_at(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::lsr_abs_x(Machine& machine) {
lsr_at(machine, get_abs_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::rol_at(Machine& machine, uint16_t address) {
uint16_t result = machine.get_memory().get_at(address) << 1;
auto& ps = machine.get_cpu().get_ps();
if (ps.is_carry_set())
result += 1;
machine.get_memory().set_at(address, result);
ps.set_carry((result & 0x100) == 0x100);
set_zero_and_neg_flags(ps, result);
}
void BitwiseOpcodeHandlerContainer::rol_acc(Machine& machine) {
uint16_t result = machine.get_cpu().get_a().get_value() << 1;
auto& ps = machine.get_cpu().get_ps();
if (ps.is_carry_set())
result += 1;
machine.get_cpu().get_a().set_value(result);
ps.set_carry((result & 0x100) == 0x100);
set_zero_and_neg_flags(ps, result);
}
void BitwiseOpcodeHandlerContainer::rol_zpg(Machine& machine) {
rol_at(machine, get_zpg_address(machine));
}
void BitwiseOpcodeHandlerContainer::rol_zpg_x(Machine& machine) {
rol_at(machine, get_zpg_x_address(machine));
}
void BitwiseOpcodeHandlerContainer::rol_abs(Machine& machine) {
rol_at(machine, get_abs_address(machine));
}
void BitwiseOpcodeHandlerContainer::rol_abs_x(Machine& machine) {
rol_at(machine, get_abs_x_address(machine));
}
}

View File

@ -0,0 +1,133 @@
#ifndef INC_6502_EMULATOR_BITWISE_OPCODE_HANDLER_CONTAINER_H
#define INC_6502_EMULATOR_BITWISE_OPCODE_HANDLER_CONTAINER_H
#include "opcode-handler-container.h"
namespace emu_6502 {
class BitwiseOpcodeHandlerContainer : public OpcodeHandlerContainer {
private:
enum Op {
AND_IMM = 0x29,
AND_ZPG = 0x25,
AND_ZPG_X = 0x35,
AND_ABS = 0x2D,
AND_ABS_X = 0x3D,
AND_ABS_Y = 0x39,
AND_IND_X = 0x21,
AND_IND_Y = 0x31,
ORA_IMM = 0x09,
ORA_ZPG = 0x05,
ORA_ZPG_X = 0x15,
ORA_ABS = 0x0D,
ORA_ABS_X = 0x1D,
ORA_ABS_Y = 0x19,
ORA_IND_X = 0x01,
ORA_IND_Y = 0x11,
EOR_IMM = 0x49,
EOR_ZPG = 0x45,
EOR_ZPG_X = 0x55,
EOR_ABS = 0x4D,
EOR_ABS_X = 0x5D,
EOR_ABS_Y = 0x59,
EOR_IND_X = 0x41,
EOR_IND_Y = 0x51,
BIT_ZPG = 0x24,
BIT_ABS = 0x2C,
ASL_ACC = 0x0A,
ASL_ZPG = 0x06,
ASL_ZPG_X = 0x16,
ASL_ABS = 0x0E,
ASL_ABS_X = 0x1E,
LSR_ACC = 0x4A,
LSR_ZPG = 0x46,
LSR_ZPG_X = 0x56,
LSR_ABS = 0x4E,
LSR_ABS_X = 0x5E,
ROL_ACC = 0x2A,
ROL_ZPG = 0x26,
ROL_ZPG_X = 0x36,
ROL_ABS = 0x2E,
ROL_ABS_X = 0x3E,
ROR_ACC = 0x6A,
ROR_ZPG = 0x66,
ROR_ZPG_X = 0x76,
ROR_ABS = 0x6E,
ROR_ABS_X = 0x7E,
};
void do_and(Machine& machine, uint8_t value);
void do_and_with(Machine& machine, uint16_t address);
void and_imm(Machine& machine);
void and_zpg(Machine& machine);
void and_zpg_x(Machine& machine);
void and_abs(Machine& machine);
void and_abs_x(Machine& machine);
void and_abs_y(Machine& machine);
void and_ind_x(Machine& machine);
void and_ind_y(Machine& machine);
void do_or(Machine& machine, uint8_t value);
void do_or_with(Machine& machine, uint16_t address);
void or_imm(Machine& machine);
void or_zpg(Machine& machine);
void or_zpg_x(Machine& machine);
void or_abs(Machine& machine);
void or_abs_x(Machine& machine);
void or_abs_y(Machine& machine);
void or_ind_x(Machine& machine);
void or_ind_y(Machine& machine);
void do_xor(Machine& machine, uint8_t value);
void do_xor_with(Machine& machine, uint16_t address);
void xor_imm(Machine& machine);
void xor_zpg(Machine& machine);
void xor_zpg_x(Machine& machine);
void xor_abs(Machine& machine);
void xor_abs_x(Machine& machine);
void xor_abs_y(Machine& machine);
void xor_ind_x(Machine& machine);
void xor_ind_y(Machine& machine);
void bit(Machine& machine, uint16_t address);
void bit_zpg(Machine& machine);
void bit_abs(Machine& machine);
void asl_at(Machine& machine, uint16_t address);
void asl_acc(Machine& machine);
void asl_zpg(Machine& machine);
void asl_zpg_x(Machine& machine);
void asl_abs(Machine& machine);
void asl_abs_x(Machine& machine);
void lsr_at(Machine& machine, uint16_t address);
void lsr_acc(Machine& machine);
void lsr_zpg(Machine& machine);
void lsr_zpg_x(Machine& machine);
void lsr_abs(Machine& machine);
void lsr_abs_x(Machine& machine);
void rol_at(Machine& machine, uint16_t address);
void rol_acc(Machine& machine);
void rol_zpg(Machine& machine);
void rol_zpg_x(Machine& machine);
void rol_abs(Machine& machine);
void rol_abs_x(Machine& machine);
public:
BitwiseOpcodeHandlerContainer();
BitwiseOpcodeHandlerContainer(const BitwiseOpcodeHandlerContainer& other) = delete;
BitwiseOpcodeHandlerContainer operator=(const BitwiseOpcodeHandlerContainer& other) = delete;
};
}
#endif //INC_6502_EMULATOR_BITWISE_OPCODE_HANDLER_CONTAINER_H

View File

@ -37,11 +37,6 @@ namespace emu_6502 {
handlers.insert({Op::DEY, [this](Machine& machine) { dey(machine); }});
}
void MathsOpcodeHandlerContainer::set_zero_neg(StatusRegister& ps, uint8_t value) {
ps.set_zero(value == 0);
ps.set_negative((value & 0x80) == 0x80);
}
void MathsOpcodeHandlerContainer::adc(Machine& machine, uint8_t value) {
auto& cpu = machine.get_cpu();
auto init_a = cpu.get_a().get_value();
@ -55,7 +50,7 @@ namespace emu_6502 {
auto a = cpu.get_a().get_value();
// 'a' may be 0 if the result wasn't 0, i.e. the cary bit is set
set_zero_neg(cpu.get_ps(), a);
set_zero_and_neg_flags(cpu.get_ps(), a);
cpu.get_ps().set_carry(result > 0xFF);
cpu.get_ps().set_overflow(
(value < 0x7F && init_a < 0x7F && a > 0x7F) ||
@ -137,7 +132,7 @@ namespace emu_6502 {
uint8_t value = machine.get_memory().get_at(address) - 1;
machine.get_memory().set_at(address, value);
set_zero_neg(machine.get_cpu().get_ps(), value);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), value);
}
void MathsOpcodeHandlerContainer::dec_zpg(Machine& machine) {
@ -160,7 +155,7 @@ namespace emu_6502 {
uint8_t value = machine.get_memory().get_at(address) + 1;
machine.get_memory().set_at(address, value);
set_zero_neg(machine.get_cpu().get_ps(), value);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), value);
}
void MathsOpcodeHandlerContainer::inc_zpg(Machine& machine) {
@ -183,7 +178,7 @@ namespace emu_6502 {
uint8_t value = reg.get_value() - 1;
reg.set_value(value);
set_zero_neg(machine.get_cpu().get_ps(), value);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), value);
}
void MathsOpcodeHandlerContainer::dex(Machine& machine) {
@ -198,7 +193,7 @@ namespace emu_6502 {
uint8_t value = reg.get_value() + 1;
reg.set_value(value);
set_zero_neg(machine.get_cpu().get_ps(), value);
set_zero_and_neg_flags(machine.get_cpu().get_ps(), value);
}
void MathsOpcodeHandlerContainer::inx(Machine& machine) {

View File

@ -41,8 +41,6 @@ namespace emu_6502 {
INY = 0xC8
};
void set_zero_neg(StatusRegister& ps, uint8_t value);
void adc(Machine& machine, uint8_t value);
void adc_imm(Machine& machine);
void adc_zpg(Machine& machine);

View File

@ -17,8 +17,6 @@ namespace emu_6502 {
OpcodeHandlerContainer(const OpcodeHandlerContainer& other) = delete;
OpcodeHandlerContainer operator=(const OpcodeHandlerContainer& other) = delete;
virtual ~OpcodeHandlerContainer() {};
const unordered_map<uint8_t, function<void(Machine&)>>& get_handlers();
};
}

View File

@ -3,6 +3,7 @@
#include "handler/store-opcode-handler-container.h"
#include "handler/transfer-opcode-handler-container.h"
#include "handler/maths-opcode-handler-container.h"
#include "handler/bitwise-opcode-handler-container.h"
#include "../utils.h"
namespace emu_6502 {
@ -12,6 +13,7 @@ namespace emu_6502 {
handler_containers.push_back(make_unique<StoreOpcodeHandlerContainer>());
handler_containers.push_back(make_unique<TransferOpcodeHandlerContainer>());
handler_containers.push_back(make_unique<MathsOpcodeHandlerContainer>());
handler_containers.push_back(make_unique<BitwiseOpcodeHandlerContainer>());
init_handlers();
}

View File

@ -8,6 +8,11 @@ namespace emu_6502 {
return ss.str();
}
void set_zero_and_neg_flags(StatusRegister& ps, uint8_t value) {
ps.set_zero(value == 0);
ps.set_negative((value & 0x80) == 0x80);
}
uint8_t get_zpg_address(Machine& machine) {
return machine.read_program_byte();
}

View File

@ -9,6 +9,9 @@ using namespace std;
namespace emu_6502 {
string uint_to_hex(uint64_t value);
void set_zero_and_neg_flags(StatusRegister& ps, uint8_t value);
uint8_t get_zpg_address(Machine& machine);
uint8_t get_zpg_x_address(Machine& machine);
uint8_t get_zpg_y_address(Machine& machine);

View File

@ -0,0 +1,785 @@
#include "gtest/gtest.h"
#include "test-utils.h"
using namespace std;
using namespace emu_6502;
const uint8_t AND_IMM = 0x29;
const uint8_t AND_ZPG = 0x25;
const uint8_t AND_ZPG_X = 0x35;
const uint8_t AND_ABS = 0x2D;
const uint8_t AND_ABS_X = 0x3D;
const uint8_t AND_ABS_Y = 0x39;
const uint8_t AND_IND_X = 0x21;
const uint8_t AND_IND_Y = 0x31;
const uint8_t ORA_IMM = 0x09;
const uint8_t ORA_ZPG = 0x05;
const uint8_t ORA_ZPG_X = 0x15;
const uint8_t ORA_ABS = 0x0D;
const uint8_t ORA_ABS_X = 0x1D;
const uint8_t ORA_ABS_Y = 0x19;
const uint8_t ORA_IND_X = 0x01;
const uint8_t ORA_IND_Y = 0x11;
const uint8_t EOR_IMM = 0x49;
const uint8_t EOR_ZPG = 0x45;
const uint8_t EOR_ZPG_X = 0x55;
const uint8_t EOR_ABS = 0x4D;
const uint8_t EOR_ABS_X = 0x5D;
const uint8_t EOR_ABS_Y = 0x59;
const uint8_t EOR_IND_X = 0x41;
const uint8_t EOR_IND_Y = 0x51;
const uint8_t BIT_ZPG = 0x24;
const uint8_t BIT_ABS = 0x2C;
const uint8_t ASL_ACC = 0x0A;
const uint8_t ASL_ZPG = 0x06;
const uint8_t ASL_ZPG_X = 0x16;
const uint8_t ASL_ABS = 0x0E;
const uint8_t ASL_ABS_X = 0x1E;
const uint8_t LSR_ACC = 0x4A;
const uint8_t LSR_ZPG = 0x46;
const uint8_t LSR_ZPG_X = 0x56;
const uint8_t LSR_ABS = 0x4E;
const uint8_t LSR_ABS_X = 0x5E;
const uint8_t ROL_ACC = 0x2A;
const uint8_t ROL_ZPG = 0x26;
const uint8_t ROL_ZPG_X = 0x36;
const uint8_t ROL_ABS = 0x2E;
const uint8_t ROL_ABS_X = 0x3E;
TEST(LoadOpcodeHandlerContainer, AND_IMM) {
auto machine = create_machine({AND_IMM, 0x23});
machine->get_cpu().get_a().set_value(0x13);
machine->execute();
ASSERT_EQ(0x03, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_IMM_ZeroFlag) {
auto machine = create_machine({AND_IMM, 0x11});
machine->get_cpu().get_a().set_value(0x22);
machine->execute();
ASSERT_EQ(0, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, AND_IMM_NegativeFlag) {
auto machine = create_machine({AND_IMM, 0xF0});
machine->get_cpu().get_a().set_value(0xA1);
machine->execute();
ASSERT_EQ(0xA0, 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, AND_ZPG) {
auto machine = create_machine({AND_ZPG, 0xF5});
machine->get_memory().set_at(0xF5, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x41, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_ZPG_X) {
auto machine = create_machine({AND_ZPG_X, 0x30});
machine->get_cpu().get_x().set_value(0x50);
machine->get_memory().set_at(0x80, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x41, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_ABS) {
auto machine = create_machine({AND_ABS, 0x30, 0x05});
machine->get_memory().set_at(0x0530, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x41, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_ABS_X) {
auto machine = create_machine({AND_ABS_X, 0x30, 0x05});
machine->get_cpu().get_x().set_value(0xA);
machine->get_memory().set_at(0x053A, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x41, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_ABS_Y) {
auto machine = create_machine({AND_ABS_Y, 0x30, 0x05});
machine->get_cpu().get_y().set_value(0xA);
machine->get_memory().set_at(0x053A, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x41, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_IND_X) {
auto machine = create_machine({AND_IND_X, 0x55});
machine->get_cpu().get_x().set_value(0x22);
machine->get_cpu().get_a().set_value(0x41);
machine->get_memory().set_at(0x77, 0x34);
machine->get_memory().set_at(0x78, 0x12);
machine->get_memory().set_at(0x1234, 0x43);
machine->execute();
ASSERT_EQ(0x41, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, AND_IND_Y) {
auto machine = create_machine({AND_IND_Y, 0x41});
machine->get_cpu().get_y().set_value(0x22);
machine->get_cpu().get_a().set_value(0xFF);
machine->get_memory().set_at(0x41, 0x34);
machine->get_memory().set_at(0x42, 0x12);
machine->get_memory().set_at(0x1256, 0x29);
machine->execute();
ASSERT_EQ(0x29, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_IMM) {
auto machine = create_machine({ORA_IMM, 0x30});
machine->get_cpu().get_a().set_value(0x13);
machine->execute();
ASSERT_EQ(0x33, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_IMM_ZeroFlag) {
auto machine = create_machine({ORA_IMM, 0x00});
machine->get_cpu().get_a().set_value(0x00);
machine->execute();
ASSERT_EQ(0, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ORA_IMM_NegativeFlag) {
auto machine = create_machine({ORA_IMM, 0xF0});
machine->get_cpu().get_a().set_value(0xA1);
machine->execute();
ASSERT_EQ(0xF1, 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, ORA_ZPG) {
auto machine = create_machine({ORA_ZPG, 0xF5});
machine->get_memory().set_at(0xF5, 0x10);
machine->get_cpu().get_a().set_value(0x25);
machine->execute();
ASSERT_EQ(0x35, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_ZPG_X) {
auto machine = create_machine({ORA_ZPG_X, 0x30});
machine->get_cpu().get_x().set_value(0x50);
machine->get_memory().set_at(0x80, 0x81);
machine->get_cpu().get_a().set_value(0x42);
machine->execute();
ASSERT_EQ(0xC3, 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, ORA_ABS) {
auto machine = create_machine({ORA_ABS, 0x30, 0x05});
machine->get_memory().set_at(0x0530, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x55, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_ABS_X) {
auto machine = create_machine({ORA_ABS_X, 0x30, 0x05});
machine->get_cpu().get_x().set_value(0xA);
machine->get_memory().set_at(0x053A, 0x40);
machine->get_cpu().get_a().set_value(0x53);
machine->execute();
ASSERT_EQ(0x53, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_ABS_Y) {
auto machine = create_machine({ORA_ABS_Y, 0x30, 0x05});
machine->get_cpu().get_y().set_value(0xA);
machine->get_memory().set_at(0x053A, 0x20);
machine->get_cpu().get_a().set_value(0x02);
machine->execute();
ASSERT_EQ(0x22, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_IND_X) {
auto machine = create_machine({ORA_IND_X, 0x55});
machine->get_cpu().get_x().set_value(0x22);
machine->get_cpu().get_a().set_value(0x18);
machine->get_memory().set_at(0x77, 0x34);
machine->get_memory().set_at(0x78, 0x12);
machine->get_memory().set_at(0x1234, 0x18);
machine->execute();
ASSERT_EQ(0x18, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ORA_IND_Y) {
auto machine = create_machine({ORA_IND_Y, 0x41});
machine->get_cpu().get_y().set_value(0x22);
machine->get_cpu().get_a().set_value(0xFF);
machine->get_memory().set_at(0x41, 0x34);
machine->get_memory().set_at(0x42, 0x12);
machine->get_memory().set_at(0x1256, 0x23);
machine->execute();
ASSERT_EQ(0xFF, 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, EOR_IMM) {
auto machine = create_machine({EOR_IMM, 0x30});
machine->get_cpu().get_a().set_value(0x13);
machine->execute();
ASSERT_EQ(0x23, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_IMM_ZeroFlag) {
auto machine = create_machine({EOR_IMM, 0x11});
machine->get_cpu().get_a().set_value(0x11);
machine->execute();
ASSERT_EQ(0, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, EOR_IMM_NegativeFlag) {
auto machine = create_machine({EOR_IMM, 0xF0});
machine->get_cpu().get_a().set_value(0x05);
machine->execute();
ASSERT_EQ(0xF5, 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, EOR_ZPG) {
auto machine = create_machine({EOR_ZPG, 0xF5});
machine->get_memory().set_at(0xF5, 0x31);
machine->get_cpu().get_a().set_value(0x25);
machine->execute();
ASSERT_EQ(0x14, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_ZPG_X) {
auto machine = create_machine({EOR_ZPG_X, 0x30});
machine->get_cpu().get_x().set_value(0x50);
machine->get_memory().set_at(0x80, 0x31);
machine->get_cpu().get_a().set_value(0x23);
machine->execute();
ASSERT_EQ(0x12, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_ABS) {
auto machine = create_machine({EOR_ABS, 0x30, 0x05});
machine->get_memory().set_at(0x0530, 0x55);
machine->get_cpu().get_a().set_value(0x41);
machine->execute();
ASSERT_EQ(0x14, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_ABS_X) {
auto machine = create_machine({EOR_ABS_X, 0x30, 0x05});
machine->get_cpu().get_x().set_value(0xA);
machine->get_memory().set_at(0x053A, 0x40);
machine->get_cpu().get_a().set_value(0x53);
machine->execute();
ASSERT_EQ(0x13, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_ABS_Y) {
auto machine = create_machine({EOR_ABS_Y, 0x30, 0x05});
machine->get_cpu().get_y().set_value(0xA);
machine->get_memory().set_at(0x053A, 0x20);
machine->get_cpu().get_a().set_value(0x02);
machine->execute();
ASSERT_EQ(0x22, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_IND_X) {
auto machine = create_machine({EOR_IND_X, 0x55});
machine->get_cpu().get_x().set_value(0x22);
machine->get_cpu().get_a().set_value(0x19);
machine->get_memory().set_at(0x77, 0x34);
machine->get_memory().set_at(0x78, 0x12);
machine->get_memory().set_at(0x1234, 0x28);
machine->execute();
ASSERT_EQ(0x31, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, EOR_IND_Y) {
auto machine = create_machine({EOR_IND_Y, 0x41});
machine->get_cpu().get_y().set_value(0x22);
machine->get_cpu().get_a().set_value(0x35);
machine->get_memory().set_at(0x41, 0x34);
machine->get_memory().set_at(0x42, 0x12);
machine->get_memory().set_at(0x1256, 0x23);
machine->execute();
ASSERT_EQ(0x16, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, BIT_ZPG) {
auto machine = create_machine({BIT_ZPG, 0x41});
machine->get_cpu().get_a().set_value(0x23);
machine->get_memory().set_at(0x41, 0x35);
machine->execute();
ASSERT_EQ(0x23, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0x35, machine->get_memory().get_at(0x41));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, BIT_ZPG_ZeroFlag) {
auto machine = create_machine({BIT_ZPG, 0x41});
machine->get_cpu().get_a().set_value(0x11);
machine->get_memory().set_at(0x41, 0x22);
machine->execute();
ASSERT_EQ(0x11, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0x22, machine->get_memory().get_at(0x41));
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, BIT_ZPG_NegativeFlag) {
auto machine = create_machine({BIT_ZPG, 0x41});
machine->get_cpu().get_a().set_value(0x23);
machine->get_memory().set_at(0x41, 0xa5);
machine->execute();
ASSERT_EQ(0x23, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0xa5, machine->get_memory().get_at(0x41));
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, BIT_ZPG_OverflowFlag) {
auto machine = create_machine({BIT_ZPG, 0x41});
machine->get_cpu().get_a().set_value(0x23);
machine->get_memory().set_at(0x41, 0x45);
machine->execute();
ASSERT_EQ(0x23, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0x45, machine->get_memory().get_at(0x41));
RegisterFlagSet flags{};
flags.overflow = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, BIT_ZPG_ZeroNegativeAndOverflowFlag) {
auto machine = create_machine({BIT_ZPG, 0x41});
machine->get_cpu().get_a().set_value(0x02);
machine->get_memory().set_at(0x41, 0xc5);
machine->execute();
ASSERT_EQ(0x02, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0xc5, machine->get_memory().get_at(0x41));
RegisterFlagSet flags{};
flags.overflow = true;
flags.negative = true;
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, BIT_ABS) {
auto machine = create_machine({BIT_ABS, 0x41, 0x90});
machine->get_cpu().get_a().set_value(0x23);
machine->get_memory().set_at(0x9041, 0x35);
machine->execute();
ASSERT_EQ(0x23, machine->get_cpu().get_a().get_value());
ASSERT_EQ(0x35, machine->get_memory().get_at(0x9041));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ASL_ACC) {
auto machine = create_machine({ASL_ACC});
machine->get_cpu().get_a().set_value(0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ASL_ACC_CarryFlag) {
auto machine = create_machine({ASL_ACC});
machine->get_cpu().get_a().set_value(0x99);
machine->execute();
ASSERT_EQ(0x32, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.carry = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ASL_ACC_ZeroFlag) {
auto machine = create_machine({ASL_ACC});
machine->get_cpu().get_a().set_value(0x80);
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, ASL_ACC_NegativeFlag) {
auto machine = create_machine({ASL_ACC});
machine->get_cpu().get_a().set_value(0xc0);
machine->execute();
ASSERT_EQ(0x80, 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, ASL_ZPG) {
auto machine = create_machine({ASL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x10));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ASL_ZPG_CarryFlag) {
auto machine = create_machine({ASL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x99);
machine->execute();
ASSERT_EQ(0x32, machine->get_memory().get_at(0x10));
RegisterFlagSet flags{};
flags.carry = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ASL_ZPG_ZeroFlag) {
auto machine = create_machine({ASL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x80);
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, ASL_ZPG_NegativeFlag) {
auto machine = create_machine({ASL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0xc0);
machine->execute();
ASSERT_EQ(0x80, 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, ASL_ZPG_X) {
auto machine = create_machine({ASL_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, ASL_ABS) {
auto machine = create_machine({ASL_ABS, 0x10, 0x85});
machine->get_memory().set_at(0x8510, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x8510));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ASL_ABS_X) {
auto machine = create_machine({ASL_ABS_X, 0x10, 0x85});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x8515, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x8515));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, LSR_ACC) {
auto machine = create_machine({LSR_ACC});
machine->get_cpu().get_a().set_value(0x8);
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, LSR_ACC_CarryFlag) {
auto machine = create_machine({LSR_ACC});
machine->get_cpu().get_a().set_value(0x9);
machine->execute();
ASSERT_EQ(0x4, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.carry = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, LSR_ACC_ZeroFlag) {
auto machine = create_machine({LSR_ACC});
machine->get_cpu().get_a().set_value(1);
machine->execute();
ASSERT_EQ(0, 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, LSR_ZPG) {
auto machine = create_machine({LSR_ZPG, 0x5});
machine->get_memory().set_at(0x5, 0x8);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x5));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, LSR_ZPG_CarryFlag) {
auto machine = create_machine({LSR_ZPG, 0x5});
machine->get_memory().set_at(0x5, 0x9);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x5));
RegisterFlagSet flags{};
flags.carry = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, LSR_ZPG_ZeroFlag) {
auto machine = create_machine({LSR_ZPG, 0x5});
machine->get_memory().set_at(0x5, 1);
machine->execute();
ASSERT_EQ(0, machine->get_memory().get_at(0x5));
RegisterFlagSet flags{};
flags.carry = true;
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, LSR_ZPG_X) {
auto machine = create_machine({LSR_ZPG_X, 0x5});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x0a, 0x8);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0xa));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, LSR_ABS) {
auto machine = create_machine({LSR_ABS, 0x5, 0x8});
machine->get_memory().set_at(0x805, 0x8);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x805));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, LSR_ABS_X) {
auto machine = create_machine({LSR_ABS_X, 0x5, 0x8});
machine->get_cpu().get_x().set_value(0x5);
machine->get_memory().set_at(0x80a, 0x8);
machine->execute();
ASSERT_EQ(0x4, machine->get_memory().get_at(0x80a));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ACC) {
auto machine = create_machine({ROL_ACC});
machine->get_cpu().get_a().set_value(0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ACC_OldCarry) {
auto machine = create_machine({ROL_ACC});
machine->get_cpu().get_a().set_value(0x09);
machine->get_cpu().get_ps().set_carry(true);
machine->execute();
ASSERT_EQ(0x13, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ACC_CarryFlag) {
auto machine = create_machine({ROL_ACC});
machine->get_cpu().get_a().set_value(0x89);
machine->get_cpu().get_ps().set_carry(true);
machine->execute();
ASSERT_EQ(0x13, machine->get_cpu().get_a().get_value());
RegisterFlagSet flags{};
flags.carry = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROL_ACC_NegativeFlag) {
auto machine = create_machine({ROL_ACC});
machine->get_cpu().get_a().set_value(0xc9);
machine->get_cpu().get_ps().set_carry(true);
machine->execute();
ASSERT_EQ(0x93, 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, ROL_ACC_ZeroFlag) {
auto machine = create_machine({ROL_ACC});
machine->get_cpu().get_a().set_value(0x80);
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, ROL_ZPG) {
auto machine = create_machine({ROL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x09);
machine->execute();
ASSERT_EQ(0x12, machine->get_memory().get_at(0x10));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ZPG_OldCarry) {
auto machine = create_machine({ROL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x09);
machine->get_cpu().get_ps().set_carry(true);
machine->execute();
ASSERT_EQ(0x13, machine->get_memory().get_at(0x10));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(LoadOpcodeHandlerContainer, ROL_ZPG_CarryFlag) {
auto machine = create_machine({ROL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x89);
machine->get_cpu().get_ps().set_carry(true);
machine->execute();
ASSERT_EQ(0x13, machine->get_memory().get_at(0x10));
RegisterFlagSet flags{};
flags.carry = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(LoadOpcodeHandlerContainer, ROL_ZPG_NegativeFlag) {
auto machine = create_machine({ROL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0xc9);
machine->get_cpu().get_ps().set_carry(true);
machine->execute();
ASSERT_EQ(0x93, 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, ROL_ZPG_ZeroFlag) {
auto machine = create_machine({ROL_ZPG, 0x10});
machine->get_memory().set_at(0x10, 0x80);
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));
}