Start to flesh out operations.

This commit is contained in:
Thomas Harte committed 2026-03-11 15:09:46 -04:00
1 parent 21d2ab9179
commit a9358d3039
2 files changed
+82 -8

No files matched your search

+62 -6
View File
@@ -53,24 +53,68 @@ inline void set(Registers &registers, const int index, const uint16_t value) {
default: break;
}
}
}
// MARK: - Arithmetic.
inline void abx(Registers &registers) {
registers.reg<R16::X>() += registers.reg<R8::B>();
}
template <R8 r, bool with_carry>
void add(Registers &registers, const uint8_t operand) {
const uint8_t source = registers.reg<r>();
const uint8_t result = source + operand + (with_carry ? registers.cc.carry() : 0);
registers.cc.set_nz(result);
registers.cc.set_overflow(result, source, operand);
registers.cc.set<ConditionCode::Carry>(result < operand);
const uint8_t half = (source & 0xf) + (operand & 0xf) + (with_carry ? registers.cc.carry() : 0);
registers.cc.set<ConditionCode::HalfCarry>(half & 0x10);
registers.reg<r>() = result;
}
inline void addd(Registers &registers, const uint16_t operand) {
const uint16_t source = registers.reg<R16::D>();
const uint16_t result = source + operand;
registers.cc.set_nz(result);
registers.cc.set<ConditionCode::Carry>(result < operand);
registers.cc.set_overflow(result, source, operand);
}
// MARK: - Logical.
template <R8 r>
inline void ld(Registers &registers, const uint8_t operand) {
void and_(Registers &registers, const uint8_t operand) {
if constexpr (r == R8::CC) {
registers.reg<R8::CC>() = registers.reg<R8::CC>() & operand;
} else {
registers.cc.set_nz(registers.reg<r>() &= operand);
registers.cc.set<ConditionCode::Overflow>(false);
}
}
// MARK: - Shifts and rolls.
// MARK: - Data Transfer.
template <R8 r>
void ld(Registers &registers, const uint8_t operand) {
registers.reg<r>() = operand;
registers.cc.set_nz(operand);
registers.cc.set<ConditionCode::Overflow>(false);
}
template <R16 r>
inline void ld(Registers &registers, const uint16_t operand) {
void ld(Registers &registers, const uint16_t operand) {
registers.reg<r>() = operand;
registers.cc.set_nz(operand >> 8);
registers.cc.set_nz(operand);
registers.cc.set<ConditionCode::Overflow>(false);
}
inline void tfr(Registers &registers, const uint8_t operand) {
const auto source = operand >> 4;
const auto destination = operand & 0xf;
@@ -91,12 +135,24 @@ inline void exg(Registers &registers, const uint8_t operand) {
Implementation::set(registers, top, source_values[1]);
}
inline void perform(const InstructionSet::M6809::Operation operation, Registers &registers, const uint16_t operand) {
// MARK: - Dispatch.
inline void perform(const InstructionSet::M6809::Operation operation, Registers &registers, uint16_t &operand) {
switch(operation) {
using enum InstructionSet::M6809::Operation;
case None: break;
case ABX: abx(registers); break;
case ADCA: add<R8::A, true>(registers, uint8_t(operand)); break;
case ADCB: add<R8::B, true>(registers, uint8_t(operand)); break;
case ADDA: add<R8::A, false>(registers, uint8_t(operand)); break;
case ADDB: add<R8::B, false>(registers, uint8_t(operand)); break;
case ADDD: addd(registers, operand); break;
case ANDA: and_<R8::A>(registers, uint8_t(operand)); break;
case ANDB: and_<R8::B>(registers, uint8_t(operand)); break;
case ANDCC: and_<R8::CC>(registers, uint8_t(operand)); break;
case LDA: ld<R8::A>(registers, uint8_t(operand)); break;
case LDB: ld<R8::B>(registers, uint8_t(operand)); break;
+20 -2
View File
@@ -83,8 +83,26 @@ struct ConditionCodeRegister {
);
}
void set_nz(const uint8_t value) {
negative_ = zero_ = value;
template <std::unsigned_integral ValueT>
requires (sizeof(ValueT) <= 2)
void set_nz(const ValueT value) {
if constexpr (std::is_same_v<ValueT, uint8_t>) {
negative_ = zero_ = value;
} else {
negative_ = uint8_t(value >> 8);
zero_ = uint8_t(value | (value >> 8));
}
}
template <std::unsigned_integral ValueT>
requires (sizeof(ValueT) <= 2)
void set_overflow(const ValueT result, const ValueT lhs, const ValueT rhs) {
const ValueT bits = (result^lhs) & (result^rhs);
if constexpr (std::is_same_v<ValueT, uint8_t>) {
overflow_ = bits;
} else {
overflow_ = uint8_t(bits >> 8);
}
}
uint8_t carry() const { return carry_; }