mirror of
https://github.com/zoriya/ComSquare.git
synced 2025-12-20 14:15:11 +00:00
Adding branch instructions
This commit is contained in:
@@ -328,7 +328,7 @@ namespace ComSquare::CPU
|
|||||||
|
|
||||||
case Instructions::XCE: this->XCE(); return 2;
|
case Instructions::XCE: this->XCE(); return 2;
|
||||||
|
|
||||||
case Instructions::SBC_IM: this->SBC(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
|
case Instructions::SBC_IM: this->SBC(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
|
||||||
case Instructions::SBC_ABS: this->SBC(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
|
case Instructions::SBC_ABS: this->SBC(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
|
||||||
case Instructions::SBC_ABSl: this->SBC(this->_getAbsoluteLongAddr()); return 5 + !this->_registers.p.m;
|
case Instructions::SBC_ABSl: this->SBC(this->_getAbsoluteLongAddr()); return 5 + !this->_registers.p.m;
|
||||||
case Instructions::SBC_DP: this->SBC(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
|
case Instructions::SBC_DP: this->SBC(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
|
||||||
@@ -359,6 +359,17 @@ namespace ComSquare::CPU
|
|||||||
case Instructions::CPY_ABS: this->CPY(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
|
case Instructions::CPY_ABS: this->CPY(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
|
||||||
case Instructions::CPY_DP: this->CPY(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
|
case Instructions::CPY_DP: this->CPY(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
|
||||||
|
|
||||||
|
case Instructions::BCC: return this->BCC(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BCS: return this->BCS(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BEQ: return this->BEQ(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BNE: return this->BNE(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BMI: return this->BMI(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BPL: return this->BPL(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BVC: return this->BVC(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BVS: return this->BVS(this->_registers.pc++) + 2 + this->_isEmulationMode;
|
||||||
|
case Instructions::BRA: this->BRA(this->_registers.pc++); return 3 + this->_isEmulationMode;
|
||||||
|
case Instructions::BRL: this->BRL(this->_registers.pc); this->_registers.pc += 2; return 4;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw InvalidOpcode("CPU", opcode);
|
throw InvalidOpcode("CPU", opcode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,7 +341,18 @@ namespace ComSquare::CPU
|
|||||||
|
|
||||||
CPY_IM = 0xC0,
|
CPY_IM = 0xC0,
|
||||||
CPY_ABS = 0xCC,
|
CPY_ABS = 0xCC,
|
||||||
CPY_DP = 0xC4
|
CPY_DP = 0xC4,
|
||||||
|
|
||||||
|
BCC = 0x90,
|
||||||
|
BCS = 0xB0,
|
||||||
|
BEQ = 0xF0,
|
||||||
|
BNE = 0xD0,
|
||||||
|
BMI = 0x30,
|
||||||
|
BPL = 0x10,
|
||||||
|
BVC = 0x50,
|
||||||
|
BVS = 0x70,
|
||||||
|
BRA = 0x80,
|
||||||
|
BRL = 0x82
|
||||||
};
|
};
|
||||||
|
|
||||||
//! @brief The main CPU
|
//! @brief The main CPU
|
||||||
@@ -509,6 +520,26 @@ namespace ComSquare::CPU
|
|||||||
void CPX(uint24_t valueAddr);
|
void CPX(uint24_t valueAddr);
|
||||||
//! @brief Compare the Y register with the memory
|
//! @brief Compare the Y register with the memory
|
||||||
void CPY(uint24_t valueAddr);
|
void CPY(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if carry clear
|
||||||
|
bool BCC(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if carry set
|
||||||
|
bool BCS(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if equal
|
||||||
|
bool BEQ(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if not equal
|
||||||
|
bool BNE(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if minus
|
||||||
|
bool BMI(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if plus
|
||||||
|
bool BPL(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if Overflow Clear
|
||||||
|
bool BVC(uint24_t valueAddr);
|
||||||
|
//! @brief Branch if Overflow Set
|
||||||
|
bool BVS(uint24_t valueAddr);
|
||||||
|
//! @brief Branch always
|
||||||
|
bool BRA(uint24_t valueAddr);
|
||||||
|
//! @brief Branch always long
|
||||||
|
bool BRL(uint24_t valueAddr);
|
||||||
public:
|
public:
|
||||||
explicit CPU(std::shared_ptr<Memory::MemoryBus> bus, Cartridge::Header &cartridgeHeader);
|
explicit CPU(std::shared_ptr<Memory::MemoryBus> bus, Cartridge::Header &cartridgeHeader);
|
||||||
CPU(const CPU &) = default;
|
CPU(const CPU &) = default;
|
||||||
|
|||||||
@@ -226,4 +226,75 @@ namespace ComSquare::CPU
|
|||||||
this->_registers.p.n = y & 0x8000u;
|
this->_registers.p.n = y & 0x8000u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPU::BCC(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (!this->_registers.p.c)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return !this->_registers.p.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BCS(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (this->_registers.p.c)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return this->_registers.p.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BEQ(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (this->_registers.p.z)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return this->_registers.p.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BNE(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (!this->_registers.p.z)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return !this->_registers.p.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BMI(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (this->_registers.p.n)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return this->_registers.p.n;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BPL(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (!this->_registers.p.n)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return !this->_registers.p.n;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BRA(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BRL(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
unsigned value = this->_bus->read(valueAddr);
|
||||||
|
value += this->_bus->read(valueAddr + 1) << 8u;
|
||||||
|
|
||||||
|
this->_registers.pac += static_cast<int16_t>(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BVC(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (!this->_registers.p.v)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return !this->_registers.p.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU::BVS(uint24_t valueAddr)
|
||||||
|
{
|
||||||
|
if (this->_registers.p.v)
|
||||||
|
this->_registers.pac += static_cast<int8_t>(this->_bus->read(valueAddr));
|
||||||
|
return this->_registers.p.v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -146,6 +146,16 @@ namespace ComSquare::Debugger
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CPUDebug::_getImmediateValue16Bits(uint24_t pc)
|
||||||
|
{
|
||||||
|
unsigned value = this->_bus->read(pc);
|
||||||
|
value += this->_bus->read(pc + 1) << 8u;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "#$" << std::hex << value;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string CPUDebug::_getDirectValue(uint24_t pc)
|
std::string CPUDebug::_getDirectValue(uint24_t pc)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -345,6 +355,17 @@ namespace ComSquare::Debugger
|
|||||||
case Instructions::CPY_ABS: return "CPY " + this->_getAbsoluteValue(pc);
|
case Instructions::CPY_ABS: return "CPY " + this->_getAbsoluteValue(pc);
|
||||||
case Instructions::CPY_DP: return "CPY";
|
case Instructions::CPY_DP: return "CPY";
|
||||||
|
|
||||||
|
case Instructions::BCC: return "BCC " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BCS: return "BCS " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BEQ: return "BEQ " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BNE: return "BNE " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BMI: return "BMI " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BPL: return "BPL " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BVC: return "BVC " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BVS: return "BVS " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BRA: return "BRA " + this->_getImmediateValue8Bits(pc);
|
||||||
|
case Instructions::BRL: return "BRL " + this->_getImmediateValue16Bits(pc);
|
||||||
|
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ namespace ComSquare::Debugger
|
|||||||
std::string _getImmediateValueForX(uint24_t pc);
|
std::string _getImmediateValueForX(uint24_t pc);
|
||||||
//! @brief Return a printable string corresponding to the value of a 8bits immediate addressing mode (used only with SEP and REP).
|
//! @brief Return a printable string corresponding to the value of a 8bits immediate addressing mode (used only with SEP and REP).
|
||||||
std::string _getImmediateValue8Bits(uint24_t pc);
|
std::string _getImmediateValue8Bits(uint24_t pc);
|
||||||
|
//! @brief Return a printable string corresponding to the value of a 16bits immediate addressing mode.
|
||||||
|
std::string _getImmediateValue16Bits(uint24_t pc);
|
||||||
//! @brief Return a printable string corresponding to the value of a direct addressing mode.
|
//! @brief Return a printable string corresponding to the value of a direct addressing mode.
|
||||||
std::string _getDirectValue(uint24_t pc);
|
std::string _getDirectValue(uint24_t pc);
|
||||||
//! @brief Return a printable string corresponding to the value of an absolute addressing mode.
|
//! @brief Return a printable string corresponding to the value of an absolute addressing mode.
|
||||||
|
|||||||
@@ -604,4 +604,283 @@ Test(CPY, negative)
|
|||||||
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set");
|
cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag should not be set");
|
||||||
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag should be set");
|
cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative 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.c, false, "The carry flag should not be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BCC, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.c = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BCC(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BCC, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.c = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BCC(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BCC, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.c = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BCC(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BCS, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.c = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BCS(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BCS, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.c = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BCS(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BCS, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.c = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BCS(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BEQ, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.z = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BEQ(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BEQ, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.z = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BEQ(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BEQ, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.z = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BEQ(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BNE, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.z = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BNE(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BNE, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.z = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BNE(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BNE, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.z = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BNE(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BMI, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.n = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BMI(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BMI, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.n = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BMI(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BMI, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.n = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BMI(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BPL, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.n = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BPL(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BPL, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.n = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BPL(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BPL, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.n = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BPL(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BRA, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BRA(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BRA, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BRA(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BRL, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.pc = 0x8080;
|
||||||
|
pair.second.wram->_data[0] = 0x00;
|
||||||
|
pair.second.wram->_data[1] = 0x10;
|
||||||
|
pair.second.cpu->BRL(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x9080, "The program counter should be equal to 0x9080 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BRL, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.pc = 0x8080;
|
||||||
|
pair.second.wram->_data[0] = 0x00;
|
||||||
|
pair.second.wram->_data[1] = 0xF0;
|
||||||
|
pair.second.cpu->BRL(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x7080, "The program counter should be equal to 0x7080 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BVC, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.v = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BVC(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BVC, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.v = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BVC(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BVC, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.v = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BVC(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Test(BVS, basic)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.v = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x50;
|
||||||
|
pair.second.cpu->BVS(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0xD0, "The program counter should be equal to 0xD0 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BVS, negativeJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.v = true;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0xF0;
|
||||||
|
pair.second.cpu->BVS(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x70, "The program counter should be equal to 0x70 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(BVS, noJump)
|
||||||
|
{
|
||||||
|
auto pair = Init();
|
||||||
|
pair.second.cpu->_registers.p.v = false;
|
||||||
|
pair.second.cpu->_registers.pc = 0x80;
|
||||||
|
pair.second.wram->_data[0] = 0x90;
|
||||||
|
pair.second.cpu->BVS(0x0);
|
||||||
|
cr_assert_eq(pair.second.cpu->_registers.pc, 0x80, "The program counter should be equal to 0x80 but it was 0x%x.", pair.second.cpu->_registers.pc);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user