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