mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-25 15:39:28 +00:00
Adding 8-bit Data Transmission Operations and so every instructions are done
Forgot an instruction in _executeInstruction function
This commit is contained in:
@@ -87,6 +87,7 @@ add_executable(unit_tests
|
||||
sources/APU/Instructions/8bitLogical.cpp
|
||||
tests/APU/testOperand.cpp
|
||||
sources/APU/Instructions/8bitArithmetic.cpp
|
||||
sources/APU/Instructions/8bitDataTransmission.cpp
|
||||
)
|
||||
|
||||
# include criterion & coverage
|
||||
@@ -185,6 +186,7 @@ add_executable(ComSquare
|
||||
sources/APU/Instructions/8bitIncrementDecrement.cpp
|
||||
sources/APU/Instructions/8bitLogical.cpp
|
||||
sources/APU/Instructions/8bitArithmetic.cpp
|
||||
sources/APU/Instructions/8bitDataTransmission.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
|
||||
|
||||
+90
-6
@@ -345,6 +345,8 @@ namespace ComSquare::APU
|
||||
return this->LSR(this->_getDirectAddrByX(), 5);
|
||||
case 0x5C:
|
||||
return this->LSR(this->_internalRegisters.a, 2, true);
|
||||
case 0x5D:
|
||||
return this->MOV(this->_internalRegisters.a, this->_internalRegisters.x);
|
||||
case 0x5E:
|
||||
return this->CMPreg(this->_internalRegisters.y, this->_getAbsoluteAddr(), 4);
|
||||
case 0x5F:
|
||||
@@ -407,6 +409,8 @@ namespace ComSquare::APU
|
||||
return this->ROR(this->_getDirectAddrByX(), 5);
|
||||
case 0x7C:
|
||||
return this->ROR(this->_internalRegisters.a, 2, true);
|
||||
case 0x7D:
|
||||
return this->MOV(this->_internalRegisters.x, this->_internalRegisters.a);
|
||||
case 0x7E:
|
||||
return this->CMPreg(this->_internalRegisters.y, this->_getDirectAddr(), 3);
|
||||
case 0x7F:
|
||||
@@ -437,8 +441,12 @@ namespace ComSquare::APU
|
||||
return this->DEC(this->_getDirectAddr(), 4);
|
||||
case 0x8C:
|
||||
return this->DEC(this->_getAbsoluteAddr(), 5);
|
||||
case 0x8D:
|
||||
return this->MOV(this->_getImmediateData(), this->_internalRegisters.y, 2);
|
||||
case 0x8E:
|
||||
return this->POP(this->_internalRegisters.psw);
|
||||
case 0x8F:
|
||||
return this->MOV(this->_getImmediateData(), this->_getDirectAddr());
|
||||
case 0x90:
|
||||
return this->BCC();
|
||||
case 0x91:
|
||||
@@ -465,6 +473,8 @@ namespace ComSquare::APU
|
||||
return this->DEC(this->_getDirectAddrByX(), 5);
|
||||
case 0x9C:
|
||||
return this->DECreg(this->_internalRegisters.a);
|
||||
case 0x9D:
|
||||
return this->MOV(this->_internalRegisters.sp, this->_internalRegisters.x);
|
||||
case 0x9E:
|
||||
return this->DIV();
|
||||
case 0x9F:
|
||||
@@ -499,6 +509,8 @@ namespace ComSquare::APU
|
||||
return this->CMPreg(this->_internalRegisters.y, this->_getImmediateData(), 2);
|
||||
case 0xAE:
|
||||
return this->POP(this->_internalRegisters.a);
|
||||
case 0xAF:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getIndexXAddr(), 4, true);
|
||||
case 0xB0:
|
||||
return this->BCS();
|
||||
case 0xB1:
|
||||
@@ -525,8 +537,12 @@ namespace ComSquare::APU
|
||||
return this->INC(this->_getDirectAddrByX(), 5);
|
||||
case 0xBC:
|
||||
return this->INCreg(this->_internalRegisters.a);
|
||||
case 0xBD:
|
||||
return this->MOV(this->_internalRegisters.x, this->_internalRegisters.sp, false);
|
||||
case 0xBE:
|
||||
return this->DAS();
|
||||
case 0xBF:
|
||||
return this->MOV(this->_getIndexXAddr(), this->_internalRegisters.a, 4, true);
|
||||
case 0xC0:
|
||||
return this->DI();
|
||||
case 0xC1:
|
||||
@@ -535,10 +551,26 @@ namespace ComSquare::APU
|
||||
return this->SET1(this->_getDirectAddr(), 6);
|
||||
case 0xC3:
|
||||
return this->BBS(this->_getDirectAddr(), 6);
|
||||
case 0xC4:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getDirectAddr(), 4);
|
||||
case 0xC5:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getAbsoluteAddr());
|
||||
case 0xC6:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getIndexXAddr(), 4);
|
||||
case 0xC7:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getAbsoluteDirectByXAddr(), 7);
|
||||
case 0xC8:
|
||||
return this->CMPreg(this->_internalRegisters.x, this->_getImmediateData(), 2);
|
||||
case 0xC9:
|
||||
return this->MOV(this->_internalRegisters.x, this->_getAbsoluteAddr(), 5);
|
||||
case 0xCA:
|
||||
return this->MOV1(this->_getAbsoluteBit());
|
||||
case 0xCB:
|
||||
return this->MOV(this->_internalRegisters.y, this->_getDirectAddr(), 4);
|
||||
case 0xCC:
|
||||
return this->MOV(this->_internalRegisters.y, this->_getAbsoluteAddr(), 5);
|
||||
case 0xCD:
|
||||
return this->MOV(this->_getImmediateData(), this->_internalRegisters.x, 2);
|
||||
case 0xCE:
|
||||
return this->POP(this->_internalRegisters.x);
|
||||
case 0xCF:
|
||||
@@ -551,22 +583,62 @@ namespace ComSquare::APU
|
||||
return this->CLR1(this->_getDirectAddr(), 6);
|
||||
case 0xD3:
|
||||
return this->BBC(this->_getDirectAddr(), 6);
|
||||
case 0xD4:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getDirectAddrByX(), 5);
|
||||
case 0xD5:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getAbsoluteAddrByX(), 6);
|
||||
case 0xD6:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getAbsoluteAddrByY(), 6);
|
||||
case 0xD7:
|
||||
return this->MOV(this->_internalRegisters.a, this->_getAbsoluteDirectAddrByY(), 7);
|
||||
case 0xD8:
|
||||
return this->MOV(this->_internalRegisters.x, this->_getDirectAddr(), 4);
|
||||
case 0xD9:
|
||||
return this->MOV(this->_internalRegisters.x, this->_getDirectAddrByY(), 5);
|
||||
case 0xDA:
|
||||
return this->MOVW(this->_getDirectAddr());
|
||||
case 0xDB:
|
||||
return this->MOV(this->_internalRegisters.y, this->_getDirectAddrByX(), 5);
|
||||
case 0xDC:
|
||||
return this->DECreg(this->_internalRegisters.y);
|
||||
case 0xDD:
|
||||
return this->MOV(this->_internalRegisters.y, this->_internalRegisters.a);
|
||||
case 0xDE:
|
||||
return this->CBNE(this->_getDirectAddrByX(), true);
|
||||
case 0xDF:
|
||||
return this->DAA();
|
||||
case 0xE0:
|
||||
return this->CLRV();
|
||||
case 0xE1:
|
||||
return this->TCALL(14);
|
||||
case 0xE2:
|
||||
return this->SET1(this->_getDirectAddr(), 7);
|
||||
case 0xE3:
|
||||
return this->BBS(this->_getDirectAddr(), 7);
|
||||
case 0xE4:
|
||||
return this->MOV(this->_getDirectAddr(), this->_internalRegisters.a, 3);
|
||||
case 0xE5:
|
||||
return this->MOV(this->_getAbsoluteAddrByX(), this->_internalRegisters.a, 5);
|
||||
case 0xE6:
|
||||
return this->MOV(this->_getIndexXAddr(), this->_internalRegisters.a, 3);
|
||||
case 0xE7:
|
||||
return this->MOV(this->_getAbsoluteDirectByXAddr(), this->_internalRegisters.a, 6);
|
||||
case 0xE8:
|
||||
return this->MOV(this->_getImmediateData(), this->_internalRegisters.a, 2);
|
||||
case 0xE9:
|
||||
return this->MOV(this->_getAbsoluteAddr(), this->_internalRegisters.x, 4);
|
||||
case 0xEA:
|
||||
return this->NOT1(this->_getAbsoluteBit());
|
||||
case 0xEB:
|
||||
return this->MOV(this->_getDirectAddr(), this->_internalRegisters.y, 3);
|
||||
case 0xEC:
|
||||
return this->MOV(this->_getAbsoluteAddr(), this->_internalRegisters.y, 4);
|
||||
case 0xED:
|
||||
return this->NOTC();
|
||||
case 0xEE:
|
||||
return this->POP(this->_internalRegisters.y);
|
||||
case 0xEF:
|
||||
return this->SLEEP();
|
||||
case 0xF0:
|
||||
return BEQ();
|
||||
case 0xF1:
|
||||
@@ -575,14 +647,26 @@ namespace ComSquare::APU
|
||||
return this->CLR1(this->_getDirectAddr(), 7);
|
||||
case 0xF3:
|
||||
return this->BBC(this->_getDirectAddr(), 7);
|
||||
case 0xF4:
|
||||
return this->MOV(this->_getDirectAddrByX(), this->_internalRegisters.a, 4);
|
||||
case 0xF5:
|
||||
return this->MOV(this->_getAbsoluteAddrByX(), this->_internalRegisters.a, 5);
|
||||
case 0xF6:
|
||||
return this->MOV(this->_getAbsoluteAddrByY(), this->_internalRegisters.a, 5);
|
||||
case 0xF7:
|
||||
return this->MOV(this->_getAbsoluteDirectAddrByY(), this->_internalRegisters.a, 6);
|
||||
case 0xF8:
|
||||
return this->MOV(this->_getDirectAddr(), this->_internalRegisters.x, 3);
|
||||
case 0xF9:
|
||||
return this->MOV(this->_getDirectAddrByY(), this->_internalRegisters.x, 4);
|
||||
case 0xFA:
|
||||
return this->MOV(this->_getDirectAddr(), this->_getDirectAddr());
|
||||
case 0xFB:
|
||||
return this->MOV(this->_getDirectAddrByX(), this->_internalRegisters.y, 4);
|
||||
case 0xFC:
|
||||
return this->INCreg(this->_internalRegisters.y);
|
||||
case 0xEA:
|
||||
return this->NOT1(this->_getAbsoluteBit());
|
||||
case 0xED:
|
||||
return this->NOTC();
|
||||
case 0xEF:
|
||||
return this->SLEEP();
|
||||
case 0xFD:
|
||||
return this->MOV(this->_internalRegisters.a, this->_internalRegisters.y);
|
||||
case 0xFE:
|
||||
return this->DBNZ();
|
||||
case 0xFF:
|
||||
|
||||
@@ -171,6 +171,8 @@ namespace ComSquare::APU
|
||||
uint24_t _getIndexYAddr();
|
||||
//! @brief Get direct page offset and add to it the X Index Flag
|
||||
uint24_t _getDirectAddrByX();
|
||||
//! @brief Get direct page offset and add to it the Y Index Flag
|
||||
uint24_t _getDirectAddrByY();
|
||||
//! @brief Get absolute direct page offset
|
||||
uint24_t _getAbsoluteAddr();
|
||||
//! @brief _get absolute direct page + X Index offset
|
||||
@@ -352,6 +354,11 @@ namespace ComSquare::APU
|
||||
int CMP(uint24_t operand1, uint24_t operand2, int cycles);
|
||||
//! @brief Compare a Register Flag with the value of the operand and set NZC flags.
|
||||
int CMPreg(uint8_t ®, uint24_t addr, int cycles);
|
||||
|
||||
int MOV(uint8_t ®From, uint8_t ®To, bool setFlags = true);
|
||||
int MOV(uint24_t memFrom, uint24_t memTo);
|
||||
int MOV(uint8_t ®From, uint24_t memTo, int cycles, bool incrementX = false);
|
||||
int MOV(uint24_t memFrom, uint8_t ®To, int cycles, bool incrementX = false);
|
||||
public:
|
||||
explicit APU(std::shared_ptr<MemoryMap> &map);
|
||||
APU(const APU &) = default;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by Melefo on 27/02/2020.
|
||||
//
|
||||
|
||||
#include "../APU.hpp"
|
||||
#include "../../Utility/Utility.hpp"
|
||||
|
||||
namespace ComSquare::APU
|
||||
{
|
||||
int APU::MOV(uint24_t memFrom, uint8_t ®To, int cycles, bool incrementX)
|
||||
{
|
||||
uint8_t data = this->_internalRead(memFrom);
|
||||
|
||||
regTo = data;
|
||||
if (incrementX)
|
||||
this->_internalRegisters.x++;
|
||||
this->_setNZflags(data);
|
||||
return cycles;
|
||||
}
|
||||
|
||||
int APU::MOV(uint8_t ®From, uint24_t memTo, int cycles, bool incrementX)
|
||||
{
|
||||
this->_internalWrite(memTo, regFrom);
|
||||
if (incrementX)
|
||||
this->_internalRegisters.x++;
|
||||
return cycles;
|
||||
}
|
||||
|
||||
int APU::MOV(uint8_t ®From, uint8_t ®To, bool setFlags)
|
||||
{
|
||||
regTo = regFrom;
|
||||
if (setFlags)
|
||||
this->_setNZflags(regFrom);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int APU::MOV(uint24_t memFrom, uint24_t memTo)
|
||||
{
|
||||
this->_internalWrite(memTo, this->_internalRead(memFrom));
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,14 @@ namespace ComSquare::APU
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint24_t APU::_getDirectAddrByY()
|
||||
{
|
||||
uint24_t addr = this->_getDirectAddr();
|
||||
|
||||
addr += this->_internalRegisters.y;
|
||||
return addr;
|
||||
}
|
||||
|
||||
uint24_t APU::_getAbsoluteAddr()
|
||||
{
|
||||
uint24_t addr1 = this->_getImmediateData();
|
||||
|
||||
@@ -1198,4 +1198,65 @@ Test(VIIIArithmetic, CMPacc)
|
||||
result = apu->CMPreg(apu->_internalRegisters.a, apu->_getIndexXAddr(), 3);
|
||||
cr_assert_eq(result, 3);
|
||||
cr_assert_eq(apu->_internalRegisters.c, true);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// //
|
||||
// (VIII)8-bit Data Transmission tests //
|
||||
// //
|
||||
/////////////////////////////////////////
|
||||
|
||||
Test(VIIIDataTransmission, MovRegToReg)
|
||||
{
|
||||
auto apu = Init().second.apu;
|
||||
int result = 0;
|
||||
|
||||
apu->_internalRegisters.a = 23;
|
||||
apu->_internalRegisters.x = 45;
|
||||
result = apu->MOV(apu->_internalRegisters.x, apu->_internalRegisters.a);
|
||||
cr_assert_eq(result, 2);
|
||||
cr_assert_eq(apu->_internalRegisters.a, 45);
|
||||
}
|
||||
|
||||
Test(VIIIDataTransmission, MovMemToMem)
|
||||
{
|
||||
auto apu = Init().second.apu;
|
||||
int result = 0;
|
||||
|
||||
apu->_internalRegisters.pc = 0x23;
|
||||
apu->_internalWrite(0x23, 0x56);
|
||||
apu->_internalWrite(0x24, 0x33);
|
||||
apu->_internalWrite(0x56, 99);
|
||||
apu->_internalWrite(0x33, 66);
|
||||
result = apu->MOV(apu->_getDirectAddr(), apu->_getDirectAddr());
|
||||
cr_assert_eq(result, 5);
|
||||
cr_assert_eq(apu->_internalRead(0x56), 66);
|
||||
}
|
||||
|
||||
Test(VIIIDataTransmission, MovRegToMem)
|
||||
{
|
||||
auto apu = Init().second.apu;
|
||||
int result = 0;
|
||||
|
||||
apu->_internalRegisters.x = 0x23;
|
||||
apu->_internalRegisters.a = 0x44;
|
||||
apu->_internalWrite(0x23, 0x56);
|
||||
result = apu->MOV(apu->_internalRegisters.a, apu->_getIndexXAddr(), 4, true);
|
||||
cr_assert_eq(result, 4);
|
||||
cr_assert_eq(apu->_internalRead(0x23), 0x44);
|
||||
cr_assert_eq(apu->_internalRegisters.x, 0x24);
|
||||
}
|
||||
|
||||
Test(VIIIDataTransmission, MovMemToReg)
|
||||
{
|
||||
auto apu = Init().second.apu;
|
||||
int result = 0;
|
||||
|
||||
apu->_internalRegisters.x = 0x23;
|
||||
apu->_internalRegisters.a = 0x44;
|
||||
apu->_internalWrite(0x23, 0x56);
|
||||
result = apu->MOV(apu->_getIndexXAddr(), apu->_internalRegisters.a, 4, true);
|
||||
cr_assert_eq(result, 4);
|
||||
cr_assert_eq(apu->_internalRegisters.x, 0x24);
|
||||
cr_assert_eq(apu->_internalRegisters.a, 0x56);
|
||||
}
|
||||
@@ -58,6 +58,16 @@ Test(_get, directbyX)
|
||||
cr_assert_eq(apu->_getDirectAddrByX(), 0x43);
|
||||
}
|
||||
|
||||
Test(_get, directbyY)
|
||||
{
|
||||
auto apu = Init().second.apu;
|
||||
|
||||
apu->_internalRegisters.pc = 0x32;
|
||||
apu->_internalRegisters.y = 0x05;
|
||||
apu->_internalWrite(0x32, 0x40);
|
||||
cr_assert_eq(apu->_getDirectAddrByY(), 0x45);
|
||||
}
|
||||
|
||||
Test(_get, absolute)
|
||||
{
|
||||
auto apu = Init().second.apu;
|
||||
|
||||
Reference in New Issue
Block a user