From a40bfd1c3c840029fa9da18ee74729c39e64ec85 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Mon, 6 Apr 2020 18:37:11 +0200
Subject: [PATCH] Implementing the EOR
---
sources/CPU/CPU.hpp | 32 ++++++++--------
.../Instructions/MathematicalOperations.cpp | 33 ++++++++++++++++
tests/CPU/Math/testOthersMath.cpp | 38 ++++++++++++++++++-
3 files changed, 87 insertions(+), 16 deletions(-)
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index a478d35..9a61baa 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -395,6 +395,8 @@ namespace ComSquare::CPU
int INC(uint24_t, AddressingMode);
//! @brief Decrement
int DEC(uint24_t, AddressingMode);
+ //! @brief XOR, Exclusive OR accumulator with memory.
+ int EOR(uint24_t, AddressingMode);
//! @brief All the instructions of the CPU.
//! @info Instructions are indexed by their opcode
@@ -464,37 +466,37 @@ namespace ComSquare::CPU
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 3E
{&CPU::AND, 5, "and", AddressingMode::AbsoluteIndexedByXLong, 4}, // 3F
{&CPU::RTI, 6, "rti", AddressingMode::Implied, 1}, // 40
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 41
+ {&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 41
{&CPU::BRK, 7, "wdm #-#", AddressingMode::Implied, 2}, // 42
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 43
+ {&CPU::EOR, 4, "eor", AddressingMode::StackRelative, 2}, // 43
{&CPU::BRK, 7, "mvp #-#", AddressingMode::Implied, 2}, // 44
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 45
+ {&CPU::EOR, 3, "eor", AddressingMode::DirectPage, 2}, // 45
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 46
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 47
+ {&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectLong, 2}, // 47
{&CPU::PHA, 3, "pha", AddressingMode::Implied, 1}, // 48
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 49
+ {&CPU::EOR, 2, "eor", AddressingMode::ImmediateForA, 2}, // 49
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 4A
{&CPU::PHK, 3, "phk", AddressingMode::Implied, 1}, // 4B
{&CPU::JMP, 3, "jmp", AddressingMode::Absolute, 3}, // 4C
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 4D
+ {&CPU::EOR, 4, "eor", AddressingMode::Absolute, 3}, // 4D
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 4E
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 4F
+ {&CPU::EOR, 5, "eor", AddressingMode::AbsoluteLong, 4}, // 4F
{&CPU::BVC, 2, "bvc", AddressingMode::Implied, 2}, // 50
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 51
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 52
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 53
+ {&CPU::EOR, 5, "eor", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 51
+ {&CPU::EOR, 5, "eor", AddressingMode::DirectPageIndirect, 2}, // 52
+ {&CPU::EOR, 4, "eor", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 53
{&CPU::BRK, 7, "mvn #-#", AddressingMode::Implied, 2}, // 54
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 55
+ {&CPU::EOR, 4, "eor", AddressingMode::DirectPageIndexedByX, 2}, // 55
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 56
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 57
+ {&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // 57
{&CPU::CLI, 2, "cli", AddressingMode::Implied, 1}, // 58
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 59
+ {&CPU::EOR, 4, "eor", AddressingMode::AbsoluteIndexedByY, 3}, // 59
{&CPU::PHY, 3, "phy", AddressingMode::Implied, 1}, // 5A
{&CPU::BRK, 7, "tcd #-#", AddressingMode::Implied, 2}, // 5B
{&CPU::JML, 4, "jml", AddressingMode::Implied, 4}, // 5C
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 5D
+ {&CPU::EOR, 4, "eor", AddressingMode::AbsoluteIndexedByX, 3}, // 5D
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 5E
- {&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 5F
+ {&CPU::EOR, 5, "eor", AddressingMode::AbsoluteIndexedByXLong, 4}, // 5F
{&CPU::RTL, 6, "rtl", AddressingMode::Implied, 1}, // 60
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 61
{&CPU::BRK, 7, "per #-#", AddressingMode::Implied, 2}, // 62
diff --git a/sources/CPU/Instructions/MathematicalOperations.cpp b/sources/CPU/Instructions/MathematicalOperations.cpp
index ff2d63e..f723978 100644
--- a/sources/CPU/Instructions/MathematicalOperations.cpp
+++ b/sources/CPU/Instructions/MathematicalOperations.cpp
@@ -365,4 +365,37 @@ namespace ComSquare::CPU
return 0;
}
}
+
+ int CPU::EOR(uint24_t valueAddr, AddressingMode mode)
+ {
+ unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
+ unsigned value = this->_bus->read(valueAddr);
+ if (!this->_registers.p.m)
+ value += this->_bus->read(valueAddr + 1) << 8u;
+ this->_registers.a ^= value;
+ this->_registers.p.z = this->_registers.a == 0;
+ this->_registers.p.n = this->_registers.a & negativeMask;
+
+ int cycles = !this->_registers.p.m;
+ switch (mode) {
+ case DirectPage:
+ case DirectPageIndirect:
+ case DirectPageIndirectLong:
+ case DirectPageIndexedByX:
+ case DirectPageIndirectIndexedByX:
+ case DirectPageIndirectIndexedByYLong:
+ cycles += this->_registers.dl != 0;
+ break;
+ case AbsoluteIndexedByX:
+ case AbsoluteIndexedByY:
+ cycles += this->_hasIndexCrossedPageBoundary;
+ break;
+ case DirectPageIndirectIndexedByY:
+ cycles += this->_registers.dl != 0 + this->_hasIndexCrossedPageBoundary;
+ break;
+ default:
+ break;
+ }
+ return cycles;
+ }
}
\ No newline at end of file
diff --git a/tests/CPU/Math/testOthersMath.cpp b/tests/CPU/Math/testOthersMath.cpp
index 1f293aa..294f4f9 100644
--- a/tests/CPU/Math/testOthersMath.cpp
+++ b/tests/CPU/Math/testOthersMath.cpp
@@ -284,4 +284,40 @@ Test(DEC, negativeNativeAccumulator)
cr_assert_eq(snes.cpu->_registers.a, 0x9000, "The incremented value should be 0x9000 but it was 0x%x.", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flags should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flags should not be set.");
-}
\ No newline at end of file
+}
+
+Test(EOR, simple)
+{
+ Init()
+ snes.cpu->_registers.p.m = true;
+ snes.cpu->_registers.a = 0x80;
+ snes.wram->_data[0] = 0x0F;
+ snes.cpu->EOR(0x0, ComSquare::CPU::AddressingMode::Implied);
+ cr_assert_eq(snes.cpu->_registers.a, 0x8F, "The accumulator's value should be 0x8F but it was 0x%x.", snes.cpu->_registers.a);
+ cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flags should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flags should not be set.");
+}
+
+Test(EOR, simple2)
+{
+ Init()
+ snes.cpu->_registers.p.m = true;
+ snes.cpu->_registers.a = 0x80;
+ snes.wram->_data[0] = 0xF0;
+ snes.cpu->EOR(0x00, ComSquare::CPU::AddressingMode::Implied);
+ cr_assert_eq(snes.cpu->_registers.a, 0x70, "The accumulator's value should be 0x70 but it was 0x%x.", snes.cpu->_registers.a);
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flags should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flags should not be set.");
+}
+
+Test(EOR, zero)
+{
+ Init()
+ snes.cpu->_registers.p.m = true;
+ snes.cpu->_registers.a = 0x00;
+ snes.wram->_data[0] = 0x00;
+ snes.cpu->EOR(0x0, ComSquare::CPU::AddressingMode::Implied);
+ cr_assert_eq(snes.cpu->_registers.a, 0x00, "The accumulator's value should be 0x00 but it was 0x%x.", snes.cpu->_registers.a);
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flags should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flags should be set.");
+}