Add PHX, PHY, PHB, PHD, PHK and PLX, PLY, PLB, PLD
This commit is contained in:
@@ -636,55 +636,55 @@ void CPU::ExecuteInstruction(uint8_t opcode) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x48: // PHA Push Accumulator
|
case 0x48: // PHA Push Accumulator
|
||||||
// PHA();
|
PHA();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8B: // PHB Push Data Bank Register
|
case 0x8B: // PHB Push Data Bank Register
|
||||||
// PHB();
|
PHB();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0B: // PHD Push Direct Page Register
|
case 0x0B: // PHD Push Direct Page Register
|
||||||
// PHD();
|
PHD();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x4B: // PHK Push Program Bank Register
|
case 0x4B: // PHK Push Program Bank Register
|
||||||
// PHK();
|
PHK();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: // PHP Push Processor Status Register
|
case 0x08: // PHP Push Processor Status Register
|
||||||
// PHP();
|
PHP();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xDA: // PHX Push X register
|
case 0xDA: // PHX Push X register
|
||||||
// PHX();
|
PHX();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x5A: // PHY Push Y register
|
case 0x5A: // PHY Push Y register
|
||||||
// PHY();
|
PHY();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x68: // PLA Pull Accumulator
|
case 0x68: // PLA Pull Accumulator
|
||||||
// PLA();
|
PLA();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xAB: // PLB Pull Data Bank Register
|
case 0xAB: // PLB Pull Data Bank Register
|
||||||
// PLB();
|
PLB();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2B: // PLD Pull Direct Page Register
|
case 0x2B: // PLD Pull Direct Page Register
|
||||||
// PLD();
|
PLD();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28: // PLP Pull Processor Status Register
|
case 0x28: // PLP Pull Processor Status Register
|
||||||
// PLP();
|
PLP();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFA: // PLX Pull X register
|
case 0xFA: // PLX Pull X register
|
||||||
// PLX();
|
PLX();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x7A: // PLY Pull Y register
|
case 0x7A: // PLY Pull Y register
|
||||||
// PLY();
|
PLY();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC2: // REP Reset status bits
|
case 0xC2: // REP Reset status bits
|
||||||
|
|||||||
@@ -400,18 +400,61 @@ class CPU : public Memory {
|
|||||||
|
|
||||||
void CLV() { status &= ~0x40; }
|
void CLV() { status &= ~0x40; }
|
||||||
|
|
||||||
|
// Push Accumulator on Stack
|
||||||
void PHA() { memory.PushByte(A); }
|
void PHA() { memory.PushByte(A); }
|
||||||
|
|
||||||
|
// Pull Accumulator from Stack
|
||||||
void PLA() {
|
void PLA() {
|
||||||
A = memory.PopByte();
|
A = memory.PopByte();
|
||||||
SetNegativeFlag((A & 0x80) != 0);
|
SetNegativeFlag((A & 0x80) != 0);
|
||||||
SetZeroFlag(A == 0);
|
SetZeroFlag(A == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Push Processor Status Register on Stack
|
||||||
void PHP() { memory.PushByte(status); }
|
void PHP() { memory.PushByte(status); }
|
||||||
|
|
||||||
|
// Pull Processor Status Register from Stack
|
||||||
void PLP() { status = memory.PopByte(); }
|
void PLP() { status = memory.PopByte(); }
|
||||||
|
|
||||||
|
void PHX() { memory.PushByte(X); }
|
||||||
|
|
||||||
|
void PLX() {
|
||||||
|
X = memory.PopByte();
|
||||||
|
SetNegativeFlag((A & 0x80) != 0);
|
||||||
|
SetZeroFlag(X == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PHY() { memory.PushByte(Y); }
|
||||||
|
|
||||||
|
void PLY() {
|
||||||
|
Y = memory.PopByte();
|
||||||
|
SetNegativeFlag((A & 0x80) != 0);
|
||||||
|
SetZeroFlag(Y == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push Data Bank Register on Stack
|
||||||
|
void PHB() { memory.PushByte(DB); }
|
||||||
|
|
||||||
|
// Pull Data Bank Register from Stack
|
||||||
|
void PLB() {
|
||||||
|
DB = memory.PopByte();
|
||||||
|
SetNegativeFlag((DB & 0x80) != 0);
|
||||||
|
SetZeroFlag(DB == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push Program Bank Register on Stack
|
||||||
|
void PHD() { memory.PushWord(D); }
|
||||||
|
|
||||||
|
// Pull Direct Page Register from Stack
|
||||||
|
void PLD() {
|
||||||
|
D = memory.PopWord();
|
||||||
|
SetNegativeFlag((D & 0x8000) != 0);
|
||||||
|
SetZeroFlag(D == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push Program Bank Register on Stack
|
||||||
|
void PHK() { memory.PushByte(PB); }
|
||||||
|
|
||||||
void SEI() { status |= 0x04; }
|
void SEI() { status |= 0x04; }
|
||||||
|
|
||||||
void SED() { status |= 0x08; }
|
void SED() { status |= 0x08; }
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ absl::Status DecodeObjFile(
|
|||||||
expected_cut = 0x900;
|
expected_cut = 0x900;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream file(filename, std::ios::binary);
|
std::ifstream file(filename.data(), std::ios::binary);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
return absl::NotFoundError("OBJ file not found.");
|
return absl::NotFoundError("OBJ file not found.");
|
||||||
}
|
}
|
||||||
|
|||||||
233
test/cpu_test.cc
233
test/cpu_test.cc
@@ -76,6 +76,12 @@ class MockMemory : public Memory {
|
|||||||
uint16_t SP_ = 0x01FF;
|
uint16_t SP_ = 0x01FF;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CPUTest : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
MockMemory mock_memory;
|
||||||
|
CPU cpu{mock_memory};
|
||||||
|
};
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
|
|
||||||
@@ -83,7 +89,7 @@ using ::testing::Return;
|
|||||||
// Infrastructure
|
// Infrastructure
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
TEST(CPUTest, CheckMemoryContents) {
|
TEST_F(CPUTest, CheckMemoryContents) {
|
||||||
MockMemory memory;
|
MockMemory memory;
|
||||||
std::vector<uint8_t> data = {0x00, 0x01, 0x02, 0x03, 0x04};
|
std::vector<uint8_t> data = {0x00, 0x01, 0x02, 0x03, 0x04};
|
||||||
memory.SetMemoryContents(data);
|
memory.SetMemoryContents(data);
|
||||||
@@ -106,9 +112,7 @@ TEST(CPUTest, CheckMemoryContents) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ADC - Add with Carry
|
// ADC - Add with Carry
|
||||||
|
|
||||||
TEST(CPUTest, ADC_Immediate_TwoPositiveNumbers) {
|
TEST_F(CPUTest, ADC_Immediate_TwoPositiveNumbers) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0x01;
|
cpu.A = 0x01;
|
||||||
std::vector<uint8_t> data = {0x69, 0x01};
|
std::vector<uint8_t> data = {0x69, 0x01};
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
@@ -119,9 +123,7 @@ TEST(CPUTest, ADC_Immediate_TwoPositiveNumbers) {
|
|||||||
EXPECT_EQ(cpu.A, 0x02);
|
EXPECT_EQ(cpu.A, 0x02);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, ADC_Immediate_PositiveAndNegativeNumbers) {
|
TEST_F(CPUTest, ADC_Immediate_PositiveAndNegativeNumbers) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 10;
|
cpu.A = 10;
|
||||||
std::vector<uint8_t> data = {0x69, static_cast<uint8_t>(-20)};
|
std::vector<uint8_t> data = {0x69, static_cast<uint8_t>(-20)};
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
@@ -132,9 +134,7 @@ TEST(CPUTest, ADC_Immediate_PositiveAndNegativeNumbers) {
|
|||||||
EXPECT_EQ(cpu.A, static_cast<uint8_t>(-10));
|
EXPECT_EQ(cpu.A, static_cast<uint8_t>(-10));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, ADC_Absolute) {
|
TEST_F(CPUTest, ADC_Absolute) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0x01;
|
cpu.A = 0x01;
|
||||||
cpu.PC = 1; // PC register
|
cpu.PC = 1; // PC register
|
||||||
cpu.status = 0x00; // 16-bit mode
|
cpu.status = 0x00; // 16-bit mode
|
||||||
@@ -149,9 +149,7 @@ TEST(CPUTest, ADC_Absolute) {
|
|||||||
EXPECT_EQ(cpu.A, 0x06);
|
EXPECT_EQ(cpu.A, 0x06);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, ADC_AbsoluteLong) {
|
TEST_F(CPUTest, ADC_AbsoluteLong) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0x01;
|
cpu.A = 0x01;
|
||||||
cpu.PC = 1; // PC register
|
cpu.PC = 1; // PC register
|
||||||
cpu.status = 0x00; // 16-bit mode
|
cpu.status = 0x00; // 16-bit mode
|
||||||
@@ -161,9 +159,9 @@ TEST(CPUTest, ADC_AbsoluteLong) {
|
|||||||
/**
|
/**
|
||||||
* Direct Page Unimplemented
|
* Direct Page Unimplemented
|
||||||
*
|
*
|
||||||
TEST(CPUTest, ADC_DirectPage) {
|
TEST_F(CPUTest, ADC_DirectPage) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0x01;
|
cpu.A = 0x01;
|
||||||
cpu.D = 0x0001;
|
cpu.D = 0x0001;
|
||||||
std::vector<uint8_t> data = {0x65, 0x01, 0x05};
|
std::vector<uint8_t> data = {0x65, 0x01, 0x05};
|
||||||
@@ -175,9 +173,9 @@ TEST(CPUTest, ADC_DirectPage) {
|
|||||||
EXPECT_EQ(cpu.A, 0x06);
|
EXPECT_EQ(cpu.A, 0x06);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, ADC_DirectPageIndirect) {
|
TEST_F(CPUTest, ADC_DirectPageIndirect) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0x01; // A register
|
cpu.A = 0x01; // A register
|
||||||
cpu.X = 0x02; // X register
|
cpu.X = 0x02; // X register
|
||||||
cpu.PC = 0; // PC register
|
cpu.PC = 0; // PC register
|
||||||
@@ -192,9 +190,9 @@ TEST(CPUTest, ADC_DirectPageIndirect) {
|
|||||||
EXPECT_EQ(cpu.A, 0x06);
|
EXPECT_EQ(cpu.A, 0x06);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, ADC_DirectPageIndexedIndirectX) {
|
TEST_F(CPUTest, ADC_DirectPageIndexedIndirectX) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0x01;
|
cpu.A = 0x01;
|
||||||
cpu.X = 0x02;
|
cpu.X = 0x02;
|
||||||
cpu.PC = 1;
|
cpu.PC = 1;
|
||||||
@@ -211,9 +209,7 @@ TEST(CPUTest, ADC_DirectPageIndexedIndirectX) {
|
|||||||
}
|
}
|
||||||
**/
|
**/
|
||||||
|
|
||||||
TEST(CPUTest, ADC_CheckCarryFlag) {
|
TEST_F(CPUTest, ADC_CheckCarryFlag) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0xFF;
|
cpu.A = 0xFF;
|
||||||
cpu.status = 0;
|
cpu.status = 0;
|
||||||
std::vector<uint8_t> data = {0x15, 0x01}; // Operand at address 0x15
|
std::vector<uint8_t> data = {0x15, 0x01}; // Operand at address 0x15
|
||||||
@@ -230,9 +226,7 @@ TEST(CPUTest, ADC_CheckCarryFlag) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// AND - Logical AND
|
// AND - Logical AND
|
||||||
|
|
||||||
TEST(CPUTest, AND_Immediate) {
|
TEST_F(CPUTest, AND_Immediate) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.PC = 0;
|
cpu.PC = 0;
|
||||||
cpu.status = 0xFF; // 8-bit mode
|
cpu.status = 0xFF; // 8-bit mode
|
||||||
cpu.A = 0b11110000; // A register
|
cpu.A = 0b11110000; // A register
|
||||||
@@ -245,9 +239,7 @@ TEST(CPUTest, AND_Immediate) {
|
|||||||
EXPECT_EQ(cpu.A, 0b10100000); // A register should now be 0b10100000
|
EXPECT_EQ(cpu.A, 0b10100000); // A register should now be 0b10100000
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, AND_Absolute) {
|
TEST_F(CPUTest, AND_Absolute) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0b11111111; // A register
|
cpu.A = 0b11111111; // A register
|
||||||
cpu.status = 0x00; // 16-bit mode
|
cpu.status = 0x00; // 16-bit mode
|
||||||
cpu.PC = 1; // PC register
|
cpu.PC = 1; // PC register
|
||||||
@@ -266,9 +258,7 @@ TEST(CPUTest, AND_Absolute) {
|
|||||||
EXPECT_EQ(cpu.A, 0b10101010); // A register should now be 0b10101010
|
EXPECT_EQ(cpu.A, 0b10101010); // A register should now be 0b10101010
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, AND_IndexedIndirect) {
|
TEST_F(CPUTest, AND_IndexedIndirect) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0b10101010; // A register
|
cpu.A = 0b10101010; // A register
|
||||||
cpu.X = 0x02; // X register
|
cpu.X = 0x02; // X register
|
||||||
std::vector<uint8_t> data = {0x21, 0x10, 0x18, 0x20, 0b01010101};
|
std::vector<uint8_t> data = {0x21, 0x10, 0x18, 0x20, 0b01010101};
|
||||||
@@ -281,9 +271,7 @@ TEST(CPUTest, AND_IndexedIndirect) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// BCC - Branch if Carry Clear
|
// BCC - Branch if Carry Clear
|
||||||
|
|
||||||
TEST(CPUTest, BCC_WhenCarryFlagClear) {
|
TEST_F(CPUTest, BCC_WhenCarryFlagClear) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.SetCarryFlag(false);
|
cpu.SetCarryFlag(false);
|
||||||
cpu.PC = 0x1000;
|
cpu.PC = 0x1000;
|
||||||
std::vector<uint8_t> data(0x1001, 2); // Operand at address 0x1001
|
std::vector<uint8_t> data(0x1001, 2); // Operand at address 0x1001
|
||||||
@@ -295,9 +283,7 @@ TEST(CPUTest, BCC_WhenCarryFlagClear) {
|
|||||||
EXPECT_EQ(cpu.PC, 0x1002);
|
EXPECT_EQ(cpu.PC, 0x1002);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CPUTest, BCC_WhenCarryFlagSet) {
|
TEST_F(CPUTest, BCC_WhenCarryFlagSet) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.SetCarryFlag(true);
|
cpu.SetCarryFlag(true);
|
||||||
cpu.PC = 0x1000;
|
cpu.PC = 0x1000;
|
||||||
std::vector<uint8_t> data(0x1001, 2); // Operand at address 0x1001
|
std::vector<uint8_t> data(0x1001, 2); // Operand at address 0x1001
|
||||||
@@ -313,9 +299,7 @@ TEST(CPUTest, BCC_WhenCarryFlagSet) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// BRL - Branch Long
|
// BRL - Branch Long
|
||||||
|
|
||||||
TEST(CPUTest, BRL) {
|
TEST_F(CPUTest, BRL) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.PC = 0x1000;
|
cpu.PC = 0x1000;
|
||||||
std::vector<uint8_t> data(0x1001, 2); // Operand at address 0x1001
|
std::vector<uint8_t> data(0x1001, 2); // Operand at address 0x1001
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
@@ -329,51 +313,130 @@ TEST(CPUTest, BRL) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Stack Tests
|
// Stack Tests
|
||||||
|
|
||||||
class CPUTestKit : public ::testing::Test {
|
TEST_F(CPUTest, PHA_PLA_Ok) {
|
||||||
protected:
|
cpu.A = 0x42;
|
||||||
MockMemory memory_;
|
EXPECT_CALL(mock_memory, PushByte(0x42)).WillOnce(Return());
|
||||||
CPU cpu_{memory_};
|
cpu.PHA();
|
||||||
};
|
cpu.A = 0x00;
|
||||||
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x42));
|
||||||
TEST_F(CPUTestKit, PHA_PLA_Test) {
|
cpu.PLA();
|
||||||
cpu_.A = 0x42;
|
EXPECT_EQ(cpu.A, 0x42);
|
||||||
EXPECT_CALL(memory_, PushByte(0x42)).WillOnce(Return());
|
|
||||||
cpu_.PHA();
|
|
||||||
cpu_.A = 0x00;
|
|
||||||
EXPECT_CALL(memory_, PopByte()).WillOnce(Return(0x42));
|
|
||||||
cpu_.PLA();
|
|
||||||
EXPECT_EQ(cpu_.A, 0x42);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CPUTestKit, PHP_PLP_Test) {
|
TEST_F(CPUTest, PHP_PLP_Ok) {
|
||||||
// Set some status flags
|
// Set some status flags
|
||||||
cpu_.SetNegativeFlag(true);
|
cpu.status = 0;
|
||||||
cpu_.SetZeroFlag(false);
|
cpu.SetNegativeFlag(true);
|
||||||
EXPECT_TRUE(cpu_.GetNegativeFlag());
|
cpu.SetZeroFlag(false);
|
||||||
EXPECT_FALSE(cpu_.GetZeroFlag());
|
EXPECT_TRUE(cpu.GetNegativeFlag());
|
||||||
|
EXPECT_FALSE(cpu.GetZeroFlag());
|
||||||
|
|
||||||
EXPECT_CALL(memory_, PushByte(0x80)).WillOnce(Return());
|
EXPECT_CALL(mock_memory, PushByte(0x80)).WillOnce(Return());
|
||||||
cpu_.PHP();
|
cpu.PHP();
|
||||||
|
|
||||||
// Clear status flags
|
// Clear status flags
|
||||||
cpu_.SetNegativeFlag(false);
|
cpu.SetNegativeFlag(false);
|
||||||
cpu_.SetZeroFlag(true);
|
cpu.SetZeroFlag(true);
|
||||||
EXPECT_FALSE(cpu_.GetNegativeFlag());
|
EXPECT_FALSE(cpu.GetNegativeFlag());
|
||||||
EXPECT_TRUE(cpu_.GetZeroFlag());
|
EXPECT_TRUE(cpu.GetZeroFlag());
|
||||||
|
|
||||||
EXPECT_CALL(memory_, PopByte()).WillOnce(Return(0x80));
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x80));
|
||||||
cpu_.PLP();
|
cpu.PLP();
|
||||||
|
|
||||||
EXPECT_TRUE(cpu_.GetNegativeFlag());
|
EXPECT_TRUE(cpu.GetNegativeFlag());
|
||||||
EXPECT_FALSE(cpu_.GetZeroFlag());
|
EXPECT_FALSE(cpu.GetZeroFlag());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// PHA, PHP, PHX, PHY, PHB, PHD, PHK
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHA_PushAccumulator) {
|
||||||
|
cpu.A = 0x12;
|
||||||
|
EXPECT_CALL(mock_memory, PushByte(0x12));
|
||||||
|
cpu.ExecuteInstruction(0x48); // PHA
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHP_PushProcessorStatusRegister) {
|
||||||
|
cpu.status = 0x34;
|
||||||
|
EXPECT_CALL(mock_memory, PushByte(0x34));
|
||||||
|
cpu.ExecuteInstruction(0x08); // PHP
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHX_PushXRegister) {
|
||||||
|
cpu.X = 0x56;
|
||||||
|
EXPECT_CALL(mock_memory, PushByte(0x56));
|
||||||
|
cpu.ExecuteInstruction(0xDA); // PHX
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHY_PushYRegister) {
|
||||||
|
cpu.Y = 0x78;
|
||||||
|
EXPECT_CALL(mock_memory, PushByte(0x78));
|
||||||
|
cpu.ExecuteInstruction(0x5A); // PHY
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHB_PushDataBankRegister) {
|
||||||
|
cpu.DB = 0x9A;
|
||||||
|
EXPECT_CALL(mock_memory, PushByte(0x9A));
|
||||||
|
cpu.ExecuteInstruction(0x8B); // PHB
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHD_PushDirectPageRegister) {
|
||||||
|
cpu.D = 0xBC;
|
||||||
|
EXPECT_CALL(mock_memory, PushWord(0xBC));
|
||||||
|
cpu.ExecuteInstruction(0x0B); // PHD
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PHK_PushProgramBankRegister) {
|
||||||
|
cpu.PB = 0xDE;
|
||||||
|
EXPECT_CALL(mock_memory, PushByte(0xDE));
|
||||||
|
cpu.ExecuteInstruction(0x4B); // PHK
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// PLA, PLP, PLX, PLY, PLB, PLD
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PLA_PullAccumulator) {
|
||||||
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x12));
|
||||||
|
cpu.ExecuteInstruction(0x68); // PLA
|
||||||
|
EXPECT_EQ(cpu.A, 0x12);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PLP_PullProcessorStatusRegister) {
|
||||||
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x34));
|
||||||
|
cpu.ExecuteInstruction(0x28); // PLP
|
||||||
|
EXPECT_EQ(cpu.status, 0x34);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PLX_PullXRegister) {
|
||||||
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x56));
|
||||||
|
cpu.ExecuteInstruction(0xFA); // PLX
|
||||||
|
EXPECT_EQ(cpu.X, 0x56);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PLY_PullYRegister) {
|
||||||
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x78));
|
||||||
|
cpu.ExecuteInstruction(0x7A); // PLY
|
||||||
|
EXPECT_EQ(cpu.Y, 0x78);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PLB_PullDataBankRegister) {
|
||||||
|
EXPECT_CALL(mock_memory, PopByte()).WillOnce(Return(0x9A));
|
||||||
|
cpu.ExecuteInstruction(0xAB); // PLB
|
||||||
|
EXPECT_EQ(cpu.DB, 0x9A);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CPUTest, PLD_PullDirectPageRegister) {
|
||||||
|
EXPECT_CALL(mock_memory, PopWord()).WillOnce(Return(0xBC));
|
||||||
|
cpu.ExecuteInstruction(0x2B); // PLD
|
||||||
|
EXPECT_EQ(cpu.D, 0xBC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// REP - Reset Processor Status Bits
|
// REP - Reset Processor Status Bits
|
||||||
|
|
||||||
TEST(CPUTest, REP) {
|
TEST_F(CPUTest, REP) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.status = 0xFF; // All flags set
|
cpu.status = 0xFF; // All flags set
|
||||||
std::vector<uint8_t> data = {0xC2, 0x30,
|
std::vector<uint8_t> data = {0xC2, 0x30,
|
||||||
0x00}; // REP #0x30 (clear N & Z flags)
|
0x00}; // REP #0x30 (clear N & Z flags)
|
||||||
@@ -386,9 +449,7 @@ TEST(CPUTest, REP) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// SEP - Set Processor Status Bits
|
// SEP - Set Processor Status Bits
|
||||||
|
|
||||||
TEST(CPUTest, SEP) {
|
TEST_F(CPUTest, SEP) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.status = 0x00; // All flags cleared
|
cpu.status = 0x00; // All flags cleared
|
||||||
std::vector<uint8_t> data = {0xE2, 0x30,
|
std::vector<uint8_t> data = {0xE2, 0x30,
|
||||||
0x00}; // SEP #0x30 (set N & Z flags)
|
0x00}; // SEP #0x30 (set N & Z flags)
|
||||||
@@ -401,9 +462,7 @@ TEST(CPUTest, SEP) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// TXA - Transfer Index X to Accumulator
|
// TXA - Transfer Index X to Accumulator
|
||||||
|
|
||||||
TEST(CPUTest, TXA) {
|
TEST_F(CPUTest, TXA) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.X = 0xAB; // X register
|
cpu.X = 0xAB; // X register
|
||||||
std::vector<uint8_t> data = {0x8A}; // TXA
|
std::vector<uint8_t> data = {0x8A}; // TXA
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
@@ -415,9 +474,7 @@ TEST(CPUTest, TXA) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// TAX - Transfer Accumulator to Index X
|
// TAX - Transfer Accumulator to Index X
|
||||||
|
|
||||||
TEST(CPUTest, TAX) {
|
TEST_F(CPUTest, TAX) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0xBC; // A register
|
cpu.A = 0xBC; // A register
|
||||||
std::vector<uint8_t> data = {0xAA}; // TAX
|
std::vector<uint8_t> data = {0xAA}; // TAX
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
@@ -429,9 +486,7 @@ TEST(CPUTest, TAX) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// TYA - Transfer Index Y to Accumulator
|
// TYA - Transfer Index Y to Accumulator
|
||||||
|
|
||||||
TEST(CPUTest, TYA) {
|
TEST_F(CPUTest, TYA) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.Y = 0xCD; // Y register
|
cpu.Y = 0xCD; // Y register
|
||||||
std::vector<uint8_t> data = {0x98}; // TYA
|
std::vector<uint8_t> data = {0x98}; // TYA
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
@@ -443,9 +498,7 @@ TEST(CPUTest, TYA) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// TAY - Transfer Accumulator to Index Y
|
// TAY - Transfer Accumulator to Index Y
|
||||||
|
|
||||||
TEST(CPUTest, TAY) {
|
TEST_F(CPUTest, TAY) {
|
||||||
MockMemory mock_memory;
|
|
||||||
CPU cpu(mock_memory);
|
|
||||||
cpu.A = 0xDE; // A register
|
cpu.A = 0xDE; // A register
|
||||||
std::vector<uint8_t> data = {0xA8}; // TAY
|
std::vector<uint8_t> data = {0xA8}; // TAY
|
||||||
mock_memory.SetMemoryContents(data);
|
mock_memory.SetMemoryContents(data);
|
||||||
|
|||||||
Reference in New Issue
Block a user