diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index 909734cea..7aeb264b1 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -294,9 +294,11 @@ template < int16_t(dest.w)); } break; - case Operation::Scc: - src.b = status.evaluate_condition(instruction.condition()) ? 0xff : 0x00; - break; + case Operation::Scc: { + const bool condition = status.evaluate_condition(instruction.condition()); + src.b = condition ? 0xff : 0x00; + flow_controller.did_scc(condition); + } break; /* CLRs: store 0 to the destination, set the zero flag, and clear diff --git a/InstructionSets/M68k/Perform.hpp b/InstructionSets/M68k/Perform.hpp index 6351b1448..3df7b5736 100644 --- a/InstructionSets/M68k/Perform.hpp +++ b/InstructionSets/M68k/Perform.hpp @@ -46,6 +46,10 @@ struct NullFlowController { /// Indicates that a bit-manipulation operation (i.e. BTST, BCHG or BSET) was performed, affecting the bit at posiition @c bit_position. void did_bit_op([[maybe_unused]] int bit_position) {} + /// Indicates that an @c Scc was performed; if @c did_set_ff is true then the condition was true and FF + /// written to the operand; otherwise 00 was written. + void did_scc([[maybe_unused]] bool did_set_ff) {} + /// Provides a notification that the upper byte of the status register has been affected by the current instruction; /// this gives an opportunity to track the supervisor flag. void did_update_status() {} diff --git a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm index 50ad7a535..ae5283cae 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm @@ -156,7 +156,7 @@ struct TestProcessor: public CPU::MC68000Mk2::BusHandler { // To limit tests run to a subset of files and/or of tests, uncomment and fill in below. _fileSet = [NSSet setWithArray:@[ -// @"addq_subq.json", + @"addq_subq.json", // Below this line are passing tests. @"abcd_sbcd.json", diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index 2dc73b281..3e7b77ab3 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -82,6 +82,10 @@ enum ExecutionState: int { CHK_no_trap, CHK_was_over, CHK_was_under, + + Scc_Dn, + Scc_Dn_did_not_set, + Scc_Dn_did_set, }; // MARK: - The state machine. @@ -504,6 +508,14 @@ void Processor( + instruction_, operand_[0], operand_[1], status_, *static_cast(this)); + + // Next state will be set by did_scc. + break; + + BeginState(Scc_Dn_did_set): + IdleBus(1); // n + [[fallthrough]]; + BeginState(Scc_Dn_did_not_set): + next_operand_ = 0; + MoveToState(StoreOperand); + + // // Various states TODO. + // #define TODOState(x) \ BeginState(x): [[fallthrough]]; @@ -1100,6 +1141,10 @@ void ProcessorBase::did_chk(bool was_under, bool was_over) { } } +void ProcessorBase::did_scc(bool did_set_ff) { + state_ = did_set_ff ? Scc_Dn_did_set : Scc_Dn_did_not_set; +} + // MARK: - External state. template diff --git a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp index 63014787b..7af820c99 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp @@ -102,6 +102,7 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { template void did_mulu(IntT) {} template void did_muls(IntT) {} inline void did_chk(bool, bool); + inline void did_scc(bool); inline void did_shift(int) {} template void did_divu(uint32_t, uint32_t) {} template void did_divs(int32_t, int32_t) {}