mirror of
https://github.com/tdinucci/6502-emulator.git
synced 2024-11-23 07:34:14 +00:00
Most bitwise operations
This commit is contained in:
parent
ade6eaec6d
commit
2bc37b1b61
314
src/opcode/handler/bitwise-opcode-handler-container.cpp
Normal file
314
src/opcode/handler/bitwise-opcode-handler-container.cpp
Normal 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));
|
||||
}
|
||||
}
|
133
src/opcode/handler/bitwise-opcode-handler-container.h
Normal file
133
src/opcode/handler/bitwise-opcode-handler-container.h
Normal 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
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
785
test/bitwise-opcode-handler-test.cpp
Normal file
785
test/bitwise-opcode-handler-test.cpp
Normal 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));
|
||||
}
|
Loading…
Reference in New Issue
Block a user