diff --git a/CMakeLists.txt b/CMakeLists.txt index 092df24..e3da882 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,7 @@ add_executable(unit_tests sources/APU/Instructions/ProgramFlow.cpp sources/APU/Operand.cpp sources/APU/Instructions/DecimalCompensation.cpp; - sources/APU/Instructions/MultiplicationDivision.cpp sources/APU/Instructions/16bitArithmetic.cpp) + sources/APU/Instructions/MultiplicationDivision.cpp sources/APU/Instructions/16bitArithmetic.cpp sources/APU/Instructions/16bitDataTransmission.cpp) # include criterion & coverage target_link_libraries(unit_tests criterion -lgcov) @@ -165,7 +165,7 @@ add_executable(ComSquare sources/APU/Instructions/ProgramFlow.cpp sources/APU/Operand.cpp sources/APU/Instructions/DecimalCompensation.cpp - sources/APU/Instructions/MultiplicationDivision.cpp sources/APU/Instructions/16bitArithmetic.cpp) + sources/APU/Instructions/MultiplicationDivision.cpp sources/APU/Instructions/16bitArithmetic.cpp sources/APU/Instructions/16bitDataTransmission.cpp) target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED) diff --git a/sources/APU/APU.cpp b/sources/APU/APU.cpp index 32f22ec..de68b60 100644 --- a/sources/APU/APU.cpp +++ b/sources/APU/APU.cpp @@ -316,6 +316,8 @@ namespace ComSquare::APU return this->CLR1(this->_getDirectAddr(), 5); case 0xB3: return this->BBC(this->_getDirectAddr(), 5); + case 0xBA: + return this->MOVW(this->_getDirectAddr(), true); case 0xBE: return this->DAS(); case 0xC0: @@ -340,6 +342,8 @@ namespace ComSquare::APU return this->CLR1(this->_getDirectAddr(), 6); case 0xD3: return this->BBC(this->_getDirectAddr(), 6); + case 0xDA: + return this->MOVW(this->_getDirectAddr()); case 0xDE: return this->CBNE(this->_getDirectAddrByX(), true); case 0xDF: diff --git a/sources/APU/APU.hpp b/sources/APU/APU.hpp index 3e6b143..d48b283 100644 --- a/sources/APU/APU.hpp +++ b/sources/APU/APU.hpp @@ -288,6 +288,9 @@ namespace ComSquare::APU int SUBW(uint24_t addr); //! @brief Compare YA with a word value. int CMPW(uint24_t addr); + + //! @brief Sets a word value equal to another + int MOVW(uint24_t addr, bool to_ya = false); public: explicit APU(std::shared_ptr &map); APU(const APU &) = default; diff --git a/sources/APU/Instructions/16bitDataTransmission.cpp b/sources/APU/Instructions/16bitDataTransmission.cpp new file mode 100644 index 0000000..ffcf0a5 --- /dev/null +++ b/sources/APU/Instructions/16bitDataTransmission.cpp @@ -0,0 +1,26 @@ +// +// Created by Melefo on 25/02/2020. +// + +#include "../APU.hpp" + +namespace ComSquare::APU +{ + int APU::MOVW(uint24_t addr, bool to_ya) + { + uint24_t addr2 = addr + 1 + (this->_internalRegisters.p ? 0x0100 : 0); + + if (to_ya) { + uint16_t value = ((this->_internalRead(addr2) << 8u) | this->_internalRead(addr)); + + this->_internalRegisters.ya = value; + this->_internalRegisters.n = value & 0x8000u; + this->_internalRegisters.z = !value; + } + else { + this->_internalWrite(addr, this->_internalRegisters.a); + this->_internalWrite(addr2, this->_internalRegisters.y); + } + return 5; + } +} \ No newline at end of file diff --git a/tests/APU/testAPUInstructions.cpp b/tests/APU/testAPUInstructions.cpp index 23dd1a8..6e87578 100644 --- a/tests/APU/testAPUInstructions.cpp +++ b/tests/APU/testAPUInstructions.cpp @@ -856,4 +856,31 @@ Test(XVIbitArithmetic, CMPW) cr_assert_eq(apu->_internalRegisters.z, true); cr_assert_eq(apu->_internalRegisters.c, true); cr_assert_eq(apu->_internalRegisters.n, false); +} + +///////////////////////////////////////// +// // +// (XVI)16-bit Data Transmission tests // +// // +///////////////////////////////////////// + +Test(XVIbitDataTransmission, MOVW) +{ + auto apu = Init().second.apu; + int result = 0; + + apu->_internalRegisters.ya = 0x2211; + apu->_internalWrite(apu->_internalRegisters.pc, 0x55); + result = apu->MOVW(apu->_getDirectAddr()); + cr_assert_eq(result, 5); + cr_assert_eq(apu->_internalRead(0x55), 0x11); + cr_assert_eq(apu->_internalRead(0x56), 0x22); + apu->_internalRegisters.ya = 0x0000; + apu->_internalRegisters.pc = 0; + apu->_internalWrite(0x55, 0x33); + apu->_internalWrite(0x55 + 1, 0x44); + apu->MOVW(apu->_getDirectAddr(), true); + cr_assert_eq(apu->_internalRegisters.ya, 0x4433); + cr_assert_eq(apu->_internalRegisters.n, false); + cr_assert_eq(apu->_internalRegisters.z, false); } \ No newline at end of file