Adding some Program Flow operations

This commit is contained in:
Melefo
2020-02-21 15:50:23 +01:00
parent b1fc2754eb
commit 21aa68a623
5 changed files with 261 additions and 0 deletions
+2
View File
@@ -73,6 +73,7 @@ add_executable(unit_tests
sources/APU/Instructions/Bit.cpp
sources/APU/Instructions/Stack.cpp
sources/APU/Instructions/Subroutine.cpp
sources/APU/Instructions/ProgramFlow.cpp
)
# include criterion & coverage
@@ -158,6 +159,7 @@ add_executable(ComSquare
sources/Debugger/APUDebug.cpp
sources/APU/Instructions/Stack.cpp
sources/APU/Instructions/Subroutine.cpp
sources/APU/Instructions/ProgramFlow.cpp
)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
+18
View File
@@ -174,6 +174,8 @@ namespace ComSquare::APU
return this->TSET1(this->_getAbsoluteAddr());
case 0x0F:
return this->BRK();
case 0x10:
return this->BPL();
case 0x11:
return this->TCALL(1);
case 0x12:
@@ -188,6 +190,10 @@ namespace ComSquare::APU
return this->OR1(this->_getAbsoluteBit(), true);
case 0x2D:
return this->PUSH(this->_internalRegisters.a);
case 0x2F:
return this->BRA();
case 0x30:
return this->BMI();
case 0x31:
return this->TCALL(3);
case 0x32:
@@ -208,6 +214,8 @@ namespace ComSquare::APU
return this->TCLR1(this->_getAbsoluteAddr());
case 0x4F:
return this->PCALL();
case 0x50:
return this->BVC();
case 0x51:
return this->TCALL(5);
case 0x52:
@@ -224,6 +232,8 @@ namespace ComSquare::APU
return this->PUSH(this->_internalRegisters.y);
case 0x6F:
return this->RET();
case 0x70:
return this->BVS();
case 0x71:
return this->TCALL(7);
case 0x72:
@@ -240,6 +250,8 @@ namespace ComSquare::APU
return this->EOR1(this->_getAbsoluteBit());
case 0x8E:
return this->POP(this->_internalRegisters.psw);
case 0x90:
return this->BCC();
case 0x91:
return this->TCALL(9);
case 0x92:
@@ -254,6 +266,8 @@ namespace ComSquare::APU
return this->MOV1(this->_getAbsoluteBit(), true);
case 0xAE:
return this->POP(this->_internalRegisters.a);
case 0xB0:
return this->BCS();
case 0xB1:
return this->TCALL(11);
case 0xB2:
@@ -268,6 +282,8 @@ namespace ComSquare::APU
return this->MOV1(this->_getAbsoluteBit());
case 0xCE:
return this->POP(this->_internalRegisters.x);
case 0xD0:
return this->BNE();
case 0xD1:
return this->TCALL(13);
case 0xD2:
@@ -278,6 +294,8 @@ namespace ComSquare::APU
return this->SET1(this->_getDirectAddr(), 7);
case 0xEE:
return this->POP(this->_internalRegisters.y);
case 0xF0:
return BEQ();
case 0xF1:
return this->TCALL(15);
case 0xF2:
+19
View File
@@ -232,6 +232,25 @@ namespace ComSquare::APU
int RET();
//! @brief Return from interrupt.
int RETI();
//! @brief Branch Always, go to the specified location from the next instruction.
int BRA();
//! @brief Branch if Zero Flag is set
int BEQ();
//! @brief Branch if Zero Flag is clear
int BNE();
//! @brief Branch if Carry Flag is set
int BCS();
//! @brief Branch if Carry Flag is clear
int BCC();
//! @brief Branch if Overflow Flag is set
int BVS();
//! @brief Branch if Overflow Flag is set
int BVC();
//! @brief Branch if Negative Flag is set
int BMI();
//! @brief Branch if Negative Flag is clear
int BPL();
public:
explicit APU(std::shared_ptr<MemoryMap> &map);
APU(const APU &) = default;
+80
View File
@@ -0,0 +1,80 @@
//
// Created by Melefo on 21/02/2020.
//
#include "../APU.hpp"
namespace ComSquare::APU
{
int APU::BRA()
{
int8_t offset = this->_internalRead(this->_internalRegisters.pc++);
this->_internalRegisters.pc += offset;
return 4;
}
int APU::BEQ()
{
if (!this->_internalRegisters.z)
return 2;
this->BRA();
return 4;
}
int APU::BNE()
{
if (this->_internalRegisters.z)
return 2;
this->BRA();
return 4;
}
int APU::BCS()
{
if (!this->_internalRegisters.c)
return 2;
this->BRA();
return 4;
}
int APU::BCC()
{
if (this->_internalRegisters.c)
return 2;
this->BRA();
return 4;
}
int APU::BVS()
{
if (!this->_internalRegisters.v)
return 2;
this->BRA();
return 4;
}
int APU::BVC()
{
if (this->_internalRegisters.v)
return 2;
this->BRA();
return 4;
}
int APU::BMI()
{
if (!this->_internalRegisters.n)
return 2;
this->BRA();
return 4;
}
int APU::BPL()
{
if (this->_internalRegisters.n)
return 2;
this->BRA();
return 4;
}
}
+142
View File
@@ -464,4 +464,146 @@ Test(Subroutine, RETI)
cr_assert_eq(apu->_internalRegisters.psw, 0x12);
cr_assert_eq(apu->_internalRegisters.pch, 0x34);
cr_assert_eq(apu->_internalRegisters.pcl, 0x56);
}
/////////////////////////////
// //
// Subroutine Program Flow //
// //
/////////////////////////////
Test(ProgramFlow, BRA)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
result = apu->BRA();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BEQ)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
result = apu->BEQ();
cr_assert_eq(result, 2);
apu->_internalRegisters.z = true;
result = apu->BEQ();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BNE)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
apu->_internalRegisters.z = true;
result = apu->BNE();
cr_assert_eq(result, 2);
apu->_internalRegisters.z = false;
result = apu->BNE();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BCS)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
result = apu->BCS();
cr_assert_eq(result, 2);
apu->_internalRegisters.c = true;
result = apu->BCS();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BCC)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
apu->_internalRegisters.c = true;
result = apu->BCC();
cr_assert_eq(result, 2);
apu->_internalRegisters.c = false;
result = apu->BCC();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BVS)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
result = apu->BVS();
cr_assert_eq(result, 2);
apu->_internalRegisters.v = true;
result = apu->BVS();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BVC)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
apu->_internalRegisters.v = true;
result = apu->BVC();
cr_assert_eq(result, 2);
apu->_internalRegisters.v = false;
result = apu->BVC();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BMI)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
result = apu->BMI();
cr_assert_eq(result, 2);
apu->_internalRegisters.n = true;
result = apu->BMI();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}
Test(ProgramFlow, BPL)
{
auto apu = Init().second.apu;
int result = 0;
apu->_internalWrite(apu->_internalRegisters.pc, 23);
apu->_internalWrite(apu->_internalRegisters.pc + 24, 101);
apu->_internalRegisters.n = true;
result = apu->BPL();
cr_assert_eq(result, 2);
apu->_internalRegisters.n = false;
result = apu->BPL();
cr_assert_eq(result, 4);
cr_assert_eq(apu->_internalRead(apu->_internalRegisters.pc), 101);
}