mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-07 03:34:55 +00:00
Implementing the EOR
This commit is contained in:
+17
-15
@@ -395,6 +395,8 @@ namespace ComSquare::CPU
|
|||||||
int INC(uint24_t, AddressingMode);
|
int INC(uint24_t, AddressingMode);
|
||||||
//! @brief Decrement
|
//! @brief Decrement
|
||||||
int DEC(uint24_t, AddressingMode);
|
int DEC(uint24_t, AddressingMode);
|
||||||
|
//! @brief XOR, Exclusive OR accumulator with memory.
|
||||||
|
int EOR(uint24_t, AddressingMode);
|
||||||
|
|
||||||
//! @brief All the instructions of the CPU.
|
//! @brief All the instructions of the CPU.
|
||||||
//! @info Instructions are indexed by their opcode
|
//! @info Instructions are indexed by their opcode
|
||||||
@@ -464,37 +466,37 @@ namespace ComSquare::CPU
|
|||||||
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 3E
|
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 3E
|
||||||
{&CPU::AND, 5, "and", AddressingMode::AbsoluteIndexedByXLong, 4}, // 3F
|
{&CPU::AND, 5, "and", AddressingMode::AbsoluteIndexedByXLong, 4}, // 3F
|
||||||
{&CPU::RTI, 6, "rti", AddressingMode::Implied, 1}, // 40
|
{&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, "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, "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, "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::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::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 4A
|
||||||
{&CPU::PHK, 3, "phk", AddressingMode::Implied, 1}, // 4B
|
{&CPU::PHK, 3, "phk", AddressingMode::Implied, 1}, // 4B
|
||||||
{&CPU::JMP, 3, "jmp", AddressingMode::Absolute, 3}, // 4C
|
{&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, "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::BVC, 2, "bvc", AddressingMode::Implied, 2}, // 50
|
||||||
{&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 51
|
{&CPU::EOR, 5, "eor", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 51
|
||||||
{&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 52
|
{&CPU::EOR, 5, "eor", AddressingMode::DirectPageIndirect, 2}, // 52
|
||||||
{&CPU::BRK, 7, "eor #-#", AddressingMode::Implied, 2}, // 53
|
{&CPU::EOR, 4, "eor", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 53
|
||||||
{&CPU::BRK, 7, "mvn #-#", AddressingMode::Implied, 2}, // 54
|
{&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, "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::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::PHY, 3, "phy", AddressingMode::Implied, 1}, // 5A
|
||||||
{&CPU::BRK, 7, "tcd #-#", AddressingMode::Implied, 2}, // 5B
|
{&CPU::BRK, 7, "tcd #-#", AddressingMode::Implied, 2}, // 5B
|
||||||
{&CPU::JML, 4, "jml", AddressingMode::Implied, 4}, // 5C
|
{&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, "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::RTL, 6, "rtl", AddressingMode::Implied, 1}, // 60
|
||||||
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 61
|
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 61
|
||||||
{&CPU::BRK, 7, "per #-#", AddressingMode::Implied, 2}, // 62
|
{&CPU::BRK, 7, "per #-#", AddressingMode::Implied, 2}, // 62
|
||||||
|
|||||||
@@ -365,4 +365,37 @@ namespace ComSquare::CPU
|
|||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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.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.n, true, "The negative flags should be set.");
|
||||||
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flags should not be set.");
|
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flags should not be set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user