More maths opcodes

This commit is contained in:
Tony Di Nucci 2019-04-20 11:22:40 +01:00
parent cab2cec9ff
commit 90e33ad6cb
7 changed files with 364 additions and 99 deletions

View File

@ -45,48 +45,34 @@ namespace emu_6502 {
}
void LoadOpcodeHandlerContainer::ld_zpg(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_zpg_address(machine.read_program_byte());
set_from(machine, reg, addr);
set_from(machine, reg, get_zpg_address(machine));
}
void LoadOpcodeHandlerContainer::ld_zpg_x(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_zpg_x_address(machine.read_program_byte(), machine.get_cpu());
set_from(machine, reg, addr);
set_from(machine, reg, get_zpg_x_address(machine));
}
void LoadOpcodeHandlerContainer::ld_zpg_y(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_zpg_y_address(machine.read_program_byte(), machine.get_cpu());
set_from(machine, reg, addr);
set_from(machine, reg, get_zpg_y_address(machine));
}
void LoadOpcodeHandlerContainer::ld_abs(Machine& machine, Register<uint8_t>& reg) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_address(low, high);
set_from(machine, reg, addr);
set_from(machine, reg, get_abs_address(machine));
}
void LoadOpcodeHandlerContainer::ld_abs_x(Machine& machine, Register<uint8_t>& reg) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_x_address(low, high, machine.get_cpu());
set_from(machine, reg, addr);
set_from(machine, reg, get_abs_x_address(machine));
}
void LoadOpcodeHandlerContainer::ld_abs_y(Machine& machine, Register<uint8_t>& reg) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_y_address(low, high, machine.get_cpu());
set_from(machine, reg, addr);
set_from(machine, reg, get_abs_y_address(machine));
}
void LoadOpcodeHandlerContainer::ld_ind_x(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_ind_x_address(machine.read_program_byte(), machine);
set_from(machine, reg, addr);
set_from(machine, reg, get_ind_x_address(machine));
}
void LoadOpcodeHandlerContainer::ld_ind_y(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_ind_y_address(machine.read_program_byte(), machine);
set_from(machine, reg, addr);
set_from(machine, reg, get_ind_y_address(machine));
}
}

View File

@ -11,12 +11,33 @@ namespace emu_6502 {
handlers.insert({Op::ADC_ABS_Y, [this](Machine& machine) { adc_abs_y(machine); }});
handlers.insert({Op::ADC_IND_X, [this](Machine& machine) { adc_ind_x(machine); }});
handlers.insert({Op::ADC_IND_Y, [this](Machine& machine) { adc_ind_y(machine); }});
handlers.insert({Op::DEC_ZPG, [this](Machine& machine) { dec_zpg(machine); }});
handlers.insert({Op::DEC_ZPG_X, [this](Machine& machine) { dec_zpg_x(machine); }});
handlers.insert({Op::DEC_ABS, [this](Machine& machine) { dec_abs(machine); }});
handlers.insert({Op::DEC_ABS_X, [this](Machine& machine) { dec_abs_x(machine); }});
handlers.insert({Op::INC_ZPG, [this](Machine& machine) { inc_zpg(machine); }});
handlers.insert({Op::INC_ZPG_X, [this](Machine& machine) { inc_zpg_x(machine); }});
handlers.insert({Op::INC_ABS, [this](Machine& machine) { inc_abs(machine); }});
handlers.insert({Op::INC_ABS_X, [this](Machine& machine) { inc_abs_x(machine); }});
handlers.insert({Op::INX, [this](Machine& machine) { inx(machine); }});
handlers.insert({Op::INY, [this](Machine& machine) { iny(machine); }});
handlers.insert({Op::DEX, [this](Machine& machine) { dex(machine); }});
handlers.insert({Op::DEY, [this](Machine& machine) { dey(machine); }});
}
void MathsOpcodeHandlerContainer::adc(Machine& machine, uint8_t value){
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();
// allow for operation to breach 8 bits
uint16_t result = value + init_a;
if (cpu.get_ps().is_carry_set())
result += 1;
@ -25,8 +46,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
cpu.get_ps().set_zero(a == 0);
cpu.get_ps().set_negative((a & 0x80) == 0x80);
set_zero_neg(cpu.get_ps(), a);
cpu.get_ps().set_carry(result > 0xFF);
cpu.get_ps().set_overflow(
(value < 0x7F && init_a < 0x7F && a > 0x7F) ||
@ -38,64 +58,107 @@ namespace emu_6502 {
}
void MathsOpcodeHandlerContainer::adc_zpg(Machine& machine) {
auto addr = get_zpg_address(machine.read_program_byte());
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_zpg_address(machine)));
}
void MathsOpcodeHandlerContainer::adc_zpg_x(Machine& machine) {
auto addr = get_zpg_x_address(machine.read_program_byte(), machine.get_cpu());
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_zpg_x_address(machine)));
}
void MathsOpcodeHandlerContainer::adc_abs(Machine& machine) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_address(low, high);
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_abs_address(machine)));
}
void MathsOpcodeHandlerContainer::adc_abs_x(Machine& machine) {
auto addr = get_abs_x_address(machine, machine.get_cpu());
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_abs_x_address(machine)));
}
void MathsOpcodeHandlerContainer::adc_abs_y(Machine& machine) {
auto addr = get_abs_y_address(machine, machine.get_cpu());
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_abs_y_address(machine)));
}
void MathsOpcodeHandlerContainer::adc_ind_x(Machine& machine) {
auto addr = get_ind_x_address(machine.read_program_byte(), machine);
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_ind_x_address(machine)));
}
void MathsOpcodeHandlerContainer::adc_ind_y(Machine& machine) {
auto addr = get_ind_y_address(machine.read_program_byte(), machine);
adc(machine, machine.get_memory().get_at(addr));
adc(machine, machine.get_memory().get_at(get_ind_y_address(machine)));
}
void MathsOpcodeHandlerContainer::dec(Machine& machine, uint16_t address) {
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);
}
void MathsOpcodeHandlerContainer::dec_zpg(Machine& machine) {
dec(machine, get_zpg_address(machine));
}
void MathsOpcodeHandlerContainer::dec_zpg_x(Machine& machine) {
dec(machine, get_zpg_x_address(machine));
}
void MathsOpcodeHandlerContainer::dec_abs(Machine& machine) {
dec(machine, get_abs_address(machine));
}
void MathsOpcodeHandlerContainer::dec_abs_x(Machine& machine) {
dec(machine, get_abs_x_address(machine));
}
void MathsOpcodeHandlerContainer::inc(Machine& machine, uint16_t address) {
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);
}
void MathsOpcodeHandlerContainer::inc_zpg(Machine& machine) {
inc(machine, get_zpg_address(machine));
}
void MathsOpcodeHandlerContainer::inc_zpg_x(Machine& machine) {
inc(machine, get_zpg_x_address(machine));
}
void MathsOpcodeHandlerContainer::inc_abs(Machine& machine) {
inc(machine, get_abs_address(machine));
}
void MathsOpcodeHandlerContainer::inc_abs_x(Machine& machine) {
inc(machine, get_abs_x_address(machine));
}
void MathsOpcodeHandlerContainer::de(Machine& machine, Register<uint8_t>& reg) {
uint8_t value = reg.get_value() - 1;
reg.set_value(value);
set_zero_neg(machine.get_cpu().get_ps(), value);
}
void MathsOpcodeHandlerContainer::dex(Machine& machine) {
de(machine, machine.get_cpu().get_x());
}
void MathsOpcodeHandlerContainer::dey(Machine& machine) {
de(machine, machine.get_cpu().get_y());
}
void MathsOpcodeHandlerContainer::in(Machine& machine, Register<uint8_t>& reg) {
uint8_t value = reg.get_value() + 1;
reg.set_value(value);
set_zero_neg(machine.get_cpu().get_ps(), value);
}
void MathsOpcodeHandlerContainer::inx(Machine& machine) {
in(machine, machine.get_cpu().get_x());
}
void MathsOpcodeHandlerContainer::iny(Machine& machine) {
in(machine, machine.get_cpu().get_y());
}
void MathsOpcodeHandlerContainer::sbc_imm(Machine& machine) {

View File

@ -41,6 +41,8 @@ namespace emu_6502 {
SBC_IND_Y = 0x0
};
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);
@ -51,13 +53,23 @@ namespace emu_6502 {
void adc_ind_x(Machine& machine);
void adc_ind_y(Machine& machine);
void dec(Machine& machine, uint16_t address);
void dec_zpg(Machine& machine);
void dec_zpg_x(Machine& machine);
void dec_abs(Machine& machine);
void dec_abs_x(Machine& machine);
void inc(Machine& machine, uint16_t address);
void inc_zpg(Machine& machine);
void inc_zpg_x(Machine& machine);
void inc_abs(Machine& machine);
void inc_abs_x(Machine& machine);
void de(Machine& machine, Register<uint8_t>& reg);
void dex(Machine& machine);
void dey(Machine& machine);
void in(Machine& machine, Register<uint8_t>& reg);
void inx(Machine& machine);
void iny(Machine& machine);

View File

@ -25,48 +25,34 @@ namespace emu_6502 {
}
void StoreOpcodeHandlerContainer::st_zpg(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_zpg_address(machine.read_program_byte());
store_to(machine, reg, addr);
store_to(machine, reg, get_zpg_address(machine));
}
void StoreOpcodeHandlerContainer::st_zpg_x(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_zpg_x_address(machine.read_program_byte(), machine.get_cpu());
store_to(machine, reg, addr);
store_to(machine, reg, get_zpg_x_address(machine));
}
void StoreOpcodeHandlerContainer::st_zpg_y(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_zpg_y_address(machine.read_program_byte(), machine.get_cpu());
store_to(machine, reg, addr);
store_to(machine, reg, get_zpg_y_address(machine));
}
void StoreOpcodeHandlerContainer::st_abs(Machine& machine, Register<uint8_t>& reg) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_address(low, high);
store_to(machine, reg, addr);
store_to(machine, reg, get_abs_address(machine));
}
void StoreOpcodeHandlerContainer::st_abs_x(Machine& machine, Register<uint8_t>& reg) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_x_address(low, high, machine.get_cpu());
store_to(machine, reg, addr);
store_to(machine, reg, get_abs_x_address(machine));
}
void StoreOpcodeHandlerContainer::st_abs_y(Machine& machine, Register<uint8_t>& reg) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
auto addr = get_abs_y_address(low, high, machine.get_cpu());
store_to(machine, reg, addr);
store_to(machine, reg, get_abs_y_address(machine));
}
void StoreOpcodeHandlerContainer::st_ind_x(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_ind_x_address(machine.read_program_byte(), machine);
store_to(machine, reg, addr);
store_to(machine, reg, get_ind_x_address(machine));
}
void StoreOpcodeHandlerContainer::st_ind_y(Machine& machine, Register<uint8_t>& reg) {
auto addr = get_ind_y_address(machine.read_program_byte(), machine);
store_to(machine, reg, addr);
store_to(machine, reg, get_ind_y_address(machine));
}
}

View File

@ -8,49 +8,43 @@ namespace emu_6502 {
return ss.str();
}
uint8_t get_zpg_address(uint8_t offset) {
return offset;
uint8_t get_zpg_address(Machine& machine) {
return machine.read_program_byte();
}
uint8_t get_zpg_x_address(uint8_t offset, Cpu& cpu) {
uint8_t get_zpg_x_address(Machine& machine) {
// expect wrap around
return offset + cpu.get_x().get_value();
return machine.read_program_byte() + machine.get_cpu().get_x().get_value();
}
uint8_t get_zpg_y_address(uint8_t offset, Cpu& cpu) {
uint8_t get_zpg_y_address(Machine& machine) {
// expect wrap around
return offset + cpu.get_y().get_value();
return machine.read_program_byte() + machine.get_cpu().get_y().get_value();
}
uint16_t get_abs_address(uint8_t low_byte, uint8_t high_byte) {
uint16_t get_abs_address(Machine& machine) {
auto low_byte = machine.read_program_byte();
auto high_byte = machine.read_program_byte();
uint16_t address = (high_byte << 8) + low_byte;
return address;
}
uint16_t get_abs_x_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu) {
uint16_t address = (high_byte << 8) + low_byte + cpu.get_x().get_value();
uint16_t get_abs_x_address(Machine& machine) {
auto low_byte = machine.read_program_byte();
auto high_byte = machine.read_program_byte();
uint16_t address = (high_byte << 8) + low_byte + machine.get_cpu().get_x().get_value();
return address;
}
uint16_t get_abs_y_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu) {
uint16_t address = (high_byte << 8) + low_byte + cpu.get_y().get_value();
uint16_t get_abs_y_address(Machine& machine) {
auto low_byte = machine.read_program_byte();
auto high_byte = machine.read_program_byte();
uint16_t address = (high_byte << 8) + low_byte + machine.get_cpu().get_y().get_value();
return address;
}
uint16_t get_abs_x_address(Machine& machine, Cpu& cpu) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
return get_abs_x_address(low, high, machine.get_cpu());
}
uint16_t get_abs_y_address(Machine& machine, Cpu& cpu) {
auto low = machine.read_program_byte();
auto high = machine.read_program_byte();
return get_abs_y_address(low, high, machine.get_cpu());
}
uint16_t get_ind_x_address(uint8_t offset, Machine& machine) {
uint8_t paddress = machine.get_cpu().get_x().get_value() + offset;
uint16_t get_ind_x_address(Machine& machine) {
uint8_t paddress = machine.get_cpu().get_x().get_value() + machine.read_program_byte();
auto low = machine.get_memory().get_at(paddress);
auto high = machine.get_memory().get_at(paddress + 1);
uint16_t address = (high << 8) + low;
@ -58,7 +52,8 @@ namespace emu_6502 {
return address;
}
uint16_t get_ind_y_address(uint8_t offset, Machine& machine) {
uint16_t get_ind_y_address(Machine& machine) {
auto offset = machine.read_program_byte();
auto low = machine.get_memory().get_at(offset);
auto high = machine.get_memory().get_at(offset + 1);
auto y = machine.get_cpu().get_y().get_value();

View File

@ -9,16 +9,16 @@ using namespace std;
namespace emu_6502 {
string uint_to_hex(uint64_t value);
uint8_t get_zpg_address(uint8_t offset);
uint8_t get_zpg_x_address(uint8_t offset, Cpu& cpu);
uint8_t get_zpg_y_address(uint8_t offset, Cpu& cpu);
uint16_t get_abs_address(uint8_t low_byte, uint8_t high_byte);
uint16_t get_abs_x_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu);
uint16_t get_abs_y_address(uint8_t low_byte, uint8_t high_byte, Cpu& cpu);
uint16_t get_abs_x_address(Machine& machine, Cpu& cpu);
uint16_t get_abs_y_address(Machine& machine, Cpu& cpu);
uint16_t get_ind_x_address(uint8_t offset, Machine& machine);
uint16_t get_ind_y_address(uint8_t offset, Machine& machine);
uint8_t get_zpg_address(Machine& machine);
uint8_t get_zpg_x_address(Machine& machine);
uint8_t get_zpg_y_address(Machine& machine);
uint16_t get_abs_address(Machine& machine);
uint16_t get_abs_x_address(Machine& machine);
uint16_t get_abs_y_address(Machine& machine);
uint16_t get_abs_x_address(Machine& machine);
uint16_t get_abs_y_address(Machine& machine);
uint16_t get_ind_x_address(Machine& machine);
uint16_t get_ind_y_address(Machine& machine);
}
#endif // INC_6502_EMULATOR_UTILS_H

View File

@ -13,6 +13,21 @@ const uint8_t ADC_ABS_Y = 0x79;
const uint8_t ADC_IND_X = 0x61;
const uint8_t ADC_IND_Y = 0x71;
const uint8_t DEC_ZPG = 0xC6;
const uint8_t DEC_ZPG_X = 0xD6;
const uint8_t DEC_ABS = 0xCE;
const uint8_t DEC_ABS_X = 0xDE;
const uint8_t INC_ZPG = 0xE6;
const uint8_t INC_ZPG_X = 0xF6;
const uint8_t INC_ABS = 0xEE;
const uint8_t INC_ABS_X = 0xFE;
const uint8_t DEX = 0xCA;
const uint8_t DEY = 0x88;
const uint8_t INX = 0xE8;
const uint8_t INY = 0xC8;
TEST(MathsOpcodeHandlerContainer, ADC_IMM) {
auto machine = create_machine({ADC_IMM, 36});
machine->get_cpu().get_a().set_value(36);
@ -175,3 +190,211 @@ TEST(MathsOpcodeHandlerContainer, ADC_IND_Y) {
ASSERT_EQ(56, machine->get_cpu().get_a().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, DEC_ZPG) {
auto machine = create_machine({DEC_ZPG, 0xf1});
machine->get_memory().set_at(0xf1, 20);
machine->execute();
ASSERT_EQ(19, machine->get_memory().get_at(0xf1));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, DEC_ZPG_ZeroFlag) {
auto machine = create_machine({DEC_ZPG, 0xf1});
machine->get_memory().set_at(0xf1, 1);
machine->execute();
ASSERT_EQ(0, machine->get_memory().get_at(0xf1));
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, DEC_ZPG_NegativeFlag) {
auto machine = create_machine({DEC_ZPG, 0xf1});
machine->get_memory().set_at(0xf1, 0);
machine->execute();
ASSERT_EQ(0xFF, machine->get_memory().get_at(0xf1));
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, DEC_ZPG_X) {
auto machine = create_machine({DEC_ZPG_X, 0x45});
machine->get_cpu().get_x().set_value(0x10);
machine->get_memory().set_at(0x55, 20);
machine->execute();
ASSERT_EQ(19, machine->get_memory().get_at(0x55));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, DEC_ABS) {
auto machine = create_machine({DEC_ABS, 0x45, 0x1a});
machine->get_memory().set_at(0x1a45, 20);
machine->execute();
ASSERT_EQ(19, machine->get_memory().get_at(0x1a45));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, DEC_ABS_X) {
auto machine = create_machine({DEC_ABS_X, 0x45, 0x1a});
machine->get_cpu().get_x().set_value(0x10);
machine->get_memory().set_at(0x1a55, 20);
machine->execute();
ASSERT_EQ(19, machine->get_memory().get_at(0x1a55));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, INC_ZPG) {
auto machine = create_machine({INC_ZPG, 0xf1});
machine->get_memory().set_at(0xf1, 20);
machine->execute();
ASSERT_EQ(21, machine->get_memory().get_at(0xf1));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, INC_ZPG_ZeroFlag) {
auto machine = create_machine({INC_ZPG, 0xf1});
machine->get_memory().set_at(0xf1, 0xff);
machine->execute();
ASSERT_EQ(0, machine->get_memory().get_at(0xf1));
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, INC_ZPG_NegativeFlag) {
auto machine = create_machine({INC_ZPG, 0xf1});
machine->get_memory().set_at(0xf1, 0x7f);
machine->execute();
ASSERT_EQ(0x80, machine->get_memory().get_at(0xf1));
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, INC_ZPG_X) {
auto machine = create_machine({INC_ZPG_X, 0x45});
machine->get_cpu().get_x().set_value(0x10);
machine->get_memory().set_at(0x55, 20);
machine->execute();
ASSERT_EQ(21, machine->get_memory().get_at(0x55));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, INC_ABS) {
auto machine = create_machine({INC_ABS, 0x45, 0x1a});
machine->get_memory().set_at(0x1a45, 20);
machine->execute();
ASSERT_EQ(21, machine->get_memory().get_at(0x1a45));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, INC_ABS_X) {
auto machine = create_machine({INC_ABS_X, 0x45, 0x1a});
machine->get_cpu().get_x().set_value(0x10);
machine->get_memory().set_at(0x1a55, 20);
machine->execute();
ASSERT_EQ(21, machine->get_memory().get_at(0x1a55));
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, INX) {
auto machine = create_machine({INX});
machine->get_cpu().get_x().set_value(5);
machine->execute();
ASSERT_EQ(6, machine->get_cpu().get_x().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, INX_ZeroFlag) {
auto machine = create_machine({INX});
machine->get_cpu().get_x().set_value(0xff);
machine->execute();
ASSERT_EQ(0, machine->get_cpu().get_x().get_value());
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, INX_NegativeFlag) {
auto machine = create_machine({INX});
machine->get_cpu().get_x().set_value(0x7f);
machine->execute();
ASSERT_EQ(0x80, machine->get_cpu().get_x().get_value());
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, INY) {
auto machine = create_machine({INY});
machine->get_cpu().get_y().set_value(5);
machine->execute();
ASSERT_EQ(6, machine->get_cpu().get_y().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, DEX) {
auto machine = create_machine({DEX});
machine->get_cpu().get_x().set_value(5);
machine->execute();
ASSERT_EQ(4, machine->get_cpu().get_x().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}
TEST(MathsOpcodeHandlerContainer, DEX_ZeroFlag) {
auto machine = create_machine({DEX});
machine->get_cpu().get_x().set_value(1);
machine->execute();
ASSERT_EQ(0, machine->get_cpu().get_x().get_value());
RegisterFlagSet flags{};
flags.zero = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, DEX_NegativeFlag) {
auto machine = create_machine({DEX});
machine->get_cpu().get_x().set_value(0);
machine->execute();
ASSERT_EQ(0xff, machine->get_cpu().get_x().get_value());
RegisterFlagSet flags{};
flags.negative = true;
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
}
TEST(MathsOpcodeHandlerContainer, DEY) {
auto machine = create_machine({DEY});
machine->get_cpu().get_y().set_value(5);
machine->execute();
ASSERT_EQ(4, machine->get_cpu().get_y().get_value());
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
}