mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +00:00
Muddles along to generating functions.
Albeit right now without a body.
This commit is contained in:
parent
10caa1a1fb
commit
cd6ac51aa6
@ -16,8 +16,9 @@ template <Operation operation> void Executor::perform(uint8_t *operand [[maybe_u
|
||||
template <Operation operation, AddressingMode addressing_mode> void Executor::perform(Executor *) {
|
||||
}
|
||||
|
||||
Executor::Action Executor::action_for(Instruction) {
|
||||
Action action;
|
||||
action.perform = &perform<Operation::ADC, AddressingMode::Immediate>;
|
||||
Executor::Action Executor::action_for(Instruction instruction) {
|
||||
Action action {
|
||||
.perform = performer_lookup_.performer(instruction.operation, instruction.addressing_mode)
|
||||
};
|
||||
return action;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define Executor_h
|
||||
|
||||
#include "Instruction.hpp"
|
||||
#include "Parser.hpp"
|
||||
|
||||
namespace InstructionSet {
|
||||
namespace M50740 {
|
||||
@ -23,7 +24,8 @@ class Executor {
|
||||
so using the Executor to enquire of memory and the program counter is sufficient.
|
||||
*/
|
||||
struct Action {
|
||||
void (* perform)(Executor *) = nullptr;
|
||||
using Performer = void (*)(Executor *);
|
||||
Performer perform = nullptr;
|
||||
};
|
||||
|
||||
Action action_for(Instruction);
|
||||
@ -38,6 +40,40 @@ class Executor {
|
||||
Performs @c operation in @c addressing_mode.
|
||||
*/
|
||||
template <Operation operation, AddressingMode addressing_mode> static void perform(Executor *);
|
||||
|
||||
/*!
|
||||
Provides dynamic lookup of @c perform(Executor*).
|
||||
*/
|
||||
class PerformerLookup {
|
||||
public:
|
||||
PerformerLookup() {
|
||||
fill<int(MinOperation), int(MinAddressingMode)>(performers);
|
||||
}
|
||||
|
||||
Action::Performer performer(Operation operation, AddressingMode addressing_mode) {
|
||||
return performers[int(addressing_mode) * (MaxOperation - MinOperation) + int(operation) - MinOperation];
|
||||
}
|
||||
|
||||
private:
|
||||
Action::Performer performers[(MaxAddressingMode - MinAddressingMode) * (MaxOperation - MinOperation)];
|
||||
|
||||
template<int operation, int addressing_mode> void fill_operation(Action::Performer *target) {
|
||||
*target = &Executor::perform<Operation(operation), AddressingMode(addressing_mode)>;
|
||||
if constexpr (addressing_mode+1 < MaxAddressingMode) {
|
||||
fill<operation, addressing_mode+1>(target + 1);
|
||||
}
|
||||
}
|
||||
|
||||
template<int operation, int addressing_mode> void fill(Action::Performer *target) {
|
||||
fill_operation<operation, addressing_mode>(target);
|
||||
target += MaxOperation - MinOperation;
|
||||
if constexpr (operation+1 < MaxOperation) {
|
||||
fill<operation+1, addressing_mode>(target);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline static PerformerLookup performer_lookup_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ enum class AddressingMode {
|
||||
Bit4ZeroPageRelative, Bit5ZeroPageRelative, Bit6ZeroPageRelative, Bit7ZeroPageRelative,
|
||||
};
|
||||
|
||||
static constexpr auto MaxAddressingMode = int(AddressingMode::Bit7ZeroPageRelative);
|
||||
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[] = {
|
||||
@ -58,6 +61,7 @@ constexpr int size(AddressingMode mode) {
|
||||
2, 2, 2, 2,
|
||||
2, 2, 2, 2,
|
||||
};
|
||||
static_assert(sizeof(sizes)/sizeof(*sizes) == int(MaxAddressingMode) + 1);
|
||||
return sizes[int(mode)];
|
||||
}
|
||||
|
||||
@ -99,6 +103,9 @@ enum class Operation: uint8_t {
|
||||
STA, STX, STY,
|
||||
};
|
||||
|
||||
static constexpr auto MaxOperation = int(Operation::STY);
|
||||
static constexpr auto MinOperation = int(Operation::BBC);
|
||||
|
||||
constexpr AccessType access_type(Operation operation) {
|
||||
if(operation < Operation::ADC) return AccessType::None;
|
||||
if(operation < Operation::ASL) return AccessType::Read;
|
||||
|
Loading…
Reference in New Issue
Block a user