mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-26 19:29:20 +00:00
Improve compatibility with .net emulator code.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
20ebbd4048
commit
d0467421ff
@ -135,11 +135,11 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
static void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
||||||
setFlag(f, AC, calculateHalfCarryAdd(before, value, calculation));
|
f = setBit(f, AC, calculateHalfCarryAdd(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustAuxiliaryCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
static void adjustAuxiliaryCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
||||||
clearFlag(f, AC, calculateHalfCarrySub(before, value, calculation));
|
f = clearBit(f, AC, calculateHalfCarrySub(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void subtract(uint8_t& operand, uint8_t value, int carry = 0);
|
void subtract(uint8_t& operand, uint8_t value, int carry = 0);
|
||||||
|
@ -36,7 +36,6 @@ void EightBit::Intel8080::handleINT() {
|
|||||||
di();
|
di();
|
||||||
Processor::execute(BUS().DATA());
|
Processor::execute(BUS().DATA());
|
||||||
}
|
}
|
||||||
tick(3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::di() {
|
void EightBit::Intel8080::di() {
|
||||||
@ -48,13 +47,13 @@ void EightBit::Intel8080::ei() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::increment(uint8_t& operand) {
|
void EightBit::Intel8080::increment(uint8_t& operand) {
|
||||||
adjustSZP<Intel8080>(F(), ++operand);
|
F() = adjustSZP<Intel8080>(F(), ++operand);
|
||||||
clearFlag(F(), AC, lowNibble(operand));
|
F() = clearBit(F(), AC, lowNibble(operand));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::decrement(uint8_t& operand) {
|
void EightBit::Intel8080::decrement(uint8_t& operand) {
|
||||||
adjustSZP<Intel8080>(F(), --operand);
|
F() = adjustSZP<Intel8080>(F(), --operand);
|
||||||
setFlag(F(), AC, lowNibble(operand) != Mask4);
|
F() = setBit(F(), AC, lowNibble(operand) != Mask4);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Intel8080::jumpConditionalFlag(const int flag) {
|
bool EightBit::Intel8080::jumpConditionalFlag(const int flag) {
|
||||||
@ -129,7 +128,7 @@ bool EightBit::Intel8080::callConditionalFlag(const int flag) {
|
|||||||
void EightBit::Intel8080::add(const register16_t value) {
|
void EightBit::Intel8080::add(const register16_t value) {
|
||||||
const auto result = HL().word + value.word;
|
const auto result = HL().word + value.word;
|
||||||
HL() = result;
|
HL() = result;
|
||||||
setFlag(F(), CF, result & Bit16);
|
F() = setBit(F(), CF, result & Bit16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::add(const uint8_t value, const int carry) {
|
void EightBit::Intel8080::add(const uint8_t value, const int carry) {
|
||||||
@ -140,8 +139,8 @@ void EightBit::Intel8080::add(const uint8_t value, const int carry) {
|
|||||||
|
|
||||||
A() = result.low;
|
A() = result.low;
|
||||||
|
|
||||||
setFlag(F(), CF, result.word & Bit8);
|
F() = setBit(F(), CF, result.word & Bit8);
|
||||||
adjustSZP<Intel8080>(F(), A());
|
F() = adjustSZP<Intel8080>(F(), A());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::adc(const uint8_t value) {
|
void EightBit::Intel8080::adc(const uint8_t value) {
|
||||||
@ -156,8 +155,8 @@ void EightBit::Intel8080::subtract(uint8_t& operand, const uint8_t value, const
|
|||||||
|
|
||||||
operand = result.low;
|
operand = result.low;
|
||||||
|
|
||||||
setFlag(F(), CF, result.word & Bit8);
|
F() = setBit(F(), CF, result.word & Bit8);
|
||||||
adjustSZP<Intel8080>(F(), operand);
|
F() = adjustSZP<Intel8080>(F(), operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::sbb(const uint8_t value) {
|
void EightBit::Intel8080::sbb(const uint8_t value) {
|
||||||
@ -165,19 +164,19 @@ void EightBit::Intel8080::sbb(const uint8_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::andr(const uint8_t value) {
|
void EightBit::Intel8080::andr(const uint8_t value) {
|
||||||
setFlag(F(), AC, (A() | value) & Bit3);
|
F() = setBit(F(), AC, (A() | value) & Bit3);
|
||||||
clearFlag(F(), CF);
|
F() = clearBit(F(), CF);
|
||||||
adjustSZP<Intel8080>(F(), A() &= value);
|
F() = adjustSZP<Intel8080>(F(), A() &= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::xorr(const uint8_t value) {
|
void EightBit::Intel8080::xorr(const uint8_t value) {
|
||||||
clearFlag(F(), AC | CF);
|
F() = clearBit(F(), AC | CF);
|
||||||
adjustSZP<Intel8080>(F(), A() ^= value);
|
F() = adjustSZP<Intel8080>(F(), A() ^= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::orr(const uint8_t value) {
|
void EightBit::Intel8080::orr(const uint8_t value) {
|
||||||
clearFlag(F(), AC | CF);
|
F() = clearBit(F(), AC | CF);
|
||||||
adjustSZP<Intel8080>(F(), A() |= value);
|
F() = adjustSZP<Intel8080>(F(), A() |= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::compare(const uint8_t value) {
|
void EightBit::Intel8080::compare(const uint8_t value) {
|
||||||
@ -188,24 +187,24 @@ void EightBit::Intel8080::compare(const uint8_t value) {
|
|||||||
void EightBit::Intel8080::rlc() {
|
void EightBit::Intel8080::rlc() {
|
||||||
const auto carry = A() & Bit7;
|
const auto carry = A() & Bit7;
|
||||||
A() = (A() << 1) | (carry >> 7);
|
A() = (A() << 1) | (carry >> 7);
|
||||||
setFlag(F(), CF, carry);
|
F() = setBit(F(), CF, carry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::rrc() {
|
void EightBit::Intel8080::rrc() {
|
||||||
const auto carry = A() & Bit0;
|
const auto carry = A() & Bit0;
|
||||||
A() = (A() >> 1) | (carry << 7);
|
A() = (A() >> 1) | (carry << 7);
|
||||||
setFlag(F(), CF, carry);
|
F() = setBit(F(), CF, carry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::rl() {
|
void EightBit::Intel8080::rl() {
|
||||||
const auto carry = F() & CF;
|
const auto carry = F() & CF;
|
||||||
setFlag(F(), CF, A() & Bit7);
|
F() = setBit(F(), CF, A() & Bit7);
|
||||||
A() = (A() << 1) | carry;
|
A() = (A() << 1) | carry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::rr() {
|
void EightBit::Intel8080::rr() {
|
||||||
const auto carry = F() & CF;
|
const auto carry = F() & CF;
|
||||||
setFlag(F(), CF, A() & Bit0);
|
F() = setBit(F(), CF, A() & Bit0);
|
||||||
A() = (A() >> 1) | (carry << 7);
|
A() = (A() >> 1) | (carry << 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +220,7 @@ void EightBit::Intel8080::daa() {
|
|||||||
carry = true;
|
carry = true;
|
||||||
}
|
}
|
||||||
add(addition);
|
add(addition);
|
||||||
setFlag(F(), CF, carry);
|
F() = setBit(F(), CF, carry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::cma() {
|
void EightBit::Intel8080::cma() {
|
||||||
@ -229,11 +228,11 @@ void EightBit::Intel8080::cma() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::stc() {
|
void EightBit::Intel8080::stc() {
|
||||||
setFlag(F(), CF);
|
F() = setBit(F(), CF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::cmc() {
|
void EightBit::Intel8080::cmc() {
|
||||||
clearFlag(F(), CF, F() & CF);
|
F() = clearBit(F(), CF, F() & CF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Intel8080::xhtl(register16_t& exchange) {
|
void EightBit::Intel8080::xhtl(register16_t& exchange) {
|
||||||
|
@ -150,11 +150,11 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void adjustHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) {
|
void adjustHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(F(), HC, calculateHalfCarryAdd(before, value, calculation));
|
F() = setBit(F(), HC, calculateHalfCarryAdd(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) {
|
void adjustHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(F(), HC, calculateHalfCarrySub(before, value, calculation));
|
F() = setBit(F(), HC, calculateHalfCarrySub(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void subtract(uint8_t& operand, uint8_t value, int carry = 0);
|
void subtract(uint8_t& operand, uint8_t value, int carry = 0);
|
||||||
|
@ -19,7 +19,7 @@ std::array<int, 8> EightBit::GameBoy::CharacterDefinition::get(int row) {
|
|||||||
|
|
||||||
for (int bit = 0; bit < 8; ++bit) {
|
for (int bit = 0; bit < 8; ++bit) {
|
||||||
|
|
||||||
const auto mask = 1 << bit;
|
const auto mask = Chip::bit(bit);
|
||||||
|
|
||||||
const auto bitLow = planeLow & mask ? 1 : 0;
|
const auto bitLow = planeLow & mask ? 1 : 0;
|
||||||
const auto bitHigh = planeHigh & mask ? 0b10 : 0;
|
const auto bitHigh = planeHigh & mask ? 0b10 : 0;
|
||||||
|
@ -125,7 +125,7 @@ void EightBit::GameBoy::Bus::validateCartridgeType() {
|
|||||||
default:
|
default:
|
||||||
if (romSizeSpecification > 6)
|
if (romSizeSpecification > 6)
|
||||||
throw std::domain_error("Invalid ROM size specification");
|
throw std::domain_error("Invalid ROM size specification");
|
||||||
gameRomBanks = 1 << (romSizeSpecification + 1);
|
gameRomBanks = Chip::bit(romSizeSpecification + 1);
|
||||||
if (gameRomBanks != m_gameRomBanks.size())
|
if (gameRomBanks != m_gameRomBanks.size())
|
||||||
throw std::domain_error("ROM size specification mismatch");
|
throw std::domain_error("ROM size specification mismatch");
|
||||||
}
|
}
|
||||||
|
@ -50,15 +50,15 @@ void EightBit::GameBoy::LR35902::ei() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::increment(uint8_t& operand) {
|
void EightBit::GameBoy::LR35902::increment(uint8_t& operand) {
|
||||||
clearFlag(F(), NF);
|
F() = clearBit(F(), NF);
|
||||||
adjustZero<LR35902>(F(), ++operand);
|
F() = adjustZero<LR35902>(F(), ++operand);
|
||||||
clearFlag(F(), HC, lowNibble(operand));
|
F() = clearBit(F(), HC, lowNibble(operand));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::decrement(uint8_t& operand) {
|
void EightBit::GameBoy::LR35902::decrement(uint8_t& operand) {
|
||||||
setFlag(F(), NF);
|
F() = setBit(F(), NF);
|
||||||
clearFlag(F(), HC, lowNibble(operand));
|
F() = clearBit(F(), HC, lowNibble(operand));
|
||||||
adjustZero<LR35902>(F(), --operand);
|
F() = adjustZero<LR35902>(F(), --operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::GameBoy::LR35902::jrConditionalFlag(const int flag) {
|
bool EightBit::GameBoy::LR35902::jrConditionalFlag(const int flag) {
|
||||||
@ -134,8 +134,8 @@ void EightBit::GameBoy::LR35902::add(register16_t& operand, const register16_t v
|
|||||||
|
|
||||||
operand.word = result;
|
operand.word = result;
|
||||||
|
|
||||||
clearFlag(F(), NF);
|
F() = clearBit(F(), NF);
|
||||||
setFlag(F(), CF, result & Bit16);
|
F() = setBit(F(), CF, result & Bit16);
|
||||||
adjustHalfCarryAdd(MEMPTR().high, value.high, operand.high);
|
adjustHalfCarryAdd(MEMPTR().high, value.high, operand.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,9 +147,9 @@ void EightBit::GameBoy::LR35902::add(uint8_t& operand, const uint8_t value, cons
|
|||||||
|
|
||||||
operand = result.low;
|
operand = result.low;
|
||||||
|
|
||||||
clearFlag(F(), NF);
|
F() = clearBit(F(), NF);
|
||||||
setFlag(F(), CF, result.word & Bit8);
|
F() = setBit(F(), CF, result.word & Bit8);
|
||||||
adjustZero<LR35902>(F(), operand);
|
F() = adjustZero<LR35902>(F(), operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::adc(uint8_t& operand, const uint8_t value) {
|
void EightBit::GameBoy::LR35902::adc(uint8_t& operand, const uint8_t value) {
|
||||||
@ -164,9 +164,9 @@ void EightBit::GameBoy::LR35902::subtract(uint8_t& operand, const uint8_t value,
|
|||||||
|
|
||||||
operand = result.low;
|
operand = result.low;
|
||||||
|
|
||||||
setFlag(F(), NF);
|
F() = setBit(F(), NF);
|
||||||
setFlag(F(), CF, result.word & Bit8);
|
F() = setBit(F(), CF, result.word & Bit8);
|
||||||
adjustZero<LR35902>(F(), operand);
|
F() = adjustZero<LR35902>(F(), operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::sbc(const uint8_t value) {
|
void EightBit::GameBoy::LR35902::sbc(const uint8_t value) {
|
||||||
@ -174,19 +174,19 @@ void EightBit::GameBoy::LR35902::sbc(const uint8_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::andr(uint8_t& operand, const uint8_t value) {
|
void EightBit::GameBoy::LR35902::andr(uint8_t& operand, const uint8_t value) {
|
||||||
setFlag(F(), HC);
|
F() = setBit(F(), HC);
|
||||||
clearFlag(F(), CF | NF);
|
F() = clearBit(F(), CF | NF);
|
||||||
adjustZero<LR35902>(F(), operand &= value);
|
F() = adjustZero<LR35902>(F(), operand &= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::xorr(const uint8_t value) {
|
void EightBit::GameBoy::LR35902::xorr(const uint8_t value) {
|
||||||
clearFlag(F(), HC | CF | NF);
|
F() = clearBit(F(), HC | CF | NF);
|
||||||
adjustZero<LR35902>(F(), A() ^= value);
|
F() = adjustZero<LR35902>(F(), A() ^= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::orr(const uint8_t value) {
|
void EightBit::GameBoy::LR35902::orr(const uint8_t value) {
|
||||||
clearFlag(F(), HC | CF | NF);
|
F() = clearBit(F(), HC | CF | NF);
|
||||||
adjustZero<LR35902>(F(), A() |= value);
|
F() = adjustZero<LR35902>(F(), A() |= value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::compare(uint8_t check, const uint8_t value) {
|
void EightBit::GameBoy::LR35902::compare(uint8_t check, const uint8_t value) {
|
||||||
@ -194,69 +194,69 @@ void EightBit::GameBoy::LR35902::compare(uint8_t check, const uint8_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::rlc(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::rlc(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
const auto carry = operand & Bit7;
|
const auto carry = operand & Bit7;
|
||||||
setFlag(F(), CF, carry);
|
F() = setBit(F(), CF, carry);
|
||||||
return (operand << 1) | (carry >> 7);
|
return (operand << 1) | (carry >> 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::rrc(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::rrc(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
const auto carry = operand & Bit0;
|
const auto carry = operand & Bit0;
|
||||||
setFlag(F(), CF, carry);
|
F() = setBit(F(), CF, carry);
|
||||||
return (operand >> 1) | (carry << 7);
|
return (operand >> 1) | (carry << 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::rl(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::rl(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
const auto carry = F() & CF;
|
const auto carry = F() & CF;
|
||||||
setFlag(F(), CF, operand & Bit7);
|
F() = setBit(F(), CF, operand & Bit7);
|
||||||
return (operand << 1) | (carry >> 4); // CF at Bit4
|
return (operand << 1) | (carry >> 4); // CF at Bit4
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::rr(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::rr(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
const auto carry = F() & CF;
|
const auto carry = F() & CF;
|
||||||
setFlag(F(), CF, operand & Bit0);
|
F() = setBit(F(), CF, operand & Bit0);
|
||||||
return (operand >> 1) | (carry << 3); // CF at Bit4
|
return (operand >> 1) | (carry << 3); // CF at Bit4
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::sla(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::sla(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
setFlag(F(), CF, operand & Bit7);
|
F() = setBit(F(), CF, operand & Bit7);
|
||||||
return operand << 1;
|
return operand << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::sra(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::sra(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
setFlag(F(), CF, operand & Bit0);
|
F() = setBit(F(), CF, operand & Bit0);
|
||||||
return (operand >> 1) | (operand & Bit7);
|
return (operand >> 1) | (operand & Bit7);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::swap(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::swap(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | CF);
|
F() = clearBit(F(), NF | HC | CF);
|
||||||
return promoteNibble(operand) | demoteNibble(operand);
|
return promoteNibble(operand) | demoteNibble(operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::srl(const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::srl(const uint8_t operand) {
|
||||||
clearFlag(F(), NF | HC | ZF);
|
F() = clearBit(F(), NF | HC | ZF);
|
||||||
setFlag(F(), CF, operand & Bit0);
|
F() = setBit(F(), CF, operand & Bit0);
|
||||||
return (operand >> 1) & ~Bit7;
|
return (operand >> 1) & ~Bit7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::bit(const int n, const uint8_t operand) {
|
void EightBit::GameBoy::LR35902::bit(const int n, const uint8_t operand) {
|
||||||
const auto carry = F() & CF;
|
const auto carry = F() & CF;
|
||||||
uint8_t discarded = operand;
|
uint8_t discarded = operand;
|
||||||
andr(discarded, 1 << n);
|
andr(discarded, Chip::bit(n));
|
||||||
setFlag(F(), CF, carry);
|
F() = setBit(F(), CF, carry);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::res(const int n, const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::res(const int n, const uint8_t operand) {
|
||||||
return operand & ~(1 << n);
|
return operand & ~Chip::bit(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::GameBoy::LR35902::set(const int n, const uint8_t operand) {
|
uint8_t EightBit::GameBoy::LR35902::set(const int n, const uint8_t operand) {
|
||||||
return operand | (1 << n);
|
return operand | Chip::bit(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::daa() {
|
void EightBit::GameBoy::LR35902::daa() {
|
||||||
@ -275,26 +275,26 @@ void EightBit::GameBoy::LR35902::daa() {
|
|||||||
updated += 0x60;
|
updated += 0x60;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearFlag(F(), HC | ZF);
|
F() = clearBit(F(), HC | ZF);
|
||||||
setFlag(F(), CF, (F() & CF) || (updated & Bit8));
|
F() = setBit(F(), CF, (F() & CF) || (updated & Bit8));
|
||||||
A() = updated & Mask8;
|
A() = updated & Mask8;
|
||||||
|
|
||||||
adjustZero<LR35902>(F(), A());
|
F() = adjustZero<LR35902>(F(), A());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::cpl() {
|
void EightBit::GameBoy::LR35902::cpl() {
|
||||||
setFlag(F(), HC | NF);
|
F() = setBit(F(), HC | NF);
|
||||||
A() = ~A();
|
A() = ~A();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::scf() {
|
void EightBit::GameBoy::LR35902::scf() {
|
||||||
setFlag(F(), CF);
|
F() = setBit(F(), CF);
|
||||||
clearFlag(F(), HC | NF);
|
F() = clearBit(F(), HC | NF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::ccf() {
|
void EightBit::GameBoy::LR35902::ccf() {
|
||||||
clearFlag(F(), NF | HC);
|
F() = clearBit(F(), NF | HC);
|
||||||
clearFlag(F(), CF, F() & CF);
|
F() = clearBit(F(), CF, F() & CF);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EightBit::GameBoy::LR35902::step() {
|
int EightBit::GameBoy::LR35902::step() {
|
||||||
@ -393,7 +393,7 @@ void EightBit::GameBoy::LR35902::executeCB(const int x, const int y, const int z
|
|||||||
}
|
}
|
||||||
tick(2);
|
tick(2);
|
||||||
R(z, operand);
|
R(z, operand);
|
||||||
adjustZero<LR35902>(F(), operand);
|
F() = adjustZero<LR35902>(F(), operand);
|
||||||
if (UNLIKELY(z == 6))
|
if (UNLIKELY(z == 6))
|
||||||
tick(2);
|
tick(2);
|
||||||
break;
|
break;
|
||||||
@ -651,9 +651,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
|
|||||||
const auto result = before + value;
|
const auto result = before + value;
|
||||||
SP() = result;
|
SP() = result;
|
||||||
const auto carried = before ^ value ^ (result & Mask16);
|
const auto carried = before ^ value ^ (result & Mask16);
|
||||||
clearFlag(F(), ZF | NF);
|
F() = clearBit(F(), ZF | NF);
|
||||||
setFlag(F(), CF, carried & Bit8);
|
F() = setBit(F(), CF, carried & Bit8);
|
||||||
setFlag(F(), HC, carried & Bit4);
|
F() = setBit(F(), HC, carried & Bit4);
|
||||||
}
|
}
|
||||||
tick(4);
|
tick(4);
|
||||||
break;
|
break;
|
||||||
@ -667,9 +667,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
|
|||||||
const auto result = before + value;
|
const auto result = before + value;
|
||||||
HL() = result;
|
HL() = result;
|
||||||
const auto carried = before ^ value ^ (result & Mask16);
|
const auto carried = before ^ value ^ (result & Mask16);
|
||||||
clearFlag(F(), ZF | NF);
|
F() = clearBit(F(), ZF | NF);
|
||||||
setFlag(F(), CF, carried & Bit8);
|
F() = setBit(F(), CF, carried & Bit8);
|
||||||
setFlag(F(), HC, carried & Bit4);
|
F() = setBit(F(), HC, carried & Bit4);
|
||||||
}
|
}
|
||||||
tick(3);
|
tick(3);
|
||||||
break;
|
break;
|
||||||
|
@ -97,12 +97,12 @@ namespace EightBit {
|
|||||||
|
|
||||||
// Addressing modes, read
|
// Addressing modes, read
|
||||||
|
|
||||||
enum PageCrossingBehavior { AlwaysReadTwice, MaybeReadTwice };
|
enum class PageCrossingBehavior { AlwaysReadTwice, MaybeReadTwice };
|
||||||
|
|
||||||
uint8_t AM_Immediate();
|
uint8_t AM_Immediate();
|
||||||
uint8_t AM_Absolute();
|
uint8_t AM_Absolute();
|
||||||
uint8_t AM_ZeroPage();
|
uint8_t AM_ZeroPage();
|
||||||
uint8_t AM_AbsoluteX(PageCrossingBehavior behaviour = MaybeReadTwice);
|
uint8_t AM_AbsoluteX(PageCrossingBehavior behaviour = PageCrossingBehavior::MaybeReadTwice);
|
||||||
uint8_t AM_AbsoluteY();
|
uint8_t AM_AbsoluteY();
|
||||||
uint8_t AM_ZeroPageX();
|
uint8_t AM_ZeroPageX();
|
||||||
uint8_t AM_ZeroPageY();
|
uint8_t AM_ZeroPageY();
|
||||||
@ -111,8 +111,8 @@ namespace EightBit {
|
|||||||
|
|
||||||
// Flag adjustment
|
// Flag adjustment
|
||||||
|
|
||||||
void adjustZero(const uint8_t datum) { clearFlag(P(), ZF, datum); }
|
void adjustZero(const uint8_t datum) { P() = clearBit(P(), ZF, datum); }
|
||||||
void adjustNegative(const uint8_t datum) { setFlag(P(), NF, datum & NF); }
|
void adjustNegative(const uint8_t datum) { P() = setBit(P(), NF, datum & NF); }
|
||||||
|
|
||||||
void adjustNZ(const uint8_t datum) {
|
void adjustNZ(const uint8_t datum) {
|
||||||
adjustZero(datum);
|
adjustZero(datum);
|
||||||
|
@ -84,7 +84,7 @@ void EightBit::MOS6502::interrupt() {
|
|||||||
pushWord(PC());
|
pushWord(PC());
|
||||||
push(P() | (software ? BF : 0));
|
push(P() | (software ? BF : 0));
|
||||||
}
|
}
|
||||||
setFlag(P(), IF); // Disable IRQ
|
P() = setBit(P(), IF); // Disable IRQ
|
||||||
const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector);
|
const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector);
|
||||||
jump(getWordPaged(0xff, vector));
|
jump(getWordPaged(0xff, vector));
|
||||||
m_handlingRESET = m_handlingNMI = m_handlingINT = false;
|
m_handlingRESET = m_handlingNMI = m_handlingINT = false;
|
||||||
@ -137,13 +137,13 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0x15: A() = orr(A(), AM_ZeroPageX()); break; // ORA (zero page, X)
|
case 0x15: A() = orr(A(), AM_ZeroPageX()); break; // ORA (zero page, X)
|
||||||
case 0x16: busReadModifyWrite(asl(AM_ZeroPageX())); break; // ASL (zero page, X)
|
case 0x16: busReadModifyWrite(asl(AM_ZeroPageX())); break; // ASL (zero page, X)
|
||||||
case 0x17: slo(AM_ZeroPageX()); break; // *SLO (zero page, X)
|
case 0x17: slo(AM_ZeroPageX()); break; // *SLO (zero page, X)
|
||||||
case 0x18: busRead(); clearFlag(P(), CF); break; // CLC (implied)
|
case 0x18: busRead(); P() = clearBit(P(), CF); break; // CLC (implied)
|
||||||
case 0x19: A() = orr(A(), AM_AbsoluteY()); break; // ORA (absolute, Y)
|
case 0x19: A() = orr(A(), AM_AbsoluteY()); break; // ORA (absolute, Y)
|
||||||
case 0x1a: busRead(); break; // *NOP (implied)
|
case 0x1a: busRead(); break; // *NOP (implied)
|
||||||
case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y)
|
case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y)
|
||||||
case 0x1c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
case 0x1c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||||
case 0x1d: A() = orr(A(), AM_AbsoluteX()); break; // ORA (absolute, X)
|
case 0x1d: A() = orr(A(), AM_AbsoluteX()); break; // ORA (absolute, X)
|
||||||
case 0x1e: busReadModifyWrite(asl(AM_AbsoluteX(AlwaysReadTwice))); break; // ASL (absolute, X)
|
case 0x1e: busReadModifyWrite(asl(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ASL (absolute, X)
|
||||||
case 0x1f: slo(AM_AbsoluteX()); break; // *SLO (absolute, X)
|
case 0x1f: slo(AM_AbsoluteX()); break; // *SLO (absolute, X)
|
||||||
|
|
||||||
case 0x20: jsr(); break; // JSR (absolute)
|
case 0x20: jsr(); break; // JSR (absolute)
|
||||||
@ -171,13 +171,13 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0x35: A() = andr(A(), AM_ZeroPageX()); break; // AND (zero page, X)
|
case 0x35: A() = andr(A(), AM_ZeroPageX()); break; // AND (zero page, X)
|
||||||
case 0x36: busReadModifyWrite(rol(AM_ZeroPageX())); break; // ROL (zero page, X)
|
case 0x36: busReadModifyWrite(rol(AM_ZeroPageX())); break; // ROL (zero page, X)
|
||||||
case 0x37: rla(AM_ZeroPageX()); break; // *RLA (zero page, X)
|
case 0x37: rla(AM_ZeroPageX()); break; // *RLA (zero page, X)
|
||||||
case 0x38: busRead(); setFlag(P(), CF); break; // SEC (implied)
|
case 0x38: busRead(); P() = setBit(P(), CF); break; // SEC (implied)
|
||||||
case 0x39: A() = andr(A(), AM_AbsoluteY()); break; // AND (absolute, Y)
|
case 0x39: A() = andr(A(), AM_AbsoluteY()); break; // AND (absolute, Y)
|
||||||
case 0x3a: busRead(); break; // *NOP (implied)
|
case 0x3a: busRead(); break; // *NOP (implied)
|
||||||
case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y)
|
case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y)
|
||||||
case 0x3c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
case 0x3c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||||
case 0x3d: A() = andr(A(), AM_AbsoluteX()); break; // AND (absolute, X)
|
case 0x3d: A() = andr(A(), AM_AbsoluteX()); break; // AND (absolute, X)
|
||||||
case 0x3e: busReadModifyWrite(rol(AM_AbsoluteX(AlwaysReadTwice))); break; // ROL (absolute, X)
|
case 0x3e: busReadModifyWrite(rol(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROL (absolute, X)
|
||||||
case 0x3f: rla(AM_AbsoluteX()); break; // *RLA (absolute, X)
|
case 0x3f: rla(AM_AbsoluteX()); break; // *RLA (absolute, X)
|
||||||
|
|
||||||
case 0x40: busRead(); rti(); break; // RTI (implied)
|
case 0x40: busRead(); rti(); break; // RTI (implied)
|
||||||
@ -205,13 +205,13 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0x55: A() = eorr(A(), AM_ZeroPageX()); break; // EOR (zero page, X)
|
case 0x55: A() = eorr(A(), AM_ZeroPageX()); break; // EOR (zero page, X)
|
||||||
case 0x56: busReadModifyWrite(lsr(AM_ZeroPageX())); break; // LSR (zero page, X)
|
case 0x56: busReadModifyWrite(lsr(AM_ZeroPageX())); break; // LSR (zero page, X)
|
||||||
case 0x57: sre(AM_ZeroPageX()); break; // *SRE (zero page, X)
|
case 0x57: sre(AM_ZeroPageX()); break; // *SRE (zero page, X)
|
||||||
case 0x58: busRead(); clearFlag(P(), IF); break; // CLI (implied)
|
case 0x58: busRead(); P() = clearBit(P(), IF); break; // CLI (implied)
|
||||||
case 0x59: A() = eorr(A(), AM_AbsoluteY()); break; // EOR (absolute, Y)
|
case 0x59: A() = eorr(A(), AM_AbsoluteY()); break; // EOR (absolute, Y)
|
||||||
case 0x5a: busRead(); break; // *NOP (implied)
|
case 0x5a: busRead(); break; // *NOP (implied)
|
||||||
case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y)
|
case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y)
|
||||||
case 0x5c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
case 0x5c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||||
case 0x5d: A() = eorr(A(), AM_AbsoluteX()); break; // EOR (absolute, X)
|
case 0x5d: A() = eorr(A(), AM_AbsoluteX()); break; // EOR (absolute, X)
|
||||||
case 0x5e: busReadModifyWrite(lsr(AM_AbsoluteX(AlwaysReadTwice))); break; // LSR (absolute, X)
|
case 0x5e: busReadModifyWrite(lsr(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // LSR (absolute, X)
|
||||||
case 0x5f: sre(AM_AbsoluteX()); break; // *SRE (absolute, X)
|
case 0x5f: sre(AM_AbsoluteX()); break; // *SRE (absolute, X)
|
||||||
|
|
||||||
case 0x60: busRead(); rts(); break; // RTS (implied)
|
case 0x60: busRead(); rts(); break; // RTS (implied)
|
||||||
@ -239,13 +239,13 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0x75: A() = adc(A(), AM_ZeroPageX()); break; // ADC (zero page, X)
|
case 0x75: A() = adc(A(), AM_ZeroPageX()); break; // ADC (zero page, X)
|
||||||
case 0x76: busReadModifyWrite(ror(AM_ZeroPageX())); break; // ROR (zero page, X)
|
case 0x76: busReadModifyWrite(ror(AM_ZeroPageX())); break; // ROR (zero page, X)
|
||||||
case 0x77: rra(AM_ZeroPageX()); break; // *RRA (zero page, X)
|
case 0x77: rra(AM_ZeroPageX()); break; // *RRA (zero page, X)
|
||||||
case 0x78: busRead(); setFlag(P(), IF); break; // SEI (implied)
|
case 0x78: busRead(); P() = setBit(P(), IF); break; // SEI (implied)
|
||||||
case 0x79: A() = adc(A(), AM_AbsoluteY()); break; // ADC (absolute, Y)
|
case 0x79: A() = adc(A(), AM_AbsoluteY()); break; // ADC (absolute, Y)
|
||||||
case 0x7a: busRead(); break; // *NOP (implied)
|
case 0x7a: busRead(); break; // *NOP (implied)
|
||||||
case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y)
|
case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y)
|
||||||
case 0x7c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
case 0x7c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||||
case 0x7d: A() = adc(A(), AM_AbsoluteX()); break; // ADC (absolute, X)
|
case 0x7d: A() = adc(A(), AM_AbsoluteX()); break; // ADC (absolute, X)
|
||||||
case 0x7e: busReadModifyWrite(ror(AM_AbsoluteX(AlwaysReadTwice))); break; // ROR (absolute, X)
|
case 0x7e: busReadModifyWrite(ror(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROR (absolute, X)
|
||||||
case 0x7f: rra(AM_AbsoluteX()); break; // *RRA (absolute, X)
|
case 0x7f: rra(AM_AbsoluteX()); break; // *RRA (absolute, X)
|
||||||
|
|
||||||
case 0x80: AM_Immediate(); break; // *NOP (immediate)
|
case 0x80: AM_Immediate(); break; // *NOP (immediate)
|
||||||
@ -307,7 +307,7 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0xb5: A() = through(AM_ZeroPageX()); break; // LDA (zero page, X)
|
case 0xb5: A() = through(AM_ZeroPageX()); break; // LDA (zero page, X)
|
||||||
case 0xb6: X() = through(AM_ZeroPageY()); break; // LDX (zero page, Y)
|
case 0xb6: X() = through(AM_ZeroPageY()); break; // LDX (zero page, Y)
|
||||||
case 0xb7: A() = X() = through(AM_ZeroPageY()); break; // *LAX (zero page, Y)
|
case 0xb7: A() = X() = through(AM_ZeroPageY()); break; // *LAX (zero page, Y)
|
||||||
case 0xb8: busRead(); clearFlag(P(), VF); break; // CLV (implied)
|
case 0xb8: busRead(); P() = clearBit(P(), VF); break; // CLV (implied)
|
||||||
case 0xb9: A() = through(AM_AbsoluteY()); break; // LDA (absolute, Y)
|
case 0xb9: A() = through(AM_AbsoluteY()); break; // LDA (absolute, Y)
|
||||||
case 0xba: busRead(); X() = through(S()); break; // TSX (implied)
|
case 0xba: busRead(); X() = through(S()); break; // TSX (implied)
|
||||||
case 0xbb: break;
|
case 0xbb: break;
|
||||||
@ -341,13 +341,13 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0xd5: cmp(A(), AM_ZeroPageX()); break; // CMP (zero page, X)
|
case 0xd5: cmp(A(), AM_ZeroPageX()); break; // CMP (zero page, X)
|
||||||
case 0xd6: busReadModifyWrite(dec(AM_ZeroPageX())); break; // DEC (zero page, X)
|
case 0xd6: busReadModifyWrite(dec(AM_ZeroPageX())); break; // DEC (zero page, X)
|
||||||
case 0xd7: dcp(AM_ZeroPageX()); break; // *DCP (zero page, X)
|
case 0xd7: dcp(AM_ZeroPageX()); break; // *DCP (zero page, X)
|
||||||
case 0xd8: busRead(); clearFlag(P(), DF); break; // CLD (implied)
|
case 0xd8: busRead(); P() = clearBit(P(), DF); break; // CLD (implied)
|
||||||
case 0xd9: cmp(A(), AM_AbsoluteY()); break; // CMP (absolute, Y)
|
case 0xd9: cmp(A(), AM_AbsoluteY()); break; // CMP (absolute, Y)
|
||||||
case 0xda: busRead(); break; // *NOP (implied)
|
case 0xda: busRead(); break; // *NOP (implied)
|
||||||
case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y)
|
case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y)
|
||||||
case 0xdc: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
case 0xdc: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||||
case 0xdd: cmp(A(), AM_AbsoluteX()); break; // CMP (absolute, X)
|
case 0xdd: cmp(A(), AM_AbsoluteX()); break; // CMP (absolute, X)
|
||||||
case 0xde: busReadModifyWrite(dec(AM_AbsoluteX(AlwaysReadTwice))); break; // DEC (absolute, X)
|
case 0xde: busReadModifyWrite(dec(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // DEC (absolute, X)
|
||||||
case 0xdf: dcp(AM_AbsoluteX()); break; // *DCP (absolute, X)
|
case 0xdf: dcp(AM_AbsoluteX()); break; // *DCP (absolute, X)
|
||||||
|
|
||||||
case 0xe0: cmp(X(), AM_Immediate()); break; // CPX (immediate)
|
case 0xe0: cmp(X(), AM_Immediate()); break; // CPX (immediate)
|
||||||
@ -375,13 +375,13 @@ int EightBit::MOS6502::execute() {
|
|||||||
case 0xf5: A() = sbc(A(), AM_ZeroPageX()); break; // SBC (zero page, X)
|
case 0xf5: A() = sbc(A(), AM_ZeroPageX()); break; // SBC (zero page, X)
|
||||||
case 0xf6: busReadModifyWrite(inc(AM_ZeroPageX())); break; // INC (zero page, X)
|
case 0xf6: busReadModifyWrite(inc(AM_ZeroPageX())); break; // INC (zero page, X)
|
||||||
case 0xf7: isb(AM_ZeroPageX()); break; // *ISB (zero page, X)
|
case 0xf7: isb(AM_ZeroPageX()); break; // *ISB (zero page, X)
|
||||||
case 0xf8: busRead(); setFlag(P(), DF); break; // SED (implied)
|
case 0xf8: busRead(); P() = setBit(P(), DF); break; // SED (implied)
|
||||||
case 0xf9: A() = sbc(A(), AM_AbsoluteY()); break; // SBC (absolute, Y)
|
case 0xf9: A() = sbc(A(), AM_AbsoluteY()); break; // SBC (absolute, Y)
|
||||||
case 0xfa: busRead(); break; // *NOP (implied)
|
case 0xfa: busRead(); break; // *NOP (implied)
|
||||||
case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y)
|
case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y)
|
||||||
case 0xfc: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
case 0xfc: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||||
case 0xfd: A() = sbc(A(), AM_AbsoluteX()); break; // SBC (absolute, X)
|
case 0xfd: A() = sbc(A(), AM_AbsoluteX()); break; // SBC (absolute, X)
|
||||||
case 0xfe: busReadModifyWrite(inc(AM_AbsoluteX(AlwaysReadTwice))); break; // INC (absolute, X)
|
case 0xfe: busReadModifyWrite(inc(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // INC (absolute, X)
|
||||||
case 0xff: isb(AM_AbsoluteX()); break; // *ISB (absolute, X)
|
case 0xff: isb(AM_AbsoluteX()); break; // *ISB (absolute, X)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +482,7 @@ uint8_t EightBit::MOS6502::AM_ZeroPage() {
|
|||||||
uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) {
|
uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) {
|
||||||
const auto [address, page] = Address_AbsoluteX();
|
const auto [address, page] = Address_AbsoluteX();
|
||||||
auto possible = getBytePaged(page, address.low);
|
auto possible = getBytePaged(page, address.low);
|
||||||
if ((behaviour == AlwaysReadTwice) || UNLIKELY(page != address.high))
|
if ((behaviour == PageCrossingBehavior::AlwaysReadTwice) || UNLIKELY(page != address.high))
|
||||||
possible = Processor::busRead(address);
|
possible = Processor::busRead(address);
|
||||||
return possible;
|
return possible;
|
||||||
}
|
}
|
||||||
@ -536,8 +536,8 @@ uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) {
|
|||||||
|
|
||||||
const auto difference = m_intermediate;
|
const auto difference = m_intermediate;
|
||||||
adjustNZ(difference.low);
|
adjustNZ(difference.low);
|
||||||
setFlag(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF);
|
P() = setBit(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF);
|
||||||
clearFlag(P(), CF, difference.high);
|
P() = clearBit(P(), CF, difference.high);
|
||||||
|
|
||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
@ -580,8 +580,8 @@ uint8_t EightBit::MOS6502::add(uint8_t operand, uint8_t data, int carry) {
|
|||||||
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) {
|
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) {
|
||||||
m_intermediate.word = operand + data + carry;
|
m_intermediate.word = operand + data + carry;
|
||||||
|
|
||||||
setFlag(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
|
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
|
||||||
setFlag(P(), CF, m_intermediate.high & CF);
|
P() = setBit(P(), CF, m_intermediate.high & CF);
|
||||||
|
|
||||||
return m_intermediate.low;
|
return m_intermediate.low;
|
||||||
}
|
}
|
||||||
@ -595,12 +595,12 @@ uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) {
|
|||||||
low += 6;
|
low += 6;
|
||||||
|
|
||||||
uint8_t high = highNibble(operand) + highNibble(data) + (low > 0xf ? 1 : 0);
|
uint8_t high = highNibble(operand) + highNibble(data) + (low > 0xf ? 1 : 0);
|
||||||
setFlag(P(), VF, ~(operand ^ data) & (operand ^ promoteNibble(high)) & NF);
|
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ promoteNibble(high)) & NF);
|
||||||
|
|
||||||
if (high > 9)
|
if (high > 9)
|
||||||
high += 6;
|
high += 6;
|
||||||
|
|
||||||
setFlag(P(), CF, high > 0xf);
|
P() = setBit(P(), CF, high > 0xf);
|
||||||
|
|
||||||
return promoteNibble(high) | lowNibble(low);
|
return promoteNibble(high) | lowNibble(low);
|
||||||
}
|
}
|
||||||
@ -610,12 +610,12 @@ uint8_t EightBit::MOS6502::andr(const uint8_t operand, const uint8_t data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::asl(const uint8_t value) {
|
uint8_t EightBit::MOS6502::asl(const uint8_t value) {
|
||||||
setFlag(P(), CF, value & Bit7);
|
P() = setBit(P(), CF, value & Bit7);
|
||||||
return through(value << 1);
|
return through(value << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) {
|
void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) {
|
||||||
setFlag(P(), VF, data & VF);
|
P() = setBit(P(), VF, data & VF);
|
||||||
adjustZero(operand & data);
|
adjustZero(operand & data);
|
||||||
adjustNegative(data);
|
adjustNegative(data);
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) {
|
|||||||
void EightBit::MOS6502::cmp(const uint8_t first, const uint8_t second) {
|
void EightBit::MOS6502::cmp(const uint8_t first, const uint8_t second) {
|
||||||
const register16_t result = first - second;
|
const register16_t result = first - second;
|
||||||
adjustNZ(result.low);
|
adjustNZ(result.low);
|
||||||
clearFlag(P(), CF, result.high);
|
P() = clearBit(P(), CF, result.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::dec(const uint8_t value) {
|
uint8_t EightBit::MOS6502::dec(const uint8_t value) {
|
||||||
@ -647,7 +647,7 @@ void EightBit::MOS6502::jsr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::lsr(const uint8_t value) {
|
uint8_t EightBit::MOS6502::lsr(const uint8_t value) {
|
||||||
setFlag(P(), CF, value & Bit0);
|
P() = setBit(P(), CF, value & Bit0);
|
||||||
return through(value >> 1);
|
return through(value >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,14 +665,14 @@ void EightBit::MOS6502::plp() {
|
|||||||
|
|
||||||
uint8_t EightBit::MOS6502::rol(const uint8_t operand) {
|
uint8_t EightBit::MOS6502::rol(const uint8_t operand) {
|
||||||
const auto carryIn = carry();
|
const auto carryIn = carry();
|
||||||
setFlag(P(), CF, operand & Bit7);
|
P() = setBit(P(), CF, operand & Bit7);
|
||||||
const uint8_t result = (operand << 1) | carryIn;
|
const uint8_t result = (operand << 1) | carryIn;
|
||||||
return through(result);
|
return through(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::ror(const uint8_t operand) {
|
uint8_t EightBit::MOS6502::ror(const uint8_t operand) {
|
||||||
const auto carryIn = carry();
|
const auto carryIn = carry();
|
||||||
setFlag(P(), CF, operand & Bit0);
|
P() = setBit(P(), CF, operand & Bit0);
|
||||||
const uint8_t result = (operand >> 1) | (carryIn << 7);
|
const uint8_t result = (operand >> 1) | (carryIn << 7);
|
||||||
return through(result);
|
return through(result);
|
||||||
}
|
}
|
||||||
@ -693,14 +693,14 @@ void EightBit::MOS6502::rts() {
|
|||||||
|
|
||||||
void EightBit::MOS6502::anc(const uint8_t value) {
|
void EightBit::MOS6502::anc(const uint8_t value) {
|
||||||
A() = andr(A(), value);
|
A() = andr(A(), value);
|
||||||
setFlag(P(), CF, A() & Bit7);
|
P() = setBit(P(), CF, A() & Bit7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::arr(const uint8_t value) {
|
void EightBit::MOS6502::arr(const uint8_t value) {
|
||||||
A() = andr(A(), value);
|
A() = andr(A(), value);
|
||||||
A() = ror(A());
|
A() = ror(A());
|
||||||
setFlag(P(), CF, A() & Bit6);
|
P() = setBit(P(), CF, A() & Bit6);
|
||||||
setFlag(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5));
|
P() = setBit(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::asr(const uint8_t value) {
|
void EightBit::MOS6502::asr(const uint8_t value) {
|
||||||
@ -710,7 +710,7 @@ void EightBit::MOS6502::asr(const uint8_t value) {
|
|||||||
|
|
||||||
void EightBit::MOS6502::axs(const uint8_t value) {
|
void EightBit::MOS6502::axs(const uint8_t value) {
|
||||||
X() = through(sub(A() & X(), value));
|
X() = through(sub(A() & X(), value));
|
||||||
clearFlag(P(), CF, m_intermediate.high);
|
P() = clearBit(P(), CF, m_intermediate.high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::dcp(const uint8_t value) {
|
void EightBit::MOS6502::dcp(const uint8_t value) {
|
||||||
|
@ -38,11 +38,11 @@ void EightBit::M6532::step() {
|
|||||||
|
|
||||||
const bool interruptPA7 = m_allowPA7Interrupts && (PA() & Bit7);
|
const bool interruptPA7 = m_allowPA7Interrupts && (PA() & Bit7);
|
||||||
if (interruptPA7)
|
if (interruptPA7)
|
||||||
setFlag(IF(), Bit6);
|
IF() = setBit(IF(), Bit6);
|
||||||
|
|
||||||
const bool interruptTimer = m_allowTimerInterrupts && (m_timerInterval == 0);
|
const bool interruptTimer = m_allowTimerInterrupts && (m_timerInterval == 0);
|
||||||
if (interruptTimer)
|
if (interruptTimer)
|
||||||
setFlag(IF(), Bit7);
|
IF() = setBit(IF(), Bit7);
|
||||||
|
|
||||||
match(IRQ(), !(interruptPA7 || interruptTimer));
|
match(IRQ(), !(interruptPA7 || interruptTimer));
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ void EightBit::M6532::step() {
|
|||||||
|
|
||||||
if (read && a2 && a0) {
|
if (read && a2 && a0) {
|
||||||
DATA() = IF();
|
DATA() = IF();
|
||||||
clearFlag(IF(), Bit6);
|
IF() = clearBit(IF(), Bit6);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_allowTimerInterrupts = !!a3;
|
m_allowTimerInterrupts = !!a3;
|
||||||
@ -115,7 +115,7 @@ void EightBit::M6532::step() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_currentIncrement = m_timerIncrement;
|
m_currentIncrement = m_timerIncrement;
|
||||||
clearFlag(IF(), Bit7);
|
IF() = clearBit(IF(), Bit7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,10 +195,10 @@ namespace EightBit {
|
|||||||
|
|
||||||
// Flag adjustment
|
// Flag adjustment
|
||||||
|
|
||||||
template<class T> void adjustZero(const T datum) { clearFlag(CC(), ZF, datum); }
|
template<class T> void adjustZero(const T datum) { CC() = clearBit(CC(), ZF, datum); }
|
||||||
void adjustZero(const register16_t datum) { clearFlag(CC(), ZF, datum.word); }
|
void adjustZero(const register16_t datum) { CC() = clearBit(CC(), ZF, datum.word); }
|
||||||
void adjustNegative(const uint8_t datum) { setFlag(CC(), NF, datum & Bit7); }
|
void adjustNegative(const uint8_t datum) { CC() = setBit(CC(), NF, datum & Bit7); }
|
||||||
void adjustNegative(const uint16_t datum) { setFlag(CC(), NF, datum & Bit15); }
|
void adjustNegative(const uint16_t datum) { CC() = setBit(CC(), NF, datum & Bit15); }
|
||||||
void adjustNegative(const register16_t datum) { adjustNegative(datum.word); }
|
void adjustNegative(const register16_t datum) { adjustNegative(datum.word); }
|
||||||
|
|
||||||
template<class T> void adjustNZ(const T datum) {
|
template<class T> void adjustNZ(const T datum) {
|
||||||
@ -206,24 +206,24 @@ namespace EightBit {
|
|||||||
adjustNegative(datum);
|
adjustNegative(datum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustCarry(const uint16_t datum) { setFlag(CC(), CF, datum & Bit8); } // 8-bit addition
|
void adjustCarry(const uint16_t datum) { CC() = setBit(CC(), CF, datum & Bit8); } // 8-bit addition
|
||||||
void adjustCarry(const uint32_t datum) { setFlag(CC(), CF, datum & Bit16); } // 16-bit addition
|
void adjustCarry(const uint32_t datum) { CC() = setBit(CC(), CF, datum & Bit16); } // 16-bit addition
|
||||||
void adjustCarry(const register16_t datum) { adjustCarry(datum.word); }
|
void adjustCarry(const register16_t datum) { adjustCarry(datum.word); }
|
||||||
|
|
||||||
void adjustBorrow(const uint16_t datum) { clearFlag(CC(), CF, datum & Bit8); } // 8-bit subtraction
|
void adjustBorrow(const uint16_t datum) { CC() = clearBit(CC(), CF, datum & Bit8); } // 8-bit subtraction
|
||||||
void adjustBorrow(const uint32_t datum) { clearFlag(CC(), CF, datum & Bit16); } // 16-bit subtraction
|
void adjustBorrow(const uint32_t datum) { CC() = clearBit(CC(), CF, datum & Bit16); } // 16-bit subtraction
|
||||||
void adjustBorrow(const register16_t datum) { adjustBorrow(datum.word); }
|
void adjustBorrow(const register16_t datum) { adjustBorrow(datum.word); }
|
||||||
|
|
||||||
void adjustOverflow(const uint8_t before, const uint8_t data, const register16_t after) {
|
void adjustOverflow(const uint8_t before, const uint8_t data, const register16_t after) {
|
||||||
const uint8_t lowAfter = after.low;
|
const uint8_t lowAfter = after.low;
|
||||||
const uint8_t highAfter = after.high;
|
const uint8_t highAfter = after.high;
|
||||||
setFlag(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 7)) & Bit7);
|
CC() = setBit(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 7)) & Bit7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustOverflow(const uint16_t before, const uint16_t data, const uint32_t after) {
|
void adjustOverflow(const uint16_t before, const uint16_t data, const uint32_t after) {
|
||||||
const uint16_t lowAfter = after & Mask16;
|
const uint16_t lowAfter = after & Mask16;
|
||||||
const uint16_t highAfter = after >> 16;
|
const uint16_t highAfter = after >> 16;
|
||||||
setFlag(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 15)) & Bit15);
|
CC() = setBit(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 15)) & Bit15);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustOverflow(const register16_t before, const register16_t data, const register16_t after) {
|
void adjustOverflow(const register16_t before, const register16_t data, const register16_t after) {
|
||||||
@ -231,7 +231,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void adjustHalfCarry(const uint8_t before, const uint8_t data, const uint8_t after) {
|
void adjustHalfCarry(const uint8_t before, const uint8_t data, const uint8_t after) {
|
||||||
setFlag(CC(), HF, (before ^ data ^ after) & Bit4);
|
CC() = setBit(CC(), HF, (before ^ data ^ after) & Bit4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustAddition(const uint8_t before, const uint8_t data, const register16_t after) {
|
void adjustAddition(const uint8_t before, const uint8_t data, const register16_t after) {
|
||||||
@ -314,7 +314,7 @@ namespace EightBit {
|
|||||||
void restoreRegisterState();
|
void restoreRegisterState();
|
||||||
|
|
||||||
template <class T> T through(const T data) {
|
template <class T> T through(const T data) {
|
||||||
clearFlag(CC(), VF);
|
CC() = clearBit(CC(), VF);
|
||||||
adjustNZ(data);
|
adjustNZ(data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,8 @@ void EightBit::mc6809::handleRESET() {
|
|||||||
lowerBA();
|
lowerBA();
|
||||||
raiseBS();
|
raiseBS();
|
||||||
DP() = 0;
|
DP() = 0;
|
||||||
setFlag(CC(), IF); // Disable IRQ
|
CC() = setBit(CC(), IF); // Disable IRQ
|
||||||
setFlag(CC(), FF); // Disable FIRQ
|
CC() = setBit(CC(), FF); // Disable FIRQ
|
||||||
jump(getWordPaged(0xff, RESETvector));
|
jump(getWordPaged(0xff, RESETvector));
|
||||||
tick(10);
|
tick(10);
|
||||||
}
|
}
|
||||||
@ -66,8 +66,8 @@ void EightBit::mc6809::handleNMI() {
|
|||||||
lowerBA();
|
lowerBA();
|
||||||
raiseBS();
|
raiseBS();
|
||||||
saveEntireRegisterState();
|
saveEntireRegisterState();
|
||||||
setFlag(CC(), IF); // Disable IRQ
|
CC() = setBit(CC(), IF); // Disable IRQ
|
||||||
setFlag(CC(), FF); // Disable FIRQ
|
CC() = setBit(CC(), FF); // Disable FIRQ
|
||||||
jump(getWordPaged(0xff, NMIvector));
|
jump(getWordPaged(0xff, NMIvector));
|
||||||
tick(12);
|
tick(12);
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ void EightBit::mc6809::handleINT() {
|
|||||||
lowerBA();
|
lowerBA();
|
||||||
raiseBS();
|
raiseBS();
|
||||||
saveEntireRegisterState();
|
saveEntireRegisterState();
|
||||||
setFlag(CC(), IF); // Disable IRQ
|
CC() = setBit(CC(), IF); // Disable IRQ
|
||||||
jump(getWordPaged(0xff, IRQvector));
|
jump(getWordPaged(0xff, IRQvector));
|
||||||
tick(12);
|
tick(12);
|
||||||
}
|
}
|
||||||
@ -87,8 +87,8 @@ void EightBit::mc6809::handleFIRQ() {
|
|||||||
lowerBA();
|
lowerBA();
|
||||||
raiseBS();
|
raiseBS();
|
||||||
savePartialRegisterState();
|
savePartialRegisterState();
|
||||||
setFlag(CC(), IF); // Disable IRQ
|
CC() = setBit(CC(), IF); // Disable IRQ
|
||||||
setFlag(CC(), FF); // Disable FIRQ
|
CC() = setBit(CC(), FF); // Disable FIRQ
|
||||||
jump(getWordPaged(0xff, FIRQvector));
|
jump(getWordPaged(0xff, FIRQvector));
|
||||||
tick(12);
|
tick(12);
|
||||||
}
|
}
|
||||||
@ -765,12 +765,12 @@ EightBit::register16_t EightBit::mc6809::AM_extended_word() {
|
|||||||
//
|
//
|
||||||
|
|
||||||
void EightBit::mc6809::saveEntireRegisterState() {
|
void EightBit::mc6809::saveEntireRegisterState() {
|
||||||
setFlag(CC(), EF);
|
CC() = setBit(CC(), EF);
|
||||||
saveRegisterState();
|
saveRegisterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::mc6809::savePartialRegisterState() {
|
void EightBit::mc6809::savePartialRegisterState() {
|
||||||
clearFlag(CC(), EF);
|
CC() = clearBit(CC(), EF);
|
||||||
saveRegisterState();
|
saveRegisterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,15 +805,15 @@ uint8_t EightBit::mc6809::andr(const uint8_t operand, const uint8_t data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::asl(uint8_t operand) {
|
uint8_t EightBit::mc6809::asl(uint8_t operand) {
|
||||||
setFlag(CC(), CF, operand & Bit7);
|
CC() = setBit(CC(), CF, operand & Bit7);
|
||||||
adjustNZ(operand <<= 1);
|
adjustNZ(operand <<= 1);
|
||||||
const auto overflow = carry() ^ (negative() >> 3);
|
const auto overflow = carry() ^ (negative() >> 3);
|
||||||
setFlag(CC(), VF, overflow);
|
CC() = setBit(CC(), VF, overflow);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::asr(uint8_t operand) {
|
uint8_t EightBit::mc6809::asr(uint8_t operand) {
|
||||||
setFlag(CC(), CF, operand & Bit0);
|
CC() = setBit(CC(), CF, operand & Bit0);
|
||||||
const uint8_t result = (operand >> 1) | Bit7;
|
const uint8_t result = (operand >> 1) | Bit7;
|
||||||
adjustNZ(result);
|
adjustNZ(result);
|
||||||
return result;
|
return result;
|
||||||
@ -824,7 +824,7 @@ void EightBit::mc6809::bit(const uint8_t operand, const uint8_t data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::clr() {
|
uint8_t EightBit::mc6809::clr() {
|
||||||
clearFlag(CC(), CF);
|
CC() = clearBit(CC(), CF);
|
||||||
return through((uint8_t)0U);
|
return through((uint8_t)0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,7 +837,7 @@ void EightBit::mc6809::cmp(const register16_t operand, const register16_t data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::com(const uint8_t operand) {
|
uint8_t EightBit::mc6809::com(const uint8_t operand) {
|
||||||
setFlag(CC(), CF);
|
CC() = setBit(CC(), CF);
|
||||||
return through((uint8_t)~operand);
|
return through((uint8_t)~operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +849,7 @@ void EightBit::mc6809::cwai(const uint8_t data) {
|
|||||||
|
|
||||||
uint8_t EightBit::mc6809::da(uint8_t operand) {
|
uint8_t EightBit::mc6809::da(uint8_t operand) {
|
||||||
|
|
||||||
setFlag(CC(), CF, operand > 0x99);
|
CC() = setBit(CC(), CF, operand > 0x99);
|
||||||
|
|
||||||
const auto lowAdjust = halfCarry() || (lowNibble(operand) > 9);
|
const auto lowAdjust = halfCarry() || (lowNibble(operand) > 9);
|
||||||
const auto highAdjust = carry() || (operand > 0x99);
|
const auto highAdjust = carry() || (operand > 0x99);
|
||||||
@ -936,7 +936,7 @@ void EightBit::mc6809::jsr(const register16_t address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::lsr(uint8_t operand) {
|
uint8_t EightBit::mc6809::lsr(uint8_t operand) {
|
||||||
setFlag(CC(), CF, operand & Bit0);
|
CC() = setBit(CC(), CF, operand & Bit0);
|
||||||
adjustNZ(operand >>= 1);
|
adjustNZ(operand >>= 1);
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
@ -944,12 +944,12 @@ uint8_t EightBit::mc6809::lsr(uint8_t operand) {
|
|||||||
EightBit::register16_t EightBit::mc6809::mul(const uint8_t first, const uint8_t second) {
|
EightBit::register16_t EightBit::mc6809::mul(const uint8_t first, const uint8_t second) {
|
||||||
const register16_t result = first * second;
|
const register16_t result = first * second;
|
||||||
adjustZero(result);
|
adjustZero(result);
|
||||||
setFlag(CC(), CF, result.low & Bit7);
|
CC() = setBit(CC(), CF, result.low & Bit7);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::neg(uint8_t operand) {
|
uint8_t EightBit::mc6809::neg(uint8_t operand) {
|
||||||
setFlag(CC(), VF, operand == Bit7);
|
CC() = setBit(CC(), VF, operand == Bit7);
|
||||||
const register16_t result = 0 - operand;
|
const register16_t result = 0 - operand;
|
||||||
operand = result.low;
|
operand = result.low;
|
||||||
adjustNZ(operand);
|
adjustNZ(operand);
|
||||||
@ -1035,8 +1035,8 @@ void EightBit::mc6809::pul(register16_t& stack, const uint8_t data) {
|
|||||||
|
|
||||||
uint8_t EightBit::mc6809::rol(const uint8_t operand) {
|
uint8_t EightBit::mc6809::rol(const uint8_t operand) {
|
||||||
const auto carryIn = carry();
|
const auto carryIn = carry();
|
||||||
setFlag(CC(), CF, operand & Bit7);
|
CC() = setBit(CC(), CF, operand & Bit7);
|
||||||
setFlag(CC(), VF, ((operand & Bit7) >> 7) ^ ((operand & Bit6) >> 6));
|
CC() = setBit(CC(), VF, ((operand & Bit7) >> 7) ^ ((operand & Bit6) >> 6));
|
||||||
const uint8_t result = (operand << 1) | carryIn;
|
const uint8_t result = (operand << 1) | carryIn;
|
||||||
adjustNZ(result);
|
adjustNZ(result);
|
||||||
return result;
|
return result;
|
||||||
@ -1044,7 +1044,7 @@ uint8_t EightBit::mc6809::rol(const uint8_t operand) {
|
|||||||
|
|
||||||
uint8_t EightBit::mc6809::ror(const uint8_t operand) {
|
uint8_t EightBit::mc6809::ror(const uint8_t operand) {
|
||||||
const auto carryIn = carry();
|
const auto carryIn = carry();
|
||||||
setFlag(CC(), CF, operand & Bit0);
|
CC() = setBit(CC(), CF, operand & Bit0);
|
||||||
const uint8_t result = (operand >> 1) | (carryIn << 7);
|
const uint8_t result = (operand >> 1) | (carryIn << 7);
|
||||||
adjustNZ(result);
|
adjustNZ(result);
|
||||||
return result;
|
return result;
|
||||||
@ -1060,8 +1060,8 @@ void EightBit::mc6809::rts() {
|
|||||||
|
|
||||||
void EightBit::mc6809::swi() {
|
void EightBit::mc6809::swi() {
|
||||||
saveEntireRegisterState();
|
saveEntireRegisterState();
|
||||||
setFlag(CC(), IF); // Disable IRQ
|
CC() = setBit(CC(), IF); // Disable IRQ
|
||||||
setFlag(CC(), FF); // Disable FIRQ
|
CC() = setBit(CC(), FF); // Disable FIRQ
|
||||||
jump(getWordPaged(0xff, SWIvector));
|
jump(getWordPaged(0xff, SWIvector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") {
|
|||||||
SECTION("Immediate (byte)") {
|
SECTION("Immediate (byte)") {
|
||||||
board.poke(0, 0x89);
|
board.poke(0, 0x89);
|
||||||
board.poke(1, 0x7c);
|
board.poke(1, 0x7c);
|
||||||
EightBit::Chip::setFlag(cpu.CC(), EightBit::mc6809::CF);
|
cpu.CC() = EightBit::Chip::setBit(cpu.CC(), EightBit::mc6809::CF);
|
||||||
cpu.A() = 0x3a;
|
cpu.A() = 0x3a;
|
||||||
cpu.step();
|
cpu.step();
|
||||||
REQUIRE(cpu.A() == 0xb7);
|
REQUIRE(cpu.A() == 0xb7);
|
||||||
@ -648,7 +648,7 @@ TEST_CASE("Subtract Memory from Accumulator with Borrow (8-bit)", "[SBC][SBCA][S
|
|||||||
board.poke(0, 0x82);
|
board.poke(0, 0x82);
|
||||||
board.poke(1, 0x34);
|
board.poke(1, 0x34);
|
||||||
cpu.A() = 0x14;
|
cpu.A() = 0x14;
|
||||||
cpu.setFlag(cpu.CC(), EightBit::mc6809::CF);
|
cpu.CC() = cpu.setBit(cpu.CC(), EightBit::mc6809::CF);
|
||||||
cpu.step();
|
cpu.step();
|
||||||
REQUIRE(cpu.A() == 0xdf);
|
REQUIRE(cpu.A() == 0xdf);
|
||||||
REQUIRE((cpu.CC() & EightBit::mc6809::ZF) == 0);
|
REQUIRE((cpu.CC() & EightBit::mc6809::ZF) == 0);
|
||||||
|
Binary file not shown.
105
Z80/inc/Z80.h
105
Z80/inc/Z80.h
@ -137,6 +137,13 @@ namespace EightBit {
|
|||||||
m_displacement = fetchByte();
|
m_displacement = fetchByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t fetchInitialOpCode() {
|
||||||
|
lowerM1();
|
||||||
|
const auto returned = fetchByte();
|
||||||
|
raiseM1();
|
||||||
|
return returned;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto& HL2() {
|
[[nodiscard]] auto& HL2() {
|
||||||
if (LIKELY(!m_displaced))
|
if (LIKELY(!m_displaced))
|
||||||
return HL();
|
return HL();
|
||||||
@ -271,12 +278,12 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustHalfCarryAdd(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
[[nodiscard]] static uint8_t adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustHalfCarrySub(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
static void adjustHalfCarrySub(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
|
f = setBit(f, HC, calculateHalfCarrySub(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustOverflowAdd(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
|
static void adjustOverflowAdd(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
|
||||||
@ -285,7 +292,7 @@ namespace EightBit {
|
|||||||
|
|
||||||
static void adjustOverflowAdd(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
|
static void adjustOverflowAdd(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
|
||||||
const auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative);
|
const auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative);
|
||||||
setFlag(f, VF, overflow);
|
f = setBit(f, VF, overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustOverflowSub(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
|
static void adjustOverflowSub(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
|
||||||
@ -294,17 +301,17 @@ namespace EightBit {
|
|||||||
|
|
||||||
static void adjustOverflowSub(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
|
static void adjustOverflowSub(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
|
||||||
const auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative);
|
const auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative);
|
||||||
setFlag(f, VF, overflow);
|
f = setBit(f, VF, overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t subtract(uint8_t operand, uint8_t value, int carry = 0);
|
static uint8_t subtract(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
|
||||||
|
|
||||||
void executeCB(int x, int y, int z);
|
void executeCB(int x, int y, int z);
|
||||||
void executeED(int x, int y, int z, int p, int q);
|
void executeED(int x, int y, int z, int p, int q);
|
||||||
void executeOther(int x, int y, int z, int p, int q);
|
void executeOther(int x, int y, int z, int p, int q);
|
||||||
|
|
||||||
[[nodiscard]] uint8_t increment(uint8_t operand);
|
[[nodiscard]] static uint8_t increment(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t decrement(uint8_t operand);
|
[[nodiscard]] static uint8_t decrement(uint8_t& f, uint8_t operand);
|
||||||
|
|
||||||
void di();
|
void di();
|
||||||
void ei();
|
void ei();
|
||||||
@ -312,60 +319,60 @@ namespace EightBit {
|
|||||||
void retn();
|
void retn();
|
||||||
void reti();
|
void reti();
|
||||||
|
|
||||||
bool jrConditionalFlag(int flag);
|
[[nodiscard]] bool jrConditionalFlag(uint8_t f, int flag);
|
||||||
bool returnConditionalFlag(int flag);
|
[[nodiscard]] bool returnConditionalFlag(uint8_t f, int flag);
|
||||||
bool jumpConditionalFlag(int flag);
|
[[nodiscard]] bool callConditionalFlag(uint8_t f, int flag);
|
||||||
bool callConditionalFlag(int flag);
|
void jumpConditionalFlag(uint8_t f, int flag);
|
||||||
|
|
||||||
register16_t sbc(register16_t operand, register16_t value);
|
[[nodiscard]] register16_t sbc(uint8_t& f, register16_t operand, register16_t value);
|
||||||
register16_t adc(register16_t operand, register16_t value);
|
[[nodiscard]] register16_t adc(uint8_t& f, register16_t operand, register16_t value);
|
||||||
register16_t add(register16_t operand, register16_t value, int carry = 0);
|
[[nodiscard]] register16_t add(uint8_t& f, register16_t operand, register16_t value, int carry = 0);
|
||||||
|
|
||||||
[[nodiscard]] uint8_t add(uint8_t operand, uint8_t value, int carry = 0);
|
[[nodiscard]] static uint8_t add(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
|
||||||
[[nodiscard]] uint8_t adc(uint8_t operand, uint8_t value);
|
[[nodiscard]] static uint8_t adc(uint8_t& f, uint8_t operand, uint8_t value);
|
||||||
[[nodiscard]] uint8_t sub(uint8_t operand, uint8_t value, int carry = 0);
|
[[nodiscard]] static uint8_t sub(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
|
||||||
[[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t value);
|
[[nodiscard]] static uint8_t sbc(uint8_t& f, uint8_t operand, uint8_t value);
|
||||||
void andr(uint8_t value);
|
[[nodiscard]] static uint8_t andr(uint8_t& f, uint8_t operand, uint8_t value);
|
||||||
void xorr(uint8_t value);
|
[[nodiscard]] static uint8_t xorr(uint8_t& f, uint8_t operand, uint8_t value);
|
||||||
void orr(uint8_t value);
|
[[nodiscard]] static uint8_t orr(uint8_t& f, uint8_t operand, uint8_t value);
|
||||||
void compare(uint8_t value);
|
static void compare(uint8_t& f, uint8_t operand, uint8_t value);
|
||||||
|
|
||||||
[[nodiscard]] uint8_t rlc(uint8_t operand);
|
[[nodiscard]] static uint8_t rlc(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t rrc(uint8_t operand);
|
[[nodiscard]] static uint8_t rrc(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t rl(uint8_t operand);
|
[[nodiscard]] static uint8_t rl(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t rr(uint8_t operand);
|
[[nodiscard]] static uint8_t rr(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t sla(uint8_t operand);
|
[[nodiscard]] static uint8_t sla(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t sra(uint8_t operand);
|
[[nodiscard]] static uint8_t sra(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t sll(uint8_t operand);
|
[[nodiscard]] static uint8_t sll(uint8_t& f, uint8_t operand);
|
||||||
[[nodiscard]] uint8_t srl(uint8_t operand);
|
[[nodiscard]] static uint8_t srl(uint8_t& f, uint8_t operand);
|
||||||
|
|
||||||
void bit(int n, uint8_t operand);
|
static void bit(uint8_t& f, int n, uint8_t operand);
|
||||||
[[nodiscard]] static uint8_t res(int n, uint8_t operand);
|
[[nodiscard]] static uint8_t res(int n, uint8_t operand);
|
||||||
[[nodiscard]] static uint8_t set(int n, uint8_t operand);
|
[[nodiscard]] static uint8_t set(int n, uint8_t operand);
|
||||||
|
|
||||||
void daa();
|
[[nodiscard]] static uint8_t daa(uint8_t& f, uint8_t operand);
|
||||||
|
|
||||||
void scf();
|
static void scf(uint8_t& f, uint8_t operand);
|
||||||
void ccf();
|
static void ccf(uint8_t& f, uint8_t operand);
|
||||||
void cpl();
|
static uint8_t cpl(uint8_t& f, uint8_t operand);
|
||||||
|
|
||||||
void xhtl(register16_t& exchange);
|
void xhtl(register16_t& exchange);
|
||||||
|
|
||||||
void blockCompare(register16_t source, register16_t& counter);
|
void blockCompare(uint8_t& f, uint8_t value, register16_t source, register16_t& counter);
|
||||||
|
|
||||||
void cpi();
|
void cpi(uint8_t& f, uint8_t value);
|
||||||
bool cpir();
|
bool cpir(uint8_t& f, uint8_t value);
|
||||||
|
|
||||||
void cpd();
|
void cpd(uint8_t& f, uint8_t value);
|
||||||
bool cpdr();
|
bool cpdr(uint8_t& f, uint8_t value);
|
||||||
|
|
||||||
void blockLoad(register16_t source, register16_t destination, register16_t& counter);
|
void blockLoad(uint8_t& f, uint8_t a, register16_t source, register16_t destination, register16_t& counter);
|
||||||
|
|
||||||
void ldi();
|
void ldi(uint8_t& f, uint8_t a);
|
||||||
bool ldir();
|
bool ldir(uint8_t& f, uint8_t a);
|
||||||
|
|
||||||
void ldd();
|
void ldd(uint8_t& f, uint8_t a);
|
||||||
bool lddr();
|
bool lddr(uint8_t& f, uint8_t a);
|
||||||
|
|
||||||
void blockIn(register16_t& source, register16_t destination);
|
void blockIn(register16_t& source, register16_t destination);
|
||||||
|
|
||||||
@ -383,10 +390,10 @@ namespace EightBit {
|
|||||||
void outd();
|
void outd();
|
||||||
bool otdr();
|
bool otdr();
|
||||||
|
|
||||||
void neg();
|
[[nodiscard]] uint8_t neg(uint8_t& f, uint8_t operand);
|
||||||
|
|
||||||
void rrd();
|
void rrd(uint8_t& f, register16_t address, uint8_t& update);
|
||||||
void rld();
|
void rld(uint8_t& f, register16_t address, uint8_t& update);
|
||||||
|
|
||||||
void writePort(uint8_t port);
|
void writePort(uint8_t port);
|
||||||
void writePort();
|
void writePort();
|
||||||
|
606
Z80/src/Z80.cpp
606
Z80/src/Z80.cpp
File diff suppressed because it is too large
Load Diff
31
inc/Chip.h
31
inc/Chip.h
@ -45,27 +45,26 @@ namespace EightBit {
|
|||||||
Mask16 = Bit16 - 1
|
Mask16 = Bit16 - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr uint8_t bit(const int which) noexcept { return 1 << which; }
|
[[nodiscard]] static constexpr uint8_t bit(const int which) noexcept { return 1 << which; }
|
||||||
|
|
||||||
static void clearFlag(uint8_t& f, const int flag) noexcept { f &= ~flag; }
|
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which) noexcept { return input | which; }
|
||||||
static void setFlag(uint8_t& f, const int flag) noexcept { f |= flag; }
|
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which, const int condition) noexcept { return setBit(input, which, !!condition); }
|
||||||
|
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which, const uint32_t condition) noexcept { return setBit(input, which, !!condition); }
|
||||||
|
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which, const bool condition) noexcept { return condition ? setBit(input, which) : clearBit(input, which); }
|
||||||
|
|
||||||
static void setFlag(uint8_t& f, const int flag, const int condition) noexcept { setFlag(f, flag, !!condition); }
|
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which) noexcept { return input & ~which; }
|
||||||
static void setFlag(uint8_t& f, const int flag, const uint32_t condition) noexcept { setFlag(f, flag, !!condition); }
|
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const int condition) noexcept { return clearBit(input, which, !!condition); }
|
||||||
static void setFlag(uint8_t& f, const int flag, const bool condition) noexcept { condition ? setFlag(f, flag) : clearFlag(f, flag); }
|
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const uint32_t condition) noexcept { return clearBit(input, which, !!condition); }
|
||||||
|
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const bool condition) noexcept { return setBit(input, which, !condition); }
|
||||||
|
|
||||||
static void clearFlag(uint8_t& f, const int flag, const int condition) noexcept { clearFlag(f, flag, !!condition); }
|
[[nodiscard]] static constexpr auto highNibble(const int value) { return value >> 4; }
|
||||||
static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) noexcept { clearFlag(f, flag, !!condition); }
|
[[nodiscard]] static constexpr auto lowNibble(const int value) { return value & Mask4; }
|
||||||
static void clearFlag(uint8_t& f, const int flag, const bool condition) noexcept { setFlag(f, flag, !condition); }
|
|
||||||
|
|
||||||
static constexpr auto highNibble(const int value) { return value >> 4; }
|
[[nodiscard]] static constexpr auto higherNibble(const int value) { return value & 0xf0; }
|
||||||
static constexpr auto lowNibble(const int value) { return value & Mask4; }
|
[[nodiscard]] static constexpr auto lowerNibble(const int value) { return lowNibble(value); }
|
||||||
|
|
||||||
static constexpr auto higherNibble(const int value) { return value & 0xf0; }
|
[[nodiscard]] static constexpr auto promoteNibble(const int value) { return value << 4; }
|
||||||
static constexpr auto lowerNibble(const int value) { return lowNibble(value); }
|
[[nodiscard]] static constexpr auto demoteNibble(const int value) { return highNibble(value); }
|
||||||
|
|
||||||
static constexpr auto promoteNibble(const int value) { return value << 4; }
|
|
||||||
static constexpr auto demoteNibble(const int value) { return highNibble(value); }
|
|
||||||
|
|
||||||
virtual ~Chip();
|
virtual ~Chip();
|
||||||
|
|
||||||
|
@ -68,9 +68,9 @@ namespace EightBit {
|
|||||||
static constexpr auto lowered(const PinLevel line) { return line == PinLevel::Low; }
|
static constexpr auto lowered(const PinLevel line) { return line == PinLevel::Low; }
|
||||||
static void lower(PinLevel& line) noexcept { line = PinLevel::Low; }
|
static void lower(PinLevel& line) noexcept { line = PinLevel::Low; }
|
||||||
|
|
||||||
static void match(PinLevel& line, int condition) { match(line, condition != 0); }
|
static void match(PinLevel& line, int condition) noexcept { match(line, condition != 0); }
|
||||||
static void match(PinLevel& line, bool condition) { condition ? raise(line) : lower(line); }
|
static void match(PinLevel& line, bool condition) noexcept { condition ? raise(line) : lower(line); }
|
||||||
static void match(PinLevel& out, PinLevel in) { out = in; }
|
static void match(PinLevel& out, PinLevel in) noexcept { out = in; }
|
||||||
|
|
||||||
virtual ~Device() {};
|
virtual ~Device() {};
|
||||||
|
|
||||||
@ -79,6 +79,6 @@ namespace EightBit {
|
|||||||
DECLARE_PIN_INPUT(POWER)
|
DECLARE_PIN_INPUT(POWER)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Device() {};
|
Device() noexcept {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ namespace EightBit {
|
|||||||
int p = 0;
|
int p = 0;
|
||||||
int q = 0;
|
int q = 0;
|
||||||
|
|
||||||
opcode_decoded_t() {}
|
opcode_decoded_t() noexcept {}
|
||||||
|
|
||||||
opcode_decoded_t(const uint8_t opcode) {
|
opcode_decoded_t(const uint8_t opcode) noexcept {
|
||||||
x = (opcode & 0b11000000) >> 6; // 0 - 3
|
x = (opcode & 0b11000000) >> 6; // 0 - 3
|
||||||
y = (opcode & 0b00111000) >> 3; // 0 - 7
|
y = (opcode & 0b00111000) >> 3; // 0 - 7
|
||||||
z = (opcode & 0b00000111); // 0 - 7
|
z = (opcode & 0b00000111); // 0 - 7
|
||||||
@ -35,7 +35,7 @@ namespace EightBit {
|
|||||||
~IntelProcessor() = default;
|
~IntelProcessor() = default;
|
||||||
|
|
||||||
[[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept {
|
[[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept {
|
||||||
return m_decodedOpcodes[i];
|
return m_decodedOpcodes.at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto& MEMPTR() noexcept { return m_memptr; }
|
[[nodiscard]] auto& MEMPTR() noexcept { return m_memptr; }
|
||||||
@ -63,59 +63,59 @@ namespace EightBit {
|
|||||||
protected:
|
protected:
|
||||||
IntelProcessor(Bus& bus);
|
IntelProcessor(Bus& bus);
|
||||||
|
|
||||||
template<class T> static void adjustSign(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustSign(uint8_t f, const uint8_t value) {
|
||||||
setFlag(f, T::SF, value & T::SF);
|
return setBit(f, T::SF, value & T::SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustZero(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustZero(uint8_t f, const uint8_t value) {
|
||||||
clearFlag(f, T::ZF, value);
|
return clearBit(f, T::ZF, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustParity(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustParity(uint8_t f, const uint8_t value) {
|
||||||
clearFlag(f, T::PF, PARITY(value));
|
return clearBit(f, T::PF, PARITY(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZ(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustSZ(uint8_t f, const uint8_t value) {
|
||||||
adjustSign<T>(f, value);
|
const auto intermediate = adjustSign<T>(f, value);
|
||||||
adjustZero<T>(f, value);
|
return adjustZero<T>(intermediate, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZP(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustSZP(uint8_t f, const uint8_t value) {
|
||||||
adjustSZ<T>(f, value);
|
const auto intermediate = adjustSZ<T>(f, value);
|
||||||
adjustParity<T>(f, value);
|
return adjustParity<T>(intermediate, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustXY(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustXY(uint8_t f, const uint8_t value) {
|
||||||
setFlag(f, T::XF, value & T::XF);
|
const auto intermediate = setBit(f, T::XF, value & T::XF);
|
||||||
setFlag(f, T::YF, value & T::YF);
|
return setBit(intermediate, T::YF, value & T::YF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZPXY(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustSZPXY(uint8_t f, const uint8_t value) {
|
||||||
adjustSZP<T>(f, value);
|
const auto intermediate = adjustSZP<T>(f, value);
|
||||||
adjustXY<T>(f, value);
|
return adjustXY<T>(intermediate, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZXY(uint8_t& f, const uint8_t value) {
|
template<class T> [[nodiscard]] static uint8_t adjustSZXY(uint8_t f, const uint8_t value) {
|
||||||
adjustSZ<T>(f, value);
|
const auto intermediate = adjustSZ<T>(f, value);
|
||||||
adjustXY<T>(f, value);
|
return adjustXY<T>(intermediate, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
static constexpr auto buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
|
[[nodiscard]] static constexpr auto buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
[[nodiscard]] static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||||
static std::array<int, 8> halfCarryTableAdd = { { 0, 0, 1, 0, 1, 0, 1, 1} };
|
static std::array<int, 8> halfCarryTableAdd = { { 0, 0, 1, 0, 1, 0, 1, 1} };
|
||||||
const auto index = buildHalfCarryIndex(before, value, calculation);
|
const auto index = buildHalfCarryIndex(before, value, calculation);
|
||||||
return halfCarryTableAdd[index & Mask3];
|
return halfCarryTableAdd.at(index & Mask3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static auto calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
[[nodiscard]] static auto calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||||
std::array<int, 8> halfCarryTableSub = { { 0, 1, 1, 1, 0, 0, 0, 1 } };
|
std::array<int, 8> halfCarryTableSub = { { 0, 1, 1, 1, 0, 0, 0, 1 } };
|
||||||
const auto index = buildHalfCarryIndex(before, value, calculation);
|
const auto index = buildHalfCarryIndex(before, value, calculation);
|
||||||
return halfCarryTableSub[index & Mask3];
|
return halfCarryTableSub.at(index & Mask3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleRESET() override;
|
void handleRESET() override;
|
||||||
@ -154,7 +154,7 @@ namespace EightBit {
|
|||||||
return !!condition;
|
return !!condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jr(const int8_t offset) {
|
void jr(const int8_t offset) noexcept {
|
||||||
jump(MEMPTR() = PC() + offset);
|
jump(MEMPTR() = PC() + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user