From 64586ca7bad40c7a4fc5ea34b4aedd774b592419 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 4 May 2022 20:57:22 -0400 Subject: [PATCH] Implement BTST/etc. --- .../Implementation/PerformImplementation.hpp | 79 +++++++------------ InstructionSets/M68k/Instruction.hpp | 2 + 2 files changed, 29 insertions(+), 52 deletions(-) diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index 90a87dcc4..9a07b31f5 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -26,18 +26,6 @@ namespace M68k { x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); \ x = ((x & 0xff00) >> 8) + (x & 0x00ff); -// TODO: decisions outstanding: -// -// (1) should I reintroduce the BTSTl/BTSTw-type distinctions, given that the only way to -// determine them otherwise is by operand types and I'm hoping to treat data into -// here as a black box? -// -// (2) to what extent, if any, should this function have responsibility for a MOVEM, MOVEP, -// etc? This factoring is inteded to separate the bus interface from internal logic so -// is there much to do here in any case? As currently drafted, something else will -// already have had to check the operation and cue up data. -// - template < Model model, typename FlowController, @@ -227,50 +215,37 @@ template < dest.l -= src.l; break; - // Two BTSTs: set the zero flag according to the value of the destination masked by - // the bit named in the source modulo the operation size. -// case Operation::BTSTb: -// status.zero_result_ = dest.l & (1 << (src.l & 7)); -// break; -// -// case Operation::BTSTl: -// zero_result_ = dest.l & (1 << (src.l & 31)); -// break; -// -// case Operation::BCLRb: -// zero_result_ = dest.l & (1 << (src.l & 7)); -// dest.l &= ~(1 << (src.l & 7)); -// break; -// -// case Operation::BCLRl: -// zero_result_ = dest.l & (1 << (src.l & 31)); -// dest.l &= ~(1 << (src.l & 31)); -// + // BTST/BCLR/etc: modulo for the mask depends on whether memory or a data register is the target. + case Operation::BTST: { + const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; + status.zero_result_ = dest.l & (1 << (src.l & mask)); + } break; + + case Operation::BCLR: { + const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; + + status.zero_result_ = dest.l & (1 << (src.l & mask)); + dest.l &= ~(1 << (src.l & mask)); + // // Clearing in the top word requires an extra four cycles. // set_next_microcycle_length(HalfCycles(8 + ((src.l & 31) / 16) * 4)); -// break; -// -// case Operation::BCHGl: -// zero_result_ = dest.l & (1 << (src.l & 31)); -// dest.l ^= 1 << (src.l & 31); + } break; + + case Operation::BCHG: { + const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; + + status.zero_result_ = dest.l & (1 << (src.l & mask)); + dest.l ^= 1 << (src.l & mask); // set_next_microcycle_length(HalfCycles(4 + (((src.l & 31) / 16) * 4))); -// break; -// -// case Operation::BCHGb: -// zero_result_ = dest.b & (1 << (src.l & 7)); -// dest.b ^= 1 << (src.l & 7); -// break; -// -// case Operation::BSETl: -// zero_result_ = dest.l & (1 << (src.l & 31)); -// dest.l |= 1 << (src.l & 31); + } break; + + case Operation::BSET: { + const uint32_t mask = (instruction.mode<1>() == AddressingMode::DataRegisterDirect) ? 31 : 7; + + status.zero_result_ = dest.l & (1 << (src.l & mask)); + dest.l |= 1 << (src.l & mask); // set_next_microcycle_length(HalfCycles(4 + (((src.l & 31) / 16) * 4))); -// break; -// -// case Operation::BSETb: -// zero_result_ = dest.b & (1 << (src.l & 7)); -// dest.b |= 1 << (src.l & 7); -// break; + } break; // Bcc: ordinarily evaluates the relevant condition and displacement size and then: // if condition is false, schedules bus operations to get past this instruction; diff --git a/InstructionSets/M68k/Instruction.hpp b/InstructionSets/M68k/Instruction.hpp index ff842c7d3..591ffacef 100644 --- a/InstructionSets/M68k/Instruction.hpp +++ b/InstructionSets/M68k/Instruction.hpp @@ -348,6 +348,8 @@ template uint8_t ope case Operation::RORb: case Operation::RORw: case Operation::RORl: case Operation::ROXLb: case Operation::ROXLw: case Operation::ROXLl: case Operation::ROXRb: case Operation::ROXRw: case Operation::ROXRl: + case Operation::BTST: case Operation::BCHG: + case Operation::BCLR: case Operation::BSET: return FetchOp1 | FetchOp2 | StoreOp2; //