diff --git a/MC6809/inc/mc6809.h b/MC6809/inc/mc6809.h index ad536a0..bd69f8a 100644 --- a/MC6809/inc/mc6809.h +++ b/MC6809/inc/mc6809.h @@ -96,6 +96,12 @@ namespace EightBit { // Register selection for "indexed" register16_t& RR(int which); + // Register selection for 8-bit transfer/exchange + uint8_t& referenceTransfer8(int specifier); + + // Register selection for 16-bit transfer/exchange + register16_t& referenceTransfer16(int specifier); + // Addressing modes void Address_direct(); // DP + fetched offset @@ -188,6 +194,7 @@ namespace EightBit { uint8_t da(uint8_t operand); uint8_t dec(uint8_t operand); uint8_t eor(uint8_t operand, uint8_t data); + void exg(uint8_t data); uint8_t neg(uint8_t operand); register16_t m_d; diff --git a/MC6809/inc/stdafx.h b/MC6809/inc/stdafx.h index bf45a08..0890f7b 100644 Binary files a/MC6809/inc/stdafx.h and b/MC6809/inc/stdafx.h differ diff --git a/MC6809/src/mc6809.cpp b/MC6809/src/mc6809.cpp index 5595925..5f06316 100644 --- a/MC6809/src/mc6809.cpp +++ b/MC6809/src/mc6809.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" #include "mc6809.h" +#include + EightBit::mc6809::mc6809(Bus& bus) : BigEndianProcessor(bus) {} @@ -182,6 +184,9 @@ int EightBit::mc6809::executeUnprefixed(uint8_t opcode) { case 0xe8: addCycles(4); B() = eor(B(), AM_indexed_byte()); break; // EOR (EORB indexed) case 0xf8: addCycles(5); B() = eor(B(), AM_extended_byte()); break; // EOR (EORB extended) + // EXG + case 0x1e: addCycles(8); exg(AM_immediate_byte()); break; // EXG (EXG R1,R2 immediate) + default: UNREACHABLE; } @@ -519,3 +524,51 @@ uint8_t EightBit::mc6809::eor(uint8_t operand, uint8_t data) { clearFlag(CC(), VF); return result; } + +uint8_t& EightBit::mc6809::referenceTransfer8(int specifier) { + switch (specifier) { + case 0b1000: + return A(); + case 0b1001: + return B(); + case 0b1010: + return CC(); + case 0b1011: + return DP(); + default: + UNREACHABLE; + } +} + +EightBit::register16_t& EightBit::mc6809::referenceTransfer16(int specifier) { + switch (specifier) { + case 0b0000: + return D(); + case 0b0001: + return X(); + case 0b0010: + return Y(); + case 0b0011: + return U(); + case 0b0100: + return S(); + case 0b0101: + return PC(); + default: + UNREACHABLE; + } +} + +void EightBit::mc6809::exg(uint8_t data) { + + const auto reg1 = highNibble(data); + const auto reg2 = lowNibble(data); + + const bool type16 = !!(reg1 & Bit3); // 16 bit exchange? + ASSUME(type16 == !!(reg2 & Bit3)); // Regardless, the register exchange must be equivalent + + if (type16) + std::swap(referenceTransfer16(reg1), referenceTransfer16(reg2)); + else + std::swap(referenceTransfer8(reg1), referenceTransfer8(reg2)); +}