diff --git a/InstructionSets/68k/Decoder.cpp b/InstructionSets/68k/Decoder.cpp index 28eb5ac25..74cc72c9a 100644 --- a/InstructionSets/68k/Decoder.cpp +++ b/InstructionSets/68k/Decoder.cpp @@ -80,6 +80,10 @@ constexpr Operation Predecoder::operation(OpT op) { case BCLRI: return Operation::BCLR; case BSETI: return Operation::BSET; + case CMPMb: return Operation::CMPb; + case CMPMw: return Operation::CMPw; + case CMPMl: return Operation::CMPl; + #define ImmediateGroup(x) \ case x##Ib: return Operation::x##b; \ case x##Iw: return Operation::x##w; \ @@ -179,13 +183,12 @@ template Preinstruction Predecoder::validated case OpT(Operation::MOVEAw): case OpT(Operation::MOVEAl): case OpT(Operation::ANDb): case OpT(Operation::ANDw): case OpT(Operation::ANDl): case OpT(Operation::EORb): case OpT(Operation::EORw): case OpT(Operation::EORl): - case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl): - case OpT(Operation::NOTb): case OpT(Operation::NOTw): case OpT(Operation::NOTl): { + case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl): { // TODO: I'm going to need get-size-by-operation elsewhere; use that here when implemented. constexpr bool is_byte = op == OpT(Operation::ADDb) || op == OpT(Operation::SUBb) || op == OpT(Operation::MOVEb) || op == ADDQb || op == SUBQb || op == OpT(Operation::ANDb) || op == OpT(Operation::EORb) || - op == OpT(Operation::ORb) || op == OpT(Operation::NOTb); + op == OpT(Operation::ORb); switch(original.mode<0>()) { default: break; @@ -214,6 +217,18 @@ template Preinstruction Predecoder::validated } } + case OpT(Operation::NOTb): case OpT(Operation::NOTw): case OpT(Operation::NOTl): + switch(original.mode<0>()) { + default: return original; + + case AddressingMode::AddressRegisterDirect: + case AddressingMode::ImmediateData: + case AddressingMode::ProgramCounterIndirectWithDisplacement: + case AddressingMode::ProgramCounterIndirectWithIndex8bitDisplacement: + case AddressingMode::None: + return Preinstruction(); + } + // ADDA, SUBA. case OpT(Operation::ADDAw): case OpT(Operation::ADDAl): case OpT(Operation::SUBAw): case OpT(Operation::SUBAl): @@ -787,6 +802,12 @@ template Preinstruction Predecoder::decode(ui Preinstruction(operation, combined_mode(ea_mode, ea_register), ea_register)); + case CMPMb: case CMPMw: case CMPMl: + return validated( + Preinstruction(operation, + AddressingMode::AddressRegisterIndirectWithPostincrement, ea_register, + AddressingMode::AddressRegisterIndirectWithPostincrement, data_register)); + // // MARK: Impossible error case. // @@ -1157,6 +1178,15 @@ template Preinstruction Predecoder::decodeB(uint16_t instruction) { using Op = Operation; + switch(instruction & 0x1f8) { + // 4-81 (p185) + case 0x108: Decode(CMPMb); + case 0x148: Decode(CMPMw); + case 0x188: Decode(CMPMl); + + default: break; + } + switch(instruction & 0x1c0) { // 4-75 (p179) case 0x000: Decode(Op::CMPb); diff --git a/InstructionSets/68k/Decoder.hpp b/InstructionSets/68k/Decoder.hpp index aca6bd70a..4de51d792 100644 --- a/InstructionSets/68k/Decoder.hpp +++ b/InstructionSets/68k/Decoder.hpp @@ -75,6 +75,8 @@ template class Predecoder { BTSTI, BCHGI, BCLRI, BSETI, + CMPMb, CMPMw, CMPMl, + MOVEq, }; diff --git a/OSBindings/Mac/Clock SignalTests/m68kDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/m68kDecoderTests.mm index 4381ad5de..21a52bcdd 100644 --- a/OSBindings/Mac/Clock SignalTests/m68kDecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/m68kDecoderTests.mm @@ -225,21 +225,21 @@ template NSString *operand(Preinstruction instruction, uint16_t opco case Operation::MOVEPl: instruction = @"MOVEP.l"; break; case Operation::MOVEPw: instruction = @"MOVEP.w"; break; - case Operation::ANDb: instruction = @"AND.b"; break; - case Operation::ANDw: instruction = @"AND.w"; break; - case Operation::ANDl: instruction = @"AND.l"; break; - - case Operation::EORb: instruction = @"EOR.b"; break; - case Operation::EORw: instruction = @"EOR.w"; break; - case Operation::EORl: instruction = @"EOR.l"; break; +// case Operation::ANDb: instruction = @"AND.b"; break; +// case Operation::ANDw: instruction = @"AND.w"; break; +// case Operation::ANDl: instruction = @"AND.l"; break; +// +// case Operation::EORb: instruction = @"EOR.b"; break; +// case Operation::EORw: instruction = @"EOR.w"; break; +// case Operation::EORl: instruction = @"EOR.l"; break; case Operation::NOTb: instruction = @"NOT.b"; break; case Operation::NOTw: instruction = @"NOT.w"; break; case Operation::NOTl: instruction = @"NOT.l"; break; - case Operation::ORb: instruction = @"OR.b"; break; - case Operation::ORw: instruction = @"OR.w"; break; - case Operation::ORl: instruction = @"OR.l"; break; +// case Operation::ORb: instruction = @"OR.b"; break; +// case Operation::ORw: instruction = @"OR.w"; break; +// case Operation::ORl: instruction = @"OR.l"; break; /* TODO: