From f46e7c65c53b5b6987427c1559e86e17828c7ff5 Mon Sep 17 00:00:00 2001 From: Thomas Harte <thomas.harte@gmail.com> Date: Thu, 19 May 2022 10:47:57 -0400 Subject: [PATCH] Add AddressRegisterIndirect fetches. --- .../Implementation/68000Mk2Implementation.hpp | 170 +++++++++++++----- 1 file changed, 128 insertions(+), 42 deletions(-) diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index b5c3d5881..1b4cbeb88 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -24,24 +24,35 @@ enum ExecutionState: int { WaitForDTACK, /// Perform the proper sequence to fetch a byte or word operand. - FetchOperandbw, + FetchOperand_bw, /// Perform the proper sequence to fetch a long-word operand. - FetchOperandl, + FetchOperand_l, StoreOperand, // Specific addressing mode fetches. - FetchAddressRegisterIndirect, - FetchAddressRegisterIndirectWithPostincrement, - FetchAddressRegisterIndirectWithPredecrement, - FetchAddressRegisterIndirectWithDisplacement, - FetchAddressRegisterIndirectWithIndex8bitDisplacement, - FetchProgramCounterIndirectWithDisplacement, - FetchProgramCounterIndirectWithIndex8bitDisplacement, - FetchAbsoluteShort, - FetchAbsoluteLong, - FetchImmediateData, + FetchAddressRegisterIndirect_bw, + FetchAddressRegisterIndirectWithPostincrement_bw, + FetchAddressRegisterIndirectWithPredecrement_bw, + FetchAddressRegisterIndirectWithDisplacement_bw, + FetchAddressRegisterIndirectWithIndex8bitDisplacement_bw, + FetchProgramCounterIndirectWithDisplacement_bw, + FetchProgramCounterIndirectWithIndex8bitDisplacement_bw, + FetchAbsoluteShort_bw, + FetchAbsoluteLong_bw, + FetchImmediateData_bw, + + FetchAddressRegisterIndirect_l, + FetchAddressRegisterIndirectWithPostincrement_l, + FetchAddressRegisterIndirectWithPredecrement_l, + FetchAddressRegisterIndirectWithDisplacement_l, + FetchAddressRegisterIndirectWithIndex8bitDisplacement_l, + FetchProgramCounterIndirectWithDisplacement_l, + FetchProgramCounterIndirectWithIndex8bitDisplacement_l, + FetchAbsoluteShort_l, + FetchAbsoluteLong_l, + FetchImmediateData_l, // Various forms of perform; each of these will // perform the current instruction, then do the @@ -248,14 +259,14 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor #define FetchOperands(x) \ if constexpr (InstructionSet::M68k::operand_size<InstructionSet::M68k::Operation::x>() == InstructionSet::M68k::DataSize::LongWord) { \ SetupDataAccess(temporary_address_, Microcycle::Read, Microcycle::SelectWord); \ - MoveToState(FetchOperandl); \ + MoveToState(FetchOperand_l); \ } else { \ if constexpr (InstructionSet::M68k::operand_size<InstructionSet::M68k::Operation::x>() == InstructionSet::M68k::DataSize::Byte) { \ SetupDataAccess(temporary_address_, Microcycle::Read, Microcycle::SelectByte); \ } else { \ SetupDataAccess(temporary_address_, Microcycle::Read, Microcycle::SelectWord); \ } \ - MoveToState(FetchOperandbw); \ + MoveToState(FetchOperand_bw); \ } switch(instruction_.operation) { @@ -281,6 +292,8 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor #undef CASE + // MARK: - Fetch, dispatch. + #define MoveToNextOperand(x) \ ++next_operand_; \ if(next_operand_ == 2) { \ @@ -289,10 +302,10 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor } \ MoveToState(x) - // 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. - BeginState(FetchOperandbw): + // Check the operand flags to determine whether the byte or word + // operand at index next_operand_ needs to be fetched, and if so + // then calculate the EA and do so. + BeginState(FetchOperand_bw): // Check that this operand is meant to be fetched; if not then either: // // (i) this operand isn't used; or @@ -308,32 +321,32 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor case Mode::AddressRegisterDirect: case Mode::DataRegisterDirect: operand_[next_operand_] = registers_[instruction_.lreg(next_operand_)]; - MoveToNextOperand(FetchOperandbw); + MoveToNextOperand(FetchOperand_bw); case Mode::Quick: operand_[next_operand_].l = InstructionSet::M68k::quick(opcode_, instruction_.operation); - MoveToNextOperand(FetchOperandbw); + MoveToNextOperand(FetchOperand_bw); case Mode::AddressRegisterIndirect: - MoveToState(FetchAddressRegisterIndirect); + MoveToState(FetchAddressRegisterIndirect_bw); case Mode::AddressRegisterIndirectWithPostincrement: - MoveToState(FetchAddressRegisterIndirectWithPostincrement); + MoveToState(FetchAddressRegisterIndirectWithPostincrement_bw); case Mode::AddressRegisterIndirectWithPredecrement: - MoveToState(FetchAddressRegisterIndirectWithPredecrement); + MoveToState(FetchAddressRegisterIndirectWithPredecrement_bw); case Mode::AddressRegisterIndirectWithDisplacement: - MoveToState(FetchAddressRegisterIndirectWithDisplacement); + MoveToState(FetchAddressRegisterIndirectWithDisplacement_bw); case Mode::AddressRegisterIndirectWithIndex8bitDisplacement: - MoveToState(FetchAddressRegisterIndirectWithIndex8bitDisplacement); + MoveToState(FetchAddressRegisterIndirectWithIndex8bitDisplacement_bw); case Mode::ProgramCounterIndirectWithDisplacement: - MoveToState(FetchProgramCounterIndirectWithDisplacement); + MoveToState(FetchProgramCounterIndirectWithDisplacement_bw); case Mode::ProgramCounterIndirectWithIndex8bitDisplacement: - MoveToState(FetchProgramCounterIndirectWithIndex8bitDisplacement); + MoveToState(FetchProgramCounterIndirectWithIndex8bitDisplacement_bw); case Mode::AbsoluteShort: - MoveToState(FetchAbsoluteShort); + MoveToState(FetchAbsoluteShort_bw); case Mode::AbsoluteLong: - MoveToState(FetchAbsoluteLong); + MoveToState(FetchAbsoluteLong_bw); case Mode::ImmediateData: - MoveToState(FetchImmediateData); + MoveToState(FetchImmediateData_bw); // Should be impossible to reach. default: @@ -341,6 +354,71 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor } break; + // As above, but for .l. + BeginState(FetchOperand_l): + if(!(operand_flags_ & (1 << next_operand_))) { + state_ = perform_state_; + continue; + } + + switch(instruction_.mode(next_operand_)) { + case Mode::AddressRegisterDirect: + case Mode::DataRegisterDirect: + operand_[next_operand_] = registers_[instruction_.lreg(next_operand_)]; + MoveToNextOperand(FetchOperand_bw); + + case Mode::Quick: + operand_[next_operand_].l = InstructionSet::M68k::quick(opcode_, instruction_.operation); + MoveToNextOperand(FetchOperand_bw); + + case Mode::AddressRegisterIndirect: + MoveToState(FetchAddressRegisterIndirect_l); + case Mode::AddressRegisterIndirectWithPostincrement: + MoveToState(FetchAddressRegisterIndirectWithPostincrement_l); + case Mode::AddressRegisterIndirectWithPredecrement: + MoveToState(FetchAddressRegisterIndirectWithPredecrement_l); + case Mode::AddressRegisterIndirectWithDisplacement: + MoveToState(FetchAddressRegisterIndirectWithDisplacement_l); + case Mode::AddressRegisterIndirectWithIndex8bitDisplacement: + MoveToState(FetchAddressRegisterIndirectWithIndex8bitDisplacement_l); + case Mode::ProgramCounterIndirectWithDisplacement: + MoveToState(FetchProgramCounterIndirectWithDisplacement_l); + case Mode::ProgramCounterIndirectWithIndex8bitDisplacement: + MoveToState(FetchProgramCounterIndirectWithIndex8bitDisplacement_l); + case Mode::AbsoluteShort: + MoveToState(FetchAbsoluteShort_l); + case Mode::AbsoluteLong: + MoveToState(FetchAbsoluteLong_l); + case Mode::ImmediateData: + MoveToState(FetchImmediateData_l); + + // Should be impossible to reach. + default: + assert(false); + } + break; + + // MARK: - Fetch, addressing modes. + + BeginState(FetchAddressRegisterIndirect_bw): + effective_address_[next_operand_] = registers_[8 + instruction_.reg(next_operand_)].l; + + temporary_address_ = effective_address_[next_operand_]; + Access(operand_[next_operand_].low); // nr + MoveToNextOperand(FetchOperand_bw); + + BeginState(FetchAddressRegisterIndirect_l): + effective_address_[next_operand_] = registers_[8 + instruction_.reg(next_operand_)].l; + + temporary_address_ = effective_address_[next_operand_]; + Access(operand_[next_operand_].high); // nR + + temporary_address_ += 2; + Access(operand_[next_operand_].low); // nr + MoveToNextOperand(FetchOperand_l); + + // MARK: - Store. + // Store operand is a lot simpler: only one operand is ever stored, and its address // is already known. So this can either skip straight back to ::Decode if the target // is a register, otherwise a single write operation can occur. @@ -409,22 +487,30 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor #define TODOState(x) \ BeginState(x): [[fallthrough]]; - TODOState(FetchAddressRegisterIndirect); - TODOState(FetchAddressRegisterIndirectWithPostincrement); - TODOState(FetchAddressRegisterIndirectWithPredecrement); - TODOState(FetchAddressRegisterIndirectWithDisplacement); - TODOState(FetchAddressRegisterIndirectWithIndex8bitDisplacement); - TODOState(FetchProgramCounterIndirectWithDisplacement); - TODOState(FetchProgramCounterIndirectWithIndex8bitDisplacement); - TODOState(FetchAbsoluteShort); - TODOState(FetchAbsoluteLong); - TODOState(FetchImmediateData); - TODOState(FetchOperandl); + TODOState(FetchAddressRegisterIndirectWithPostincrement_bw); + TODOState(FetchAddressRegisterIndirectWithPredecrement_bw); + TODOState(FetchAddressRegisterIndirectWithDisplacement_bw); + TODOState(FetchAddressRegisterIndirectWithIndex8bitDisplacement_bw); + TODOState(FetchProgramCounterIndirectWithDisplacement_bw); + TODOState(FetchProgramCounterIndirectWithIndex8bitDisplacement_bw); + TODOState(FetchAbsoluteShort_bw); + TODOState(FetchAbsoluteLong_bw); + TODOState(FetchImmediateData_bw); + + TODOState(FetchAddressRegisterIndirectWithPostincrement_l); + TODOState(FetchAddressRegisterIndirectWithPredecrement_l); + TODOState(FetchAddressRegisterIndirectWithDisplacement_l); + TODOState(FetchAddressRegisterIndirectWithIndex8bitDisplacement_l); + TODOState(FetchProgramCounterIndirectWithDisplacement_l); + TODOState(FetchProgramCounterIndirectWithIndex8bitDisplacement_l); + TODOState(FetchAbsoluteShort_l); + TODOState(FetchAbsoluteLong_l); + TODOState(FetchImmediateData_l); #undef TODOState default: - printf("Unhandled state: %d\n", state_); + printf("Unhandled state: %d; opcode is %04x\n", state_, opcode_); assert(false); }}