mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
ADDA: correct decoding, add validation.
This commit is contained in:
parent
5b22e94a4b
commit
1f585d67b6
@ -155,6 +155,24 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
|||||||
return Preinstruction();
|
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>()) {
|
switch(original.mode<1>()) {
|
||||||
default: return original;
|
default: return original;
|
||||||
|
|
||||||
@ -210,59 +228,37 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
|
|||||||
// b6–b8: an opmode, i.e. source + direction.
|
// b6–b8: an opmode, i.e. source + direction.
|
||||||
//
|
//
|
||||||
case OpT(Operation::ADDb): case OpT(Operation::ADDw): case OpT(Operation::ADDl):
|
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::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::SUBAw): case OpT(Operation::SUBAl):
|
||||||
case OpT(Operation::CMPAw): case OpT(Operation::CMPAl):
|
case OpT(Operation::CMPAw): case OpT(Operation::CMPAl):
|
||||||
case OpT(Operation::ANDb): case OpT(Operation::ANDw): case OpT(Operation::ANDl):
|
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::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl):
|
||||||
case OpT(Operation::EORb): case OpT(Operation::EORw): case OpT(Operation::EORl): {
|
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.
|
constexpr bool is_address_operation =
|
||||||
// if(opmode == 7) {
|
op == OpT(Operation::ADDAw) || op == OpT(Operation::ADDAl) ||
|
||||||
// return Preinstruction();
|
op == OpT(Operation::SUBAw) || op == OpT(Operation::SUBAl) ||
|
||||||
// }
|
op == OpT(Operation::CMPAw) || op == OpT(Operation::CMPAl);
|
||||||
|
constexpr auto register_addressing_mode = is_address_operation
|
||||||
// constexpr bool is_eor =
|
? AddressingMode::AddressRegisterDirect : AddressingMode::DataRegisterDirect;
|
||||||
// operation == Operation::EORb ||
|
|
||||||
// operation == Operation::EORw ||
|
|
||||||
// operation == Operation::EORl;
|
|
||||||
|
|
||||||
const auto ea_combined_mode = combined_mode(ea_mode, ea_register);
|
const auto ea_combined_mode = combined_mode(ea_mode, ea_register);
|
||||||
|
|
||||||
if(opmode & 4) {
|
if(!is_address_operation && (opmode & 4)) {
|
||||||
// Dn Λ < ea > → < ea >
|
// Dn Λ < ea > → < ea >
|
||||||
|
|
||||||
// The operations other than EOR do not permit <ea>
|
|
||||||
// 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<op, validate>(
|
return validated<op, validate>(
|
||||||
Preinstruction(operation,
|
Preinstruction(operation,
|
||||||
AddressingMode::DataRegisterDirect, data_register,
|
register_addressing_mode, data_register,
|
||||||
ea_combined_mode, ea_register));
|
ea_combined_mode, ea_register));
|
||||||
} else {
|
} else {
|
||||||
// < ea > Λ Dn → Dn
|
// < ea > Λ Dn → Dn
|
||||||
|
|
||||||
// EOR doesn't permit → Dn.
|
|
||||||
// if constexpr (is_eor) {
|
|
||||||
// return Preinstruction();
|
|
||||||
// }
|
|
||||||
|
|
||||||
return validated<op, validate>(
|
return validated<op, validate>(
|
||||||
Preinstruction(operation,
|
Preinstruction(operation,
|
||||||
ea_combined_mode, ea_register,
|
ea_combined_mode, ea_register,
|
||||||
AddressingMode::DataRegisterDirect, data_register));
|
register_addressing_mode, data_register));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Preinstruction();
|
return Preinstruction();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user