mirror of
https://github.com/tdinucci/6502-emulator.git
synced 2025-02-17 08:30:39 +00:00
Stack opcodes
This commit is contained in:
parent
51812ebd71
commit
248be24ef8
30
src/opcode/handler/stack-opcode-handler-container.cpp
Normal file
30
src/opcode/handler/stack-opcode-handler-container.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "stack-opcode-handler-container.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
namespace emu_6502 {
|
||||
StackOpcodeHandlerContainer::StackOpcodeHandlerContainer() {
|
||||
handlers.insert({Op::PHA, [this](Machine& machine) { pha(machine); }});
|
||||
handlers.insert({Op::PHP, [this](Machine& machine) { php(machine); }});
|
||||
|
||||
handlers.insert({Op::PLA, [this](Machine& machine) { pla(machine); }});
|
||||
handlers.insert({Op::PLP, [this](Machine& machine) { plp(machine); }});
|
||||
}
|
||||
|
||||
void StackOpcodeHandlerContainer::pha(Machine& machine) {
|
||||
machine.get_stack().push(machine.get_cpu().get_a().get_value());
|
||||
}
|
||||
|
||||
void StackOpcodeHandlerContainer::php(Machine& machine) {
|
||||
machine.get_stack().push(machine.get_cpu().get_ps().get_value().to_ulong());
|
||||
}
|
||||
|
||||
void StackOpcodeHandlerContainer::pla(Machine& machine) {
|
||||
auto value = machine.get_stack().pop();
|
||||
machine.get_cpu().get_a().set_value(value);
|
||||
set_zero_and_neg_flags(machine.get_cpu().get_ps(), value);
|
||||
}
|
||||
|
||||
void StackOpcodeHandlerContainer::plp(Machine& machine) {
|
||||
machine.get_cpu().get_ps().set_value(machine.get_stack().pop());
|
||||
}
|
||||
}
|
30
src/opcode/handler/stack-opcode-handler-container.h
Normal file
30
src/opcode/handler/stack-opcode-handler-container.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef INC_6502_EMULATOR_STACK_OPCODE_HANDLER_CONTAINER_H
|
||||
#define INC_6502_EMULATOR_STACK_OPCODE_HANDLER_CONTAINER_H
|
||||
|
||||
#include "opcode-handler-container.h"
|
||||
|
||||
namespace emu_6502 {
|
||||
class StackOpcodeHandlerContainer : public OpcodeHandlerContainer {
|
||||
private:
|
||||
enum Op {
|
||||
PHA = 0x48,
|
||||
PHP = 0x08,
|
||||
PLA = 0x68,
|
||||
PLP = 0x28,
|
||||
};
|
||||
|
||||
void pha(Machine& machine);
|
||||
void php(Machine& machine);
|
||||
|
||||
void pla(Machine& machine);
|
||||
void plp(Machine& machine);
|
||||
|
||||
public:
|
||||
StackOpcodeHandlerContainer();
|
||||
StackOpcodeHandlerContainer(const StackOpcodeHandlerContainer&) = delete;
|
||||
StackOpcodeHandlerContainer& operator=(const StackOpcodeHandlerContainer&) = delete;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //INC_6502_EMULATOR_STACK_OPCODE_HANDLER_CONTAINER_H
|
@ -6,6 +6,7 @@
|
||||
#include "handler/bitwise-opcode-handler-container.h"
|
||||
#include "handler/status-opcode-handler-container.h"
|
||||
#include "handler/compare-opcode-handler-container.h"
|
||||
#include "handler/stack-opcode-handler-container.h"
|
||||
#include "../utils.h"
|
||||
|
||||
namespace emu_6502 {
|
||||
@ -18,6 +19,7 @@ namespace emu_6502 {
|
||||
handler_containers.push_back(make_unique<BitwiseOpcodeHandlerContainer>());
|
||||
handler_containers.push_back(make_unique<StatusOpcodeHandlerContainer>());
|
||||
handler_containers.push_back(make_unique<CompareOpcodeHandlerContainer>());
|
||||
handler_containers.push_back(make_unique<StackOpcodeHandlerContainer>());
|
||||
|
||||
init_handlers();
|
||||
}
|
||||
|
90
test/stack-opcode-handler-test.cpp
Normal file
90
test/stack-opcode-handler-test.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace emu_6502;
|
||||
|
||||
const uint8_t PHA = 0x48;
|
||||
const uint8_t PHP = 0x08;
|
||||
const uint8_t PLA = 0x68;
|
||||
const uint8_t PLP = 0x28;
|
||||
|
||||
const uint8_t CLC = 0x18;
|
||||
const uint8_t CLD = 0xD8;
|
||||
const uint8_t CLI = 0x58;
|
||||
const uint8_t CLV = 0xB8;
|
||||
|
||||
TEST(StackOpcodeHandlerContainer, PHA) {
|
||||
auto machine = create_machine({PHA});
|
||||
machine->get_cpu().get_a().set_value(0x13);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0x13, machine->get_cpu().get_a().get_value());
|
||||
ASSERT_EQ(0x13, machine->get_stack().pop());
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||
}
|
||||
|
||||
TEST(StackOpcodeHandlerContainer, PHP) {
|
||||
auto machine = create_machine({PHP});
|
||||
machine->get_cpu().get_ps().set_value(0xFF);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0xFF, machine->get_cpu().get_ps().get_value().to_ulong());
|
||||
ASSERT_EQ(0xFF, machine->get_stack().pop());
|
||||
}
|
||||
|
||||
TEST(StackOpcodeHandlerContainer, PLA) {
|
||||
auto machine = create_machine({PLA});
|
||||
machine->get_stack().push(0x05);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0x05, machine->get_cpu().get_a().get_value());
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), RegisterFlagSet{}));
|
||||
}
|
||||
|
||||
TEST(StackOpcodeHandlerContainer, PLA_NegativeFlag) {
|
||||
auto machine = create_machine({PLA});
|
||||
machine->get_stack().push(0xf5);
|
||||
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(StackOpcodeHandlerContainer, PLA_ZeroFlag) {
|
||||
auto machine = create_machine({PLA});
|
||||
machine->get_stack().push(0x0);
|
||||
machine->execute();
|
||||
|
||||
ASSERT_EQ(0x0, machine->get_cpu().get_a().get_value());
|
||||
RegisterFlagSet flags{};
|
||||
flags.zero = true;
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
||||
|
||||
TEST(StackOpcodeHandlerContainer, PLP) {
|
||||
auto machine = create_machine({PHP, CLC, CLD, CLI, CLV, PLP});
|
||||
|
||||
auto& ps = machine->get_cpu().get_ps();
|
||||
ps.set_zero(true);
|
||||
ps.set_negative(true);
|
||||
ps.set_carry(true);
|
||||
ps.set_overflow(true);
|
||||
ps.set_interupt_disable(true);
|
||||
ps.set_decimal(true);
|
||||
ps.set_break(true);
|
||||
|
||||
machine->execute();
|
||||
|
||||
RegisterFlagSet flags{};
|
||||
flags.zero = true;
|
||||
flags.negative = true;
|
||||
flags.carry = true;
|
||||
flags.overflow = true;
|
||||
flags.interupt_disable = true;
|
||||
flags.decimal = true;
|
||||
flags.brk = true;
|
||||
ASSERT_TRUE(are_flags_set(machine->get_cpu().get_ps(), flags));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user