From f7da03d46b8ceda1247bb3d30f76dda44a3dc2a4 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Mon, 9 Nov 2020 11:48:59 +0000 Subject: [PATCH] Bring the LR35902 code to be more like the Z80 Signed-off-by: Adrian Conlon --- LR35902/inc/LR35902.h | 122 +++++++----- LR35902/src/LR35902.cpp | 397 +++++++++++++++++++--------------------- Z80/inc/Z80.h | 24 +-- Z80/src/Z80.cpp | 5 +- inc/IntelProcessor.h | 6 +- 5 files changed, 290 insertions(+), 264 deletions(-) diff --git a/LR35902/inc/LR35902.h b/LR35902/inc/LR35902.h index 9dceaa1..2ef8b9d 100644 --- a/LR35902/inc/LR35902.h +++ b/LR35902/inc/LR35902.h @@ -30,19 +30,51 @@ namespace EightBit { return cycles() * 4; } - virtual register16_t& AF() final; - virtual register16_t& BC() final; - virtual register16_t& DE() final; - virtual register16_t& HL() final; + [[nodiscard]] register16_t& AF() final; + [[nodiscard]] register16_t& BC() final; + [[nodiscard]] register16_t& DE() final; + [[nodiscard]] register16_t& HL() final; - uint8_t maskedInterrupts(); + [[nodiscard]] uint8_t maskedInterrupts(); protected: virtual int execute() final; virtual int step() final; - virtual void handleRESET() final; - virtual void handleINT() final; + void handleRESET() final; + void handleINT() final; + + void jr(int8_t offset) final { + IntelProcessor::jr(offset); + tick(5); + } + + int callConditional(const int condition) final { + if (IntelProcessor::callConditional(condition)) + tick(3); + tick(3); + return condition; + } + + int jumpConditional(const int condition) final { + IntelProcessor::jumpConditional(condition); + tick(3); + return condition; + } + + int returnConditional(const int condition) final { + if (IntelProcessor::returnConditional(condition)) + tick(3); + tick(2); + return condition; + } + + int jrConditional(const int condition) final { + if (IntelProcessor::jrConditional(condition)) + tick(); + tick(2); + return condition; + } private: Bus& m_bus; @@ -59,7 +91,7 @@ namespace EightBit { bool& IME() noexcept { return m_ime; } - auto R(const int r) { + [[nodiscard]] auto R(const int r) { ASSUME(r >= 0); ASSUME(r <= 7); switch (r) { @@ -117,7 +149,7 @@ namespace EightBit { } } - auto& RP(const int rp) { + [[nodiscard]] auto& RP(const int rp) { ASSUME(rp >= 0); ASSUME(rp <= 3); switch (rp) { @@ -134,7 +166,7 @@ namespace EightBit { } } - auto& RP2(const int rp) { + [[nodiscard]] auto& RP2(const int rp) { ASSUME(rp >= 0); ASSUME(rp <= 3); switch (rp) { @@ -151,21 +183,23 @@ namespace EightBit { } } - void adjustHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) { - F() = setBit(F(), HC, calculateHalfCarryAdd(before, value, calculation)); + [[nodiscard]] static auto adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { + return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation)); } - void adjustHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) { - F() = setBit(F(), HC, calculateHalfCarrySub(before, value, calculation)); + [[nodiscard]] static auto adjustHalfCarrySub(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { + return setBit(f, HC, calculateHalfCarrySub(before, value, calculation)); } - void subtract(uint8_t& operand, uint8_t value, int carry = 0); + [[nodiscard]] static bool convertCondition(uint8_t f, int flag); + + static uint8_t subtract(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0); 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 increment(uint8_t& operand); - void 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 stop(bool value = true) noexcept { m_stopped = value; } void start() noexcept { stop(false); } @@ -176,40 +210,40 @@ namespace EightBit { void reti(); - int jrConditionalFlag(int flag); - int returnConditionalFlag(int flag); - int jumpConditionalFlag(int flag); - int callConditionalFlag(int flag); + void jrConditionalFlag(uint8_t f, int flag); + void returnConditionalFlag(uint8_t f, int flag); + void jumpConditionalFlag(uint8_t f, int flag); + void callConditionalFlag(uint8_t f, int flag); - void add(register16_t& operand, register16_t value); + [[nodiscard]] register16_t add(uint8_t& f, register16_t operand, register16_t value); - void add(uint8_t& operand, uint8_t value, int carry = 0); - void adc(uint8_t& operand, uint8_t value); - void sbc(uint8_t value); - void andr(uint8_t& operand, uint8_t value); - void xorr(uint8_t value); - void orr(uint8_t value); - void compare(uint8_t check, 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 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); + [[nodiscard]] static void compare(uint8_t& f, uint8_t operand, uint8_t value); - uint8_t rlc(uint8_t operand); - uint8_t rrc(uint8_t operand); - uint8_t rl(uint8_t operand); - uint8_t rr(uint8_t operand); - uint8_t sla(uint8_t operand); - uint8_t sra(uint8_t operand); - 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 srl(uint8_t& f, uint8_t operand); - void bit(int n, uint8_t operand); - static uint8_t res(int n, uint8_t operand); - static uint8_t set(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); - uint8_t swap(uint8_t operand); + static uint8_t swap(uint8_t& f, uint8_t operand); }; } } \ No newline at end of file diff --git a/LR35902/src/LR35902.cpp b/LR35902/src/LR35902.cpp index 4ce44e0..51a3d9f 100644 --- a/LR35902/src/LR35902.cpp +++ b/LR35902/src/LR35902.cpp @@ -49,46 +49,57 @@ void EightBit::GameBoy::LR35902::ei() { IME() = true; } -void EightBit::GameBoy::LR35902::increment(uint8_t& operand) { - F() = clearBit(F(), NF); - F() = adjustZero(F(), ++operand); - F() = clearBit(F(), HC, lowNibble(operand)); +uint8_t EightBit::GameBoy::LR35902::increment(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF); + const uint8_t result = operand + 1; + f = adjustZero(f, result); + f = clearBit(f, HC, lowNibble(result)); + return result; } -void EightBit::GameBoy::LR35902::decrement(uint8_t& operand) { - F() = setBit(F(), NF); - F() = clearBit(F(), HC, lowNibble(operand)); - F() = adjustZero(F(), --operand); +uint8_t EightBit::GameBoy::LR35902::decrement(uint8_t& f, const uint8_t operand) { + f = setBit(f, NF); + f = clearBit(f, HC, lowNibble(operand)); + const uint8_t result = operand - 1; + f = adjustZero(f, result); + return result; } -int EightBit::GameBoy::LR35902::jrConditionalFlag(const int flag) { +bool EightBit::GameBoy::LR35902::convertCondition(const uint8_t f, int flag) { + ASSUME(flag >= 0); + ASSUME(flag <= 7); switch (flag) { - case 0: // NZ - return jrConditional(!(F() & ZF)); - case 1: // Z - return jrConditional(F() & ZF); - case 2: // NC - return jrConditional(!(F() & CF)); - case 3: // C - return jrConditional(F() & CF); + case 0: + return !(f & ZF); + case 1: + return f & ZF; + case 2: + return !(f & CF); + case 3: + return f & CF; default: UNREACHABLE; } } -int EightBit::GameBoy::LR35902::jumpConditionalFlag(const int flag) { - switch (flag) { - case 0: // NZ - return jumpConditional(!(F() & ZF)); - case 1: // Z - return jumpConditional(F() & ZF); - case 2: // NC - return jumpConditional(!(F() & CF)); - case 3: // C - return jumpConditional(F() & CF); - default: - UNREACHABLE; +void EightBit::GameBoy::LR35902::returnConditionalFlag(const uint8_t f, const int flag) { + if (convertCondition(f, flag)) { + tick(3); + ret(); } + tick(2); +} + +void EightBit::GameBoy::LR35902::jrConditionalFlag(const uint8_t f, const int flag) { + jrConditional(convertCondition(f, flag)); +} + +void EightBit::GameBoy::LR35902::jumpConditionalFlag(uint8_t f, const int flag) { + jumpConditional(convertCondition(f, flag)); +} + +void EightBit::GameBoy::LR35902::callConditionalFlag(uint8_t f, const int flag) { + callConditional(convertCondition(f, flag)); } void EightBit::GameBoy::LR35902::reti() { @@ -96,205 +107,192 @@ void EightBit::GameBoy::LR35902::reti() { ei(); } -int EightBit::GameBoy::LR35902::returnConditionalFlag(const int flag) { - switch (flag) { - case 0: // NZ - return returnConditional(!(F() & ZF)); - case 1: // Z - return returnConditional(F() & ZF); - case 2: // NC - return returnConditional(!(F() & CF)); - case 3: // C - return returnConditional(F() & CF); - default: - UNREACHABLE; - } +EightBit::register16_t EightBit::GameBoy::LR35902::add(uint8_t& f, const register16_t operand, const register16_t value) { + + const int addition = operand.word + value.word; + const register16_t result = addition; + + f = clearBit(f, NF); + f = setBit(f, CF, addition & Bit16); + f = adjustHalfCarryAdd(f, operand.high, value.high, result.high); + + MEMPTR() = operand + 1; + + return result; } -int EightBit::GameBoy::LR35902::callConditionalFlag(const int flag) { - switch (flag) { - case 0: // NZ - return callConditional(!(F() & ZF)); - case 1: // Z - return callConditional(F() & ZF); - case 2: // NC - return callConditional(!(F() & CF)); - case 3: // C - return callConditional(F() & CF); - default: - UNREACHABLE; - } +uint8_t EightBit::GameBoy::LR35902::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; + + f = adjustHalfCarryAdd(f, operand, value, result); + + f = clearBit(f, NF); + f = setBit(f, CF, addition.high & Bit0); + f = adjustZero(f, result); + + return result; } -void EightBit::GameBoy::LR35902::add(register16_t& operand, const register16_t value) { - - MEMPTR() = operand; - - const auto result = MEMPTR().word + value.word; - - operand.word = result; - - F() = clearBit(F(), NF); - F() = setBit(F(), CF, result & Bit16); - adjustHalfCarryAdd(MEMPTR().high, value.high, operand.high); +uint8_t EightBit::GameBoy::LR35902::adc(uint8_t& f, const uint8_t operand, const uint8_t value) { + return add(f, operand, value, (f & CF) >> 4); } -void EightBit::GameBoy::LR35902::add(uint8_t& operand, const uint8_t value, const int carry) { +uint8_t EightBit::GameBoy::LR35902::subtract(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) { - const register16_t result = operand + value + carry; + const register16_t subtraction = operand - value - carry; + const auto result = subtraction.low; - adjustHalfCarryAdd(operand, value, result.low); + f = adjustHalfCarrySub(f, operand, value, result); - operand = result.low; + f = setBit(f, NF); + f = setBit(f, CF, subtraction.high & Bit0); + f = adjustZero(f, result); - F() = clearBit(F(), NF); - F() = setBit(F(), CF, result.word & Bit8); - F() = adjustZero(F(), operand); + return result; } -void EightBit::GameBoy::LR35902::adc(uint8_t& operand, const uint8_t value) { - add(operand, value, (F() & CF) >> 4); +uint8_t EightBit::GameBoy::LR35902::sbc(uint8_t& f, const uint8_t operand, const uint8_t value) { + return subtract(f, operand, value, (f & CF) >> 4); } -void EightBit::GameBoy::LR35902::subtract(uint8_t& operand, const uint8_t value, const int carry) { - - const register16_t result = operand - value - carry; - - adjustHalfCarrySub(operand, value, result.low); - - operand = result.low; - - F() = setBit(F(), NF); - F() = setBit(F(), CF, result.word & Bit8); - F() = adjustZero(F(), operand); +uint8_t EightBit::GameBoy::LR35902::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 = adjustZero(f, result); + return result; } -void EightBit::GameBoy::LR35902::sbc(const uint8_t value) { - subtract(A(), value, (F() & CF) >> 4); +uint8_t EightBit::GameBoy::LR35902::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 = adjustZero(f, result); + return result; } -void EightBit::GameBoy::LR35902::andr(uint8_t& operand, const uint8_t value) { - F() = setBit(F(), HC); - F() = clearBit(F(), CF | NF); - F() = adjustZero(F(), operand &= value); +uint8_t EightBit::GameBoy::LR35902::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 = adjustZero(f, result); + return result; } -void EightBit::GameBoy::LR35902::xorr(const uint8_t value) { - F() = clearBit(F(), HC | CF | NF); - F() = adjustZero(F(), A() ^= value); +void EightBit::GameBoy::LR35902::compare(uint8_t& f, uint8_t operand, const uint8_t value) { + subtract(f, operand, value); } -void EightBit::GameBoy::LR35902::orr(const uint8_t value) { - F() = clearBit(F(), HC | CF | NF); - F() = adjustZero(F(), A() |= value); -} - -void EightBit::GameBoy::LR35902::compare(uint8_t check, const uint8_t value) { - subtract(check, value); -} - -uint8_t EightBit::GameBoy::LR35902::rlc(const uint8_t operand) { - F() = clearBit(F(), NF | HC | ZF); +uint8_t EightBit::GameBoy::LR35902::rlc(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC | ZF); const auto carry = operand & Bit7; - F() = setBit(F(), CF, carry); + f = setBit(f, CF, carry); return (operand << 1) | (carry >> 7); } -uint8_t EightBit::GameBoy::LR35902::rrc(const uint8_t operand) { - F() = clearBit(F(), NF | HC | ZF); +uint8_t EightBit::GameBoy::LR35902::rrc(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC | ZF); const auto carry = operand & Bit0; - F() = setBit(F(), CF, carry); + f = setBit(f, CF, carry); return (operand >> 1) | (carry << 7); } -uint8_t EightBit::GameBoy::LR35902::rl(const uint8_t operand) { - F() = clearBit(F(), NF | HC | ZF); - const auto carry = F() & CF; - F() = setBit(F(), CF, operand & Bit7); +uint8_t EightBit::GameBoy::LR35902::rl(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC | ZF); + const auto carry = f & CF; + f = setBit(f, CF, operand & Bit7); return (operand << 1) | (carry >> 4); // CF at Bit4 } -uint8_t EightBit::GameBoy::LR35902::rr(const uint8_t operand) { - F() = clearBit(F(), NF | HC | ZF); - const auto carry = F() & CF; - F() = setBit(F(), CF, operand & Bit0); +uint8_t EightBit::GameBoy::LR35902::rr(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC | ZF); + const auto carry = f & CF; + f = setBit(f, CF, operand & Bit0); return (operand >> 1) | (carry << 3); // CF at Bit4 } -uint8_t EightBit::GameBoy::LR35902::sla(const uint8_t operand) { - F() = clearBit(F(), NF | HC | ZF); - F() = setBit(F(), CF, operand & Bit7); +uint8_t EightBit::GameBoy::LR35902::sla(uint8_t& f, const uint8_t operand) { + 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) { - F() = clearBit(F(), NF | HC | ZF); - F() = setBit(F(), CF, operand & Bit0); +uint8_t EightBit::GameBoy::LR35902::sra(uint8_t& f, const uint8_t operand) { + 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) { - F() = clearBit(F(), NF | HC | CF); +uint8_t EightBit::GameBoy::LR35902::swap(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC | CF); return promoteNibble(operand) | demoteNibble(operand); } -uint8_t EightBit::GameBoy::LR35902::srl(const uint8_t operand) { - F() = clearBit(F(), NF | HC | ZF); - F() = setBit(F(), CF, operand & Bit0); +uint8_t EightBit::GameBoy::LR35902::srl(uint8_t& f, const uint8_t operand) { + 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; +void EightBit::GameBoy::LR35902::bit(uint8_t& f, const int n, const uint8_t operand) { + ASSUME(n >= 0); + ASSUME(n <= 7); + const auto carry = f & CF; uint8_t discarded = operand; - andr(discarded, Chip::bit(n)); - F() = setBit(F(), CF, carry); + andr(f, discarded, Chip::bit(n)); + f = setBit(f, CF, carry); } uint8_t EightBit::GameBoy::LR35902::res(const int n, const uint8_t operand) { - return operand & ~Chip::bit(n); + ASSUME(n >= 0); + ASSUME(n <= 7); + return clearBit(operand, Chip::bit(n)); } uint8_t EightBit::GameBoy::LR35902::set(const int n, const uint8_t operand) { - return operand | Chip::bit(n); + ASSUME(n >= 0); + ASSUME(n <= 7); + return setBit(operand, Chip::bit(n)); } -void EightBit::GameBoy::LR35902::daa() { +uint8_t EightBit::GameBoy::LR35902::daa(uint8_t& f, uint8_t operand) { - int updated = A(); + int updated = operand; - if (F() & NF) { - if (F() & HC) + if (f & NF) { + if (f & HC) updated = (updated - 6) & Mask8; - if (F() & CF) + if (f & CF) updated -= 0x60; } else { - if ((F() & HC) || lowNibble(updated) > 9) + if ((f & HC) || lowNibble(updated) > 9) updated += 6; - if ((F() & CF) || updated > 0x9F) + if ((f & CF) || updated > 0x9F) updated += 0x60; } - F() = clearBit(F(), HC | ZF); - F() = setBit(F(), CF, (F() & CF) || (updated & Bit8)); - A() = updated & Mask8; + f = clearBit(f, HC | ZF); + f = setBit(f, CF, (f & CF) || (updated & Bit8)); + const uint8_t result = updated & Mask8; - F() = adjustZero(F(), A()); + f = adjustZero(f, result); + + return result; } -void EightBit::GameBoy::LR35902::cpl() { - F() = setBit(F(), HC | NF); - A() = ~A(); +uint8_t EightBit::GameBoy::LR35902::cpl(uint8_t& f, const uint8_t operand) { + f = setBit(f, HC | NF); + return ~operand; } -void EightBit::GameBoy::LR35902::scf() { - F() = setBit(F(), CF); - F() = clearBit(F(), HC | NF); +void EightBit::GameBoy::LR35902::scf(uint8_t& f, const uint8_t operand) { + f = setBit(f, CF); + f = clearBit(f, HC | NF); } -void EightBit::GameBoy::LR35902::ccf() { - F() = clearBit(F(), NF | HC); - F() = clearBit(F(), CF, F() & CF); +void EightBit::GameBoy::LR35902::ccf(uint8_t& f, const uint8_t operand) { + f = clearBit(f, NF | HC); + f = clearBit(f, CF, f & CF); } uint8_t EightBit::GameBoy::LR35902::maskedInterrupts() { @@ -367,28 +365,28 @@ void EightBit::GameBoy::LR35902::executeCB(const int x, const int y, const int z auto operand = 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: // GB: SWAP r - operand = swap(operand); + operand = swap(F(), operand); break; case 7: - operand = srl(operand); + operand = srl(F(), operand); break; default: UNREACHABLE; @@ -400,7 +398,7 @@ void EightBit::GameBoy::LR35902::executeCB(const int x, const int y, const int z tick(2); break; } case 1: // BIT y, r[z] - bit(y, R(z)); + bit(F(), y, R(z)); tick(2); if (UNLIKELY(z == 6)) tick(2); @@ -448,9 +446,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in case 5: case 6: case 7: - if (jrConditionalFlag(y - 4)) - tick(); - tick(2); + jrConditionalFlag(F(), y - 4); break; default: UNREACHABLE; @@ -463,7 +459,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in tick(3); break; case 1: // ADD HL,rp - add(HL(), RP(p)); + HL() = add(F(), HL(), RP(p)); tick(2); break; default: @@ -535,16 +531,14 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in break; case 4: { // 8-bit INC auto operand = R(y); - increment(operand); - R(y, operand); + R(y, increment(F(), operand)); tick(); if (UNLIKELY(y == 6)) tick(2); break; } case 5: { // 8-bit DEC auto operand = R(y); - decrement(operand); - R(y, operand); + R(y, decrement(F(), operand)); tick(); if (UNLIKELY(y == 6)) tick(2); @@ -556,28 +550,28 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, 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; @@ -601,28 +595,28 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in case 2: // Operate on accumulator and register/memory location switch (y) { case 0: // ADD A,r - add(A(), R(z)); + A() = add(F(), A(), R(z)); break; case 1: // ADC A,r - adc(A(), R(z)); + A() = adc(F(), A(), R(z)); break; case 2: // SUB r - subtract(A(), R(z)); + A() = subtract(F(), A(), R(z)); break; case 3: // SBC A,r - sbc(R(z)); + A() = sbc(F(), A(), R(z)); break; case 4: // AND r - andr(A(), R(z)); + A() = andr(F(), A(), R(z)); break; case 5: // XOR r - xorr(R(z)); + A() = xorr(F(), A(), R(z)); break; case 6: // OR r - orr(R(z)); + A() = orr(F(), A(), R(z)); break; case 7: // CP r - compare(A(), R(z)); + compare(F(), A(), R(z)); break; default: UNREACHABLE; @@ -639,9 +633,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in case 1: case 2: case 3: - if (returnConditionalFlag(y)) - tick(3); - tick(2); + returnConditionalFlag(F(), y); break; case 4: // GB: LD (FF00 + n),A IntelProcessor::memoryWrite(IoRegisters::BASE + fetchByte(), A()); @@ -717,8 +709,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in case 1: case 2: case 3: - jumpConditionalFlag(y); - tick(3); + jumpConditionalFlag(F(), y); break; case 4: // GB: LD (FF00 + C),A IntelProcessor::memoryWrite(IoRegisters::BASE + C(), A()); @@ -763,9 +754,7 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in } break; case 4: // Conditional call: CALL cc[y], nn - if (callConditionalFlag(y)) - tick(3); - tick(3); + callConditionalFlag(F(), y); break; case 5: // PUSH & various ops switch (q) { @@ -788,28 +777,28 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in case 6: // Operate on accumulator and immediate operand: alu[y] n switch (y) { case 0: // ADD A,n - add(A(), fetchByte()); + A() = add(F(), A(), fetchByte()); break; case 1: // ADC A,n - adc(A(), fetchByte()); + A() = adc(F(), A(), fetchByte()); break; case 2: // SUB n - subtract(A(), fetchByte()); + A() = subtract(F(), A(), fetchByte()); break; case 3: // SBC A,n - sbc(fetchByte()); + A() = sbc(F(), A(), fetchByte()); break; case 4: // AND n - andr(A(), fetchByte()); + A() = andr(F(), A(), fetchByte()); break; case 5: // XOR n - xorr(fetchByte()); + A() = xorr(F(), A(), fetchByte()); break; case 6: // OR n - orr(fetchByte()); + A() = orr(F(), A(), fetchByte()); break; case 7: // CP n - compare(A(), fetchByte()); + compare(F(), A(), fetchByte()); break; default: UNREACHABLE; diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 9dd86aa..44b8eef 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -12,6 +11,9 @@ #include namespace EightBit { + + class Bus; + class Z80 final : public IntelProcessor { public: struct refresh_t { @@ -230,13 +232,13 @@ namespace EightBit { ASSUME(rp >= 0); ASSUME(rp <= 3); switch (rp) { - case 0: + case 0b00: return BC(); - case 1: + case 0b01: return DE(); - case 2: + case 0b10: return HL2(); - case 3: + case 0b11: return SP(); default: UNREACHABLE; @@ -247,13 +249,13 @@ namespace EightBit { ASSUME(rp >= 0); ASSUME(rp <= 3); switch (rp) { - case 0: + case 0b00: return BC(); - case 1: + case 0b01: return DE(); - case 2: + case 0b10: return HL2(); - case 3: + case 0b11: return AF(); default: UNREACHABLE; @@ -351,11 +353,11 @@ namespace EightBit { } } - [[nodiscard]] static uint8_t adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { + [[nodiscard]] static auto adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation)); } - [[nodiscard]] static uint8_t adjustHalfCarrySub(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { + [[nodiscard]] static auto adjustHalfCarrySub(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { return setBit(f, HC, calculateHalfCarrySub(before, value, calculation)); } diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 0b8c9b9..6980c95 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -1049,8 +1049,9 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p break; case 7: // CPDR if (cpdr(F(), A())) { - MEMPTR() = --PC(); - --PC(); + MEMPTR() = PC() - 2; + //MEMPTR() = --PC(); + //--PC(); tick(5); } else { MEMPTR() = PC() - 2; diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index 5be5e6f..7b8de0b 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -136,21 +136,21 @@ namespace EightBit { call(MEMPTR() = { address, 0 }); } - auto callConditional(const int condition) { + virtual int callConditional(const int condition) { MEMPTR() = fetchWord(); if (condition) call(MEMPTR()); return condition; } - auto jumpConditional(const int condition) { + virtual int jumpConditional(const int condition) { MEMPTR() = fetchWord(); if (condition) jump(MEMPTR()); return condition; } - auto returnConditional(const int condition) { + virtual int returnConditional(const int condition) { if (condition) ret(); return condition;