diff --git a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp index 9db51f972..dddaf45e8 100644 --- a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp +++ b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp @@ -48,7 +48,6 @@ IntT Executor::read(uint32_t address, bool is_from_pc) { throw AccessException(code, address, Exception::AddressError | (int(is_from_pc) << 3) | (1 << 4)); } - // TODO: omit generation of the FunctionCode if the BusHandler doesn't receive it. return bus_handler_.template read(address, code); } @@ -120,11 +119,8 @@ typename Executor::EffectiveAddress Executor::EffectiveAddress Executor()); ea.requires_fetch = true; @@ -214,9 +207,7 @@ typename Executor::EffectiveAddress Executor::run(int &count) { // operands by default both: (i) because they might be values, // rather than addresses; and (ii) then they'll be there for use // by LEA and PEA. - // - // TODO: much of this work should be performed by a full Decoder, - // so that it can be cached. effective_address_[0] = calculate_effective_address(instruction, instruction_opcode_, 0); effective_address_[1] = calculate_effective_address(instruction, instruction_opcode_, 1); operand_[0] = effective_address_[0].value; operand_[1] = effective_address_[1].value; // Obtain the appropriate sequence. - // - // TODO: make a decision about whether this goes into a fully-decoded Instruction. const auto flags = operand_flags(instruction.operation); -// TODO: potential alignment exception, here and in store. #define fetch_operand(n) \ if(effective_address_[n].requires_fetch) { \ read(instruction.operand_size(), effective_address_[n].value.l, operand_[n]); \ @@ -344,14 +329,9 @@ void Executor::run(int &count) { perform(instruction, operand_[0], operand_[1], status_, *this); -// TODO: rephrase to avoid conditional below. #define store_operand(n) \ if(!effective_address_[n].requires_fetch) { \ - if(instruction.mode(n) == AddressingMode::DataRegisterDirect) { \ - Dn(instruction.reg(n)) = operand_[n]; \ - } else { \ - An(instruction.reg(n)) = operand_[n]; \ - } \ + registers_[instruction.lreg(n)] = operand_[n]; \ } else { \ write(instruction.operand_size(), effective_address_[n].value.l, operand_[n]); \ } diff --git a/InstructionSets/M68k/Instruction.hpp b/InstructionSets/M68k/Instruction.hpp index 58e0870d7..a016fac9c 100644 --- a/InstructionSets/M68k/Instruction.hpp +++ b/InstructionSets/M68k/Instruction.hpp @@ -278,7 +278,7 @@ class Preinstruction { // other than 0 and 1 are undefined. AddressingMode mode(int index) const { - return AddressingMode(operands_[index] & 0x1f); + return AddressingMode(operands_[index] >> 3); } template AddressingMode mode() const { if constexpr (index > 1) { @@ -287,7 +287,7 @@ class Preinstruction { return mode(index); } int reg(int index) const { - return operands_[index] >> 5; + return operands_[index] & 7; } template int reg() const { if constexpr (index > 1) { @@ -296,6 +296,13 @@ class Preinstruction { return reg(index); } + /// @returns 0–7 to indicate data registers 0 to 7, or 8–15 to indicate address registers 0 to 7 respectively. + /// Provides undefined results if the addressing mode is not either @c DataRegisterDirect or + /// @c AddressRegisterDirect. + int lreg(int index) const { + return operands_[index] & 0xf; + } + bool requires_supervisor() const { return flags_ & 0x80; } @@ -321,8 +328,8 @@ class Preinstruction { DataSize size, Condition condition) : operation(operation) { - operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5); - operands_[1] = uint8_t(op2_mode) | uint8_t(op2_reg << 5); + operands_[0] = uint8_t((uint8_t(op1_mode) << 3) | op1_reg); + operands_[1] = uint8_t((uint8_t(op2_mode) << 3) | op2_reg); flags_ = uint8_t( (is_supervisor ? 0x80 : 0x00) | (int(condition) << 2) |