From ad11210771d7d364e3fe5d58fa41eb584fde4e66 Mon Sep 17 00:00:00 2001
From: AnonymusRaccoon
Date: Fri, 14 Feb 2020 15:49:46 +0100
Subject: [PATCH] Implementing Pull from stack
---
sources/CPU/CPU.cpp | 7 +
sources/CPU/CPU.hpp | 10 +-
.../CPU/Instructions/InternalInstruction.cpp | 27 ++-
tests/CPU/testInternal.cpp | 189 ++++++++++++++++++
4 files changed, 221 insertions(+), 12 deletions(-)
diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp
index 3c438e1..b71549d 100644
--- a/sources/CPU/CPU.cpp
+++ b/sources/CPU/CPU.cpp
@@ -289,6 +289,13 @@ namespace ComSquare::CPU
case Instructions::PHX: this->PHX(); return 3 + !this->_registers.p.x_b;
case Instructions::PHY: this->PHY(); return 3 + !this->_registers.p.x_b;
+ case Instructions::PLA: this->PLA(); return 4 + !this->_registers.p.m;
+ case Instructions::PLB: this->PLB(); return 4;
+ case Instructions::PLD: this->PLD(); return 5;
+ case Instructions::PLP: this->PLP(); return 4;
+ case Instructions::PLX: this->PLX(); return 4 + !this->_registers.p.x_b;
+ case Instructions::PLY: this->PLY(); return 4 + !this->_registers.p.x_b;
+
case Instructions::JSR_ABS: this->JSR(this->_getAbsoluteAddr()); return 6;
case Instructions::JSR_ABSXi: this->JSR(this->_getAbsoluteIndirectIndexedByXAddr()); return 8;
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index 4953bb4..e992b33 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -272,8 +272,16 @@ namespace ComSquare::CPU
PHX = 0xDA,
PHY = 0x5A,
+ PLA = 0x68,
+ PLB = 0xAB,
+ PLD = 0x2B,
+ PLP = 0x28,
+ PLX = 0xFA,
+ PLY = 0x7A,
+
JSR_ABS = 0x20,
JSR_ABSXi = 0xFC,
+
JSL = 0x22
};
@@ -401,8 +409,6 @@ namespace ComSquare::CPU
void PLB();
//! @brief Pull the direct page register to the stack.
void PLD();
- //! @brief Pull the program bank register to the stack.
- void PLK();
//! @brief Pull the processor status register to the stack.
void PLP();
//! @brief Pull the x index register to the stack.
diff --git a/sources/CPU/Instructions/InternalInstruction.cpp b/sources/CPU/Instructions/InternalInstruction.cpp
index b2ba2fc..28d342a 100644
--- a/sources/CPU/Instructions/InternalInstruction.cpp
+++ b/sources/CPU/Instructions/InternalInstruction.cpp
@@ -78,31 +78,38 @@ namespace ComSquare::CPU
void CPU::PLB()
{
-
+ this->_registers.dbr = this->_pop();
+ this->_registers.p.z = this->_registers.dbr == 0;
+ this->_registers.p.n = this->_registers.dbr & 0x80u;
}
void CPU::PLD()
{
-
- }
-
- void CPU::PLK()
- {
-
+ this->_registers.d = this->_pop16();
+ this->_registers.p.z = this->_registers.d == 0;
+ this->_registers.p.n = this->_registers.d & 0x8000u;
}
void CPU::PLP()
{
-
+ this->_registers.p.flags = this->_pop();
+ if (this->_isEmulationMode) {
+ this->_registers.p.m = true;
+ this->_registers.p.x_b = true;
+ }
}
void CPU::PLX()
{
-
+ this->_registers.x = this->_pop16();
+ this->_registers.p.z = this->_registers.x == 0;
+ this->_registers.p.n = this->_registers.x & 0x8000u;
}
void CPU::PLY()
{
-
+ this->_registers.y = this->_pop16();
+ this->_registers.p.z = this->_registers.y == 0;
+ this->_registers.p.n = this->_registers.y & 0x8000u;
}
}
\ No newline at end of file
diff --git a/tests/CPU/testInternal.cpp b/tests/CPU/testInternal.cpp
index 61404a9..4098f47 100644
--- a/tests/CPU/testInternal.cpp
+++ b/tests/CPU/testInternal.cpp
@@ -216,4 +216,193 @@ Test(PLA, negative)
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag not should be set.", pair.second.cpu->_registers.p.z);
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.", pair.second.cpu->_registers.p.n);
cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLX, basic)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0xCD;
+ pair.second.wram->_data[2] = 0x7B;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLX();
+ auto data = pair.second.cpu->_registers.x;
+ cr_assert_eq(data, 0x7BCD, "The X register should be 0x7BCD but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLX, zero)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.wram->_data[2] = 0x00;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLX();
+ auto data = pair.second.cpu->_registers.x;
+ cr_assert_eq(data, 0x0000, "The x register should be 0x0000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLX, negative)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.wram->_data[2] = 0xA0;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLX();
+ auto data = pair.second.cpu->_registers.x;
+ cr_assert_eq(data, 0xA000, "The x register should be 0xA000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag not should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLY, basic)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0xCD;
+ pair.second.wram->_data[2] = 0x7B;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLY();
+ auto data = pair.second.cpu->_registers.y;
+ cr_assert_eq(data, 0x7BCD, "The Y register should be 0x7BCD but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLY, zero)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.wram->_data[2] = 0x00;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLY();
+ auto data = pair.second.cpu->_registers.y;
+ cr_assert_eq(data, 0x0000, "The y register should be 0x0000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLY, negative)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.wram->_data[2] = 0xA0;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLY();
+ auto data = pair.second.cpu->_registers.y;
+ cr_assert_eq(data, 0xA000, "The y register should be 0xA000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag not should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLD, basic)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0xCD;
+ pair.second.wram->_data[2] = 0x7B;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLD();
+ auto data = pair.second.cpu->_registers.d;
+ cr_assert_eq(data, 0x7BCD, "The D register should be 0x7BCD but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLD, zero)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.wram->_data[2] = 0x00;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLD();
+ auto data = pair.second.cpu->_registers.d;
+ cr_assert_eq(data, 0x0000, "The d register should be 0x0000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLD, negative)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.wram->_data[2] = 0xA0;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLD();
+ auto data = pair.second.cpu->_registers.d;
+ cr_assert_eq(data, 0xA000, "The D register should be 0xA000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag not should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLB, basic)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x7D;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLB();
+ auto data = pair.second.cpu->_registers.dbr;
+ cr_assert_eq(data, 0x7D, "The DBR should be 0x7D but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLB, zero)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLB();
+ auto data = pair.second.cpu->_registers.dbr;
+ cr_assert_eq(data, 0x00, "The dbr should be 0x00 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLB, negative)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0xA0;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->PLB();
+ auto data = pair.second.cpu->_registers.dbr;
+ cr_assert_eq(data, 0xA0, "The D register should be 0xA0 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag not should be set.", pair.second.cpu->_registers.p.z);
+ cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.", pair.second.cpu->_registers.p.n);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLP, basic)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x7D;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->_isEmulationMode = false;
+ pair.second.cpu->PLP();
+ auto data = pair.second.cpu->_registers.p.flags;
+ cr_assert_eq(data, 0x7D, "The flags should be 0x7D but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", pair.second.cpu->_registers.s);
+}
+
+Test(PLP, emulation)
+{
+ auto pair = Init();
+ pair.second.wram->_data[1] = 0x00;
+ pair.second.cpu->_registers.s = 0x00;
+ pair.second.cpu->_isEmulationMode = true;
+ pair.second.cpu->PLP();
+ auto data = pair.second.cpu->_registers.p.flags;
+ cr_assert_eq(data, 0b00110000, "The flags should be 0b00110000 but it was %x", data);
+ cr_assert_eq(pair.second.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", pair.second.cpu->_registers.s);
}
\ No newline at end of file