Implementing the XCE instruction

This commit is contained in:
Anonymus Raccoon
2020-02-25 23:05:15 +01:00
parent 8dbaea89ed
commit 4da96894ae
5 changed files with 56 additions and 1 deletions
+2
View File
@@ -326,6 +326,8 @@ namespace ComSquare::CPU
case Instructions::AND_SR: this->AND(this->_getStackRelativeAddr()); return 4 + !this->_registers.p.m; case Instructions::AND_SR: this->AND(this->_getStackRelativeAddr()); return 4 + !this->_registers.p.m;
case Instructions::AND_SRYi: this->AND(this->_getStackRelativeIndirectIndexedYAddr()); return 7 + !this->_registers.p.m; case Instructions::AND_SRYi: this->AND(this->_getStackRelativeIndirectIndexedYAddr()); return 7 + !this->_registers.p.m;
case Instructions::XCE: this->XCE(); return 2;
default: default:
throw InvalidOpcode("CPU", opcode); throw InvalidOpcode("CPU", opcode);
} }
+5 -1
View File
@@ -308,7 +308,9 @@ namespace ComSquare::CPU
AND_DPYi = 0x31, AND_DPYi = 0x31,
AND_DPYil = 0x37, AND_DPYil = 0x37,
AND_SR = 0x23, AND_SR = 0x23,
AND_SRYi = 0x33 AND_SRYi = 0x33,
XCE = 0xFB
}; };
//! @brief The main CPU //! @brief The main CPU
@@ -455,6 +457,8 @@ namespace ComSquare::CPU
void SED(); void SED();
//! @brief Set the Interrupt Disable flag. //! @brief Set the Interrupt Disable flag.
void SEI(); void SEI();
//! @brief Exchange Carry and Emulation Flags
void XCE();
//! @brief And accumulator with memory. //! @brief And accumulator with memory.
void AND(uint24_t valueAddr); void AND(uint24_t valueAddr);
public: public:
@@ -150,4 +150,18 @@ namespace ComSquare::CPU
this->_registers.p.z = this->_registers.y == 0; this->_registers.p.z = this->_registers.y == 0;
this->_registers.p.n = this->_registers.y & 0x8000u; this->_registers.p.n = this->_registers.y & 0x8000u;
} }
void CPU::XCE()
{
bool oldCarry = this->_registers.p.c;
this->_registers.p.c = this->_isEmulationMode;
this->_isEmulationMode = oldCarry;
if (!this->_isEmulationMode) {
this->_registers.p.m = true;
this->_registers.p.x_b = true;
this->_registers.xh = 0;
this->_registers.yh = 0;
}
}
} }
+2
View File
@@ -240,6 +240,8 @@ namespace ComSquare::Debugger
case Instructions::AND_SR: return "AND"; case Instructions::AND_SR: return "AND";
case Instructions::AND_SRYi: return "AND"; case Instructions::AND_SRYi: return "AND";
case Instructions::XCE: return "XCE";
default: return "Unknown"; default: return "Unknown";
} }
} }
+33
View File
@@ -461,4 +461,37 @@ Test(SED, set)
pair.second.cpu->_registers.p.flags = 0x00; pair.second.cpu->_registers.p.flags = 0x00;
pair.second.cpu->SED(); pair.second.cpu->SED();
cr_assert_eq(pair.second.cpu->_registers.p.d, true, "The decimal flag should be set"); cr_assert_eq(pair.second.cpu->_registers.p.d, true, "The decimal flag should be set");
}
Test(XCE, enableEmulation)
{
auto pair = Init();
pair.second.cpu->_isEmulationMode = false;
pair.second.cpu->_registers.p.flags = 0;
pair.second.cpu->_registers.p.c = true;
pair.second.cpu->_registers.xh = 0xFF;
pair.second.cpu->_registers.yh = 0xFF;
pair.second.cpu->XCE();
cr_assert_eq(pair.second.cpu->_isEmulationMode, true, "The e flag should be set");
cr_assert_eq(pair.second.cpu->_registers.p.c, false, "The carry flag should not be set");
cr_assert_eq(pair.second.cpu->_registers.p.m, false, "The memory width flag should be untouched (unset)");
cr_assert_eq(pair.second.cpu->_registers.p.x_b, false, "The index width flag should be untouched (unset)");
cr_assert_eq(pair.second.cpu->_registers.xh, 0xFF, "The high byte of the x index flag should be untouched (0xFF)");
cr_assert_eq(pair.second.cpu->_registers.yh, 0xFF, "The high byte of the y index flag should be untouched (0xFF)");
}
Test(XCE, enableNative)
{
auto pair = Init();
pair.second.cpu->_isEmulationMode = true;
pair.second.cpu->_registers.p.flags = 0;
pair.second.cpu->_registers.xh = 0xFF;
pair.second.cpu->_registers.yh = 0xFF;
pair.second.cpu->XCE();
cr_assert_eq(pair.second.cpu->_isEmulationMode, false, "The e flag should be not set");
cr_assert_eq(pair.second.cpu->_registers.p.c, true, "The carry flag should be set");
cr_assert_eq(pair.second.cpu->_registers.p.m, true, "The memory width flag should be set");
cr_assert_eq(pair.second.cpu->_registers.p.x_b, true, "The index width flag should be set");
cr_assert_eq(pair.second.cpu->_registers.xh, 0, "The high byte of the x index flag should be set to 0");
cr_assert_eq(pair.second.cpu->_registers.yh, 0, "The high byte of the y index flag should be set to 0");
} }