1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-19 08:31:11 +00:00
CLK/InstructionSets/M50740/Instruction.hpp
2021-01-21 23:13:00 -05:00

124 lines
2.9 KiB
C++

//
// Instruction.hpp
// Clock Signal
//
// Created by Thomas Harte on 15/01/21.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef InstructionSets_M50740_Instruction_h
#define InstructionSets_M50740_Instruction_h
#include <cstdint>
#include "../AccessType.hpp"
namespace InstructionSet {
namespace M50740 {
enum class AddressingMode {
Implied, Accumulator, Immediate,
Absolute, AbsoluteX, AbsoluteY,
ZeroPage, ZeroPageX, ZeroPageY,
XIndirect, IndirectY,
Relative,
AbsoluteIndirect, ZeroPageIndirect,
SpecialPage,
ImmediateZeroPage,
AccumulatorRelative, ZeroPageRelative
};
static constexpr auto MaxAddressingMode = int(AddressingMode::ZeroPageRelative);
static constexpr auto MinAddressingMode = int(AddressingMode::Implied);
constexpr int size(AddressingMode mode) {
// This is coupled to the AddressingMode list above; be careful!
constexpr int sizes[] = {
0, 0, 1,
2, 2, 2,
1, 1, 1,
1, 1,
1,
2, 1,
1,
2,
1, 2
};
static_assert(sizeof(sizes)/sizeof(*sizes) == int(MaxAddressingMode) + 1);
return sizes[int(mode)];
}
enum class Operation: uint8_t {
Invalid,
// Operations that don't access memory.
BBC0, BBC1, BBC2, BBC3, BBC4, BBC5, BBC6, BBC7,
BBS0, BBS1, BBS2, BBS3, BBS4, BBS5, BBS6, BBS7,
BCC, BCS,
BEQ, BMI, BNE, BPL,
BVC, BVS, BRA, BRK,
JMP, JSR,
RTI, RTS,
CLC, CLD, CLI, CLT, CLV,
SEC, SED, SEI, SET,
INX, INY, DEX, DEY,
FST, SLW,
NOP,
PHA, PHP, PLA, PLP,
STP,
TAX, TAY, TSX, TXA,
TXS, TYA,
// Read operations.
ADC, SBC,
AND, ORA, EOR, BIT,
CMP, CPX, CPY,
LDA, LDX, LDY,
TST,
// Read-modify-write operations.
ASL, LSR,
CLB0, CLB1, CLB2, CLB3, CLB4, CLB5, CLB6, CLB7,
SEB0, SEB1, SEB2, SEB3, SEB4, SEB5, SEB6, SEB7,
COM,
DEC, INC,
ROL, ROR, RRF,
// Write operations.
LDM,
STA, STX, STY,
};
static constexpr auto MaxOperation = int(Operation::STY);
static constexpr auto MinOperation = int(Operation::BBC0);
constexpr AccessType access_type(Operation operation) {
if(operation < Operation::ADC) return AccessType::None;
if(operation < Operation::ASL) return AccessType::Read;
if(operation < Operation::LDM) return AccessType::Write;
return AccessType::ReadModifyWrite;
}
constexpr bool uses_index_mode(Operation operation) {
return
operation == Operation::ADC || operation == Operation::AND ||
operation == Operation::CMP || operation == Operation::EOR ||
operation == Operation::LDA || operation == Operation::ORA ||
operation == Operation::SBC;
}
struct Instruction {
Operation operation = Operation::Invalid;
AddressingMode addressing_mode = AddressingMode::Implied;
uint8_t opcode = 0;
Instruction(Operation operation, AddressingMode addressing_mode, uint8_t opcode) : operation(operation), addressing_mode(addressing_mode), opcode(opcode) {}
Instruction(uint8_t opcode) : opcode(opcode) {}
Instruction() {}
};
}
}
#endif /* InstructionSets_M50740_Instruction_h */