diff --git a/M6502/HarteTest_6502/checker_t.h b/M6502/HarteTest_6502/checker_t.h index e77370a..ce53ad2 100644 --- a/M6502/HarteTest_6502/checker_t.h +++ b/M6502/HarteTest_6502/checker_t.h @@ -84,7 +84,7 @@ public: [[nodiscard]] constexpr auto cycles() const noexcept { return m_cycles; } [[nodiscard]] constexpr auto valid() const noexcept { return m_valid; } [[nodiscard]] constexpr auto invalid() const noexcept { return !valid(); } - [[nodiscard]] constexpr auto unimplemented() const noexcept { return invalid() && m_cycle_count_mismatch && (cycles() == 0); } + [[nodiscard]] constexpr auto unimplemented() const noexcept { return invalid() && m_cycle_count_mismatch && (cycles() == 1); } [[nodiscard]] constexpr auto implemented() const noexcept { return !unimplemented(); } [[nodiscard]] constexpr const auto& messages() const noexcept { return m_messages; } diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index 0185654..277b888 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -21,25 +21,42 @@ DEFINE_PIN_LEVEL_CHANGERS(RDY, MOS6502) DEFINE_PIN_LEVEL_CHANGERS(RW, MOS6502) int EightBit::MOS6502::step() noexcept { + resetCycles(); + ExecutingInstruction.fire(*this); if (LIKELY(powered())) { + + tick(); // A cycle is used, whether or RDY is high or not + if (UNLIKELY(lowered(SO()))) handleSO(); + if (LIKELY(raised(RDY()))) { + lowerSYNC(); // Instruction fetch beginning + + // Read the opcode within the existing cycle + assert(cycles() == 1 && "An extra cycle has occurred"); + // Can't use fetchByte, since that would add an extra tick. raiseRW(); - opcode() = BUS().read(PC()++); // can't use fetchByte + opcode() = BUS().read(PC()++); + assert(cycles() == 1 && "BUS read has introduced stray cycles"); + + // Priority: RESET > NMI > INT if (UNLIKELY(lowered(RESET()))) handleRESET(); else if (UNLIKELY(lowered(NMI()))) handleNMI(); else if (UNLIKELY(lowered(INT()) && !interruptMasked())) handleINT(); + + // Whatever opcode is available, execute it. execute(); } } ExecutedInstruction.fire(*this); + return cycles(); }