diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index fd38d6ba3..fcbcd0db9 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -158,6 +158,8 @@ enum ExecutionState: int { MOVEMtoM_l_write, MOVEMtoM_w_write, MOVEMtoM_l_write_predec, MOVEMtoM_w_write_predec, MOVEMtoM_finish, + + DIVU_DIVS, }; // MARK: - The state machine. @@ -685,6 +687,9 @@ void Processor( instruction_, operand_[0], operand_[1], status_, *static_cast(this)); - IdleBus(1 + did_bit_op_high_); + IdleBus(1 + dynamic_instruction_length_); registers_[instruction_.reg(1)] = operand_[1]; MoveToState(Decode); @@ -1533,7 +1538,7 @@ void Processor( instruction_, operand_[0], operand_[1], status_, *static_cast(this)); - IdleBus(2 + did_bit_op_high_); + IdleBus(2 + dynamic_instruction_length_); registers_[instruction_.reg(1)] = operand_[1]; MoveToState(Decode); @@ -1828,6 +1833,32 @@ void Processor( + instruction_, operand_[0], operand_[1], status_, *static_cast(this)); + + // Delay the correct amount of time. + IdleBus(dynamic_instruction_length_); + + // Either dispatch an exception or don't. + if(exception_vector_ >= 0) { + MoveToState(StandardException); + } + + // DIVU and DIVS are always to a register, so just write back here + // to save on dispatch costs. + registers_[instruction_.reg(1)] = operand_[1]; + + Prefetch(); // np + MoveToState(Decode); + // // Various states TODO. // @@ -1911,7 +1942,26 @@ void ProcessorBase::bsr(uint32_t offset) { } void ProcessorBase::did_bit_op(int bit_position) { - did_bit_op_high_ = bit_position > 15; + dynamic_instruction_length_ = int(bit_position > 15); +} + +template void ProcessorBase::did_divu(uint32_t, uint32_t) { + // TODO: calculate cost. +} + +template void ProcessorBase::did_divs(int32_t, int32_t) { + // TODO: calculate cost. +} + +template void ProcessorBase::raise_exception(int vector) { + // No overt action is taken here; instructions that might throw an exception are required + // to check-in after the fact. + // + // As implemented above, that means: + // + // * DIVU; + // * DIVS. + exception_vector_ = vector; } // MARK: - External state. diff --git a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp index b8508e59b..3470b7ba2 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Storage.hpp @@ -95,9 +95,10 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { /// Transient storage for exception processing. SlicedInt16 captured_status_; - /// An internal flag used during BCHG, BSET and BCLR processing to - /// determine total operation cost. - bool did_bit_op_high_ = false; + /// An internal flag used during various dynamically-sized instructions + /// (e.g. BCHG, DIVU) to indicate how much additional processing happened; + /// this is measured in microcycles. + int dynamic_instruction_length_ = 0; /// Two bits of state for MOVEM, being the curent register and what to /// add to it to get to the next register. @@ -126,8 +127,8 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { 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) {} // + template void did_divu(uint32_t, uint32_t); + template void did_divs(int32_t, int32_t); inline void did_bit_op(int); inline void did_update_status(); template void complete_bcc(bool, IntT); @@ -146,7 +147,7 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { inline void move_to_usp(uint32_t) {} // inline void move_from_usp(uint32_t &) {} // inline void tas(Preinstruction, uint32_t) {} // - template void raise_exception(int) {} + template void raise_exception(int); // These aren't implemented because the specific details of the implementation // mean that the performer call-out isn't necessary.