mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-01 17:55:30 +00:00
Implementing the XCE instruction
This commit is contained in:
@@ -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
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user