From da9fb216b16eeff4fd4acb3b8c31aba03a36733b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 18 May 2022 16:45:40 -0400 Subject: [PATCH] Remove setup_operation in favour of doing the equivalent inline. ... as it'll probably allow me a route to `goto` straight out of there, too. At least, if I can find a sufficiently neat macro formulation. --- Processors/68000Mk2/68000Mk2.hpp | 1 - .../Implementation/68000Mk2Implementation.hpp | 138 ++++++++++++------ 2 files changed, 92 insertions(+), 47 deletions(-) diff --git a/Processors/68000Mk2/68000Mk2.hpp b/Processors/68000Mk2/68000Mk2.hpp index 4f4eddad5..5e1f81363 100644 --- a/Processors/68000Mk2/68000Mk2.hpp +++ b/Processors/68000Mk2/68000Mk2.hpp @@ -401,7 +401,6 @@ class Processor: private ProcessorBase { private: BusHandler &bus_handler_; - void setup_operation(); }; } diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index d6c6eba57..b9d741349 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -25,6 +25,19 @@ enum ExecutionState: int { FetchOperand, StoreOperand, + // Specific addressing mode fetches. + + FetchAddressRegisterIndirect, + FetchAddressRegisterIndirectWithPostincrement, + FetchAddressRegisterIndirectWithPredecrement, + FetchAddressRegisterIndirectWithDisplacement, + FetchAddressRegisterIndirectWithIndex8bitDisplacement, + FetchProgramCounterIndirectWithDisplacement, + FetchProgramCounterIndirectWithIndex8bitDisplacement, + FetchAbsoluteShort, + FetchAbsoluteLong, + FetchImmediateData, + // Various forms of perform; each of these will // perform the current instruction, then do the // indicated bus cycle. @@ -57,10 +70,10 @@ void Processor(); + + switch(instruction_.operation) { + CASE(NBCD) + if(instruction_.mode(0) == Mode::DataRegisterDirect) { + perform_state_ = Perform_np_n; + } else { + perform_state_ = Perform_np; + } + break; + + default: + assert(false); + } + +#undef CASE [[fallthrough]]; +#define MoveToNextOperand() \ + ++next_operand_; \ + if(next_operand_ == 2) { \ + state_ = perform_state_; \ + continue; \ + } \ + MoveToState(FetchOperand) + // Check the operand flags to determine whether the operand at index // operand_ needs to be fetched, and if so then calculate the EA and // do so. - // - // Per Yacht, all instructions other than MOVE.[b/w/;] will read all - // relevant operands — even when that's a useless endeavour, such as - // for CLR or MOVE SR, . - // - // TODO: add MOVE special case, somewhere. BeginState(FetchOperand): - // Check that this operand is meant to be fetched. + // Check that this operand is meant to be fetched; if not then either: + // + // (i) this operand isn't used; or + // (ii) its address calculation will end up conflated with performance, + // so there's no generic bus-accurate approach. if(!(operand_flags_ & (1 << next_operand_))) { state_ = perform_state_; continue; @@ -237,13 +274,34 @@ void Processor -void Processor::setup_operation() { - -#define BIND(x, p) \ - case InstructionSet::M68k::Operation::x: \ - operand_flags_ = InstructionSet::M68k::operand_flags(); \ - perform_state_ = p; \ - break; - - using Mode = InstructionSet::M68k::AddressingMode; - - switch(instruction_.operation) { - BIND(NBCD, instruction_.mode(0) == Mode::DataRegisterDirect ? ExecutionState::Perform_np_n : ExecutionState::Perform_np); - - // MOVEs are a special case for having an operand they write but did not read. So they segue into a - // specialised state for writing the result. - BIND(MOVEw, ExecutionState::MOVEWrite); - - default: - assert(false); - } - -#undef BIND -} - // MARK: - Flow Controller. void ProcessorBase::did_update_status() {