1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Completes the M50740 decoder.

Completely untested.
This commit is contained in:
Thomas Harte 2021-01-15 22:47:52 -05:00
parent 2910faf963
commit 37a20e125c
3 changed files with 58 additions and 19 deletions

View File

@ -8,6 +8,8 @@
#include "Decoder.hpp"
#include <algorithm>
namespace InstructionSet {
namespace M50740 {
@ -21,6 +23,7 @@ std::pair<int, InstructionSet::M50740::Instruction> Decoder::decode(const uint8_
switch(instruction) {
default:
consumed_ = 0;
return std::make_pair(1, Instruction());
#define Map(opcode, operation, addressing_mode) case opcode: instr_ = Instruction(Operation::operation, AddressingMode::addressing_mode); break
@ -236,11 +239,31 @@ std::pair<int, InstructionSet::M50740::Instruction> Decoder::decode(const uint8_
#undef Map
}
// TODO: can I build these into the AddressingMode constants, to avoid the switch?
switch(instr_.addressing_mode) {
default: operand_size_ = 0; break;
}
operand_size_ = size(instr_.addressing_mode);
phase_ = operand_size_ ? Phase::AwaitingOperand : Phase::ReadyToPost;
operand_bytes_ = 0;
}
if(phase_ == Phase::AwaitingOperand && source != end) {
const int outstanding_bytes = operand_size_ - operand_bytes_;
const int bytes_to_consume = std::min(int(end - source), outstanding_bytes);
consumed_ += bytes_to_consume;
source += bytes_to_consume;
operand_bytes_ += bytes_to_consume;
if(operand_size_ == operand_bytes_) {
phase_ = Phase::ReadyToPost;
} else {
return std::make_pair(-(operand_size_ - operand_bytes_), Instruction());
}
}
if(phase_ == Phase::ReadyToPost) {
const auto result = std::make_pair(consumed_, instr_);
consumed_ = 0;
phase_ = Phase::Instruction;
return result;
}
return std::make_pair(0, Instruction());

View File

@ -24,9 +24,10 @@ class Decoder {
private:
enum class Phase {
Instruction,
AwaitingOperand
AwaitingOperand,
ReadyToPost
} phase_ = Phase::Instruction;
int operand_size_ = 0;
int operand_size_ = 0, operand_bytes_ = 0;
int consumed_ = 0;
Instruction instr_;
};

View File

@ -15,20 +15,12 @@ namespace InstructionSet {
namespace M50740 {
enum class AddressingMode {
Implied,
Accumulator,
Immediate,
Absolute,
AbsoluteX,
AbsoluteY,
ZeroPage,
ZeroPageX,
ZeroPageY,
XIndirect,
IndirectY,
Implied, Accumulator, Immediate,
Absolute, AbsoluteX, AbsoluteY,
ZeroPage, ZeroPageX, ZeroPageY,
XIndirect, IndirectY,
Relative,
AbsoluteIndirect,
ZeroPageIndirect,
AbsoluteIndirect, ZeroPageIndirect,
SpecialPage,
ImmediateZeroPage,
@ -45,6 +37,29 @@ enum class AddressingMode {
Bit4ZeroPageRelative, Bit5ZeroPageRelative, Bit6ZeroPageRelative, Bit7ZeroPageRelative,
};
inline int size(AddressingMode mode) {
// This is coupled to the AddressingMode list above; be careful!
constexpr int sizes[] = {
0, 0, 0,
2, 2, 2,
1, 1, 1,
1, 1,
1,
2, 1,
1,
2,
0, 0, 0, 0,
0, 0, 0, 0,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
2, 2, 2, 2,
2, 2, 2, 2,
};
return sizes[int(mode)];
}
enum class Operation: uint8_t {
Invalid,