diff --git a/Processors/68000Mk2/68000Mk2.hpp b/Processors/68000Mk2/68000Mk2.hpp index 54dcf4979..1590755d1 100644 --- a/Processors/68000Mk2/68000Mk2.hpp +++ b/Processors/68000Mk2/68000Mk2.hpp @@ -121,6 +121,7 @@ struct Microcycle { SlicedInt16 *value = nullptr; Microcycle(OperationT operation) : operation(operation) {} + Microcycle(OperationT operation, HalfCycles length) : operation(operation), length(length) {} Microcycle() {} /// @returns @c true if two Microcycles are equal; @c false otherwise. diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index 37e8123b4..53e84857e 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -20,7 +20,7 @@ namespace MC68000Mk2 { // TODO: VPA, BERR, interrupt inputs, etc. // Also, from Instruction.hpp: // -// NOP, MOVEAw, MOVEAl, MOVE[to/from]USP, STOP, RESET +// MOVEAw, MOVEAl, MOVE[to/from]USP, STOP // // Not provided by a 68000: Bccl, BSRl @@ -134,11 +134,11 @@ enum ExecutionState: int { DBcc_condition_true, DBcc_counter_overflow, - Bcc_b, - Bcc_w, + Bccb, + Bccw, Bcc_branch_taken, - Bcc_b_branch_not_taken, - Bcc_w_branch_not_taken, + Bccb_branch_not_taken, + Bccw_branch_not_taken, BSR, @@ -177,8 +177,10 @@ enum ExecutionState: int { RTR, RTE, RTS, - LINK, + LINKw, UNLINK, + RESET, + NOP, }; // MARK: - The state machine. @@ -461,6 +463,8 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor ); \ [[fallthrough]]; +#define SpecialCASE(x) case InstructionSet::M68k::Operation::x: MoveToStateSpecific(x) + switch(instruction_.operation) { StdCASE(NBCD, { if(instruction_.mode(0) == Mode::DataRegisterDirect) { @@ -612,10 +616,10 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor } }); - StdCASE(DBcc, MoveToStateSpecific(DBcc)); + SpecialCASE(DBcc); - StdCASE(Bccb, MoveToStateSpecific(Bcc_b)); - StdCASE(Bccw, MoveToStateSpecific(Bcc_w)); + SpecialCASE(Bccb); + SpecialCASE(Bccw); StdCASE(BSRb, perform_state_ = BSR); StdCASE(BSRw, perform_state_ = BSR); @@ -756,9 +760,9 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor MoveToStateSpecific(CalcEffectiveAddress); }); - StdCASE(RTR, MoveToStateSpecific(RTR)); - StdCASE(RTE, MoveToStateSpecific(RTE)); - StdCASE(RTS, MoveToStateSpecific(RTS)); + SpecialCASE(RTR); + SpecialCASE(RTE); + SpecialCASE(RTS); #define ShiftGroup(suffix, state) \ Duplicate(ASL##suffix, ASR##suffix); \ @@ -776,8 +780,11 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor ShiftGroup(l, Perform_idle_dyamic_Dn) #undef ShiftGroup - StdCASE(LINKw, MoveToStateSpecific(LINK)); - StdCASE(UNLINK, MoveToStateSpecific(UNLINK)); + SpecialCASE(LINKw); + SpecialCASE(UNLINK); + + SpecialCASE(RESET); + SpecialCASE(NOP); default: assert(false); @@ -786,6 +793,7 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor #undef Duplicate #undef StdCASE #undef CASE +#undef SpecialCASE // MARK: - Fetch, dispatch. @@ -1563,14 +1571,14 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor // // Bcc [.b and .w] // - BeginState(Bcc_b): + BeginState(Bccb): operand_[0].b = uint8_t(opcode_); PerformSpecific(Bccb); // Next state was set by complete_bcc. break; - BeginState(Bcc_w): + BeginState(Bccw): operand_[0].w = prefetch_.w; PerformSpecific(Bccw); @@ -1583,12 +1591,12 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor Prefetch(); // np MoveToStateSpecific(Decode); - BeginState(Bcc_b_branch_not_taken): + BeginState(Bccb_branch_not_taken): IdleBus(2); // nn Prefetch(); // np MoveToStateSpecific(Decode); - BeginState(Bcc_w_branch_not_taken): + BeginState(Bccw_branch_not_taken): IdleBus(2); // nn Prefetch(); // np Prefetch(); // np @@ -2124,9 +2132,9 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor MoveToStateSpecific(Decode); // - // LINK and UNLINK + // LINK[.w] and UNLINK // - BeginState(LINK): + BeginState(LINKw): Prefetch(); // Ensure that the stack pointer is [seemingly] captured after @@ -2152,6 +2160,22 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor Prefetch(); MoveToStateSpecific(Decode); + // + // RESET + // + BeginState(RESET): + IdleBus(2); + PerformBusOperation(reset_cycle); + Prefetch(); + MoveToStateSpecific(Decode); + + // + // NOP + // + BeginState(NOP): + Prefetch(); + MoveToStateSpecific(Decode); + // // Various states TODO. // @@ -2232,7 +2256,7 @@ template <typename IntT> void ProcessorBase::complete_bcc(bool take_branch, IntT state_ = (instruction_.operation == InstructionSet::M68k::Operation::Bccb) ? - Bcc_b_branch_not_taken : Bcc_w_branch_not_taken; + Bccb_branch_not_taken : Bccw_branch_not_taken; } void ProcessorBase::bsr(uint32_t offset) { diff --git a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp index 458239a04..aa28ebcf2 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp @@ -141,7 +141,6 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { inline void complete_dbcc(bool, bool, int16_t); inline void bsr(uint32_t); inline void stop() {} // TODO - inline void reset() {} // TODO inline void move_to_usp(uint32_t) {} // TODO inline void move_from_usp(uint32_t &) {} // TODO inline void tas(Preinstruction, uint32_t); @@ -160,6 +159,7 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { inline void rtr() {} inline void rte() {} inline void rts() {} + inline void reset() {} // Some microcycles that will be modified as required and used in the main loop; // the semantics of a switch statement make in-place declarations awkward and @@ -191,6 +191,9 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { { Microcycle::SameAddress | Microcycle::IsData | Microcycle::SelectByte }, }; + // Reset. + Microcycle reset_cycle { Microcycle::Reset, HalfCycles(248) }; + // Holding spot when awaiting DTACK/etc. Microcycle awaiting_dtack; };