From 2ec1090a2bdf605f4fe712234dd7570eddb8393b Mon Sep 17 00:00:00 2001 From: Melefo <42809472+Melefo@users.noreply.github.com> Date: Thu, 27 Feb 2020 14:58:42 +0100 Subject: [PATCH] Adding 8-bit Data Transmission Operations and so every instructions are done Forgot an instruction in _executeInstruction function --- CMakeLists.txt | 2 + sources/APU/APU.cpp | 96 +++++++++++++++++-- sources/APU/APU.hpp | 7 ++ .../APU/Instructions/8bitDataTransmission.cpp | 42 ++++++++ sources/APU/Operand.cpp | 8 ++ tests/APU/testAPUInstructions.cpp | 61 ++++++++++++ tests/APU/testOperand.cpp | 10 ++ 7 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 sources/APU/Instructions/8bitDataTransmission.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e09d2d6..4513dc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/sources/APU/APU.cpp b/sources/APU/APU.cpp index 7103d74..85f9707 100644 --- a/sources/APU/APU.cpp +++ b/sources/APU/APU.cpp @@ -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: diff --git a/sources/APU/APU.hpp b/sources/APU/APU.hpp index e5cbeed..825b955 100644 --- a/sources/APU/APU.hpp +++ b/sources/APU/APU.hpp @@ -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 &map); APU(const APU &) = default; diff --git a/sources/APU/Instructions/8bitDataTransmission.cpp b/sources/APU/Instructions/8bitDataTransmission.cpp new file mode 100644 index 0000000..0b4f593 --- /dev/null +++ b/sources/APU/Instructions/8bitDataTransmission.cpp @@ -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; + } +} \ No newline at end of file diff --git a/sources/APU/Operand.cpp b/sources/APU/Operand.cpp index fc5e2ba..4242612 100644 --- a/sources/APU/Operand.cpp +++ b/sources/APU/Operand.cpp @@ -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(); diff --git a/tests/APU/testAPUInstructions.cpp b/tests/APU/testAPUInstructions.cpp index cecc59f..7fa0aed 100644 --- a/tests/APU/testAPUInstructions.cpp +++ b/tests/APU/testAPUInstructions.cpp @@ -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); } \ No newline at end of file diff --git a/tests/APU/testOperand.cpp b/tests/APU/testOperand.cpp index 2e723b0..512b094 100644 --- a/tests/APU/testOperand.cpp +++ b/tests/APU/testOperand.cpp @@ -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;