2021-01-17 01:51:02 +00:00
|
|
|
//
|
|
|
|
// Executor.h
|
|
|
|
// Clock Signal
|
|
|
|
//
|
2021-01-17 03:09:19 +00:00
|
|
|
// Created by Thomas Harte on 16/01/21.
|
2021-01-17 01:51:02 +00:00
|
|
|
// Copyright © 2021 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef Executor_h
|
|
|
|
#define Executor_h
|
|
|
|
|
|
|
|
#include "Instruction.hpp"
|
2021-01-17 02:45:44 +00:00
|
|
|
#include "Parser.hpp"
|
2021-01-17 03:06:16 +00:00
|
|
|
#include "../CachingExecutor.hpp"
|
2021-01-17 01:51:02 +00:00
|
|
|
|
|
|
|
namespace InstructionSet {
|
|
|
|
namespace M50740 {
|
|
|
|
|
|
|
|
class Executor;
|
|
|
|
|
2021-01-18 16:20:45 +00:00
|
|
|
class Executor: public CachingExecutor<Executor, 0x2000, 256, void> {
|
2021-01-17 01:51:02 +00:00
|
|
|
public:
|
2021-01-18 01:03:36 +00:00
|
|
|
Executor();
|
2021-01-17 01:51:02 +00:00
|
|
|
|
2021-01-17 03:06:16 +00:00
|
|
|
private:
|
2021-01-18 01:03:36 +00:00
|
|
|
// MARK: - CachingExecutor-facing interface.
|
|
|
|
|
2021-01-18 16:20:45 +00:00
|
|
|
friend CachingExecutor<Executor, 0x2000, 256, void>;
|
2021-01-17 01:51:02 +00:00
|
|
|
|
|
|
|
/*!
|
2021-01-18 01:03:36 +00:00
|
|
|
Maps instructions to performers; called by the CachingExecutor and for this instruction set, extremely trivial.
|
2021-01-17 01:51:02 +00:00
|
|
|
*/
|
2021-01-18 01:03:36 +00:00
|
|
|
inline PerformerIndex action_for(Instruction instruction) {
|
|
|
|
// This is a super-simple processor, so the opcode can be used directly to index the performers.
|
|
|
|
return instruction.opcode;
|
|
|
|
}
|
2021-01-17 01:51:02 +00:00
|
|
|
|
2021-01-18 01:03:36 +00:00
|
|
|
private:
|
|
|
|
// MARK: - Internal framework for generator performers.
|
2021-01-17 02:45:44 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Provides dynamic lookup of @c perform(Executor*).
|
|
|
|
*/
|
|
|
|
class PerformerLookup {
|
|
|
|
public:
|
|
|
|
PerformerLookup() {
|
|
|
|
fill<int(MinOperation), int(MinAddressingMode)>(performers);
|
|
|
|
}
|
|
|
|
|
2021-01-18 01:53:11 +00:00
|
|
|
Performer performer(Operation operation, AddressingMode addressing_mode) {
|
2021-01-17 02:45:44 +00:00
|
|
|
return performers[int(addressing_mode) * (MaxOperation - MinOperation) + int(operation) - MinOperation];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2021-01-18 01:53:11 +00:00
|
|
|
Performer performers[(MaxAddressingMode - MinAddressingMode) * (MaxOperation - MinOperation)];
|
2021-01-17 02:45:44 +00:00
|
|
|
|
2021-01-18 01:53:11 +00:00
|
|
|
template<int operation, int addressing_mode> void fill_operation(Performer *target) {
|
2021-01-17 02:45:44 +00:00
|
|
|
*target = &Executor::perform<Operation(operation), AddressingMode(addressing_mode)>;
|
|
|
|
if constexpr (addressing_mode+1 < MaxAddressingMode) {
|
2021-01-17 02:50:48 +00:00
|
|
|
fill_operation<operation, addressing_mode+1>(target + 1);
|
2021-01-17 02:45:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-18 01:53:11 +00:00
|
|
|
template<int operation, int addressing_mode> void fill(Performer *target) {
|
2021-01-17 02:45:44 +00:00
|
|
|
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_;
|
2021-01-18 01:03:36 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Performs @c operation using @c operand as the value fetched from memory, if any.
|
|
|
|
*/
|
2021-01-18 01:53:11 +00:00
|
|
|
template <Operation operation> void perform(uint8_t *operand);
|
2021-01-18 01:03:36 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Performs @c operation in @c addressing_mode.
|
|
|
|
*/
|
2021-01-18 01:53:11 +00:00
|
|
|
template <Operation operation, AddressingMode addressing_mode> void perform();
|
2021-01-18 01:03:36 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
// MARK: - Instruction set state.
|
2021-01-18 01:53:11 +00:00
|
|
|
|
|
|
|
// Memory.
|
2021-01-17 03:06:16 +00:00
|
|
|
uint8_t memory_[0x2000];
|
2021-01-18 01:53:11 +00:00
|
|
|
|
|
|
|
// Registers.
|
|
|
|
uint8_t a_, x_, y_;
|
2021-01-17 01:51:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* Executor_h */
|