Adding Decimal Compensation Operations

This commit is contained in:
Melefo
2020-02-25 10:59:59 +01:00
parent e9a7b9e8d7
commit c84bdd8be4
5 changed files with 94 additions and 8 deletions

View File

@@ -69,12 +69,15 @@ add_executable(unit_tests
tests/CPU/testInternal.cpp
sources/Ram/ExtendedRam.cpp
sources/Ram/ExtendedRam.hpp
sources/Utility/Utility.hpp sources/Utility/Utility.cpp
sources/Utility/Utility.hpp
sources/Utility/Utility.cpp
sources/APU/Instructions/Bit.cpp
sources/APU/Instructions/Stack.cpp
sources/APU/Instructions/Subroutine.cpp
sources/APU/Instructions/ProgramFlow.cpp
sources/APU/Operand.cpp)
sources/APU/Operand.cpp
sources/APU/Instructions/DecimalCompensation.cpp;
)
# include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov)
@@ -160,7 +163,9 @@ add_executable(ComSquare
sources/APU/Instructions/Stack.cpp
sources/APU/Instructions/Subroutine.cpp
sources/APU/Instructions/ProgramFlow.cpp
sources/APU/Operand.cpp)
sources/APU/Operand.cpp
sources/APU/Instructions/DecimalCompensation.cpp
)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)

View File

@@ -304,6 +304,8 @@ namespace ComSquare::APU
return this->CLR1(this->_getDirectAddr(), 5);
case 0xB3:
return this->BBC(this->_getDirectAddr(), 5);
case 0xBE:
return this->DAS();
case 0xC0:
return this->DI();
case 0xC1:
@@ -326,6 +328,8 @@ namespace ComSquare::APU
return this->BBC(this->_getDirectAddr(), 6);
case 0xDE:
return this->CBNE(this->_getDirectAddrByX(), true);
case 0xDF:
return this->DAA();
case 0xE1:
return this->TCALL(14);
case 0xE2:

View File

@@ -267,6 +267,11 @@ namespace ComSquare::APU
int DBNZ(bool direct_addr = false);
//! @brief Jump to the specified location.
int JMP(uint24_t addr, bool by_x = false);
//! @brief Decimal adjusts A for addition.
int DAA();
//! @brief Decimal adjusts A for subtraction.
int DAS();
public:
explicit APU(std::shared_ptr<MemoryMap> &map);
APU(const APU &) = default;

View File

@@ -0,0 +1,36 @@
//
// Created by Melefo on 25/02/2020.
//
#include "../APU.hpp"
namespace ComSquare::APU
{
int APU::DAA()
{
if (this->_internalRegisters.c || this->_internalRegisters.a > 0x99) {
this->_internalRegisters.c = true;
this->_internalRegisters.a += 0x60;
}
if (this->_internalRegisters.h || (this->_internalRegisters.a & 0x0Fu) > 0x09) {
this->_internalRegisters.a += 0x06;
}
this->_internalRegisters.n = this->_internalRegisters.a & 0x80u;
this->_internalRegisters.z = !this->_internalRegisters.a;
return 3;
}
int APU::DAS()
{
if (!this->_internalRegisters.c || this->_internalRegisters.a > 0x99) {
this->_internalRegisters.c = false;
this->_internalRegisters.a -= 0x60;
}
if (!this->_internalRegisters.h || (this->_internalRegisters.a & 0x0Fu) > 0x09) {
this->_internalRegisters.a -= 0x06;
}
this->_internalRegisters.n = this->_internalRegisters.a & 0x80u;
this->_internalRegisters.z = !this->_internalRegisters.a;
return 3;
}
}

View File

@@ -466,11 +466,11 @@ Test(Subroutine, RETI)
cr_assert_eq(apu->_internalRegisters.pcl, 0x56);
}
/////////////////////////////
// //
// Subroutine Program Flow //
// //
/////////////////////////////
////////////////////////
// //
// Program Flow tests //
// //
////////////////////////
Test(ProgramFlow, BRA)
{
@@ -696,4 +696,40 @@ Test(ProgramFlow, JMP)
result = apu->JMP(apu->_getAbsoluteAddrByX(), true);
cr_assert_eq(result, 6);
cr_assert_eq(apu->_internalRegisters.pc, 61712);
}
////////////////////////////////
// //
// Decimal Compensation tests //
// //
////////////////////////////////
Test(DecimalCompensation, DAA)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalRegisters.c = true;
apu->_internalRegisters.h = true;
apu->_internalRegisters.a = 0x1A;
result = apu->DAA();
cr_assert_eq(result, 3);
cr_assert_eq(apu->_internalRegisters.a, 0x80);
cr_assert_eq(apu->_internalRegisters.n, true);
cr_assert_eq(apu->_internalRegisters.z, false);
}
Test(DecimalCompensation, DAS)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalRegisters.c = false;
apu->_internalRegisters.h = false;
apu->_internalRegisters.a = 0xFF;
result = apu->DAS();
cr_assert_eq(result, 3);
cr_assert_eq(apu->_internalRegisters.a, 0x99);
cr_assert_eq(apu->_internalRegisters.n, true);
cr_assert_eq(apu->_internalRegisters.z, false);
}