mirror of
https://github.com/zoriya/ComSquare.git
synced 2025-12-20 14:15:11 +00:00
Adding Multiplication Division Operations
This commit is contained in:
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
35
sources/APU/Instructions/MultiplicationDivision.cpp
Normal file
35
sources/APU/Instructions/MultiplicationDivision.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user