mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-26 15:59:22 +00:00
Implementing some transfer registers instructions
This commit is contained in:
+2
-2
@@ -77,7 +77,7 @@ add_executable(unit_tests
|
||||
sources/APU/Instructions/Stack.cpp
|
||||
sources/APU/Instructions/Subroutine.cpp
|
||||
sources/APU/Instructions/ProgramFlow.cpp
|
||||
tests/CPU/Math/testSBC.cpp)
|
||||
tests/CPU/Math/testSBC.cpp sources/CPU/Instructions/TransferRegisters.cpp tests/CPU/TransferRegisters.cpp)
|
||||
|
||||
# include criterion & coverage
|
||||
target_link_libraries(unit_tests criterion -lgcov)
|
||||
@@ -166,7 +166,7 @@ add_executable(ComSquare
|
||||
sources/APU/Instructions/Stack.cpp
|
||||
sources/APU/Instructions/Subroutine.cpp
|
||||
sources/APU/Instructions/ProgramFlow.cpp
|
||||
)
|
||||
sources/CPU/Instructions/TransferRegisters.cpp)
|
||||
|
||||
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
|
||||
|
||||
|
||||
@@ -344,6 +344,10 @@ namespace ComSquare::CPU
|
||||
case Instructions::SBC_SR: this->SBC(this->_getStackRelativeAddr()); return 4 + !this->_registers.p.m;
|
||||
case Instructions::SBC_SRYi: this->SBC(this->_getStackRelativeIndirectIndexedYAddr()); return 7 + !this->_registers.p.m;
|
||||
|
||||
case Instructions::TAX: this->TAX(); return 2;
|
||||
case Instructions::TAY: this->TAY(); return 2;
|
||||
case Instructions::TXS: this->TXS(); return 2;
|
||||
|
||||
default:
|
||||
throw InvalidOpcode("CPU", opcode);
|
||||
}
|
||||
|
||||
@@ -327,6 +327,10 @@ namespace ComSquare::CPU
|
||||
SBC_DPYil = 0xF7,
|
||||
SBC_SR = 0xE3,
|
||||
SBC_SRYi = 0xF3,
|
||||
|
||||
TAX = 0xAA,
|
||||
TAY = 0xA8,
|
||||
TXS = 0x9A
|
||||
};
|
||||
|
||||
//! @brief The main CPU
|
||||
@@ -478,6 +482,12 @@ namespace ComSquare::CPU
|
||||
void AND(uint24_t valueAddr);
|
||||
//! @brief Subtract with Borrow from Accumulator.
|
||||
void SBC(uint24_t valueAddr);
|
||||
//! @brief Transfer A to X
|
||||
void TAX();
|
||||
//! @brief Transfer A to Y
|
||||
void TAY();
|
||||
//! @brief Transfer X to SP
|
||||
void TXS();
|
||||
public:
|
||||
explicit CPU(std::shared_ptr<Memory::MemoryBus> bus, Cartridge::Header &cartridgeHeader);
|
||||
CPU(const CPU &) = default;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Created by anonymus-raccoon on 2/28/20.
|
||||
//
|
||||
|
||||
#include "../CPU.hpp"
|
||||
|
||||
namespace ComSquare::CPU
|
||||
{
|
||||
void CPU::TAX()
|
||||
{
|
||||
if (this->_registers.p.x_b) {
|
||||
this->_registers.xl = this->_registers.al;
|
||||
this->_registers.p.z = this->_registers.xl == 0;
|
||||
this->_registers.p.n = this->_registers.x & 0x80u;
|
||||
} else {
|
||||
this->_registers.x = this->_registers.a;
|
||||
this->_registers.p.z = this->_registers.x == 0;
|
||||
this->_registers.p.n = this->_registers.x & 0x8000u;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::TAY()
|
||||
{
|
||||
if (this->_registers.p.x_b) {
|
||||
this->_registers.yl = this->_registers.al;
|
||||
this->_registers.p.z = this->_registers.yl == 0;
|
||||
this->_registers.p.n = this->_registers.y & 0x80u;
|
||||
} else {
|
||||
this->_registers.y = this->_registers.a;
|
||||
this->_registers.p.z = this->_registers.y == 0;
|
||||
this->_registers.p.n = this->_registers.y & 0x8000u;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::TXS()
|
||||
{
|
||||
if (this->_registers.p.x_b) {
|
||||
this->_registers.sh = 0;
|
||||
this->_registers.sl = this->_registers.xl;
|
||||
this->_registers.p.z = this->_registers.sl == 0;
|
||||
this->_registers.p.n = this->_registers.s & 0x80u;
|
||||
} else {
|
||||
this->_registers.s = this->_registers.x;
|
||||
this->_registers.p.z = this->_registers.s == 0;
|
||||
this->_registers.p.n = this->_registers.s & 0x8000u;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,6 +292,10 @@ namespace ComSquare::Debugger
|
||||
case Instructions::SBC_SR: return "SBC";
|
||||
case Instructions::SBC_SRYi: return "SBC";
|
||||
|
||||
case Instructions::TAX: return "TAX";
|
||||
case Instructions::TAY: return "TAY";
|
||||
case Instructions::TXS: return "TXS";
|
||||
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// Created by anonymus-raccoon on 2/28/20.
|
||||
//
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
#include "../tests.hpp"
|
||||
#include "../../sources/SNES.hpp"
|
||||
using namespace ComSquare;
|
||||
|
||||
Test(TAX, 16bitsTo16Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = false;
|
||||
pair.second.cpu->_registers.p.m = false;
|
||||
pair.second.cpu->_registers.x = 0xABCD;
|
||||
pair.second.cpu->_registers.a = 0xFEDC;
|
||||
pair.second.cpu->TAX();
|
||||
cr_assert_eq(pair.second.cpu->_registers.x, 0xFEDC, "The flags should be 0xFEDC but it was %x", pair.second.cpu->_registers.x);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.");
|
||||
}
|
||||
|
||||
Test(TAX, 16bitsTo8Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = true;
|
||||
pair.second.cpu->_registers.p.m = false;
|
||||
pair.second.cpu->_registers.x = 0xFEDC;
|
||||
pair.second.cpu->_registers.a = 0xAB00;
|
||||
pair.second.cpu->TAX();
|
||||
cr_assert_eq(pair.second.cpu->_registers.x, 0xFE00, "The flags should be 0xFE00 but it was %x", pair.second.cpu->_registers.x);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag should be set.");
|
||||
}
|
||||
|
||||
Test(TAX, 8bitsTo16Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = false;
|
||||
pair.second.cpu->_registers.p.m = true;
|
||||
pair.second.cpu->_registers.x = 0xFEDC;
|
||||
pair.second.cpu->_registers.a = 0xAB;
|
||||
pair.second.cpu->TAX();
|
||||
cr_assert_eq(pair.second.cpu->_registers.x, 0x00AB, "The flags should be 0x00AB but it was %x", pair.second.cpu->_registers.x);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.");
|
||||
}
|
||||
|
||||
Test(TAX, 8bitsTo8Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = true;
|
||||
pair.second.cpu->_registers.p.m = true;
|
||||
pair.second.cpu->_registers.x = 0xFE;
|
||||
pair.second.cpu->_registers.a = 0xAB;
|
||||
pair.second.cpu->TAX();
|
||||
cr_assert_eq(pair.second.cpu->_registers.x, 0xAB, "The flags should be 0xAB but it was %x", pair.second.cpu->_registers.x);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should be not set.");
|
||||
}
|
||||
|
||||
|
||||
Test(TAY, 16bitsTo16Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = false;
|
||||
pair.second.cpu->_registers.p.m = false;
|
||||
pair.second.cpu->_registers.y = 0xABCD;
|
||||
pair.second.cpu->_registers.a = 0xFEDC;
|
||||
pair.second.cpu->TAY();
|
||||
cr_assert_eq(pair.second.cpu->_registers.y, 0xFEDC, "The y register should be 0xFEDC but it was %x", pair.second.cpu->_registers.y);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.");
|
||||
}
|
||||
|
||||
Test(TAY, 16bitsTo8Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = true;
|
||||
pair.second.cpu->_registers.p.m = false;
|
||||
pair.second.cpu->_registers.y = 0xFEDC;
|
||||
pair.second.cpu->_registers.a = 0xAB00;
|
||||
pair.second.cpu->TAY();
|
||||
cr_assert_eq(pair.second.cpu->_registers.y, 0xFE00, "The y register should be 0xFE00 but it was %x", pair.second.cpu->_registers.y);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag should be set.");
|
||||
}
|
||||
|
||||
Test(TAY, 8bitsTo16Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = false;
|
||||
pair.second.cpu->_registers.p.m = true;
|
||||
pair.second.cpu->_registers.y = 0xFEDC;
|
||||
pair.second.cpu->_registers.a = 0xAB;
|
||||
pair.second.cpu->TAY();
|
||||
cr_assert_eq(pair.second.cpu->_registers.y, 0x00AB, "The y register should be 0x00AB but it was %x", pair.second.cpu->_registers.y);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag should not be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set.");
|
||||
}
|
||||
|
||||
Test(TAY, 8bitsTo8Bits)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = true;
|
||||
pair.second.cpu->_registers.p.m = true;
|
||||
pair.second.cpu->_registers.y = 0xFE;
|
||||
pair.second.cpu->_registers.a = 0xAB;
|
||||
pair.second.cpu->TAY();
|
||||
cr_assert_eq(pair.second.cpu->_registers.y, 0xAB, "The y register should be 0xAB but it was %x", pair.second.cpu->_registers.y);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should be not set.");
|
||||
}
|
||||
|
||||
Test(TXS, 16bitsIndex)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = false;
|
||||
pair.second.cpu->_registers.x = 0xABCD;
|
||||
pair.second.cpu->TXS();
|
||||
cr_assert_eq(pair.second.cpu->_registers.s, 0xABCD, "The stack pointer should be 0xABCD but it was %x", pair.second.cpu->_registers.s);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should be not set.");
|
||||
}
|
||||
|
||||
Test(TXS, 8bitsIndex)
|
||||
{
|
||||
auto pair = Init();
|
||||
pair.second.cpu->_isEmulationMode = false;
|
||||
pair.second.cpu->_registers.p.x_b = true;
|
||||
pair.second.cpu->_registers.x = 0xABCD;
|
||||
pair.second.cpu->TXS();
|
||||
cr_assert_eq(pair.second.cpu->_registers.s, 0x00CD, "The stack pointer should be 0x00CD but it was %x", pair.second.cpu->_registers.s);
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set.");
|
||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should be not set.");
|
||||
}
|
||||
Reference in New Issue
Block a user