mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-07 23:25:00 +00:00
Completes the M50740 decoder.
Completely untested.
This commit is contained in:
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "Decoder.hpp"
|
#include "Decoder.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace InstructionSet {
|
namespace InstructionSet {
|
||||||
namespace M50740 {
|
namespace M50740 {
|
||||||
|
|
||||||
@@ -21,6 +23,7 @@ std::pair<int, InstructionSet::M50740::Instruction> Decoder::decode(const uint8_
|
|||||||
|
|
||||||
switch(instruction) {
|
switch(instruction) {
|
||||||
default:
|
default:
|
||||||
|
consumed_ = 0;
|
||||||
return std::make_pair(1, Instruction());
|
return std::make_pair(1, Instruction());
|
||||||
|
|
||||||
#define Map(opcode, operation, addressing_mode) case opcode: instr_ = Instruction(Operation::operation, AddressingMode::addressing_mode); break
|
#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
|
#undef Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: can I build these into the AddressingMode constants, to avoid the switch?
|
operand_size_ = size(instr_.addressing_mode);
|
||||||
switch(instr_.addressing_mode) {
|
phase_ = operand_size_ ? Phase::AwaitingOperand : Phase::ReadyToPost;
|
||||||
default: operand_size_ = 0; break;
|
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());
|
return std::make_pair(0, Instruction());
|
||||||
|
@@ -24,9 +24,10 @@ class Decoder {
|
|||||||
private:
|
private:
|
||||||
enum class Phase {
|
enum class Phase {
|
||||||
Instruction,
|
Instruction,
|
||||||
AwaitingOperand
|
AwaitingOperand,
|
||||||
|
ReadyToPost
|
||||||
} phase_ = Phase::Instruction;
|
} phase_ = Phase::Instruction;
|
||||||
int operand_size_ = 0;
|
int operand_size_ = 0, operand_bytes_ = 0;
|
||||||
int consumed_ = 0;
|
int consumed_ = 0;
|
||||||
Instruction instr_;
|
Instruction instr_;
|
||||||
};
|
};
|
||||||
|
@@ -15,20 +15,12 @@ namespace InstructionSet {
|
|||||||
namespace M50740 {
|
namespace M50740 {
|
||||||
|
|
||||||
enum class AddressingMode {
|
enum class AddressingMode {
|
||||||
Implied,
|
Implied, Accumulator, Immediate,
|
||||||
Accumulator,
|
Absolute, AbsoluteX, AbsoluteY,
|
||||||
Immediate,
|
ZeroPage, ZeroPageX, ZeroPageY,
|
||||||
Absolute,
|
XIndirect, IndirectY,
|
||||||
AbsoluteX,
|
|
||||||
AbsoluteY,
|
|
||||||
ZeroPage,
|
|
||||||
ZeroPageX,
|
|
||||||
ZeroPageY,
|
|
||||||
XIndirect,
|
|
||||||
IndirectY,
|
|
||||||
Relative,
|
Relative,
|
||||||
AbsoluteIndirect,
|
AbsoluteIndirect, ZeroPageIndirect,
|
||||||
ZeroPageIndirect,
|
|
||||||
SpecialPage,
|
SpecialPage,
|
||||||
ImmediateZeroPage,
|
ImmediateZeroPage,
|
||||||
|
|
||||||
@@ -45,6 +37,29 @@ enum class AddressingMode {
|
|||||||
Bit4ZeroPageRelative, Bit5ZeroPageRelative, Bit6ZeroPageRelative, Bit7ZeroPageRelative,
|
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 {
|
enum class Operation: uint8_t {
|
||||||
Invalid,
|
Invalid,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user