From 23108a8536fa5910ef7d9d0352e7ef73ecd648b0 Mon Sep 17 00:00:00 2001 From: "Adrian.Conlon" Date: Sun, 18 Jun 2017 18:14:39 +0100 Subject: [PATCH] Bring performance back to par by: inlining and static flag register access, where possible. Signed-off-by: Adrian.Conlon --- Intel8080/inc/Intel8080.h | 136 +++++++------- LR35902/inc/LR35902.h | 14 +- LR35902/src/LR35902.cpp | 190 +++++++++++--------- Z80/inc/Z80.h | 44 ++--- Z80/src/Z80.cpp | 360 +++++++++++++++++++++----------------- inc/IntelProcessor.h | 38 ++-- src/IntelProcessor.cpp | 20 --- 7 files changed, 436 insertions(+), 366 deletions(-) diff --git a/Intel8080/inc/Intel8080.h b/Intel8080/inc/Intel8080.h index 1e181a2..722d211 100644 --- a/Intel8080/inc/Intel8080.h +++ b/Intel8080/inc/Intel8080.h @@ -83,37 +83,37 @@ namespace EightBit { AF().low |= Bit1; } - void adjustSign(uint8_t value) { setFlag(SF, value & SF); } - void adjustZero(uint8_t value) { clearFlag(ZF, value);} + static void adjustSign(uint8_t& f, uint8_t value) { setFlag(f, SF, value & SF); } + static void adjustZero(uint8_t& f, uint8_t value) { clearFlag(f, ZF, value); } - void adjustParity(uint8_t value) { + void adjustParity(uint8_t& f, uint8_t value) { static const uint8_t lookup[0x10] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; auto set = (lookup[highNibble(value)] + lookup[lowNibble(value)]); - clearFlag(PF, set % 2); + clearFlag(f, PF, set % 2); } - void adjustSZP(uint8_t value) { - adjustSign(value); - adjustZero(value); - adjustParity(value); + void adjustSZP(uint8_t& f, uint8_t value) { + adjustSign(f, value); + adjustZero(f, value); + adjustParity(f, value); } - void adjustAuxiliaryCarryAdd(uint8_t value, int calculation) { - setFlag(AC, calculateHalfCarryAdd(A(), value, calculation)); + void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t value, int calculation) { + setFlag(f, AC, calculateHalfCarryAdd(A(), value, calculation)); } - void adjustAuxiliaryCarrySub(uint8_t value, int calculation) { - clearFlag(AC, calculateHalfCarrySub(A(), value, calculation)); + void adjustAuxiliaryCarrySub(uint8_t& f, uint8_t value, int calculation) { + clearFlag(f, AC, calculateHalfCarrySub(A(), value, calculation)); } - void postIncrement(uint8_t value) { - adjustSZP(value); - clearFlag(AC, lowNibble(value)); + void postIncrement(uint8_t& f, uint8_t value) { + adjustSZP(f, value); + clearFlag(f, AC, lowNibble(value)); } - void postDecrement(uint8_t value) { - adjustSZP(value); - setFlag(AC, lowNibble(value) != Mask4); + void postDecrement(uint8_t& f, uint8_t value) { + adjustSZP(f, value); + setFlag(f, AC, lowNibble(value) != Mask4); } static Instruction INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles); @@ -124,35 +124,40 @@ namespace EightBit { // void compare(uint8_t value) { + auto& f = F(); uint16_t subtraction = A() - value; - adjustSZP((uint8_t)subtraction); - adjustAuxiliaryCarrySub(value, subtraction); - setFlag(CF, subtraction & Bit8); + adjustSZP(f, (uint8_t)subtraction); + adjustAuxiliaryCarrySub(f, value, subtraction); + setFlag(f, CF, subtraction & Bit8); } void anda(uint8_t value) { - setFlag(AC, (A() | value) & Bit3); - clearFlag(CF); - adjustSZP(A() &= value); + auto& f = F(); + setFlag(f, AC, (A() | value) & Bit3); + clearFlag(f, CF); + adjustSZP(f, A() &= value); } void ora(uint8_t value) { - clearFlag(AC | CF); - adjustSZP(A() |= value); + auto& f = F(); + clearFlag(f, AC | CF); + adjustSZP(f, A() |= value); } void xra(uint8_t value) { - clearFlag(AC | CF); - adjustSZP(A() ^= value); + auto& f = F(); + clearFlag(f, AC | CF); + adjustSZP(f, A() ^= value); } void add(uint8_t value, int carry = 0) { + auto& f = F(); register16_t sum; sum.word = A() + value + carry; - adjustAuxiliaryCarryAdd(value, sum.word); + adjustAuxiliaryCarryAdd(f, value, sum.word); A() = sum.low; - setFlag(CF, sum.word & Bit8); - adjustSZP(A()); + setFlag(f, CF, sum.word & Bit8); + adjustSZP(f, A()); } void adc(uint8_t value) { @@ -160,18 +165,20 @@ namespace EightBit { } void dad(uint16_t value) { + auto& f = F(); uint32_t sum = HL().word + value; - setFlag(CF, sum > 0xffff); + setFlag(f, CF, sum > 0xffff); HL().word = (uint16_t)sum; } void sub(uint8_t value, int carry = 0) { + auto& f = F(); register16_t difference; difference.word = A() - value - carry; - adjustAuxiliaryCarrySub(value, difference.word); + adjustAuxiliaryCarrySub(f, value, difference.word); A() = difference.low; - setFlag(CF, difference.word & Bit8); - adjustSZP(A()); + setFlag(f, CF, difference.word & Bit8); + adjustSZP(f, A()); } void sbb(uint8_t value) { @@ -410,31 +417,31 @@ namespace EightBit { // increment and decrement - void inr_a() { postIncrement(++A()); } - void inr_b() { postIncrement(++B()); } - void inr_c() { postIncrement(++C()); } - void inr_d() { postIncrement(++D()); } - void inr_e() { postIncrement(++E()); } - void inr_h() { postIncrement(++H()); } - void inr_l() { postIncrement(++L()); } + void inr_a() { postIncrement(F(), ++A()); } + void inr_b() { postIncrement(F(), ++B()); } + void inr_c() { postIncrement(F(), ++C()); } + void inr_d() { postIncrement(F(), ++D()); } + void inr_e() { postIncrement(F(), ++E()); } + void inr_h() { postIncrement(F(), ++H()); } + void inr_l() { postIncrement(F(), ++L()); } void inr_m() { auto value = m_memory.get(HL().word); - postIncrement(++value); + postIncrement(F(), ++value); m_memory.set(HL().word, value); } - void dcr_a() { postDecrement(--A()); } - void dcr_b() { postDecrement(--B()); } - void dcr_c() { postDecrement(--C()); } - void dcr_d() { postDecrement(--D()); } - void dcr_e() { postDecrement(--E()); } - void dcr_h() { postDecrement(--H()); } - void dcr_l() { postDecrement(--L()); } + void dcr_a() { postDecrement(F(), --A()); } + void dcr_b() { postDecrement(F(), --B()); } + void dcr_c() { postDecrement(F(), --C()); } + void dcr_d() { postDecrement(F(), --D()); } + void dcr_e() { postDecrement(F(), --E()); } + void dcr_h() { postDecrement(F(), --H()); } + void dcr_l() { postDecrement(F(), --L()); } void dcr_m() { auto value = m_memory.get(HL().word); - postDecrement(--value); + postDecrement(F(), --value); m_memory.set(HL().word, value); } @@ -589,48 +596,51 @@ namespace EightBit { auto carry = A() & Bit7; A() <<= 1; carry ? A() |= Bit0 : A() &= ~Bit0; - setFlag(CF, carry); + setFlag(F(), CF, carry); } void rrc() { auto carry = A() & Bit0; A() >>= 1; carry ? A() |= Bit7 : A() &= ~Bit7; - setFlag(CF, carry); + setFlag(F(), CF, carry); } void ral() { + auto& f = F(); auto carry = A() & Bit7; A() <<= 1; - A() |= (F() & CF); - setFlag(CF, carry); + A() |= (f & CF); + setFlag(f, CF, carry); } void rar() { + auto& f = F(); auto carry = A() & 1; A() >>= 1; - A() |= (F() & CF) << 7; - setFlag(CF, carry); + A() |= (f & CF) << 7; + setFlag(f, CF, carry); } // specials void cma() { A() ^= Mask8; } - void stc() { setFlag(CF); } - void cmc() { clearFlag(CF, F() & CF); } + void stc() { setFlag(F(), CF); } + void cmc() { clearFlag(F(), CF, F() & CF); } void daa() { - auto carry = F() & CF; + auto& f = F(); + auto carry = f & CF; uint8_t addition = 0; - if ((F() & AC) || lowNibble(A()) > 9) { + if ((f & AC) || lowNibble(A()) > 9) { addition = 0x6; } - if ((F() & CF) || highNibble(A()) > 9 || (highNibble(A()) >= 9 && lowNibble(A()) > 9)) { + if ((f & CF) || highNibble(A()) > 9 || (highNibble(A()) >= 9 && lowNibble(A()) > 9)) { addition |= 0x60; carry = true; } add(addition); - setFlag(CF, carry); + setFlag(f, CF, carry); } // input/output diff --git a/LR35902/inc/LR35902.h b/LR35902/inc/LR35902.h index 054a77d..eb77d87 100644 --- a/LR35902/inc/LR35902.h +++ b/LR35902/inc/LR35902.h @@ -113,21 +113,21 @@ namespace EightBit { } } - void adjustHalfCarryAdd(uint8_t before, uint8_t value, int calculation) { - setFlag(HC, calculateHalfCarryAdd(before, value, calculation)); + void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) { + setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation)); } - void adjustHalfCarrySub(uint8_t before, uint8_t value, int calculation) { - setFlag(HC, calculateHalfCarrySub(before, value, calculation)); + void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) { + setFlag(f, HC, calculateHalfCarrySub(before, value, calculation)); } void executeCB(int x, int y, int z, int p, int q); void executeOther(int x, int y, int z, int p, int q); - void adjustZero(uint8_t value); + void adjustZero(uint8_t& f, uint8_t value); - void postIncrement(uint8_t value); - void postDecrement(uint8_t value); + void postIncrement(uint8_t& f, uint8_t value); + void postDecrement(uint8_t& f, uint8_t value); void reti(); diff --git a/LR35902/src/LR35902.cpp b/LR35902/src/LR35902.cpp index 0921d77..618d177 100644 --- a/LR35902/src/LR35902.cpp +++ b/LR35902/src/LR35902.cpp @@ -50,20 +50,20 @@ int EightBit::LR35902::interrupt(uint8_t value) { #pragma region Flag manipulation helpers -void EightBit::LR35902::adjustZero(uint8_t value) { - clearFlag(ZF, value); +void EightBit::LR35902::adjustZero(uint8_t& f, uint8_t value) { + clearFlag(f, ZF, value); } -void EightBit::LR35902::postIncrement(uint8_t value) { - adjustZero(value); - clearFlag(NF); - clearFlag(HC, lowNibble(value)); +void EightBit::LR35902::postIncrement(uint8_t& f, uint8_t value) { + adjustZero(f, value); + clearFlag(f, NF); + clearFlag(f, HC, lowNibble(value)); } -void EightBit::LR35902::postDecrement(uint8_t value) { - adjustZero(value); - setFlag(NF); - clearFlag(HC, lowNibble(value + 1)); +void EightBit::LR35902::postDecrement(uint8_t& f, uint8_t value) { + adjustZero(f, value); + setFlag(f, NF); + clearFlag(f, HC, lowNibble(value + 1)); } #pragma endregion Flag manipulation helpers @@ -142,10 +142,11 @@ void EightBit::LR35902::sbc(register16_t& operand, register16_t value) { auto result = before.word - value.word - (F() & CF); operand.word = result; - clearFlag(ZF, operand.word); - adjustHalfCarrySub(before.high, value.high, operand.high); - setFlag(NF); - setFlag(CF, result & Bit16); + auto& f = F(); + clearFlag(f, ZF, operand.word); + adjustHalfCarrySub(f, before.high, value.high, operand.high); + setFlag(f, NF); + setFlag(f, CF, result & Bit16); } void EightBit::LR35902::adc(register16_t& operand, register16_t value) { @@ -155,10 +156,11 @@ void EightBit::LR35902::adc(register16_t& operand, register16_t value) { auto result = before.word + value.word + (F() & CF); operand.word = result; - clearFlag(ZF, result); - adjustHalfCarryAdd(before.high, value.high, operand.high); - clearFlag(NF); - setFlag(CF, result & Bit16); + auto& f = F(); + clearFlag(f, ZF, result); + adjustHalfCarryAdd(f, before.high, value.high, operand.high); + clearFlag(f, NF); + setFlag(f, CF, result & Bit16); } void EightBit::LR35902::add(register16_t& operand, register16_t value) { @@ -169,9 +171,10 @@ void EightBit::LR35902::add(register16_t& operand, register16_t value) { operand.word = result; - clearFlag(NF); - setFlag(CF, result & Bit16); - adjustHalfCarryAdd(before.high, value.high, operand.high); + auto& f = F(); + clearFlag(f, NF); + setFlag(f, CF, result & Bit16); + adjustHalfCarryAdd(f, before.high, value.high, operand.high); } #pragma endregion 16-bit arithmetic @@ -180,16 +183,18 @@ void EightBit::LR35902::add(register16_t& operand, register16_t value) { void EightBit::LR35902::add(uint8_t& operand, uint8_t value, int carry) { + auto& f = F(); + register16_t result; result.word = operand + value + carry; - adjustHalfCarryAdd(operand, value, result.low); + adjustHalfCarryAdd(f, operand, value, result.low); operand = result.low; - clearFlag(NF); - setFlag(CF, result.word & Bit8); - adjustZero(operand); + clearFlag(f, NF); + setFlag(f, CF, result.word & Bit8); + adjustZero(f, operand); } void EightBit::LR35902::adc(uint8_t& operand, uint8_t value) { @@ -198,16 +203,18 @@ void EightBit::LR35902::adc(uint8_t& operand, uint8_t value) { void EightBit::LR35902::sub(uint8_t& operand, uint8_t value, int carry) { + auto& f = F(); + register16_t result; result.word = operand - value - carry; - adjustHalfCarrySub(operand, value, result.low); + adjustHalfCarrySub(f, operand, value, result.low); operand = result.low; - setFlag(NF); - setFlag(CF, result.word & Bit8); - adjustZero(operand); + setFlag(f, NF); + setFlag(f, CF, result.word & Bit8); + adjustZero(f, operand); } void EightBit::LR35902::sbc(uint8_t& operand, uint8_t value) { @@ -215,22 +222,25 @@ void EightBit::LR35902::sbc(uint8_t& operand, uint8_t value) { } void EightBit::LR35902::andr(uint8_t& operand, uint8_t value) { + auto& f = F(); operand &= value; - setFlag(HC); - clearFlag(CF | NF); - adjustZero(operand); + setFlag(f, HC); + clearFlag(f, CF | NF); + adjustZero(f, operand); } void EightBit::LR35902::xorr(uint8_t& operand, uint8_t value) { + auto& f = F(); operand ^= value; - clearFlag(HC | CF | NF); - adjustZero(operand); + clearFlag(f, HC | CF | NF); + adjustZero(f, operand); } void EightBit::LR35902::orr(uint8_t& operand, uint8_t value) { + auto& f = F(); operand |= value; - clearFlag(HC | CF | NF); - adjustZero(operand); + clearFlag(f, HC | CF | NF); + adjustZero(f, operand); } void EightBit::LR35902::compare(uint8_t value) { @@ -243,70 +253,77 @@ void EightBit::LR35902::compare(uint8_t value) { #pragma region Shift and rotate void EightBit::LR35902::rlc(uint8_t& operand) { + auto& f = F(); auto carry = operand & Bit7; operand <<= 1; - setFlag(CF, carry); + setFlag(f, CF, carry); carry ? operand |= Bit0 : operand &= ~Bit0; - clearFlag(NF | HC); - adjustZero(operand); + clearFlag(f, NF | HC); + adjustZero(f, operand); } void EightBit::LR35902::rrc(uint8_t& operand) { + auto& f = F(); auto carry = operand & Bit0; operand >>= 1; carry ? operand |= Bit7 : operand &= ~Bit7; - setFlag(CF, carry); - clearFlag(NF | HC); - adjustZero(operand); + setFlag(f, CF, carry); + clearFlag(f, NF | HC); + adjustZero(f, operand); } void EightBit::LR35902::rl(uint8_t& operand) { - auto oldCarry = F() & CF; + auto& f = F(); + auto oldCarry = f & CF; auto newCarry = operand & Bit7; operand <<= 1; oldCarry ? operand |= Bit0 : operand &= ~Bit0; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustZero(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustZero(f, operand); } void EightBit::LR35902::rr(uint8_t& operand) { - auto oldCarry = F() & CF; + auto& f = F(); + auto oldCarry = f & CF; auto newCarry = operand & Bit0; operand >>= 1; operand |= oldCarry << 7; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustZero(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustZero(f, operand); } // void EightBit::LR35902::sla(uint8_t& operand) { + auto& f = F(); auto newCarry = operand & Bit7; operand <<= 1; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustZero(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustZero(f, operand); } void EightBit::LR35902::sra(uint8_t& operand) { + auto& f = F(); auto new7 = operand & Bit7; auto newCarry = operand & Bit0; operand >>= 1; operand |= new7; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustZero(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustZero(f, operand); } void EightBit::LR35902::srl(uint8_t& operand) { + auto& f = F(); auto newCarry = operand & Bit0; operand >>= 1; operand &= ~Bit7; // clear bit 7 - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustZero(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustZero(f, operand); } #pragma endregion Shift and rotate @@ -314,10 +331,11 @@ void EightBit::LR35902::srl(uint8_t& operand) { #pragma region BIT/SET/RES void EightBit::LR35902::bit(int n, uint8_t& operand) { - auto carry = F() & CF; + auto& f = F(); + auto carry = f & CF; uint8_t discarded = operand; andr(discarded, 1 << n); - setFlag(CF, carry); + setFlag(f, CF, carry); } void EightBit::LR35902::res(int n, uint8_t& operand) { @@ -336,10 +354,12 @@ void EightBit::LR35902::set(int n, uint8_t& operand) { void EightBit::LR35902::daa() { + auto& f = F(); + uint8_t a = A(); - auto lowAdjust = (F() & HC) | ((A() & Mask4) > 9); - auto highAdjust = (F() & CF) | (A() > 0x99); + auto lowAdjust = (f & HC) | ((A() & Mask4) > 9); + auto highAdjust = (f & CF) | (A() > 0x99); if (F() & NF) { if (lowAdjust) @@ -353,35 +373,39 @@ void EightBit::LR35902::daa() { a += 0x60; } - F() = (F() & (CF | NF)) | (A() > 0x99) | ((A() ^ a) & HC); + f = (f & (CF | NF)) | (A() > 0x99) | ((A() ^ a) & HC); - adjustZero(a); + adjustZero(f, a); A() = a; } void EightBit::LR35902::cpl() { A() = ~A(); - setFlag(HC | NF); + auto& f = F(); + setFlag(f, HC | NF); } void EightBit::LR35902::scf() { - setFlag(CF); - clearFlag(HC | NF); + auto& f = F(); + setFlag(f, CF); + clearFlag(f, HC | NF); } void EightBit::LR35902::ccf() { - auto carry = F() & CF; - clearFlag(CF, carry); - clearFlag(NF | HC); + auto& f = F(); + auto carry = f & CF; + clearFlag(f, CF, carry); + clearFlag(f, NF | HC); } void EightBit::LR35902::swap(uint8_t& operand) { + auto& f = F(); auto low = lowNibble(operand); auto high = highNibble(operand); operand = promoteNibble(low) | demoteNibble(high); - adjustZero(operand); - clearFlag(NF | HC | CF); + adjustZero(f, operand); + clearFlag(f, NF | HC | CF); } #pragma endregion Miscellaneous instructions @@ -442,7 +466,7 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) { srl(R(z)); break; } - adjustZero(R(z)); + adjustZero(F(), R(z)); cycles += 2; if (z == 6) cycles += 2; @@ -577,13 +601,13 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) { cycles += 2; break; case 4: // 8-bit INC - postIncrement(++R(y)); // INC r + postIncrement(F(), ++R(y)); // INC r cycles++; if (y == 6) cycles += 2; break; case 5: // 8-bit DEC - postDecrement(--R(y)); // DEC r + postDecrement(F(), --R(y)); // DEC r cycles++; if (y == 6) cycles += 2; @@ -678,12 +702,13 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) { cycles += 3; break; case 5: { // GB: ADD SP,dd + auto& f = F(); auto before = sp; auto value = fetchByte(); sp.word += (int8_t)value; - clearFlag(ZF | NF); - setFlag(CF, sp.word & Bit16); - adjustHalfCarryAdd(before.high, value, sp.high); + clearFlag(f, ZF | NF); + setFlag(f, CF, sp.word & Bit16); + adjustHalfCarryAdd(f, before.high, value, sp.high); } cycles += 4; break; @@ -692,12 +717,13 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) { cycles += 3; break; case 7: { // GB: LD HL,SP + dd + auto& f = F(); auto before = sp; auto value = fetchByte(); HL().word = before.word + (int8_t)value; - clearFlag(ZF | NF); - setFlag(CF, HL().word & Bit16); - adjustHalfCarryAdd(before.high, value, HL().high); + clearFlag(f, ZF | NF); + setFlag(f, CF, HL().word & Bit16); + adjustHalfCarryAdd(f, before.high, value, HL().high); } cycles += 3; break; diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 85375ab..2035837 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -225,47 +225,47 @@ namespace EightBit { adc(hl, operand); } - void adjustHalfCarryAdd(uint8_t before, uint8_t value, int calculation) { - setFlag(HC, calculateHalfCarryAdd(before, value, calculation)); + void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) { + setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation)); } - void adjustHalfCarrySub(uint8_t before, uint8_t value, int calculation) { - setFlag(HC, calculateHalfCarrySub(before, value, calculation)); + void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) { + setFlag(f, HC, calculateHalfCarrySub(before, value, calculation)); } - void adjustOverflowAdd(uint8_t before, uint8_t value, uint8_t calculation) { - adjustOverflowAdd(before & SF, value & SF, calculation & SF); + void adjustOverflowAdd(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) { + adjustOverflowAdd(f, before & SF, value & SF, calculation & SF); } - void adjustOverflowAdd(int beforeNegative, int valueNegative, int afterNegative) { + void adjustOverflowAdd(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) { auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative); - setFlag(VF, overflow); + setFlag(f, VF, overflow); } - void adjustOverflowSub(uint8_t before, uint8_t value, uint8_t calculation) { - adjustOverflowSub(before & SF, value & SF, calculation & SF); + void adjustOverflowSub(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) { + adjustOverflowSub(f, before & SF, value & SF, calculation & SF); } - void adjustOverflowSub(int beforeNegative, int valueNegative, int afterNegative) { + void adjustOverflowSub(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) { auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative); - setFlag(VF, overflow); + setFlag(f, VF, overflow); } void executeCB(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 adjustSign(uint8_t value); - void adjustZero(uint8_t value); - void adjustParity(uint8_t value); - void adjustSZ(uint8_t value); - void adjustSZP(uint8_t value); - void adjustXY(uint8_t value); - void adjustSZPXY(uint8_t value); - void adjustSZXY(uint8_t value); + static void adjustSign(uint8_t& f, uint8_t value); + static void adjustZero(uint8_t& f, uint8_t value); + static void adjustParity(uint8_t& f, uint8_t value); + static void adjustSZ(uint8_t& f, uint8_t value); + static void adjustSZP(uint8_t& f, uint8_t value); + static void adjustXY(uint8_t& f, uint8_t value); + static void adjustSZPXY(uint8_t& f, uint8_t value); + static void adjustSZXY(uint8_t& f, uint8_t value); - void postIncrement(uint8_t value); - void postDecrement(uint8_t value); + void postIncrement(uint8_t& f, uint8_t value); + void postDecrement(uint8_t& f, uint8_t value); void retn(); void reti(); diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 6083169..e342b25 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -106,57 +106,57 @@ int EightBit::Z80::interrupt(bool maskable, uint8_t value) { #pragma region Flag manipulation helpers -void EightBit::Z80::adjustSign(uint8_t value) { - setFlag(SF, value & SF); +void EightBit::Z80::adjustSign(uint8_t& f, uint8_t value) { + setFlag(f, SF, value & SF); } -void EightBit::Z80::adjustZero(uint8_t value) { - clearFlag(ZF, value); +void EightBit::Z80::adjustZero(uint8_t& f, uint8_t value) { + clearFlag(f, ZF, value); } -void EightBit::Z80::adjustParity(uint8_t value) { +void EightBit::Z80::adjustParity(uint8_t& f, uint8_t value) { static const uint8_t lookup[0x10] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; auto set = lookup[highNibble(value)] + lookup[lowNibble(value)]; - clearFlag(PF, set % 2); + clearFlag(f, PF, set % 2); } -void EightBit::Z80::adjustSZ(uint8_t value) { - adjustSign(value); - adjustZero(value); +void EightBit::Z80::adjustSZ(uint8_t& f, uint8_t value) { + adjustSign(f, value); + adjustZero(f, value); } -void EightBit::Z80::adjustSZP(uint8_t value) { - adjustSZ(value); - adjustParity(value); +void EightBit::Z80::adjustSZP(uint8_t& f, uint8_t value) { + adjustSZ(f, value); + adjustParity(f, value); } -void EightBit::Z80::adjustXY(uint8_t value) { - setFlag(XF, value & XF); - setFlag(YF, value & YF); +void EightBit::Z80::adjustXY(uint8_t& f, uint8_t value) { + setFlag(f, XF, value & XF); + setFlag(f, YF, value & YF); } -void EightBit::Z80::adjustSZPXY(uint8_t value) { - adjustSZP(value); - adjustXY(value); +void EightBit::Z80::adjustSZPXY(uint8_t& f, uint8_t value) { + adjustSZP(f, value); + adjustXY(f, value); } -void EightBit::Z80::adjustSZXY(uint8_t value) { - adjustSZ(value); - adjustXY(value); +void EightBit::Z80::adjustSZXY(uint8_t& f, uint8_t value) { + adjustSZ(f, value); + adjustXY(f, value); } -void EightBit::Z80::postIncrement(uint8_t value) { - adjustSZXY(value); - clearFlag(NF); - setFlag(VF, value == Bit7); - clearFlag(HC, lowNibble(value)); +void EightBit::Z80::postIncrement(uint8_t& f, uint8_t value) { + adjustSZXY(f, value); + clearFlag(f, NF); + setFlag(f, VF, value == Bit7); + clearFlag(f, HC, lowNibble(value)); } -void EightBit::Z80::postDecrement(uint8_t value) { - adjustSZXY(value); - setFlag(NF); - setFlag(VF, value == Mask7); - clearFlag(HC, lowNibble(value + 1)); +void EightBit::Z80::postDecrement(uint8_t& f, uint8_t value) { + adjustSZXY(f, value); + setFlag(f, NF); + setFlag(f, VF, value == Mask7); + clearFlag(f, HC, lowNibble(value + 1)); } #pragma endregion Flag manipulation helpers @@ -266,58 +266,64 @@ bool EightBit::Z80::callConditionalFlag(int flag) { void EightBit::Z80::sbc(register16_t& operand, register16_t value) { + auto& f = F(); + auto before = operand; auto beforeNegative = before.high & SF; auto valueNegative = value.high & SF; - auto result = before.word - value.word - (F() & CF); + auto result = before.word - value.word - (f & CF); operand.word = result; auto afterNegative = operand.high & SF; - setFlag(SF, afterNegative); - clearFlag(ZF, operand.word); - adjustHalfCarrySub(before.high, value.high, operand.high); - adjustOverflowSub(beforeNegative, valueNegative, afterNegative); - setFlag(NF); - setFlag(CF, result & Bit16); - adjustXY(operand.high); + setFlag(f, SF, afterNegative); + clearFlag(f, ZF, operand.word); + adjustHalfCarrySub(f, before.high, value.high, operand.high); + adjustOverflowSub(f, beforeNegative, valueNegative, afterNegative); + setFlag(f, NF); + setFlag(f, CF, result & Bit16); + adjustXY(f, operand.high); } void EightBit::Z80::adc(register16_t& operand, register16_t value) { + auto& f = F(); + auto before = operand; auto beforeNegative = before.high & SF; auto valueNegative = value.high & SF; - auto result = before.word + value.word + (F() & CF); + auto result = before.word + value.word + (f & CF); operand.word = result; auto afterNegative = operand.high & SF; - setFlag(SF, afterNegative); - clearFlag(ZF, result); - adjustHalfCarryAdd(before.high, value.high, operand.high); - adjustOverflowAdd(beforeNegative, valueNegative, afterNegative); - clearFlag(NF); - setFlag(CF, result & Bit16); - adjustXY(operand.high); + setFlag(f, SF, afterNegative); + clearFlag(f, ZF, result); + adjustHalfCarryAdd(f, before.high, value.high, operand.high); + adjustOverflowAdd(f, beforeNegative, valueNegative, afterNegative); + clearFlag(f, NF); + setFlag(f, CF, result & Bit16); + adjustXY(f, operand.high); } void EightBit::Z80::add(register16_t& operand, register16_t value) { + auto& f = F(); + auto before = operand; auto result = before.word + value.word; operand.word = result; - clearFlag(NF); - setFlag(CF, result & Bit16); - adjustHalfCarryAdd(before.high, value.high, operand.high); - adjustXY(operand.high); + clearFlag(f, NF); + setFlag(f, CF, result & Bit16); + adjustHalfCarryAdd(f, before.high, value.high, operand.high); + adjustXY(f, operand.high); } #pragma endregion 16-bit arithmetic @@ -326,17 +332,19 @@ void EightBit::Z80::add(register16_t& operand, register16_t value) { void EightBit::Z80::add(uint8_t& operand, uint8_t value, int carry) { + auto& f = F(); + register16_t result; result.word = operand + value + carry; - adjustHalfCarryAdd(operand, value, result.low); - adjustOverflowAdd(operand, value, result.low); + adjustHalfCarryAdd(f, operand, value, result.low); + adjustOverflowAdd(f, operand, value, result.low); operand = result.low; - clearFlag(NF); - setFlag(CF, result.word & Bit8); - adjustSZXY(operand); + clearFlag(f, NF); + setFlag(f, CF, result.word & Bit8); + adjustSZXY(f, operand); } void EightBit::Z80::adc(uint8_t& operand, uint8_t value) { @@ -345,17 +353,19 @@ void EightBit::Z80::adc(uint8_t& operand, uint8_t value) { void EightBit::Z80::sub(uint8_t& operand, uint8_t value, int carry) { + auto& f = F(); + register16_t result; result.word = operand - value - carry; - adjustHalfCarrySub(operand, value, result.low); - adjustOverflowSub(operand, value, result.low); + adjustHalfCarrySub(f, operand, value, result.low); + adjustOverflowSub(f, operand, value, result.low); operand = result.low; - setFlag(NF); - setFlag(CF, result.word & Bit8); - adjustSZXY(operand); + setFlag(f, NF); + setFlag(f, CF, result.word & Bit8); + adjustSZXY(f, operand); } void EightBit::Z80::sbc(uint8_t& operand, uint8_t value) { @@ -363,28 +373,32 @@ void EightBit::Z80::sbc(uint8_t& operand, uint8_t value) { } void EightBit::Z80::andr(uint8_t& operand, uint8_t value) { + auto& f = F(); operand &= value; - setFlag(HC); - clearFlag(CF | NF); - adjustSZPXY(operand); + setFlag(f, HC); + clearFlag(f, CF | NF); + adjustSZPXY(f, operand); } void EightBit::Z80::xorr(uint8_t& operand, uint8_t value) { + auto& f = F(); operand ^= value; - clearFlag(HC | CF | NF); - adjustSZPXY(operand); + clearFlag(f, HC | CF | NF); + adjustSZPXY(f, operand); } void EightBit::Z80::orr(uint8_t& operand, uint8_t value) { + auto& f = F(); operand |= value; - clearFlag(HC | CF | NF); - adjustSZPXY(operand); + clearFlag(f, HC | CF | NF); + adjustSZPXY(f, operand); } void EightBit::Z80::compare(uint8_t value) { + auto& f = F(); auto check = A(); sub(check, value); - adjustXY(value); + adjustXY(f, value); } #pragma endregion ALU @@ -392,87 +406,95 @@ void EightBit::Z80::compare(uint8_t value) { #pragma region Shift and rotate uint8_t& EightBit::Z80::rlc(uint8_t& operand) { + auto& f = F(); auto carry = operand & Bit7; operand <<= 1; carry ? operand |= Bit0 : operand &= ~Bit0; - setFlag(CF, carry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, carry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } uint8_t& EightBit::Z80::rrc(uint8_t& operand) { + auto& f = F(); auto carry = operand & Bit0; operand >>= 1; carry ? operand |= Bit7 : operand &= ~Bit7; - setFlag(CF, carry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, carry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } uint8_t& EightBit::Z80::rl(uint8_t& operand) { - auto oldCarry = F() & CF; + auto& f = F(); + auto oldCarry = f & CF; auto newCarry = operand & Bit7; operand <<= 1; oldCarry ? operand |= Bit0 : operand &= ~Bit0; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } uint8_t& EightBit::Z80::rr(uint8_t& operand) { - auto oldCarry = F() & CF; + auto& f = F(); + auto oldCarry = f & CF; auto newCarry = operand & Bit0; operand >>= 1; operand |= oldCarry << 7; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } // uint8_t& EightBit::Z80::sla(uint8_t& operand) { + auto& f = F(); auto newCarry = operand & Bit7; operand <<= 1; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } uint8_t& EightBit::Z80::sra(uint8_t& operand) { + auto& f = F(); auto new7 = operand & Bit7; auto newCarry = operand & Bit0; operand >>= 1; operand |= new7; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } uint8_t& EightBit::Z80::sll(uint8_t& operand) { + auto& f = F(); auto newCarry = operand & Bit7; operand <<= 1; operand |= 1; - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustXY(operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustXY(f, operand); return operand; } uint8_t& EightBit::Z80::srl(uint8_t& operand) { + auto& f = F(); auto newCarry = operand & Bit0; operand >>= 1; operand &= ~Bit7; // clear bit 7 - setFlag(CF, newCarry); - clearFlag(NF | HC); - adjustXY(operand); - setFlag(ZF, operand); + setFlag(f, CF, newCarry); + clearFlag(f, NF | HC); + adjustXY(f, operand); + setFlag(f, ZF, operand); return operand; } @@ -481,11 +503,12 @@ uint8_t& EightBit::Z80::srl(uint8_t& operand) { #pragma region BIT/SET/RES void EightBit::Z80::bit(int n, uint8_t& operand) { - auto carry = F() & CF; + auto& f = F(); + auto carry = f & CF; uint8_t discarded = operand; andr(discarded, 1 << n); - clearFlag(PF, discarded); - setFlag(CF, carry); + clearFlag(f, PF, discarded); + setFlag(f, CF, carry); } void EightBit::Z80::res(int n, uint8_t& operand) { @@ -503,21 +526,24 @@ void EightBit::Z80::set(int n, uint8_t& operand) { #pragma region Miscellaneous instructions void EightBit::Z80::neg() { + auto& f = F(); auto original = A(); A() = 0; sub(A(), original); - setFlag(PF, original == Bit7); - setFlag(CF, original); + setFlag(f, PF, original == Bit7); + setFlag(f, CF, original); } void EightBit::Z80::daa() { + auto& f = F(); + uint8_t a = A(); - auto lowAdjust = (F() & HC) | (lowNibble(A()) > 9); - auto highAdjust = (F() & CF) | (A() > 0x99); + auto lowAdjust = (f & HC) | (lowNibble(A()) > 9); + auto highAdjust = (f & CF) | (A() > 0x99); - if (F() & NF) { + if (f & NF) { if (lowAdjust) a -= 6; if (highAdjust) @@ -529,31 +555,34 @@ void EightBit::Z80::daa() { a += 0x60; } - F() = (F() & (CF | NF)) | (A() > 0x99) | ((A() ^ a) & HC); + f = (f & (CF | NF)) | (A() > 0x99) | ((A() ^ a) & HC); - adjustSZPXY(a); + adjustSZPXY(f, a); A() = a; } void EightBit::Z80::cpl() { + auto& f = F(); A() = ~A(); - adjustXY(A()); - setFlag(HC | NF); + adjustXY(f, A()); + setFlag(f, HC | NF); } void EightBit::Z80::scf() { - setFlag(CF); - adjustXY(A()); - clearFlag(HC | NF); + auto& f = F(); + setFlag(f, CF); + adjustXY(f, A()); + clearFlag(f, HC | NF); } void EightBit::Z80::ccf() { - auto carry = F() & CF; - setFlag(HC, carry); - clearFlag(CF, carry); - clearFlag(NF); - adjustXY(A()); + auto& f = F(); + auto carry = f & CF; + setFlag(f, HC, carry); + clearFlag(f, CF, carry); + clearFlag(f, NF); + adjustXY(f, A()); } void EightBit::Z80::xhtl(register16_t& operand) { @@ -579,22 +608,24 @@ void EightBit::Z80::xhtl() { void EightBit::Z80::blockCompare() { + auto& f = F(); + m_memory.ADDRESS() = HL(); auto value = m_memory.reference(); uint8_t result = A() - value; - setFlag(PF, --BC().word); + setFlag(f, PF, --BC().word); - adjustSZ(result); - adjustHalfCarrySub(A(), value, result); - setFlag(NF); + adjustSZ(f, result); + adjustHalfCarrySub(f, A(), value, result); + setFlag(f, NF); - if (F() & HC) + if (f & HC) result -= 1; - setFlag(YF, result & Bit1); - setFlag(XF, result & Bit3); + setFlag(f, YF, result & Bit1); + setFlag(f, XF, result & Bit3); } void EightBit::Z80::cpi() { @@ -632,15 +663,16 @@ bool EightBit::Z80::cpdr() { #pragma region Block load instructions void EightBit::Z80::blockLoad(register16_t source, register16_t destination) { + auto& f = F(); m_memory.ADDRESS() = source; auto value = m_memory.reference(); m_memory.ADDRESS() = destination; m_memory.reference() = value; auto xy = A() + value; - setFlag(XF, xy & 8); - setFlag(YF, xy & 2); - clearFlag(NF | HC); - setFlag(PF, --BC().word); + setFlag(f, XF, xy & 8); + setFlag(f, YF, xy & 2); + clearFlag(f, NF | HC); + setFlag(f, PF, --BC().word); } void EightBit::Z80::ldd() { @@ -676,25 +708,27 @@ bool EightBit::Z80::lddr() { #pragma region Block input instructions void EightBit::Z80::ini() { + auto& f = F(); MEMPTR() = m_memory.ADDRESS() = BC(); MEMPTR().word++; readPort(); auto value = m_memory.DATA(); m_memory.ADDRESS().word = HL().word++; m_memory.reference() = value; - postDecrement(--B()); - setFlag(NF); + postDecrement(f, --B()); + setFlag(f, NF); } void EightBit::Z80::ind() { + auto& f = F(); MEMPTR() = m_memory.ADDRESS() = BC(); MEMPTR().word--; readPort(); auto value = m_memory.DATA(); m_memory.ADDRESS().word = HL().word--; m_memory.reference() = value; - postDecrement(--B()); - setFlag(NF); + postDecrement(f, --B()); + setFlag(f, NF); } bool EightBit::Z80::inir() { @@ -712,13 +746,14 @@ bool EightBit::Z80::indr() { #pragma region Block output instructions void EightBit::Z80::blockOut() { + auto& f = F(); auto value = m_memory.reference(); m_memory.ADDRESS().word = BC().word; writePort(); - postDecrement(--B()); - setFlag(NF, value & Bit7); - setFlag(HC | CF, (L() + value) > 0xff); - adjustParity(((value + L()) & 7) ^ B()); + postDecrement(f, --B()); + setFlag(f, NF, value & Bit7); + setFlag(f, HC | CF, (L() + value) > 0xff); + adjustParity(f, ((value + L()) & 7) ^ B()); } void EightBit::Z80::outi() { @@ -750,21 +785,23 @@ bool EightBit::Z80::otdr() { #pragma region Nibble rotation void EightBit::Z80::rrd() { + auto& f = F(); MEMPTR() = HL(); auto memory = memptrReference(); m_memory.reference() = promoteNibble(A()) | highNibble(memory); A() = (A() & 0xf0) | lowNibble(memory); - adjustSZPXY(A()); - clearFlag(NF | HC); + adjustSZPXY(f, A()); + clearFlag(f, NF | HC); } void EightBit::Z80::rld() { + auto& f = F(); MEMPTR() = HL(); auto memory = memptrReference(); m_memory.reference() = promoteNibble(memory) | lowNibble(A()); A() = (A() & 0xf0) | highNibble(memory); - adjustSZPXY(A()); - clearFlag(NF | HC); + adjustSZPXY(f, A()); + clearFlag(f, NF | HC); } #pragma endregion Nibble rotation @@ -807,32 +844,33 @@ int EightBit::Z80::execute(uint8_t opcode) { } void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) { + auto& f = F(); switch (x) { case 0: // rot[y] r[z] switch (y) { case 0: - adjustSZP(m_displaced ? R2(z) = rlc(DISPLACED()) : rlc(R(z))); + adjustSZP(f, m_displaced ? R2(z) = rlc(DISPLACED()) : rlc(R(z))); break; case 1: - adjustSZP(m_displaced ? R2(z) = rrc(DISPLACED()) : rrc(R(z))); + adjustSZP(f, m_displaced ? R2(z) = rrc(DISPLACED()) : rrc(R(z))); break; case 2: - adjustSZP(m_displaced ? R2(z) = rl(DISPLACED()) : rl(R(z))); + adjustSZP(f, m_displaced ? R2(z) = rl(DISPLACED()) : rl(R(z))); break; case 3: - adjustSZP(m_displaced ? R2(z) = rr(DISPLACED()) : rr(R(z))); + adjustSZP(f, m_displaced ? R2(z) = rr(DISPLACED()) : rr(R(z))); break; case 4: - adjustSZP(m_displaced ? R2(z) = sla(DISPLACED()) : sla(R(z))); + adjustSZP(f, m_displaced ? R2(z) = sla(DISPLACED()) : sla(R(z))); break; case 5: - adjustSZP(m_displaced ? R2(z) = sra(DISPLACED()) : sra(R(z))); + adjustSZP(f, m_displaced ? R2(z) = sra(DISPLACED()) : sra(R(z))); break; case 6: - adjustSZP(m_displaced ? R2(z) = sll(DISPLACED()) : sll(R(z))); + adjustSZP(f, m_displaced ? R2(z) = sll(DISPLACED()) : sll(R(z))); break; case 7: - adjustSZP(m_displaced ? R2(z) = srl(DISPLACED()) : srl(R(z))); + adjustSZP(f, m_displaced ? R2(z) = srl(DISPLACED()) : srl(R(z))); break; } if (m_displaced) { @@ -846,17 +884,17 @@ void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) { case 1: // BIT y, r[z] if (m_displaced) { bit(y, DISPLACED()); - adjustXY(MEMPTR().high); + adjustXY(f, MEMPTR().high); cycles += 20; } else { auto operand = R(z); bit(y, operand); cycles += 8; if (z == 6) { - adjustXY(MEMPTR().high); + adjustXY(f, MEMPTR().high); cycles += 4; } else { - adjustXY(operand); + adjustXY(f, operand); } } break; @@ -888,6 +926,7 @@ void EightBit::Z80::executeCB(int x, int y, int z, int p, int q) { } void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { + auto& f = F(); switch (x) { case 0: case 3: // Invalid instruction, equivalent to NONI followed by NOP @@ -901,8 +940,8 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { readPort(); if (y != 6) // IN r[y],(C) R(y) = m_memory.DATA(); - adjustSZPXY(m_memory.DATA()); - clearFlag(NF | HC); + adjustSZPXY(f, m_memory.DATA()); + clearFlag(f, NF | HC); cycles += 12; break; case 1: // Output to port with 16-bit address @@ -986,16 +1025,16 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { break; case 2: // LD A,I A() = IV(); - adjustSZXY(A()); - setFlag(PF, IFF2()); - clearFlag(NF | HC); + adjustSZXY(f, A()); + setFlag(f, PF, IFF2()); + clearFlag(f, NF | HC); cycles += 9; break; case 3: // LD A,R A() = REFRESH(); - adjustSZXY(A()); - clearFlag(NF | HC); - setFlag(PF, IFF2()); + adjustSZXY(f, A()); + clearFlag(f, NF | HC); + setFlag(f, PF, IFF2()); cycles += 9; break; case 4: // RRD @@ -1111,6 +1150,7 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { } void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { + auto& f = F(); switch (x) { case 0: switch (z) { @@ -1215,11 +1255,11 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { cycles += 6; break; case 4: // 8-bit INC - postIncrement(++R(y)); // INC r + postIncrement(f, ++R(y)); // INC r cycles += 4; break; case 5: // 8-bit DEC - postDecrement(--R(y)); // DEC r + postDecrement(f, --R(y)); // DEC r cycles += 4; if (y == 6) cycles += 7; diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index fe7c97d..9362c86 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -29,16 +29,16 @@ namespace EightBit { protected: IntelProcessor(Memory& memory); - void clearFlag(int flag) { F() &= ~flag; } - void setFlag(int flag) { F() |= flag; } + static void clearFlag(uint8_t& f, int flag) { f &= ~flag; } + static void setFlag(uint8_t& f, int flag) { f |= flag; } - void setFlag(int flag, int condition) { setFlag(flag, condition != 0); } - void setFlag(int flag, uint32_t condition) { setFlag(flag, condition != 0); } - void setFlag(int flag, bool condition) { condition ? setFlag(flag) : clearFlag(flag); } + static void setFlag(uint8_t& f, int flag, int condition) { setFlag(f, flag, condition != 0); } + static void setFlag(uint8_t& f, int flag, uint32_t condition) { setFlag(f, flag, condition != 0); } + static void setFlag(uint8_t& f, int flag, bool condition) { condition ? setFlag(f, flag) : clearFlag(f, flag); } - void clearFlag(int flag, int condition) { clearFlag(flag, condition != 0); } - void clearFlag(int flag, uint32_t condition) { clearFlag(flag, condition != 0); } - void clearFlag(int flag, bool condition) { condition ? clearFlag(flag) : setFlag(flag); } + static void clearFlag(uint8_t& f, int flag, int condition) { clearFlag(f, flag, condition != 0); } + static void clearFlag(uint8_t& f, int flag, uint32_t condition) { clearFlag(f, flag, condition != 0); } + static void clearFlag(uint8_t& f, int flag, bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); } std::array m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } }; std::array m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } }; @@ -57,11 +57,25 @@ namespace EightBit { return m_halfCarryTableSub[index & Mask3]; } - void push(uint8_t value); - void pushWord(register16_t value); + void push(uint8_t value) { + m_memory.ADDRESS().word = --sp.word; + m_memory.reference() = value; + } - uint8_t pop(); - void popWord(register16_t& output); + void pushWord(register16_t value) { + push(value.high); + push(value.low); + } + + uint8_t pop() { + m_memory.ADDRESS().word = sp.word++; + return m_memory.reference(); + } + + void popWord(register16_t& output) { + output.low = pop(); + output.high = pop(); + } void fetchWord() { Processor::fetchWord(MEMPTR()); diff --git a/src/IntelProcessor.cpp b/src/IntelProcessor.cpp index fca5b89..5f89687 100644 --- a/src/IntelProcessor.cpp +++ b/src/IntelProcessor.cpp @@ -10,23 +10,3 @@ void EightBit::IntelProcessor::initialise() { Processor::initialise(); MEMPTR().word = 0; } - -void EightBit::IntelProcessor::push(uint8_t value) { - m_memory.ADDRESS().word = --sp.word; - m_memory.reference() = value; -} - -void EightBit::IntelProcessor::pushWord(register16_t value) { - push(value.high); - push(value.low); -} - -uint8_t EightBit::IntelProcessor::pop() { - m_memory.ADDRESS().word = sp.word++; - return m_memory.reference(); -} - -void EightBit::IntelProcessor::popWord(register16_t& output) { - output.low = pop(); - output.high = pop(); -}