From cb0e259339dffb667f1f9c64e4cc4364ce720c68 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 21 Oct 2022 15:28:29 -0400 Subject: [PATCH] Start the process of decoding 68020 operations. --- InstructionSets/M68k/Decoder.cpp | 76 ++++++++++++++++++- .../Implementation/InstructionOperandSize.hpp | 4 + InstructionSets/M68k/Instruction.hpp | 38 +++++++++- 3 files changed, 115 insertions(+), 3 deletions(-) diff --git a/InstructionSets/M68k/Decoder.cpp b/InstructionSets/M68k/Decoder.cpp index e63f29f6a..35ac44cfd 100644 --- a/InstructionSets/M68k/Decoder.cpp +++ b/InstructionSets/M68k/Decoder.cpp @@ -316,6 +316,7 @@ template uint32_t Predecoder::invalid_operands() { case OpT(Operation::Bccb): case OpT(Operation::BSRb): case OpT(Operation::TRAP): + case OpT(Operation::BKPT): return ~OneOperandMask< Quick >::value; @@ -335,6 +336,20 @@ template uint32_t Predecoder::invalid_operands() { AllModesNoAn >::value; + case OpT(Operation::BFCHG): case OpT(Operation::BFCLR): case OpT(Operation::BFSET): + case OpT(Operation::BFINS): + return ~TwoOperandMask< + Imm, + Dn | Ind | d16An | d8AnXn | XXXw | XXXl + >::value; + + case OpT(Operation::BFTST): case OpT(Operation::BFFFO): case OpT(Operation::BFEXTU): + case OpT(Operation::BFEXTS): + return ~TwoOperandMask< + Imm, + Dn | Ind | d16An | d8AnXn | XXXw | XXXl | d16PC | d8PCXn + >::value; + case CMPIb: case CMPIl: case CMPIw: if constexpr (model == Model::M68000) { return ~TwoOperandMask< @@ -421,6 +436,16 @@ template uint32_t Predecoder::invalid_operands() { Dn >::value; + case OpT(Operation::RTD): + return ~OneOperandMask< + Imm + >::value; + + case OpT(Operation::CALLM): + return ~OneOperandMask< + ControlAddressingModes + >::value; + case OpT(Operation::JMP): case OpT(Operation::JSR): case OpT(Operation::PEA): @@ -802,10 +827,11 @@ template Preinstruction Predecoder::decode(ui combined_mode(ea_mode, ea_register), ea_register); // - // MARK: TRAP, BCCb, BSRb + // MARK: TRAP, BCCb, BSRb, BKPT // - // No further operands decoded, but note that one is somewhere in the opcode. + // No further operands decoded, but one is somewhere in the opcode. // + case OpT(Operation::BKPT): case OpT(Operation::TRAP): case OpT(Operation::BSRb): return validated(AddressingMode::Quick); @@ -858,6 +884,7 @@ template Preinstruction Predecoder::decode(ui // b0–b2: a register to shift (the source here, for consistency with the memory operations); // b8: 0 => b9–b11 are a direct count of bits to shift; 1 => b9–b11 identify a register containing the shift count; // b9–b11: either a quick value or a register. + // case OpT(Operation::ASRb): case OpT(Operation::ASRw): case OpT(Operation::ASRl): case OpT(Operation::LSRb): case OpT(Operation::LSRw): case OpT(Operation::LSRl): case OpT(Operation::ROXRb): case OpT(Operation::ROXRw): case OpT(Operation::ROXRl): @@ -886,6 +913,36 @@ template Preinstruction Predecoder::decode(ui AddressingMode::AddressRegisterIndirectWithPostincrement, ea_register, AddressingMode::AddressRegisterIndirectWithPostincrement, data_register); + // + // MARK: BFCHG, BFTST, BFFFO, BFEXTU, BFEXTS, BFCLR, BFSET, BFINS + // + // b0–b2 and b3–b5: an effective address. + // There is also an immedate operand describing an offset and width. + // + case OpT(Operation::BFCHG): case OpT(Operation::BFTST): case OpT(Operation::BFFFO): + case OpT(Operation::BFEXTU): case OpT(Operation::BFEXTS): case OpT(Operation::BFCLR): + case OpT(Operation::BFSET): case OpT(Operation::BFINS): + return validated( + AddressingMode::ImmediateData, 0, + combined_mode(ea_mode, ea_register), ea_register); + + // + // MARK: CALLM + // + // b0–b2 and b3–b5: an effective address. + // There is also an immedate operand providing argument count. + // + case OpT(Operation::CALLM): + return validated( + AddressingMode::ImmediateData, 0, + combined_mode(ea_mode, ea_register), ea_register); + + // + // MARK: RTD + // + case OpT(Operation::RTD): + return validated(AddressingMode::ImmediateData); + // // MARK: Impossible error case. // @@ -898,6 +955,7 @@ template Preinstruction Predecoder::decode(ui // MARK: - Page decoders. #define Decode(y) return decode(instruction) +#define DecodeReq(x, y) if constexpr (x) Decode(y); break; template Preinstruction Predecoder::decode0(uint16_t instruction) { @@ -957,6 +1015,8 @@ Preinstruction Predecoder::decode0(uint16_t instruction) { case 0xc40: Decode(CMPIw); case 0xc80: Decode(CMPIl); + case 0x6c0: DecodeReq(model == Model::M68020, Op::CALLM); // 4-64 (p168) + default: break; } @@ -1023,6 +1083,7 @@ Preinstruction Predecoder::decode4(uint16_t instruction) { case 0xe71: Decode(Op::NOP); // 4-147 (p251) case 0xe72: Decode(Op::STOP); // 6-85 (p539) case 0xe73: Decode(Op::RTE); // 6-84 (p538) + case 0xe74: DecodeReq(model >= Model::M68010, Op::RTD); // 4-166 (p270) case 0xe75: Decode(Op::RTS); // 4-169 (p273) case 0xe76: Decode(Op::TRAPV); // 4-191 (p295) case 0xe77: Decode(Op::RTR); // 4-168 (p272) @@ -1031,6 +1092,7 @@ Preinstruction Predecoder::decode4(uint16_t instruction) { switch(instruction & 0xff8) { case 0x840: Decode(Op::SWAP); // 4-185 (p289) + case 0x848: DecodeReq(model >= Model::M68010, Op::BKPT); // 4-54 (p158) case 0x880: Decode(Op::EXTbtow); // 4-106 (p210) case 0x8c0: Decode(Op::EXTwtol); // 4-106 (p210) case 0xe50: Decode(Op::LINKw); // 4-111 (p215) @@ -1399,6 +1461,15 @@ Preinstruction Predecoder::decodeE(uint16_t instruction) { case 0x6c0: Decode(Op::RORm); // 4-160 (p264) case 0x7c0: Decode(Op::ROLm); // 4-160 (p264) + case 0x8c0: DecodeReq(model >= Model::M68020, Op::BFTST); // 4-51 (p155) + case 0x9c0: DecodeReq(model >= Model::M68020, Op::BFFFO); // 4-43 (p147) + case 0xac0: DecodeReq(model >= Model::M68020, Op::BFCHG); // 4-33 (p137) + case 0xbc0: DecodeReq(model >= Model::M68020, Op::BFEXTS); // 4-37 (p141) + case 0xcc0: DecodeReq(model >= Model::M68020, Op::BFCLR); // 4-35 (p139) + case 0xdc0: DecodeReq(model >= Model::M68020, Op::BFEXTU); // 4-40 (p144) [though the given opcode is wrong] + case 0xec0: DecodeReq(model >= Model::M68020, Op::BFSET); // 4-49 (p153) + case 0xfc0: DecodeReq(model >= Model::M68020, Op::BFINS); // 4-46 (p150) + default: break; } @@ -1455,6 +1526,7 @@ Preinstruction Predecoder::decodeF(uint16_t) { } #undef Decode +#undef DecodeRef // MARK: - Main decoder. diff --git a/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp b/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp index 67242e522..ff3f07b53 100644 --- a/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp +++ b/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp @@ -112,6 +112,10 @@ constexpr DataSize operand_size(Operation r_operation) { case Operation::EXTwtol: case Operation::UNLINK: return DataSize::LongWord; + + default: + // 68020 TODO. + return DataSize::Byte; } } diff --git a/InstructionSets/M68k/Instruction.hpp b/InstructionSets/M68k/Instruction.hpp index de3871762..1ef7cf7cf 100644 --- a/InstructionSets/M68k/Instruction.hpp +++ b/InstructionSets/M68k/Instruction.hpp @@ -21,6 +21,10 @@ namespace M68k { enum class Operation: uint8_t { Undefined, + // + // 68000 operations. + // + NOP, ABCD, SBCD, NBCD, @@ -101,7 +105,38 @@ enum class Operation: uint8_t { STOP, RESET, - Max = RESET + // + // 68020 additions. + // + BKPT, + + BFCHG, BFCLR, + BFEXTS, BFEXTU, + BFFFO, BFINS, + BFSET, BFTST, + + CALLM, RTD, RTM, + + CAS, CAS2, + CHK2, CMP2, + + DIVSL, + EXTbtol, + PACK, UNPK, + + TRAPcc, + + cpBcc, cpDBcc, cpGEN, + cpScc, cpTRAPcc, cpRESTORE, + cpSAVE, + + MOVEfromCCR, + MOVEC, MOVES, + + // + // Introspection. + // + Max = MOVES }; const char *to_string(Operation op); @@ -147,6 +182,7 @@ constexpr uint32_t quick(uint16_t instruction, Operation r_op = Operation::Undef case Operation::BSRb: case Operation::MOVEl: return uint32_t(int8_t(instruction)); case Operation::TRAP: return uint32_t(instruction & 15); + case Operation::BKPT: return uint32_t(instruction & 7); default: { uint32_t value = (instruction >> 9) & 7; value |= (value - 1)&8;