1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-02 16:04:59 +00:00
CLK/InstructionSets/M68k/Decoder.hpp
2022-04-30 09:00:47 -04:00

117 lines
3.3 KiB
C++

//
// Decoder.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/04/2022.
// Copyright © 2022 Thomas Harte. All rights reserved.
//
#ifndef InstructionSets_M68k_Decoder_hpp
#define InstructionSets_M68k_Decoder_hpp
#include "Instruction.hpp"
#include "Model.hpp"
namespace InstructionSet {
namespace M68k {
/*!
A stateless decoder that can map from instruction words to preinstructions
(i.e. enough to know the operation and size, and either know the addressing mode
and registers or else know how many further extension words are needed).
WARNING: at present this handles the original 68000 instruction set only. It
requires a model only for the sake of not baking in assumptions about MOVE SR, etc,
and supporting extended addressing modes in some cases.
But it does not yet decode any operations which were not present on the 68000.
*/
template <Model model> class Predecoder {
public:
Preinstruction decode(uint16_t instruction);
private:
// Page by page decoders; each gets a bit ad hoc so
// it is neater to separate them.
Preinstruction decode0(uint16_t instruction);
Preinstruction decode1(uint16_t instruction);
Preinstruction decode2(uint16_t instruction);
Preinstruction decode3(uint16_t instruction);
Preinstruction decode4(uint16_t instruction);
Preinstruction decode5(uint16_t instruction);
Preinstruction decode6(uint16_t instruction);
Preinstruction decode7(uint16_t instruction);
Preinstruction decode8(uint16_t instruction);
Preinstruction decode9(uint16_t instruction);
Preinstruction decodeA(uint16_t instruction);
Preinstruction decodeB(uint16_t instruction);
Preinstruction decodeC(uint16_t instruction);
Preinstruction decodeD(uint16_t instruction);
Preinstruction decodeE(uint16_t instruction);
Preinstruction decodeF(uint16_t instruction);
using OpT = uint8_t;
// Specific instruction decoders.
template <OpT operation, bool validate = true> Preinstruction decode(uint16_t instruction);
template <OpT operation, bool validate> Preinstruction validated(
AddressingMode op1_mode = AddressingMode::None, int op1_reg = 0,
AddressingMode op2_mode = AddressingMode::None, int op2_reg = 0,
Condition condition = Condition::True
);
template <uint8_t op> uint32_t invalid_operands();
// Extended operation list; collapses into a single byte enough information to
// know both the type of operation and how to decode the operands. Most of the
// time that's knowable from the Operation alone, hence the rather awkward
// extension of @c Operation.
enum ExtendedOperation: OpT {
MOVEMtoRl = uint8_t(Operation::Max) + 1, MOVEMtoRw,
MOVEMtoMl, MOVEMtoMw,
MOVEPtoRl, MOVEPtoRw,
MOVEPtoMl, MOVEPtoMw,
MOVEQ,
ADDQb, ADDQw, ADDQl,
ADDQAw, ADDQAl,
SUBQb, SUBQw, SUBQl,
SUBQAw, SUBQAl,
ADDIb, ADDIw, ADDIl,
ORIb, ORIw, ORIl,
SUBIb, SUBIw, SUBIl,
ANDIb, ANDIw, ANDIl,
EORIb, EORIw, EORIl,
CMPIb, CMPIw, CMPIl,
BTSTI, BCHGI, BCLRI, BSETI,
CMPMb, CMPMw, CMPMl,
MOVEq,
ADDtoMb, ADDtoMw, ADDtoMl,
ADDtoRb, ADDtoRw, ADDtoRl,
SUBtoMb, SUBtoMw, SUBtoMl,
SUBtoRb, SUBtoRw, SUBtoRl,
ANDtoMb, ANDtoMw, ANDtoMl,
ANDtoRb, ANDtoRw, ANDtoRl,
ORtoMb, ORtoMw, ORtoMl,
ORtoRb, ORtoRw, ORtoRl,
EXGRtoR, EXGAtoA, EXGRtoA,
};
static constexpr Operation operation(OpT op);
};
}
}
#endif /* InstructionSets_M68k_Decoder_hpp */