From 1f585d67b6863f1f7cf903ed37d56f1d0df852b6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 19 Apr 2022 14:43:01 -0400 Subject: [PATCH] ADDA: correct decoding, add validation. --- InstructionSets/68k/Decoder.cpp | 60 +++++++++++++++------------------ 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/InstructionSets/68k/Decoder.cpp b/InstructionSets/68k/Decoder.cpp index 39c2bb980..6d58c62fb 100644 --- a/InstructionSets/68k/Decoder.cpp +++ b/InstructionSets/68k/Decoder.cpp @@ -155,6 +155,24 @@ template Preinstruction Predecoder::validated return Preinstruction(); } + switch(original.mode<1>()) { + default: return original; + + case AddressingMode::ImmediateData: + case AddressingMode::ProgramCounterIndirectWithDisplacement: + case AddressingMode::ProgramCounterIndirectWithIndex8bitDisplacement: + case AddressingMode::None: + return Preinstruction(); + } + + // ADDA. + case OpT(Operation::ADDAw): case OpT(Operation::ADDAl): + switch(original.mode<0>()) { + default: break; + case AddressingMode::None: + return Preinstruction(); + } + switch(original.mode<1>()) { default: return original; @@ -210,59 +228,37 @@ template Preinstruction Predecoder::decode(ui // b6–b8: an opmode, i.e. source + direction. // case OpT(Operation::ADDb): case OpT(Operation::ADDw): case OpT(Operation::ADDl): - case OpT(Operation::ADDAw): case OpT(Operation::ADDAl): case OpT(Operation::SUBb): case OpT(Operation::SUBw): case OpT(Operation::SUBl): + case OpT(Operation::ADDAw): case OpT(Operation::ADDAl): case OpT(Operation::SUBAw): case OpT(Operation::SUBAl): case OpT(Operation::CMPAw): case OpT(Operation::CMPAl): case OpT(Operation::ANDb): case OpT(Operation::ANDw): case OpT(Operation::ANDl): case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl): case OpT(Operation::EORb): case OpT(Operation::EORw): case OpT(Operation::EORl): { - // TODO: I strongly suspect that most of the potential exits to Preinstruction() - // below are completely unnecessary, being merely relics of the old method I applied - // to instruction decoding; I assume that all missing operation modes and addressing - // modes are actually caused by the instruction codes being otherwise allocated. - // Disabled for now. Will need to verify! - // Opmode 7 is illegal. -// if(opmode == 7) { -// return Preinstruction(); -// } - -// constexpr bool is_eor = -// operation == Operation::EORb || -// operation == Operation::EORw || -// operation == Operation::EORl; + constexpr bool is_address_operation = + op == OpT(Operation::ADDAw) || op == OpT(Operation::ADDAl) || + op == OpT(Operation::SUBAw) || op == OpT(Operation::SUBAl) || + op == OpT(Operation::CMPAw) || op == OpT(Operation::CMPAl); + constexpr auto register_addressing_mode = is_address_operation + ? AddressingMode::AddressRegisterDirect : AddressingMode::DataRegisterDirect; const auto ea_combined_mode = combined_mode(ea_mode, ea_register); - if(opmode & 4) { + if(!is_address_operation && (opmode & 4)) { // Dn Λ < ea > → < ea > - // The operations other than EOR do not permit - // to be a data register; targetting a data register - // should be achieved with the alternative opmode. -// if constexpr (!is_eor) { -// if(ea_combined_mode == AddressingMode::DataRegisterDirect) { -// return Preinstruction(); -// } -// } - return validated( Preinstruction(operation, - AddressingMode::DataRegisterDirect, data_register, + register_addressing_mode, data_register, ea_combined_mode, ea_register)); } else { // < ea > Λ Dn → Dn - // EOR doesn't permit → Dn. -// if constexpr (is_eor) { -// return Preinstruction(); -// } - return validated( Preinstruction(operation, ea_combined_mode, ea_register, - AddressingMode::DataRegisterDirect, data_register)); + register_addressing_mode, data_register)); } return Preinstruction();