From 76a5872d178109ac34b99cfa652a3c6d53ee759c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 24 Oct 2025 21:24:05 -0400 Subject: [PATCH] Install extra cycle for 65c02 decimal arithmetic. --- Processors/6502Mk2/Implementation/6502.hpp | 45 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/Processors/6502Mk2/Implementation/6502.hpp b/Processors/6502Mk2/Implementation/6502.hpp index 8ec4d0280..5b74e591b 100644 --- a/Processors/6502Mk2/Implementation/6502.hpp +++ b/Processors/6502Mk2/Implementation/6502.hpp @@ -86,7 +86,7 @@ void Processor::run_for(const Cycles cycles) { default: __builtin_unreachable(); - // MARK: - Read, write or modify accesses. + // MARK: - Read, write or modify a zero-page address. access_zero: ++registers.pc.full; @@ -100,6 +100,18 @@ void Processor::run_for(const Cycles cycles) { goto access_zero_write; } + // ADC and SBC decimal take an extra cycle on the 65c02. + if constexpr (is_65c02(model)) { + if( + ( + Storage::decoded_.operation == Operation::ADC || + Storage::decoded_.operation == Operation::SBC + ) && registers.flags.decimal + ) { + goto access_zero_65c02_decimal; + } + } + // Read. check_interrupt(); access(BusOperation::Read, ZeroPage(Storage::address_.halves.low), Storage::operand_); @@ -123,6 +135,15 @@ void Processor::run_for(const Cycles cycles) { goto fetch_decode; + access_zero_65c02_decimal: + access(BusOperation::Read, ZeroPage(Storage::address_.halves.low), Storage::operand_); + check_interrupt(); + access(BusOperation::Read, ZeroPage(Storage::address_.halves.low), Storage::operand_); + perform_operation(); + goto fetch_decode; + + // MARK: - Read, write or modify an arbitrary address. + access_absolute: ++registers.pc.full; if constexpr (is_65c02(model)) { @@ -134,6 +155,18 @@ void Processor::run_for(const Cycles cycles) { goto access_absolute_write; } + // ADC and SBC decimal take an extra cycle on the 65c02. + if constexpr (is_65c02(model)) { + if( + ( + Storage::decoded_.operation == Operation::ADC || + Storage::decoded_.operation == Operation::SBC + ) && registers.flags.decimal + ) { + goto access_absolute_65c02_decimal; + } + } + // Read. check_interrupt(); access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_); @@ -157,6 +190,13 @@ void Processor::run_for(const Cycles cycles) { goto fetch_decode; + access_absolute_65c02_decimal: + access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_); + check_interrupt(); + perform_operation(); + access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_); + goto fetch_decode; + // MARK: - Fetch/decode. fetch_decode: @@ -172,9 +212,6 @@ void Processor::run_for(const Cycles cycles) { goto interrupt; } - if constexpr (is_65c02(model)) { - check_interrupt(); - } access(BusOperation::ReadOpcode, Literal(registers.pc.full), Storage::opcode_); ++registers.pc.full; Storage::decoded_ = Decoder::decode(Storage::opcode_);