Adding Multiplication Division Operations

This commit is contained in:
Melefo
2020-02-25 11:48:48 +01:00
parent c84bdd8be4
commit a0f53ebd70
5 changed files with 84 additions and 4 deletions

View File

@@ -77,7 +77,7 @@ add_executable(unit_tests
sources/APU/Instructions/ProgramFlow.cpp sources/APU/Instructions/ProgramFlow.cpp
sources/APU/Operand.cpp sources/APU/Operand.cpp
sources/APU/Instructions/DecimalCompensation.cpp; sources/APU/Instructions/DecimalCompensation.cpp;
) sources/APU/Instructions/MultiplicationDivision.cpp)
# include criterion & coverage # include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov) target_link_libraries(unit_tests criterion -lgcov)
@@ -165,7 +165,7 @@ add_executable(ComSquare
sources/APU/Instructions/ProgramFlow.cpp sources/APU/Instructions/ProgramFlow.cpp
sources/APU/Operand.cpp sources/APU/Operand.cpp
sources/APU/Instructions/DecimalCompensation.cpp sources/APU/Instructions/DecimalCompensation.cpp
) sources/APU/Instructions/MultiplicationDivision.cpp)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED) target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)

View File

@@ -284,6 +284,8 @@ namespace ComSquare::APU
return this->CLR1(this->_getDirectAddr(), 4); return this->CLR1(this->_getDirectAddr(), 4);
case 0x93: case 0x93:
return this->BBC(this->_getDirectAddr(), 4); return this->BBC(this->_getDirectAddr(), 4);
case 0x9E:
return this->DIV();
case 0xA0: case 0xA0:
return this->EI(); return this->EI();
case 0xA1: case 0xA1:
@@ -318,6 +320,8 @@ namespace ComSquare::APU
return this->MOV1(this->_getAbsoluteBit()); return this->MOV1(this->_getAbsoluteBit());
case 0xCE: case 0xCE:
return this->POP(this->_internalRegisters.x); return this->POP(this->_internalRegisters.x);
case 0xCF:
return this->MUL();
case 0xD0: case 0xD0:
return this->BNE(); return this->BNE();
case 0xD1: case 0xD1:

View File

@@ -268,10 +268,15 @@ namespace ComSquare::APU
//! @brief Jump to the specified location. //! @brief Jump to the specified location.
int JMP(uint24_t addr, bool by_x = false); int JMP(uint24_t addr, bool by_x = false);
//! @brief Decimal adjusts A for addition. //! @brief Decimal adjust A for addition.
int DAA(); int DAA();
//! @brief Decimal adjusts A for subtraction. //! @brief Decimal adjust A for subtraction.
int DAS(); int DAS();
//! @brief Store the 16-bit value of Y * A into YA
int MUL();
//! @brief Divide the 16-bit value YA by X, storing the quotient in A and the remainder in Y.
int DIV();
public: public:
explicit APU(std::shared_ptr<MemoryMap> &map); explicit APU(std::shared_ptr<MemoryMap> &map);
APU(const APU &) = default; APU(const APU &) = default;

View File

@@ -0,0 +1,35 @@
//
// Created by Melefo on 25/02/2020.
//
#include "../APU.hpp"
namespace ComSquare::APU
{
int APU::MUL()
{
this->_internalRegisters.ya = this->_internalRegisters.y * this->_internalRegisters.a;
this->_internalRegisters.n = this->_internalRegisters.a & 0x80u;
this->_internalRegisters.z = !this->_internalRegisters.y;
return 9;
}
int APU::DIV()
{
uint16_t ya = this->_internalRegisters.ya;
this->_internalRegisters.v = this->_internalRegisters.y >= this->_internalRegisters.x;
this->_internalRegisters.h = (this->_internalRegisters.y & 0x0Fu) >= (this->_internalRegisters.x & 0x0Fu);
if (this->_internalRegisters.y < (this->_internalRegisters.x << 1u)) {
this->_internalRegisters.a = ya / this->_internalRegisters.x;
this->_internalRegisters.y = ya % this->_internalRegisters.x;
}
else {
this->_internalRegisters.a = 0xFF - (ya - (this->_internalRegisters.x << 9u)) / (0x100 - this->_internalRegisters.x);
this->_internalRegisters.y = this->_internalRegisters.x + (ya - (this->_internalRegisters.x << 9u)) % (0x100 - this->_internalRegisters.x);
}
this->_internalRegisters.z = !this->_internalRegisters.a;
this->_internalRegisters.n = this->_internalRegisters.a & 0x80u;
return 12;
}
}

View File

@@ -732,4 +732,40 @@ Test(DecimalCompensation, DAS)
cr_assert_eq(apu->_internalRegisters.a, 0x99); cr_assert_eq(apu->_internalRegisters.a, 0x99);
cr_assert_eq(apu->_internalRegisters.n, true); cr_assert_eq(apu->_internalRegisters.n, true);
cr_assert_eq(apu->_internalRegisters.z, false); cr_assert_eq(apu->_internalRegisters.z, false);
}
///////////////////////////////////
// //
// Multiplication Division tests //
// //
///////////////////////////////////
Test(MultiplicationDivision, MUL)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalRegisters.a = 10;
apu->_internalRegisters.y = 23;
result = apu->MUL();
cr_assert_eq(result, 9);
cr_assert_eq(apu->_internalRegisters.ya, 230);
}
Test(MultiplicationDivision, DIV)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalRegisters.ya = 235;
apu->_internalRegisters.x = 10;
result = apu->DIV();
cr_assert_eq(result, 12);
cr_assert_eq(apu->_internalRegisters.y, 5);
cr_assert_eq(apu->_internalRegisters.a, 23);
apu->_internalRegisters.ya = 12345;
apu->_internalRegisters.x = 2;
result = apu->DIV();
cr_assert_eq(apu->_internalRegisters.y, 147);
cr_assert_eq(apu->_internalRegisters.a, 211);
} }