diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 6bcb18a..f7132a3 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -195,10 +195,11 @@ namespace EightBit { [[nodiscard]] constexpr auto displaced() const noexcept { return m_prefixDD || m_prefixFD; } - [[nodiscard]] constexpr uint16_t displacedAddress() noexcept { - const auto address = (m_prefixDD ? IX() : IY()).word + m_displacement; + [[nodiscard]] constexpr const register16_t& displacedAddress() noexcept { + const auto& index_register = m_prefixDD ? IX() : IY(); + const auto address = index_register.word + m_displacement; MEMPTR().word = address; - return address; + return MEMPTR(); } void fetchDisplacement() noexcept; diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index b5107c6..40aa223 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -289,7 +289,7 @@ EightBit::register16_t EightBit::Z80::sbc(uint8_t& f, const register16_t operand const register16_t result = subtraction; f = setBit(f, NF); - f = clearBit(f, ZF, result.word); + f = setBit(f, ZF, result.zero()); f = setBit(f, CF, subtraction & Bit16); f = adjustHalfCarrySub(f, operand.high, value.high, result.high); f = adjustXY(f, result.high); @@ -310,7 +310,7 @@ EightBit::register16_t EightBit::Z80::sbc(uint8_t& f, const register16_t operand EightBit::register16_t EightBit::Z80::adc(uint8_t& f, const register16_t operand, const register16_t value) noexcept { const auto result = add(f, operand, value, f & CF); - f = clearBit(f, ZF, result.word); + f = setBit(f, ZF, result.zero()); const auto beforeNegative = operand.high & SF; const auto valueNegative = value.high & SF; @@ -688,7 +688,7 @@ uint8_t EightBit::Z80::R(const int r) noexcept { case 5: return HL2().low; case 6: - return IntelProcessor::memoryRead(UNLIKELY(displaced()) ? displacedAddress() : HL().word); + return IntelProcessor::memoryRead(UNLIKELY(displaced()) ? displacedAddress() : HL()); case 7: return A(); default: @@ -717,7 +717,7 @@ void EightBit::Z80::R(const int r, const uint8_t value) noexcept { HL2().low = value; break; case 6: - IntelProcessor::memoryWrite(UNLIKELY(displaced()) ? displacedAddress() : HL().word, value); + IntelProcessor::memoryWrite(UNLIKELY(displaced()) ? displacedAddress() : HL(), value); break; case 7: A() = value; @@ -1380,7 +1380,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 3: // Assorted operations switch (y) { case 0: // JP nn - jump(MEMPTR() = fetchWord()); + jumpIndirect(); break; case 1: // CB prefix m_prefixCB = true; @@ -1425,7 +1425,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 1: switch (p) { case 0: // CALL nn - call(MEMPTR() = fetchWord()); + callIndirect(); break; case 1: // DD prefix m_prefixDD = true; diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index d01d7a5..824236e 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -158,6 +158,11 @@ namespace EightBit { virtual int jrConditional(int condition); void ret() override; + virtual void fetchWordMEMPTR(); + + void jumpIndirect(); + void callIndirect(); + void resetWorkingRegisters() noexcept; private: diff --git a/inc/Processor.h b/inc/Processor.h index d73f81a..23acb22 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -27,6 +27,9 @@ namespace EightBit { [[nodiscard]] constexpr auto& PC() noexcept { return m_pc; } [[nodiscard]] constexpr const auto& PC() const noexcept { return m_pc; } + [[nodiscard]] constexpr auto& intermediate() noexcept { return m_intermediate; } + [[nodiscard]] constexpr const auto& intermediate() const noexcept { return m_intermediate; } + int run(int limit) noexcept; virtual int step() noexcept = 0; virtual void execute() noexcept = 0; @@ -88,5 +91,6 @@ namespace EightBit { Bus& m_bus; uint8_t m_opcode = Mask8; register16_t m_pc; + register16_t m_intermediate; }; } diff --git a/inc/Register.h b/inc/Register.h index 893c72f..3fac1e9 100644 --- a/inc/Register.h +++ b/inc/Register.h @@ -75,6 +75,9 @@ namespace EightBit { [[nodiscard]] constexpr auto operator<=(const register16_t& rhs) const noexcept { return word <= rhs.word; } [[nodiscard]] constexpr auto operator>(const register16_t& rhs) const noexcept { return word > rhs.word; } [[nodiscard]] constexpr auto operator>=(const register16_t& rhs) const noexcept { return word >= rhs.word; } + + [[nodiscard]] constexpr auto zero() const noexcept { return word == 0; } + [[nodiscard]] constexpr auto nonzero() const noexcept { return word != 0; } }; [[nodiscard]] constexpr inline auto operator+(register16_t lhs, const register16_t rhs) noexcept { diff --git a/src/IntelProcessor.cpp b/src/IntelProcessor.cpp index 687331d..56c4f15 100644 --- a/src/IntelProcessor.cpp +++ b/src/IntelProcessor.cpp @@ -63,14 +63,14 @@ void EightBit::IntelProcessor::restart(const uint8_t address) { } int EightBit::IntelProcessor::callConditional(const int condition) { - MEMPTR() = fetchWord(); + fetchWordMEMPTR(); if (condition) call(MEMPTR()); return condition; } int EightBit::IntelProcessor::jumpConditional(const int condition) { - MEMPTR() = fetchWord(); + fetchWordMEMPTR(); if (condition) jump(MEMPTR()); return condition; @@ -100,6 +100,21 @@ void EightBit::IntelProcessor::ret() { MEMPTR() = PC(); } +void EightBit::IntelProcessor::fetchWordMEMPTR() { + const auto _ = fetchWord(); + MEMPTR() = intermediate(); +} + +void EightBit::IntelProcessor::jumpIndirect() { + fetchWordMEMPTR(); + jump(MEMPTR()); +} + +void EightBit::IntelProcessor::callIndirect() { + fetchWordMEMPTR(); + call(MEMPTR()); +} + bool EightBit::IntelProcessor::operator==(const EightBit::IntelProcessor& rhs) const noexcept { return LittleEndianProcessor::operator==(rhs) diff --git a/src/LittleEndianProcessor.cpp b/src/LittleEndianProcessor.cpp index 6da923c..feaaa17 100644 --- a/src/LittleEndianProcessor.cpp +++ b/src/LittleEndianProcessor.cpp @@ -34,9 +34,9 @@ void EightBit::LittleEndianProcessor::setWordPaged(register16_t value) { } EightBit::register16_t EightBit::LittleEndianProcessor::fetchWord() { - const auto low = fetchByte(); - const auto high = fetchByte(); - return { low, high }; + intermediate().low = fetchByte(); + intermediate().high = fetchByte(); + return intermediate(); } void EightBit::LittleEndianProcessor::pushWord(const register16_t value) {