diff --git a/Intel8080/inc/Intel8080.h b/Intel8080/inc/Intel8080.h index fc12d3b..3beb3ba 100644 --- a/Intel8080/inc/Intel8080.h +++ b/Intel8080/inc/Intel8080.h @@ -135,11 +135,11 @@ namespace EightBit { } 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) { - 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); diff --git a/Intel8080/src/Intel8080.cpp b/Intel8080/src/Intel8080.cpp index 0292307..858d026 100644 --- a/Intel8080/src/Intel8080.cpp +++ b/Intel8080/src/Intel8080.cpp @@ -36,7 +36,6 @@ void EightBit::Intel8080::handleINT() { di(); Processor::execute(BUS().DATA()); } - tick(3); } void EightBit::Intel8080::di() { @@ -48,13 +47,13 @@ void EightBit::Intel8080::ei() { } void EightBit::Intel8080::increment(uint8_t& operand) { - adjustSZP(F(), ++operand); - clearFlag(F(), AC, lowNibble(operand)); + F() = adjustSZP(F(), ++operand); + F() = clearBit(F(), AC, lowNibble(operand)); } void EightBit::Intel8080::decrement(uint8_t& operand) { - adjustSZP(F(), --operand); - setFlag(F(), AC, lowNibble(operand) != Mask4); + F() = adjustSZP(F(), --operand); + F() = setBit(F(), AC, lowNibble(operand) != Mask4); } 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) { const auto result = HL().word + value.word; HL() = result; - setFlag(F(), CF, result & Bit16); + F() = setBit(F(), CF, result & Bit16); } 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; - setFlag(F(), CF, result.word & Bit8); - adjustSZP(F(), A()); + F() = setBit(F(), CF, result.word & Bit8); + F() = adjustSZP(F(), A()); } 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; - setFlag(F(), CF, result.word & Bit8); - adjustSZP(F(), operand); + F() = setBit(F(), CF, result.word & Bit8); + F() = adjustSZP(F(), operand); } 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) { - setFlag(F(), AC, (A() | value) & Bit3); - clearFlag(F(), CF); - adjustSZP(F(), A() &= value); + F() = setBit(F(), AC, (A() | value) & Bit3); + F() = clearBit(F(), CF); + F() = adjustSZP(F(), A() &= value); } void EightBit::Intel8080::xorr(const uint8_t value) { - clearFlag(F(), AC | CF); - adjustSZP(F(), A() ^= value); + F() = clearBit(F(), AC | CF); + F() = adjustSZP(F(), A() ^= value); } void EightBit::Intel8080::orr(const uint8_t value) { - clearFlag(F(), AC | CF); - adjustSZP(F(), A() |= value); + F() = clearBit(F(), AC | CF); + F() = adjustSZP(F(), A() |= 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() { const auto carry = A() & Bit7; A() = (A() << 1) | (carry >> 7); - setFlag(F(), CF, carry); + F() = setBit(F(), CF, carry); } void EightBit::Intel8080::rrc() { const auto carry = A() & Bit0; A() = (A() >> 1) | (carry << 7); - setFlag(F(), CF, carry); + F() = setBit(F(), CF, carry); } void EightBit::Intel8080::rl() { const auto carry = F() & CF; - setFlag(F(), CF, A() & Bit7); + F() = setBit(F(), CF, A() & Bit7); A() = (A() << 1) | carry; } void EightBit::Intel8080::rr() { const auto carry = F() & CF; - setFlag(F(), CF, A() & Bit0); + F() = setBit(F(), CF, A() & Bit0); A() = (A() >> 1) | (carry << 7); } @@ -221,7 +220,7 @@ void EightBit::Intel8080::daa() { carry = true; } add(addition); - setFlag(F(), CF, carry); + F() = setBit(F(), CF, carry); } void EightBit::Intel8080::cma() { @@ -229,11 +228,11 @@ void EightBit::Intel8080::cma() { } void EightBit::Intel8080::stc() { - setFlag(F(), CF); + F() = setBit(F(), CF); } void EightBit::Intel8080::cmc() { - clearFlag(F(), CF, F() & CF); + F() = clearBit(F(), CF, F() & CF); } void EightBit::Intel8080::xhtl(register16_t& exchange) { diff --git a/LR35902/inc/LR35902.h b/LR35902/inc/LR35902.h index 5478cf1..9835566 100644 --- a/LR35902/inc/LR35902.h +++ b/LR35902/inc/LR35902.h @@ -150,11 +150,11 @@ namespace EightBit { } 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) { - 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); diff --git a/LR35902/src/CharacterDefinition.cpp b/LR35902/src/CharacterDefinition.cpp index 4be04c4..0af30ad 100644 --- a/LR35902/src/CharacterDefinition.cpp +++ b/LR35902/src/CharacterDefinition.cpp @@ -19,7 +19,7 @@ std::array EightBit::GameBoy::CharacterDefinition::get(int row) { 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 bitHigh = planeHigh & mask ? 0b10 : 0; diff --git a/LR35902/src/GameBoyBus.cpp b/LR35902/src/GameBoyBus.cpp index 755073e..9381a0b 100644 --- a/LR35902/src/GameBoyBus.cpp +++ b/LR35902/src/GameBoyBus.cpp @@ -125,7 +125,7 @@ void EightBit::GameBoy::Bus::validateCartridgeType() { default: if (romSizeSpecification > 6) throw std::domain_error("Invalid ROM size specification"); - gameRomBanks = 1 << (romSizeSpecification + 1); + gameRomBanks = Chip::bit(romSizeSpecification + 1); if (gameRomBanks != m_gameRomBanks.size()) throw std::domain_error("ROM size specification mismatch"); } diff --git a/LR35902/src/LR35902.cpp b/LR35902/src/LR35902.cpp index 1193a8c..c61d762 100644 --- a/LR35902/src/LR35902.cpp +++ b/LR35902/src/LR35902.cpp @@ -50,15 +50,15 @@ void EightBit::GameBoy::LR35902::ei() { } void EightBit::GameBoy::LR35902::increment(uint8_t& operand) { - clearFlag(F(), NF); - adjustZero(F(), ++operand); - clearFlag(F(), HC, lowNibble(operand)); + F() = clearBit(F(), NF); + F() = adjustZero(F(), ++operand); + F() = clearBit(F(), HC, lowNibble(operand)); } void EightBit::GameBoy::LR35902::decrement(uint8_t& operand) { - setFlag(F(), NF); - clearFlag(F(), HC, lowNibble(operand)); - adjustZero(F(), --operand); + F() = setBit(F(), NF); + F() = clearBit(F(), HC, lowNibble(operand)); + F() = adjustZero(F(), --operand); } 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; - clearFlag(F(), NF); - setFlag(F(), CF, result & Bit16); + F() = clearBit(F(), NF); + F() = setBit(F(), CF, result & Bit16); 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; - clearFlag(F(), NF); - setFlag(F(), CF, result.word & Bit8); - adjustZero(F(), operand); + F() = clearBit(F(), NF); + F() = setBit(F(), CF, result.word & Bit8); + F() = adjustZero(F(), operand); } 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; - setFlag(F(), NF); - setFlag(F(), CF, result.word & Bit8); - adjustZero(F(), operand); + F() = setBit(F(), NF); + F() = setBit(F(), CF, result.word & Bit8); + F() = adjustZero(F(), operand); } 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) { - setFlag(F(), HC); - clearFlag(F(), CF | NF); - adjustZero(F(), operand &= value); + F() = setBit(F(), HC); + F() = clearBit(F(), CF | NF); + F() = adjustZero(F(), operand &= value); } void EightBit::GameBoy::LR35902::xorr(const uint8_t value) { - clearFlag(F(), HC | CF | NF); - adjustZero(F(), A() ^= value); + F() = clearBit(F(), HC | CF | NF); + F() = adjustZero(F(), A() ^= value); } void EightBit::GameBoy::LR35902::orr(const uint8_t value) { - clearFlag(F(), HC | CF | NF); - adjustZero(F(), A() |= value); + F() = clearBit(F(), HC | CF | NF); + F() = adjustZero(F(), A() |= 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) { - clearFlag(F(), NF | HC | ZF); + F() = clearBit(F(), NF | HC | ZF); const auto carry = operand & Bit7; - setFlag(F(), CF, carry); + F() = setBit(F(), CF, carry); return (operand << 1) | (carry >> 7); } 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; - setFlag(F(), CF, carry); + F() = setBit(F(), CF, carry); return (operand >> 1) | (carry << 7); } 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; - setFlag(F(), CF, operand & Bit7); + F() = setBit(F(), CF, operand & Bit7); return (operand << 1) | (carry >> 4); // CF at Bit4 } 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; - setFlag(F(), CF, operand & Bit0); + F() = setBit(F(), CF, operand & Bit0); return (operand >> 1) | (carry << 3); // CF at Bit4 } uint8_t EightBit::GameBoy::LR35902::sla(const uint8_t operand) { - clearFlag(F(), NF | HC | ZF); - setFlag(F(), CF, operand & Bit7); + F() = clearBit(F(), NF | HC | ZF); + F() = setBit(F(), CF, operand & Bit7); return operand << 1; } uint8_t EightBit::GameBoy::LR35902::sra(const uint8_t operand) { - clearFlag(F(), NF | HC | ZF); - setFlag(F(), CF, operand & Bit0); + F() = clearBit(F(), NF | HC | ZF); + F() = setBit(F(), CF, operand & Bit0); return (operand >> 1) | (operand & Bit7); } 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); } uint8_t EightBit::GameBoy::LR35902::srl(const uint8_t operand) { - clearFlag(F(), NF | HC | ZF); - setFlag(F(), CF, operand & Bit0); + F() = clearBit(F(), NF | HC | ZF); + F() = setBit(F(), CF, operand & Bit0); return (operand >> 1) & ~Bit7; } void EightBit::GameBoy::LR35902::bit(const int n, const uint8_t operand) { const auto carry = F() & CF; uint8_t discarded = operand; - andr(discarded, 1 << n); - setFlag(F(), CF, carry); + andr(discarded, Chip::bit(n)); + F() = setBit(F(), CF, carry); } 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) { - return operand | (1 << n); + return operand | Chip::bit(n); } void EightBit::GameBoy::LR35902::daa() { @@ -275,26 +275,26 @@ void EightBit::GameBoy::LR35902::daa() { updated += 0x60; } - clearFlag(F(), HC | ZF); - setFlag(F(), CF, (F() & CF) || (updated & Bit8)); + F() = clearBit(F(), HC | ZF); + F() = setBit(F(), CF, (F() & CF) || (updated & Bit8)); A() = updated & Mask8; - adjustZero(F(), A()); + F() = adjustZero(F(), A()); } void EightBit::GameBoy::LR35902::cpl() { - setFlag(F(), HC | NF); + F() = setBit(F(), HC | NF); A() = ~A(); } void EightBit::GameBoy::LR35902::scf() { - setFlag(F(), CF); - clearFlag(F(), HC | NF); + F() = setBit(F(), CF); + F() = clearBit(F(), HC | NF); } void EightBit::GameBoy::LR35902::ccf() { - clearFlag(F(), NF | HC); - clearFlag(F(), CF, F() & CF); + F() = clearBit(F(), NF | HC); + F() = clearBit(F(), CF, F() & CF); } 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); R(z, operand); - adjustZero(F(), operand); + F() = adjustZero(F(), operand); if (UNLIKELY(z == 6)) tick(2); break; @@ -651,9 +651,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in const auto result = before + value; SP() = result; const auto carried = before ^ value ^ (result & Mask16); - clearFlag(F(), ZF | NF); - setFlag(F(), CF, carried & Bit8); - setFlag(F(), HC, carried & Bit4); + F() = clearBit(F(), ZF | NF); + F() = setBit(F(), CF, carried & Bit8); + F() = setBit(F(), HC, carried & Bit4); } tick(4); break; @@ -667,9 +667,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in const auto result = before + value; HL() = result; const auto carried = before ^ value ^ (result & Mask16); - clearFlag(F(), ZF | NF); - setFlag(F(), CF, carried & Bit8); - setFlag(F(), HC, carried & Bit4); + F() = clearBit(F(), ZF | NF); + F() = setBit(F(), CF, carried & Bit8); + F() = setBit(F(), HC, carried & Bit4); } tick(3); break; diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index 56766bd..7793879 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -97,12 +97,12 @@ namespace EightBit { // Addressing modes, read - enum PageCrossingBehavior { AlwaysReadTwice, MaybeReadTwice }; + enum class PageCrossingBehavior { AlwaysReadTwice, MaybeReadTwice }; uint8_t AM_Immediate(); uint8_t AM_Absolute(); 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_ZeroPageX(); uint8_t AM_ZeroPageY(); @@ -111,8 +111,8 @@ namespace EightBit { // Flag adjustment - void adjustZero(const uint8_t datum) { clearFlag(P(), ZF, datum); } - void adjustNegative(const uint8_t datum) { setFlag(P(), NF, datum & NF); } + void adjustZero(const uint8_t datum) { P() = clearBit(P(), ZF, datum); } + void adjustNegative(const uint8_t datum) { P() = setBit(P(), NF, datum & NF); } void adjustNZ(const uint8_t datum) { adjustZero(datum); diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index 94589c6..0e1d30e 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -84,7 +84,7 @@ void EightBit::MOS6502::interrupt() { pushWord(PC()); 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); jump(getWordPaged(0xff, vector)); 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 0x16: busReadModifyWrite(asl(AM_ZeroPageX())); break; // ASL (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 0x1a: busRead(); break; // *NOP (implied) case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y) case 0x1c: AM_AbsoluteX(); break; // *NOP (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 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 0x36: busReadModifyWrite(rol(AM_ZeroPageX())); break; // ROL (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 0x3a: busRead(); break; // *NOP (implied) case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y) case 0x3c: AM_AbsoluteX(); break; // *NOP (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 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 0x56: busReadModifyWrite(lsr(AM_ZeroPageX())); break; // LSR (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 0x5a: busRead(); break; // *NOP (implied) case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y) case 0x5c: AM_AbsoluteX(); break; // *NOP (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 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 0x76: busReadModifyWrite(ror(AM_ZeroPageX())); break; // ROR (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 0x7a: busRead(); break; // *NOP (implied) case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y) case 0x7c: AM_AbsoluteX(); break; // *NOP (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 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 0xb6: X() = through(AM_ZeroPageY()); break; // LDX (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 0xba: busRead(); X() = through(S()); break; // TSX (implied) case 0xbb: break; @@ -341,13 +341,13 @@ int EightBit::MOS6502::execute() { case 0xd5: cmp(A(), AM_ZeroPageX()); break; // CMP (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 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 0xda: busRead(); break; // *NOP (implied) case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y) case 0xdc: AM_AbsoluteX(); break; // *NOP (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 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 0xf6: busReadModifyWrite(inc(AM_ZeroPageX())); break; // INC (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 0xfa: busRead(); break; // *NOP (implied) case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y) case 0xfc: AM_AbsoluteX(); break; // *NOP (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) } @@ -482,7 +482,7 @@ uint8_t EightBit::MOS6502::AM_ZeroPage() { uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) { const auto [address, page] = Address_AbsoluteX(); 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); return possible; } @@ -536,8 +536,8 @@ uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) { const auto difference = m_intermediate; adjustNZ(difference.low); - setFlag(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF); - clearFlag(P(), CF, difference.high); + P() = setBit(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF); + P() = clearBit(P(), CF, difference.high); 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) { m_intermediate.word = operand + data + carry; - setFlag(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF); - setFlag(P(), CF, m_intermediate.high & CF); + P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF); + P() = setBit(P(), CF, m_intermediate.high & CF); return m_intermediate.low; } @@ -595,12 +595,12 @@ uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) { low += 6; 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) high += 6; - setFlag(P(), CF, high > 0xf); + P() = setBit(P(), CF, high > 0xf); 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) { - setFlag(P(), CF, value & Bit7); + P() = setBit(P(), CF, value & Bit7); return through(value << 1); } 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); 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) { const register16_t result = first - second; adjustNZ(result.low); - clearFlag(P(), CF, result.high); + P() = clearBit(P(), CF, result.high); } 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) { - setFlag(P(), CF, value & Bit0); + P() = setBit(P(), CF, value & Bit0); return through(value >> 1); } @@ -665,14 +665,14 @@ void EightBit::MOS6502::plp() { uint8_t EightBit::MOS6502::rol(const uint8_t operand) { const auto carryIn = carry(); - setFlag(P(), CF, operand & Bit7); + P() = setBit(P(), CF, operand & Bit7); const uint8_t result = (operand << 1) | carryIn; return through(result); } uint8_t EightBit::MOS6502::ror(const uint8_t operand) { const auto carryIn = carry(); - setFlag(P(), CF, operand & Bit0); + P() = setBit(P(), CF, operand & Bit0); const uint8_t result = (operand >> 1) | (carryIn << 7); return through(result); } @@ -693,14 +693,14 @@ void EightBit::MOS6502::rts() { void EightBit::MOS6502::anc(const uint8_t value) { A() = andr(A(), value); - setFlag(P(), CF, A() & Bit7); + P() = setBit(P(), CF, A() & Bit7); } void EightBit::MOS6502::arr(const uint8_t value) { A() = andr(A(), value); A() = ror(A()); - setFlag(P(), CF, A() & Bit6); - setFlag(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5)); + P() = setBit(P(), CF, A() & Bit6); + P() = setBit(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5)); } 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) { 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) { diff --git a/M6532/src/M6532.cpp b/M6532/src/M6532.cpp index ab2dc55..2598837 100644 --- a/M6532/src/M6532.cpp +++ b/M6532/src/M6532.cpp @@ -38,11 +38,11 @@ void EightBit::M6532::step() { const bool interruptPA7 = m_allowPA7Interrupts && (PA() & Bit7); if (interruptPA7) - setFlag(IF(), Bit6); + IF() = setBit(IF(), Bit6); const bool interruptTimer = m_allowTimerInterrupts && (m_timerInterval == 0); if (interruptTimer) - setFlag(IF(), Bit7); + IF() = setBit(IF(), Bit7); match(IRQ(), !(interruptPA7 || interruptTimer)); @@ -93,7 +93,7 @@ void EightBit::M6532::step() { if (read && a2 && a0) { DATA() = IF(); - clearFlag(IF(), Bit6); + IF() = clearBit(IF(), Bit6); } m_allowTimerInterrupts = !!a3; @@ -115,7 +115,7 @@ void EightBit::M6532::step() { break; } m_currentIncrement = m_timerIncrement; - clearFlag(IF(), Bit7); + IF() = clearBit(IF(), Bit7); } } } diff --git a/MC6809/inc/mc6809.h b/MC6809/inc/mc6809.h index 91a2306..8c24dbd 100644 --- a/MC6809/inc/mc6809.h +++ b/MC6809/inc/mc6809.h @@ -195,10 +195,10 @@ namespace EightBit { // Flag adjustment - template void adjustZero(const T datum) { clearFlag(CC(), ZF, datum); } - void adjustZero(const register16_t datum) { clearFlag(CC(), ZF, datum.word); } - void adjustNegative(const uint8_t datum) { setFlag(CC(), NF, datum & Bit7); } - void adjustNegative(const uint16_t datum) { setFlag(CC(), NF, datum & Bit15); } + template void adjustZero(const T datum) { CC() = clearBit(CC(), ZF, datum); } + void adjustZero(const register16_t datum) { CC() = clearBit(CC(), ZF, datum.word); } + void adjustNegative(const uint8_t datum) { CC() = setBit(CC(), NF, datum & Bit7); } + void adjustNegative(const uint16_t datum) { CC() = setBit(CC(), NF, datum & Bit15); } void adjustNegative(const register16_t datum) { adjustNegative(datum.word); } template void adjustNZ(const T datum) { @@ -206,24 +206,24 @@ namespace EightBit { adjustNegative(datum); } - void adjustCarry(const uint16_t datum) { setFlag(CC(), CF, datum & Bit8); } // 8-bit addition - void adjustCarry(const uint32_t datum) { setFlag(CC(), CF, datum & Bit16); } // 16-bit addition + void adjustCarry(const uint16_t datum) { CC() = setBit(CC(), CF, datum & Bit8); } // 8-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 adjustBorrow(const uint16_t datum) { clearFlag(CC(), CF, datum & Bit8); } // 8-bit subtraction - void adjustBorrow(const uint32_t datum) { clearFlag(CC(), CF, datum & Bit16); } // 16-bit subtraction + void adjustBorrow(const uint16_t datum) { CC() = clearBit(CC(), CF, datum & Bit8); } // 8-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 adjustOverflow(const uint8_t before, const uint8_t data, const register16_t after) { const uint8_t lowAfter = after.low; 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) { const uint16_t lowAfter = after & Mask16; 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) { @@ -231,7 +231,7 @@ namespace EightBit { } 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) { @@ -314,7 +314,7 @@ namespace EightBit { void restoreRegisterState(); template T through(const T data) { - clearFlag(CC(), VF); + CC() = clearBit(CC(), VF); adjustNZ(data); return data; } diff --git a/MC6809/src/mc6809.cpp b/MC6809/src/mc6809.cpp index d941c19..5252b2c 100644 --- a/MC6809/src/mc6809.cpp +++ b/MC6809/src/mc6809.cpp @@ -55,8 +55,8 @@ void EightBit::mc6809::handleRESET() { lowerBA(); raiseBS(); DP() = 0; - setFlag(CC(), IF); // Disable IRQ - setFlag(CC(), FF); // Disable FIRQ + CC() = setBit(CC(), IF); // Disable IRQ + CC() = setBit(CC(), FF); // Disable FIRQ jump(getWordPaged(0xff, RESETvector)); tick(10); } @@ -66,8 +66,8 @@ void EightBit::mc6809::handleNMI() { lowerBA(); raiseBS(); saveEntireRegisterState(); - setFlag(CC(), IF); // Disable IRQ - setFlag(CC(), FF); // Disable FIRQ + CC() = setBit(CC(), IF); // Disable IRQ + CC() = setBit(CC(), FF); // Disable FIRQ jump(getWordPaged(0xff, NMIvector)); tick(12); } @@ -77,7 +77,7 @@ void EightBit::mc6809::handleINT() { lowerBA(); raiseBS(); saveEntireRegisterState(); - setFlag(CC(), IF); // Disable IRQ + CC() = setBit(CC(), IF); // Disable IRQ jump(getWordPaged(0xff, IRQvector)); tick(12); } @@ -87,8 +87,8 @@ void EightBit::mc6809::handleFIRQ() { lowerBA(); raiseBS(); savePartialRegisterState(); - setFlag(CC(), IF); // Disable IRQ - setFlag(CC(), FF); // Disable FIRQ + CC() = setBit(CC(), IF); // Disable IRQ + CC() = setBit(CC(), FF); // Disable FIRQ jump(getWordPaged(0xff, FIRQvector)); tick(12); } @@ -765,12 +765,12 @@ EightBit::register16_t EightBit::mc6809::AM_extended_word() { // void EightBit::mc6809::saveEntireRegisterState() { - setFlag(CC(), EF); + CC() = setBit(CC(), EF); saveRegisterState(); } void EightBit::mc6809::savePartialRegisterState() { - clearFlag(CC(), EF); + CC() = clearBit(CC(), EF); 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) { - setFlag(CC(), CF, operand & Bit7); + CC() = setBit(CC(), CF, operand & Bit7); adjustNZ(operand <<= 1); const auto overflow = carry() ^ (negative() >> 3); - setFlag(CC(), VF, overflow); + CC() = setBit(CC(), VF, overflow); return 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; adjustNZ(result); return result; @@ -824,7 +824,7 @@ void EightBit::mc6809::bit(const uint8_t operand, const uint8_t data) { } uint8_t EightBit::mc6809::clr() { - clearFlag(CC(), CF); + CC() = clearBit(CC(), CF); 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) { - setFlag(CC(), CF); + CC() = setBit(CC(), CF); 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) { - setFlag(CC(), CF, operand > 0x99); + CC() = setBit(CC(), CF, operand > 0x99); const auto lowAdjust = halfCarry() || (lowNibble(operand) > 9); 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) { - setFlag(CC(), CF, operand & Bit0); + CC() = setBit(CC(), CF, operand & Bit0); adjustNZ(operand >>= 1); 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) { const register16_t result = first * second; adjustZero(result); - setFlag(CC(), CF, result.low & Bit7); + CC() = setBit(CC(), CF, result.low & Bit7); return result; } 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; operand = result.low; 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) { const auto carryIn = carry(); - setFlag(CC(), CF, operand & Bit7); - setFlag(CC(), VF, ((operand & Bit7) >> 7) ^ ((operand & Bit6) >> 6)); + CC() = setBit(CC(), CF, operand & Bit7); + CC() = setBit(CC(), VF, ((operand & Bit7) >> 7) ^ ((operand & Bit6) >> 6)); const uint8_t result = (operand << 1) | carryIn; adjustNZ(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) { const auto carryIn = carry(); - setFlag(CC(), CF, operand & Bit0); + CC() = setBit(CC(), CF, operand & Bit0); const uint8_t result = (operand >> 1) | (carryIn << 7); adjustNZ(result); return result; @@ -1060,8 +1060,8 @@ void EightBit::mc6809::rts() { void EightBit::mc6809::swi() { saveEntireRegisterState(); - setFlag(CC(), IF); // Disable IRQ - setFlag(CC(), FF); // Disable FIRQ + CC() = setBit(CC(), IF); // Disable IRQ + CC() = setBit(CC(), FF); // Disable FIRQ jump(getWordPaged(0xff, SWIvector)); } diff --git a/MC6809/unittest/mc6809_tests.cpp b/MC6809/unittest/mc6809_tests.cpp index 799539b..ee2f111 100644 --- a/MC6809/unittest/mc6809_tests.cpp +++ b/MC6809/unittest/mc6809_tests.cpp @@ -77,7 +77,7 @@ TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") { SECTION("Immediate (byte)") { board.poke(0, 0x89); 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.step(); 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(1, 0x34); cpu.A() = 0x14; - cpu.setFlag(cpu.CC(), EightBit::mc6809::CF); + cpu.CC() = cpu.setBit(cpu.CC(), EightBit::mc6809::CF); cpu.step(); REQUIRE(cpu.A() == 0xdf); REQUIRE((cpu.CC() & EightBit::mc6809::ZF) == 0); diff --git a/MC6850/src/MC6850.cpp b/MC6850/src/MC6850.cpp index 3645f2d..fb8b250 100644 Binary files a/MC6850/src/MC6850.cpp and b/MC6850/src/MC6850.cpp differ diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 9a2cf29..a1d9aea 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -137,6 +137,13 @@ namespace EightBit { m_displacement = fetchByte(); } + uint8_t fetchInitialOpCode() { + lowerM1(); + const auto returned = fetchByte(); + raiseM1(); + return returned; + } + [[nodiscard]] auto& HL2() { if (LIKELY(!m_displaced)) 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) { - setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation)); + [[nodiscard]] static uint8_t adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int 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) { - 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) { @@ -285,7 +292,7 @@ namespace EightBit { static void adjustOverflowAdd(uint8_t& f, const int beforeNegative, const int valueNegative, const int 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) { @@ -294,17 +301,17 @@ namespace EightBit { static void adjustOverflowSub(uint8_t& f, const int beforeNegative, const int valueNegative, const int 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 executeED(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]] uint8_t decrement(uint8_t operand); + [[nodiscard]] static uint8_t increment(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t decrement(uint8_t& f, uint8_t operand); void di(); void ei(); @@ -312,60 +319,60 @@ namespace EightBit { void retn(); void reti(); - bool jrConditionalFlag(int flag); - bool returnConditionalFlag(int flag); - bool jumpConditionalFlag(int flag); - bool callConditionalFlag(int flag); + [[nodiscard]] bool jrConditionalFlag(uint8_t f, int flag); + [[nodiscard]] bool returnConditionalFlag(uint8_t f, int flag); + [[nodiscard]] bool callConditionalFlag(uint8_t f, int flag); + void jumpConditionalFlag(uint8_t f, int flag); - register16_t sbc(register16_t operand, register16_t value); - register16_t adc(register16_t operand, register16_t value); - register16_t add(register16_t operand, register16_t value, int carry = 0); + [[nodiscard]] register16_t sbc(uint8_t& f, register16_t operand, register16_t value); + [[nodiscard]] register16_t adc(uint8_t& f, register16_t operand, register16_t value); + [[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]] uint8_t adc(uint8_t operand, uint8_t value); - [[nodiscard]] uint8_t sub(uint8_t operand, uint8_t value, int carry = 0); - [[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t value); - void andr(uint8_t value); - void xorr(uint8_t value); - void orr(uint8_t value); - void compare(uint8_t value); + [[nodiscard]] static uint8_t add(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0); + [[nodiscard]] static uint8_t adc(uint8_t& f, uint8_t operand, uint8_t value); + [[nodiscard]] static uint8_t sub(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0); + [[nodiscard]] static uint8_t sbc(uint8_t& f, uint8_t operand, uint8_t value); + [[nodiscard]] static uint8_t andr(uint8_t& f, uint8_t operand, uint8_t value); + [[nodiscard]] static uint8_t xorr(uint8_t& f, uint8_t operand, uint8_t value); + [[nodiscard]] static uint8_t orr(uint8_t& f, uint8_t operand, uint8_t value); + static void compare(uint8_t& f, uint8_t operand, uint8_t value); - [[nodiscard]] uint8_t rlc(uint8_t operand); - [[nodiscard]] uint8_t rrc(uint8_t operand); - [[nodiscard]] uint8_t rl(uint8_t operand); - [[nodiscard]] uint8_t rr(uint8_t operand); - [[nodiscard]] uint8_t sla(uint8_t operand); - [[nodiscard]] uint8_t sra(uint8_t operand); - [[nodiscard]] uint8_t sll(uint8_t operand); - [[nodiscard]] uint8_t srl(uint8_t operand); + [[nodiscard]] static uint8_t rlc(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t rrc(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t rl(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t rr(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t sla(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t sra(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t sll(uint8_t& f, 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 set(int n, uint8_t operand); - void daa(); + [[nodiscard]] static uint8_t daa(uint8_t& f, uint8_t operand); - void scf(); - void ccf(); - void cpl(); + static void scf(uint8_t& f, uint8_t operand); + static void ccf(uint8_t& f, uint8_t operand); + static uint8_t cpl(uint8_t& f, uint8_t operand); 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(); - bool cpir(); + void cpi(uint8_t& f, uint8_t value); + bool cpir(uint8_t& f, uint8_t value); - void cpd(); - bool cpdr(); + void cpd(uint8_t& f, uint8_t value); + 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(); - bool ldir(); + void ldi(uint8_t& f, uint8_t a); + bool ldir(uint8_t& f, uint8_t a); - void ldd(); - bool lddr(); + void ldd(uint8_t& f, uint8_t a); + bool lddr(uint8_t& f, uint8_t a); void blockIn(register16_t& source, register16_t destination); @@ -383,10 +390,10 @@ namespace EightBit { void outd(); bool otdr(); - void neg(); + [[nodiscard]] uint8_t neg(uint8_t& f, uint8_t operand); - void rrd(); - void rld(); + void rrd(uint8_t& f, register16_t address, uint8_t& update); + void rld(uint8_t& f, register16_t address, uint8_t& update); void writePort(uint8_t port); void writePort(); diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 8cc84d6..ae2b7de 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -10,6 +10,7 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports) raiseM1(); raiseIORQ(); + raiseMREQ(); raiseRD(); raiseWR(); @@ -122,61 +123,69 @@ void EightBit::Z80::ei() { IFF1() = IFF2() = true; } -uint8_t EightBit::Z80::increment(const uint8_t operand) { - clearFlag(F(), NF); +uint8_t EightBit::Z80::increment(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF); const uint8_t result = operand + 1; - adjustSZXY(F(), result); - setFlag(F(), VF, result == Bit7); - clearFlag(F(), HC, lowNibble(result)); + f = adjustSZXY(f, result); + f = setBit(f, VF, result == Bit7); + f = clearBit(f, HC, lowNibble(result)); return result; } -uint8_t EightBit::Z80::decrement(const uint8_t operand) { - setFlag(F(), NF); - clearFlag(F(), HC, lowNibble(operand)); +uint8_t EightBit::Z80::decrement(uint8_t& f, const uint8_t operand) { + f = setBit(f, NF); + f = clearBit(f, HC, lowNibble(operand)); const uint8_t result = operand - 1; - adjustSZXY(F(), result); - setFlag(F(), VF, result == Mask7); + f = adjustSZXY(f, result); + f = setBit(f, VF, result == Mask7); return result; } -bool EightBit::Z80::jrConditionalFlag(const int flag) { +bool EightBit::Z80::jrConditionalFlag(const uint8_t f, const int flag) { ASSUME(flag >= 0); ASSUME(flag <= 3); switch (flag) { case 0: // NZ - return jrConditional(!(F() & ZF)); + return jrConditional(!(f & ZF)); case 1: // Z - return jrConditional(F() & ZF); + return jrConditional(f & ZF); case 2: // NC - return jrConditional(!(F() & CF)); + return jrConditional(!(f & CF)); case 3: // C - return jrConditional(F() & CF); + return jrConditional(f & CF); default: UNREACHABLE; } } -bool EightBit::Z80::jumpConditionalFlag(const int flag) { +void EightBit::Z80::jumpConditionalFlag(const uint8_t f, const int flag) { ASSUME(flag >= 0); ASSUME(flag <= 7); switch (flag) { case 0: // NZ - return jumpConditional(!(F() & ZF)); + jumpConditional(!(f & ZF)); + break; case 1: // Z - return jumpConditional(F() & ZF); + jumpConditional(f & ZF); + break; case 2: // NC - return jumpConditional(!(F() & CF)); + jumpConditional(!(f & CF)); + break; case 3: // C - return jumpConditional(F() & CF); + jumpConditional(f & CF); + break; case 4: // PO - return jumpConditional(!(F() & PF)); + jumpConditional(!(f & PF)); + break; case 5: // PE - return jumpConditional(F() & PF); + jumpConditional(f & PF); + break; case 6: // P - return jumpConditional(!(F() & SF)); + jumpConditional(!(f & SF)); + break; case 7: // M - return jumpConditional(F() & SF); + jumpConditional(f & SF); + break; default: UNREACHABLE; } @@ -191,254 +200,260 @@ void EightBit::Z80::reti() { retn(); } -bool EightBit::Z80::returnConditionalFlag(const int flag) { +bool EightBit::Z80::returnConditionalFlag(const uint8_t f, const int flag) { ASSUME(flag >= 0); ASSUME(flag <= 7); switch (flag) { case 0: // NZ - return returnConditional(!(F() & ZF)); + return returnConditional(!(f & ZF)); case 1: // Z - return returnConditional(F() & ZF); + return returnConditional(f & ZF); case 2: // NC - return returnConditional(!(F() & CF)); + return returnConditional(!(f & CF)); case 3: // C - return returnConditional(F() & CF); + return returnConditional(f & CF); case 4: // PO - return returnConditional(!(F() & PF)); + return returnConditional(!(f & PF)); case 5: // PE - return returnConditional(F() & PF); + return returnConditional(f & PF); case 6: // P - return returnConditional(!(F() & SF)); + return returnConditional(!(f & SF)); case 7: // M - return returnConditional(F() & SF); + return returnConditional(f & SF); default: UNREACHABLE; } } -bool EightBit::Z80::callConditionalFlag(const int flag) { +bool EightBit::Z80::callConditionalFlag(const uint8_t f, const int flag) { ASSUME(flag >= 0); ASSUME(flag <= 7); switch (flag) { case 0: // NZ - return callConditional(!(F() & ZF)); + return callConditional(!(f & ZF)); case 1: // Z - return callConditional(F() & ZF); + return callConditional(f & ZF); case 2: // NC - return callConditional(!(F() & CF)); + return callConditional(!(f & CF)); case 3: // C - return callConditional(F() & CF); + return callConditional(f & CF); case 4: // PO - return callConditional(!(F() & PF)); + return callConditional(!(f & PF)); case 5: // PE - return callConditional(F() & PF); + return callConditional(f & PF); case 6: // P - return callConditional(!(F() & SF)); + return callConditional(!(f & SF)); case 7: // M - return callConditional(F() & SF); + return callConditional(f & SF); default: UNREACHABLE; } } -EightBit::register16_t EightBit::Z80::sbc(const register16_t operand, const register16_t value) { +EightBit::register16_t EightBit::Z80::sbc(uint8_t& f, const register16_t operand, const register16_t value) { - const auto subtraction = operand.word - value.word - (F() & CF); + const auto subtraction = operand.word - value.word - (f & CF); const register16_t result = subtraction; - setFlag(F(), NF); - clearFlag(F(), ZF, result.word); - setFlag(F(), CF, subtraction & Bit16); - adjustHalfCarrySub(F(), operand.high, value.high, result.high); - adjustXY(F(), result.high); + f = setBit(f, NF); + f = clearBit(f, ZF, result.word); + f = setBit(f, CF, subtraction & Bit16); + adjustHalfCarrySub(f, operand.high, value.high, result.high); + f = adjustXY(f, result.high); const auto beforeNegative = operand.high & SF; const auto valueNegative = value.high & SF; const auto afterNegative = result.high & SF; - setFlag(F(), SF, afterNegative); - adjustOverflowSub(F(), beforeNegative, valueNegative, afterNegative); + f = setBit(f, SF, afterNegative); + adjustOverflowSub(f, beforeNegative, valueNegative, afterNegative); MEMPTR() = operand + 1; return result; } -EightBit::register16_t EightBit::Z80::adc(const register16_t operand, const register16_t value) { +EightBit::register16_t EightBit::Z80::adc(uint8_t& f, const register16_t operand, const register16_t value) { - const auto result = add(operand, value, F() & CF); - clearFlag(F(), ZF, result.word); + const auto result = add(f, operand, value, f & CF); + f = clearBit(f, ZF, result.word); const auto beforeNegative = operand.high & SF; const auto valueNegative = value.high & SF; const auto afterNegative = result.high & SF; - setFlag(F(), SF, afterNegative); - adjustOverflowAdd(F(), beforeNegative, valueNegative, afterNegative); + f = setBit(f, SF, afterNegative); + adjustOverflowAdd(f, beforeNegative, valueNegative, afterNegative); return result; } -EightBit::register16_t EightBit::Z80::add(const register16_t operand, const register16_t value, int carry) { +EightBit::register16_t EightBit::Z80::add(uint8_t& f, const register16_t operand, const register16_t value, int carry) { const int addition = operand.word + value.word + carry; const register16_t result = addition; - clearFlag(F(), NF); - setFlag(F(), CF, addition & Bit16); - adjustHalfCarryAdd(F(), operand.high, value.high, result.high); - adjustXY(F(), result.high); + f = clearBit(f, NF); + f = setBit(f, CF, addition & Bit16); + f = adjustHalfCarryAdd(f, operand.high, value.high, result.high); + f = adjustXY(f, result.high); MEMPTR() = operand + 1; return result; } -uint8_t EightBit::Z80::add(const uint8_t operand, const uint8_t value, const int carry) { +uint8_t EightBit::Z80::add(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) { const register16_t addition = operand + value + carry; const auto result = addition.low; - adjustHalfCarryAdd(F(), operand, value, result); - adjustOverflowAdd(F(), operand, value, result); + f = adjustHalfCarryAdd(f, operand, value, result); + adjustOverflowAdd(f, operand, value, result); - clearFlag(F(), NF); - setFlag(F(), CF, addition.high & CF); - adjustSZXY(F(), result); + f = clearBit(f, NF); + f = setBit(f, CF, addition.high & CF); + f = adjustSZXY(f, result); return result; } -uint8_t EightBit::Z80::adc(const uint8_t operand, const uint8_t value) { - return add(operand, value, F() & CF); +uint8_t EightBit::Z80::adc(uint8_t& f, const uint8_t operand, const uint8_t value) { + return add(f, operand, value, f & CF); } -uint8_t EightBit::Z80::subtract(const uint8_t operand, const uint8_t value, const int carry) { +uint8_t EightBit::Z80::subtract(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) { const register16_t subtraction = operand - value - carry; const auto result = subtraction.low; - adjustHalfCarrySub(F(), operand, value, result); - adjustOverflowSub(F(), operand, value, result); + adjustHalfCarrySub(f, operand, value, result); + adjustOverflowSub(f, operand, value, result); - setFlag(F(), NF); - setFlag(F(), CF, subtraction.high & CF); - adjustSZ(F(), result); + f = setBit(f, NF); + f = setBit(f, CF, subtraction.high & CF); + f = adjustSZ(f, result); return result; } -uint8_t EightBit::Z80::sub(const uint8_t operand, const uint8_t value, const int carry) { - const auto subtraction = subtract(operand, value, carry); - adjustXY(F(), subtraction); +uint8_t EightBit::Z80::sub(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) { + const auto subtraction = subtract(f, operand, value, carry); + f = adjustXY(f, subtraction); return subtraction; } -uint8_t EightBit::Z80::sbc(const uint8_t operand, const uint8_t value) { - return sub(operand, value, F() & CF); +uint8_t EightBit::Z80::sbc(uint8_t& f, const uint8_t operand, const uint8_t value) { + return sub(f, operand, value, f & CF); } -void EightBit::Z80::andr(const uint8_t value) { - setFlag(F(), HC); - clearFlag(F(), CF | NF); - adjustSZPXY(F(), A() &= value); +uint8_t EightBit::Z80::andr(uint8_t& f, const uint8_t operand, const uint8_t value) { + f = setBit(f, HC); + f = clearBit(f, CF | NF); + const uint8_t result = operand & value; + f = adjustSZPXY(f, result); + return result; } -void EightBit::Z80::xorr(const uint8_t value) { - clearFlag(F(), HC | CF | NF); - adjustSZPXY(F(), A() ^= value); +uint8_t EightBit::Z80::xorr(uint8_t& f, const uint8_t operand, const uint8_t value) { + f = clearBit(f, HC | CF | NF); + const uint8_t result = operand ^ value; + f = adjustSZPXY(f, result); + return result; } -void EightBit::Z80::orr(const uint8_t value) { - clearFlag(F(), HC | CF | NF); - adjustSZPXY(F(), A() |= value); +uint8_t EightBit::Z80::orr(uint8_t& f, const uint8_t operand, const uint8_t value) { + f = clearBit(f, HC | CF | NF); + const uint8_t result = operand | value; + f = adjustSZPXY(f, result); + return result; } -void EightBit::Z80::compare(const uint8_t value) { - subtract(A(), value); - adjustXY(F(), value); +void EightBit::Z80::compare(uint8_t& f, uint8_t operand, const uint8_t value) { + subtract(f, operand, value); + f = adjustXY(f, value); } -uint8_t EightBit::Z80::rlc(const uint8_t operand) { - clearFlag(F(), NF | HC); +uint8_t EightBit::Z80::rlc(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); const auto carry = operand & Bit7; - setFlag(F(), CF, carry); + f = setBit(f, CF, carry); const uint8_t result = (operand << 1) | (carry >> 7); - adjustXY(F(), result); + f = adjustXY(f, result); return result; } -uint8_t EightBit::Z80::rrc(const uint8_t operand) { - clearFlag(F(), NF | HC); +uint8_t EightBit::Z80::rrc(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); const auto carry = operand & Bit0; - setFlag(F(), CF, carry); + f = setBit(f, CF, carry); const uint8_t result = (operand >> 1) | (carry << 7); - adjustXY(F(), result); + f = adjustXY(f, result); return result; } -uint8_t EightBit::Z80::rl(const uint8_t operand) { - clearFlag(F(), NF | HC); - const auto carry = F() & CF; - setFlag(F(), CF, operand & Bit7); +uint8_t EightBit::Z80::rl(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + const auto carry = f & CF; + f = setBit(f, CF, operand & Bit7); const uint8_t result = (operand << 1) | carry; - adjustXY(F(), result); + f = adjustXY(f, result); return result; } -uint8_t EightBit::Z80::rr(const uint8_t operand) { - clearFlag(F(), NF | HC); - const auto carry = F() & CF; - setFlag(F(), CF, operand & Bit0); +uint8_t EightBit::Z80::rr(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + const auto carry = f & CF; + f = setBit(f, CF, operand & Bit0); const uint8_t result = (operand >> 1) | (carry << 7); - adjustXY(F(), result); + f = adjustXY(f, result); return result; } // -uint8_t EightBit::Z80::sla(const uint8_t operand) { - clearFlag(F(), NF | HC); - setFlag(F(), CF, operand & Bit7); +uint8_t EightBit::Z80::sla(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + f = setBit(f, CF, operand & Bit7); const uint8_t result = operand << 1; - adjustXY(F(), result); + f = adjustXY(f, result); return result; } -uint8_t EightBit::Z80::sra(const uint8_t operand) { - clearFlag(F(), NF | HC); - setFlag(F(), CF, operand & Bit0); +uint8_t EightBit::Z80::sra(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + f = setBit(f, CF, operand & Bit0); const uint8_t result = (operand >> 1) | (operand & Bit7); - adjustXY(F(), result); + f = adjustXY(f, result); return result; } -uint8_t EightBit::Z80::sll(const uint8_t operand) { - clearFlag(F(), NF | HC); - setFlag(F(), CF, operand & Bit7); +uint8_t EightBit::Z80::sll(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + f = setBit(f, CF, operand & Bit7); const uint8_t result = (operand << 1) | Bit0; - adjustXY(F(), result); + f = adjustXY(f, result); return result; } -uint8_t EightBit::Z80::srl(const uint8_t operand) { - clearFlag(F(), NF | HC); - setFlag(F(), CF, operand & Bit0); +uint8_t EightBit::Z80::srl(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + f = setBit(f, CF, operand & Bit0); const uint8_t result = (operand >> 1) & ~Bit7; - adjustXY(F(), result); - setFlag(F(), ZF, result); + f = adjustXY(f, result); + f = setBit(f, ZF, result); return result; } -void EightBit::Z80::bit(const int n, const uint8_t operand) { +void EightBit::Z80::bit(uint8_t& f, const int n, const uint8_t operand) { ASSUME(n >= 0); ASSUME(n <= 7); - setFlag(F(), HC); - clearFlag(F(), NF); + f = setBit(f, HC); + f = clearBit(f, NF); const auto discarded = operand & Chip::bit(n); - adjustSZ(F(), discarded); - clearFlag(F(), PF, discarded); + f = adjustSZ(f, discarded); + f = clearBit(f, PF, discarded); } uint8_t EightBit::Z80::res(const int n, const uint8_t operand) { @@ -453,30 +468,29 @@ uint8_t EightBit::Z80::set(const int n, const uint8_t operand) { return operand | Chip::bit(n); } -void EightBit::Z80::neg() { +uint8_t EightBit::Z80::neg(uint8_t& f, uint8_t operand) { - setFlag(F(), PF, A() == Bit7); - setFlag(F(), CF, A()); - setFlag(F(), NF); + f = setBit(f, PF, operand == Bit7); + f = setBit(f, CF, operand); + f = setBit(f, NF); - const auto original = A(); + const uint8_t result = (~operand + 1); // two's complement - A() = (~A() + 1); // two's complement + adjustHalfCarrySub(f, 0U, operand, result); + adjustOverflowSub(f, 0U, operand, result); - adjustHalfCarrySub(F(), 0U, original, A()); - adjustOverflowSub(F(), 0U, original, A()); + f = adjustSZXY(f, result); - adjustSZXY(F(), A()); + return result; } -void EightBit::Z80::daa() { +uint8_t EightBit::Z80::daa(uint8_t& f, uint8_t operand) { - auto updated = A(); + const auto lowAdjust = (f & HC) || (lowNibble(operand) > 9); + const auto highAdjust = (f & CF) || (operand > 0x99); - const auto lowAdjust = (F() & HC) || (lowNibble(A()) > 9); - const auto highAdjust = (F() & CF) || (A() > 0x99); - - if (F() & NF) { + auto updated = operand; + if (f & NF) { if (lowAdjust) updated -= 6; if (highAdjust) @@ -488,28 +502,32 @@ void EightBit::Z80::daa() { updated += 0x60; } - F() = (F() & (CF | NF)) | (A() > 0x99 ? CF : 0) | ((A() ^ updated) & HC); + f = (f & (CF | NF)) | (operand > 0x99 ? CF : 0) | ((operand ^ updated) & HC); - adjustSZPXY(F(), A() = updated); + f = adjustSZPXY(f, updated); + + return updated; } -void EightBit::Z80::cpl() { - setFlag(F(), HC | NF); - adjustXY(F(), A() = ~A()); +uint8_t EightBit::Z80::cpl(uint8_t& f, const uint8_t operand) { + f = setBit(f, HC | NF); + const uint8_t result = ~operand; + f = adjustXY(f, result); + return result; } -void EightBit::Z80::scf() { - setFlag(F(), CF); - clearFlag(F(), HC | NF); - adjustXY(F(), A()); +void EightBit::Z80::scf(uint8_t& f, const uint8_t operand) { + f = setBit(f, CF); + f = clearBit(f, HC | NF); + f = adjustXY(f, operand); } -void EightBit::Z80::ccf() { - clearFlag(F(), NF); - const auto carry = F() & CF; - setFlag(F(), HC, carry); - clearFlag(F(), CF, carry); - adjustXY(F(), A()); +void EightBit::Z80::ccf(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF); + const auto carry = f & CF; + f = setBit(f, HC, carry); + f = clearBit(f, CF, carry); + f = adjustXY(f, operand); } void EightBit::Z80::xhtl(register16_t& exchange) { @@ -523,77 +541,77 @@ void EightBit::Z80::xhtl(register16_t& exchange) { exchange.low = MEMPTR().low; } -void EightBit::Z80::blockCompare(const register16_t source, register16_t& counter) { +void EightBit::Z80::blockCompare(uint8_t& f, const uint8_t value, const register16_t source, register16_t& counter) { - const auto value = IntelProcessor::busRead(source); - uint8_t result = A() - value; + const auto contents = IntelProcessor::busRead(source); + uint8_t result = value - contents; - setFlag(F(), PF, --counter.word); + f = setBit(f, PF, --counter.word); - adjustSZ(F(), result); - adjustHalfCarrySub(F(), A(), value, result); - setFlag(F(), NF); + f = adjustSZ(f, result); + adjustHalfCarrySub(f, value, contents, result); + f = setBit(f, NF); - result -= ((F() & HC) >> 4); + result -= ((f & HC) >> 4); - setFlag(F(), YF, result & Bit1); - setFlag(F(), XF, result & Bit3); + f = setBit(f, YF, result & Bit1); + f = setBit(f, XF, result & Bit3); } -void EightBit::Z80::cpi() { - blockCompare(HL()++, BC()); +void EightBit::Z80::cpi(uint8_t& f, uint8_t value) { + blockCompare(f, value, HL()++, BC()); ++MEMPTR(); } -void EightBit::Z80::cpd() { - blockCompare(HL()--, BC()); +void EightBit::Z80::cpd(uint8_t& f, uint8_t value) { + blockCompare(f, value, HL()--, BC()); --MEMPTR(); } -bool EightBit::Z80::cpir() { - cpi(); - return (F() & PF) && !(F() & ZF); // See CPI +bool EightBit::Z80::cpir(uint8_t& f, uint8_t value) { + cpi(f, value); + return (f & PF) && !(f & ZF); // See CPI } -bool EightBit::Z80::cpdr() { - cpd(); - return (F() & PF) && !(F() & ZF); // See CPD +bool EightBit::Z80::cpdr(uint8_t& f, uint8_t value) { + cpd(f, value); + return (f & PF) && !(f & ZF); // See CPD } -void EightBit::Z80::blockLoad(const register16_t source, const register16_t destination, register16_t& counter) { +void EightBit::Z80::blockLoad(uint8_t& f, const uint8_t a, const register16_t source, const register16_t destination, register16_t& counter) { const auto value = IntelProcessor::busRead(source); IntelProcessor::busWrite(destination, value); - const auto xy = A() + value; - setFlag(F(), XF, xy & Bit3); - setFlag(F(), YF, xy & Bit1); - clearFlag(F(), NF | HC); - setFlag(F(), PF, --counter.word); + const auto xy = a + value; + f = setBit(f, XF, xy & Bit3); + f = setBit(f, YF, xy & Bit1); + f = clearBit(f, NF | HC); + f = setBit(f, PF, --counter.word); } -void EightBit::Z80::ldd() { - blockLoad(HL()--, DE()--, BC()); +void EightBit::Z80::ldd(uint8_t& f, const uint8_t a) { + blockLoad(f, a, HL()--, DE()--, BC()); } -void EightBit::Z80::ldi() { - blockLoad(HL()++, DE()++, BC()); +void EightBit::Z80::ldi(uint8_t& f, const uint8_t a) { + blockLoad(f, a, HL()++, DE()++, BC()); } -bool EightBit::Z80::ldir() { - ldi(); - return !!(F() & PF); // See LDI +bool EightBit::Z80::ldir(uint8_t& f, const uint8_t a) { + ldi(f, a); + return !!(f & PF); // See LDI } -bool EightBit::Z80::lddr() { - ldd(); - return !!(F() & PF); // See LDD +bool EightBit::Z80::lddr(uint8_t& f, const uint8_t a) { + ldd(f, a); + return !!(f & PF); // See LDD } void EightBit::Z80::blockIn(register16_t& source, const register16_t destination) { MEMPTR() = BUS().ADDRESS() = source; const auto value = readPort(); IntelProcessor::busWrite(destination, value); - source.high = decrement(source.high); - setFlag(F(), NF); + source.high = decrement(F(), source.high); + F() = setBit(F(), NF); } void EightBit::Z80::ini() { @@ -618,13 +636,13 @@ bool EightBit::Z80::indr() { void EightBit::Z80::blockOut(const register16_t source, register16_t& destination) { const auto value = IntelProcessor::busRead(source); - destination.high = decrement(destination.high); + destination.high = decrement(F(), destination.high); BUS().ADDRESS() = destination; writePort(); MEMPTR() = destination; - setFlag(F(), NF, value & Bit7); - setFlag(F(), HC | CF, (L() + value) > 0xff); - adjustParity(F(), ((value + L()) & Mask3) ^ B()); + F() = setBit(F(), NF, value & Bit7); + F() = setBit(F(), HC | CF, (L() + value) > 0xff); + F() = adjustParity(F(), ((value + L()) & Mask3) ^ B()); } void EightBit::Z80::outi() { @@ -647,22 +665,22 @@ bool EightBit::Z80::otdr() { return !(F() & ZF); // See OUTD } -void EightBit::Z80::rrd() { - (MEMPTR() = BUS().ADDRESS() = HL())++; +void EightBit::Z80::rrd(uint8_t& f, register16_t address, uint8_t& update) { + (MEMPTR() = BUS().ADDRESS() = address)++; const auto memory = busRead(); - IntelProcessor::busWrite(promoteNibble(A()) | highNibble(memory)); - A() = higherNibble(A()) | lowerNibble(memory); - adjustSZPXY(F(), A()); - clearFlag(F(), NF | HC); + IntelProcessor::busWrite(promoteNibble(update) | highNibble(memory)); + update = higherNibble(update) | lowerNibble(memory); + f = adjustSZPXY(f, update); + f = clearBit(f, NF | HC); } -void EightBit::Z80::rld() { - (MEMPTR() = BUS().ADDRESS() = HL())++; +void EightBit::Z80::rld(uint8_t& f, register16_t address, uint8_t& update) { + (MEMPTR() = BUS().ADDRESS() = address)++; const auto memory = busRead(); - IntelProcessor::busWrite(promoteNibble(memory) | lowNibble(A())); - A() = higherNibble(A()) | highNibble(memory); - adjustSZPXY(F(), A()); - clearFlag(F(), NF | HC); + IntelProcessor::busWrite(promoteNibble(memory) | lowNibble(update)); + update = higherNibble(update) | highNibble(memory); + f = adjustSZPXY(f, update); + f = clearBit(f, NF | HC); } void EightBit::Z80::writePort(const uint8_t port) { @@ -717,10 +735,8 @@ int EightBit::Z80::step() { execute(0); // NOP handled = true; } - if (!handled) { - lowerM1(); - execute(fetchByte()); - } + if (!handled) + execute(fetchInitialOpCode()); } ExecutedInstruction.fire(*this); return cycles(); @@ -728,8 +744,6 @@ int EightBit::Z80::step() { int EightBit::Z80::execute() { - raiseM1(); - const auto& decoded = getDecodedOpcode(opcode()); const auto x = decoded.x; @@ -760,43 +774,43 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) { case 0: { // rot[y] r[z] switch (y) { case 0: - operand = rlc(operand); + operand = rlc(F(), operand); break; case 1: - operand = rrc(operand); + operand = rrc(F(), operand); break; case 2: - operand = rl(operand); + operand = rl(F(), operand); break; case 3: - operand = rr(operand); + operand = rr(F(), operand); break; case 4: - operand = sla(operand); + operand = sla(F(), operand); break; case 5: - operand = sra(operand); + operand = sra(F(), operand); break; case 6: - operand = sll(operand); + operand = sll(F(), operand); break; case 7: - operand = srl(operand); + operand = srl(F(), operand); break; default: UNREACHABLE; } - adjustSZP(F(), operand); + F() = adjustSZP(F(), operand); tick(8); break; } case 1: // BIT y, r[z] tick(8); - bit(y, operand); + bit(F(), y, operand); if (indirect) { - adjustXY(F(), MEMPTR().high); + F() = adjustXY(F(), MEMPTR().high); tick(4); } else { - adjustXY(F(), operand); + F() = adjustXY(F(), operand); } break; case 2: // RES y, r[z] @@ -839,8 +853,8 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p readPort(); if (y != 6) // IN r[y],(C) R(y, BUS().DATA()); - adjustSZPXY(F(), BUS().DATA()); - clearFlag(F(), NF | HC); + F() = adjustSZPXY(F(), BUS().DATA()); + F() = clearBit(F(), NF | HC); tick(12); break; case 1: // Output to port with 16-bit address @@ -855,10 +869,10 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p case 2: // 16-bit add/subtract with carry switch (q) { case 0: // SBC HL, rp[p] - HL2() = sbc(HL2(), RP(p)); + HL2() = sbc(F(), HL2(), RP(p)); break; case 1: // ADC HL, rp[p] - HL2() = adc(HL2(), RP(p)); + HL2() = adc(F(), HL2(), RP(p)); break; default: UNREACHABLE; @@ -880,7 +894,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p tick(20); break; case 4: // Negate accumulator - neg(); + A() = neg(F(), A()); tick(8); break; case 5: // Return from interrupt @@ -926,23 +940,23 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p tick(9); break; case 2: // LD A,I - adjustSZXY(F(), A() = IV()); - clearFlag(F(), NF | HC); - setFlag(F(), PF, IFF2()); + F() = adjustSZXY(F(), A() = IV()); + F() = clearBit(F(), NF | HC); + F() = setBit(F(), PF, IFF2()); tick(9); break; case 3: // LD A,R - adjustSZXY(F(), A() = REFRESH()); - clearFlag(F(), NF | HC); - setFlag(F(), PF, IFF2()); + F() = adjustSZXY(F(), A() = REFRESH()); + F() = clearBit(F(), NF | HC); + F() = setBit(F(), PF, IFF2()); tick(9); break; case 4: // RRD - rrd(); + rrd(F(), HL(), A()); tick(18); break; case 5: // RLD - rld(); + rld(F(), HL(), A()); tick(18); break; case 6: // NOP @@ -962,20 +976,20 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p case 0: // LD switch (y) { case 4: // LDI - ldi(); + ldi(F(), A()); break; case 5: // LDD - ldd(); + ldd(F(), A()); break; case 6: // LDIR - if (ldir()) { + if (ldir(F(), A())) { MEMPTR() = --PC(); --PC(); tick(5); } break; case 7: // LDDR - if (lddr()) { + if (lddr(F(), A())) { MEMPTR() = --PC(); --PC(); tick(5); @@ -986,20 +1000,20 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p case 1: // CP switch (y) { case 4: // CPI - cpi(); + cpi(F(), A()); break; case 5: // CPD - cpd(); + cpd(F(), A()); break; case 6: // CPIR - if (cpir()) { + if (cpir(F(), A())) { MEMPTR() = --PC(); --PC(); tick(5); } break; case 7: // CPDR - if (cpdr()) { + if (cpdr(F(), A())) { MEMPTR() = --PC(); --PC(); tick(5); @@ -1089,7 +1103,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 5: case 6: case 7: - if (jrConditionalFlag(y - 4)) + if (jrConditionalFlag(F(), y - 4)) tick(5); tick(5); break; @@ -1104,7 +1118,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in tick(10); break; case 1: // ADD HL,rp - HL2() = add(HL2(), RP(p)); + HL2() = add(F(), HL2(), RP(p)); tick(11); break; default: @@ -1188,7 +1202,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 4: // 8-bit INC if (m_displaced && memoryY) fetchDisplacement(); - R(y, increment(R(y))); + R(y, increment(F(), R(y))); tick(4); break; case 5: // 8-bit DEC @@ -1197,7 +1211,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in if (m_displaced) fetchDisplacement(); } - R(y, decrement(R(y))); + R(y, decrement(F(), R(y))); tick(4); break; case 6: // 8-bit load immediate @@ -1212,28 +1226,28 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 7: // Assorted operations on accumulator/flags switch (y) { case 0: - A() = rlc(A()); + A() = rlc(F(), A()); break; case 1: - A() = rrc(A()); + A() = rrc(F(), A()); break; case 2: - A() = rl(A()); + A() = rl(F(), A()); break; case 3: - A() = rr(A()); + A() = rr(F(), A()); break; case 4: - daa(); + A() = daa(F(), A()); break; case 5: - cpl(); + A() = cpl(F(), A()); break; case 6: - scf(); + scf(F(), A()); break; case 7: - ccf(); + ccf(F(), A()); break; default: UNREACHABLE; @@ -1293,28 +1307,28 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in const auto value = R(z); switch (y) { case 0: // ADD A,r - A() = add(A(), value); + A() = add(F(), A(), value); break; case 1: // ADC A,r - A() = adc(A(), value); + A() = adc(F(), A(), value); break; case 2: // SUB r - A() = sub(A(), value); + A() = sub(F(), A(), value); break; case 3: // SBC A,r - A() = sbc(A(), value); + A() = sbc(F(), A(), value); break; case 4: // AND r - andr(value); + A() = andr(F(), A(), value); break; case 5: // XOR r - xorr(value); + A() = xorr(F(), A(), value); break; case 6: // OR r - orr(value); + A() = orr(F(), A(), value); break; case 7: // CP r - compare(value); + compare(F(), A(), value); break; default: UNREACHABLE; @@ -1325,7 +1339,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 3: switch (z) { case 0: // Conditional return - if (returnConditionalFlag(y)) + if (returnConditionalFlag(F(), y)) tick(6); tick(5); break; @@ -1362,7 +1376,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in } break; case 2: // Conditional jump - jumpConditionalFlag(y); + jumpConditionalFlag(F(), y); tick(10); break; case 3: // Assorted operations @@ -1373,11 +1387,12 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; case 1: // CB prefix m_prefixCB = true; - if (m_displaced) + if (m_displaced) { fetchDisplacement(); - else - lowerM1(); - execute(fetchByte()); + execute(fetchByte()); + } else { + execute(fetchInitialOpCode()); + } break; case 2: // OUT (n),A writePort(fetchByte()); @@ -1408,7 +1423,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in } break; case 4: // Conditional call: CALL cc[y], nn - if (callConditionalFlag(y)) + if (callConditionalFlag(F(), y)) tick(7); tick(10); break; @@ -1426,18 +1441,15 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; case 1: // DD prefix m_displaced = m_prefixDD = true; - lowerM1(); - execute(fetchByte()); + execute(fetchInitialOpCode()); break; case 2: // ED prefix m_prefixED = true; - lowerM1(); - execute(fetchByte()); + execute(fetchInitialOpCode()); break; case 3: // FD prefix m_displaced = m_prefixFD = true; - lowerM1(); - execute(fetchByte()); + execute(fetchInitialOpCode()); break; default: UNREACHABLE; @@ -1451,28 +1463,28 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in const auto operand = fetchByte(); switch (y) { case 0: // ADD A,n - A() = add(A(), operand); + A() = add(F(), A(), operand); break; case 1: // ADC A,n - A() = adc(A(), operand); + A() = adc(F(), A(), operand); break; case 2: // SUB n - A() = sub(A(), operand); + A() = sub(F(), A(), operand); break; case 3: // SBC A,n - A() = sbc(A(), operand); + A() = sbc(F(), A(), operand); break; case 4: // AND n - andr(operand); + A() = andr(F(), A(), operand); break; case 5: // XOR n - xorr(operand); + A() = xorr(F(), A(), operand); break; case 6: // OR n - orr(operand); + A() = orr(F(), A(), operand); break; case 7: // CP n - compare(operand); + compare(F(), A(), operand); break; default: UNREACHABLE; diff --git a/inc/Chip.h b/inc/Chip.h index db4d956..64ffc7b 100644 --- a/inc/Chip.h +++ b/inc/Chip.h @@ -45,27 +45,26 @@ namespace EightBit { 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; } - static void setFlag(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; } + [[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); } - static void setFlag(uint8_t& f, const int flag, const uint32_t condition) noexcept { setFlag(f, flag, !!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) noexcept { return input & ~which; } + [[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const int condition) noexcept { return clearBit(input, which, !!condition); } + [[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); } - static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) noexcept { clearFlag(f, flag, !!condition); } - static void clearFlag(uint8_t& f, const int flag, const bool condition) noexcept { setFlag(f, flag, !condition); } + [[nodiscard]] static constexpr auto highNibble(const int value) { return value >> 4; } + [[nodiscard]] static constexpr auto lowNibble(const int value) { return value & Mask4; } - static constexpr auto highNibble(const int value) { return value >> 4; } - static constexpr auto lowNibble(const int value) { return value & Mask4; } + [[nodiscard]] static constexpr auto higherNibble(const int value) { return value & 0xf0; } + [[nodiscard]] static constexpr auto lowerNibble(const int value) { return lowNibble(value); } - static constexpr auto higherNibble(const int value) { return value & 0xf0; } - static constexpr auto lowerNibble(const int value) { return lowNibble(value); } - - static constexpr auto promoteNibble(const int value) { return value << 4; } - static constexpr auto demoteNibble(const int value) { return highNibble(value); } + [[nodiscard]] static constexpr auto promoteNibble(const int value) { return value << 4; } + [[nodiscard]] static constexpr auto demoteNibble(const int value) { return highNibble(value); } virtual ~Chip(); diff --git a/inc/Device.h b/inc/Device.h index d47ac57..770615c 100644 --- a/inc/Device.h +++ b/inc/Device.h @@ -68,9 +68,9 @@ namespace EightBit { static constexpr auto lowered(const PinLevel line) { return 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, bool condition) { condition ? raise(line) : lower(line); } - static void match(PinLevel& out, PinLevel in) { out = in; } + static void match(PinLevel& line, int condition) noexcept { match(line, condition != 0); } + static void match(PinLevel& line, bool condition) noexcept { condition ? raise(line) : lower(line); } + static void match(PinLevel& out, PinLevel in) noexcept { out = in; } virtual ~Device() {}; @@ -79,6 +79,6 @@ namespace EightBit { DECLARE_PIN_INPUT(POWER) protected: - Device() {}; + Device() noexcept {}; }; } diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index 381df2f..80a0f2d 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -21,9 +21,9 @@ namespace EightBit { int p = 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 y = (opcode & 0b00111000) >> 3; // 0 - 7 z = (opcode & 0b00000111); // 0 - 7 @@ -35,7 +35,7 @@ namespace EightBit { ~IntelProcessor() = default; [[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; } @@ -63,59 +63,59 @@ namespace EightBit { protected: IntelProcessor(Bus& bus); - template static void adjustSign(uint8_t& f, const uint8_t value) { - setFlag(f, T::SF, value & T::SF); + template [[nodiscard]] static uint8_t adjustSign(uint8_t f, const uint8_t value) { + return setBit(f, T::SF, value & T::SF); } - template static void adjustZero(uint8_t& f, const uint8_t value) { - clearFlag(f, T::ZF, value); + template [[nodiscard]] static uint8_t adjustZero(uint8_t f, const uint8_t value) { + return clearBit(f, T::ZF, value); } - template static void adjustParity(uint8_t& f, const uint8_t value) { - clearFlag(f, T::PF, PARITY(value)); + template [[nodiscard]] static uint8_t adjustParity(uint8_t f, const uint8_t value) { + return clearBit(f, T::PF, PARITY(value)); } - template static void adjustSZ(uint8_t& f, const uint8_t value) { - adjustSign(f, value); - adjustZero(f, value); + template [[nodiscard]] static uint8_t adjustSZ(uint8_t f, const uint8_t value) { + const auto intermediate = adjustSign(f, value); + return adjustZero(intermediate, value); } - template static void adjustSZP(uint8_t& f, const uint8_t value) { - adjustSZ(f, value); - adjustParity(f, value); + template [[nodiscard]] static uint8_t adjustSZP(uint8_t f, const uint8_t value) { + const auto intermediate = adjustSZ(f, value); + return adjustParity(intermediate, value); } - template static void adjustXY(uint8_t& f, const uint8_t value) { - setFlag(f, T::XF, value & T::XF); - setFlag(f, T::YF, value & T::YF); + template [[nodiscard]] static uint8_t adjustXY(uint8_t f, const uint8_t value) { + const auto intermediate = setBit(f, T::XF, value & T::XF); + return setBit(intermediate, T::YF, value & T::YF); } - template static void adjustSZPXY(uint8_t& f, const uint8_t value) { - adjustSZP(f, value); - adjustXY(f, value); + template [[nodiscard]] static uint8_t adjustSZPXY(uint8_t f, const uint8_t value) { + const auto intermediate = adjustSZP(f, value); + return adjustXY(intermediate, value); } - template static void adjustSZXY(uint8_t& f, const uint8_t value) { - adjustSZ(f, value); - adjustXY(f, value); + template [[nodiscard]] static uint8_t adjustSZXY(uint8_t f, const uint8_t value) { + const auto intermediate = adjustSZ(f, value); + return adjustXY(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); } [[nodiscard]] static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) noexcept { static std::array halfCarryTableAdd = { { 0, 0, 1, 0, 1, 0, 1, 1} }; 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 { std::array halfCarryTableSub = { { 0, 1, 1, 1, 0, 0, 0, 1 } }; const auto index = buildHalfCarryIndex(before, value, calculation); - return halfCarryTableSub[index & Mask3]; + return halfCarryTableSub.at(index & Mask3); } void handleRESET() override; @@ -154,7 +154,7 @@ namespace EightBit { return !!condition; } - void jr(const int8_t offset) { + void jr(const int8_t offset) noexcept { jump(MEMPTR() = PC() + offset); }