#pragma once // Uses some information from: // http://www.cpu-world.com/Arch/6809.html #include #include #include namespace EightBit { class mc6809 : public BigEndianProcessor { public: enum StatusBits { // Entire flag: set if the complete machine state was saved in the stack. // If this bit is not set then only program counter and condition code // registers were saved in the stack. This bit is used by interrupt // handling routines only. // The bit is cleared by fast interrupts, and set by all other interrupts. EF = Bit7, // Fast interrupt mask: set if the FIRQ interrupt is disabled. FF = Bit6, // Half carry: set if there was a carry from bit 3 to bit 4 of the result // during the last add operation. HF = Bit5, // Interrupt mask: set if the IRQ interrupt is disabled. IF = Bit4, // Negative: set if the most significant bit of the result is set. // This bit can be set not only by arithmetic and logical operations, // but also by load / store operations. NF = Bit3, // Zero: set if the result is zero. Like the N bit, this bit can be // set not only by arithmetic and logical operations, but also // by load / store operations. ZF = Bit2, // Overflow: set if there was an overflow during last result calculation. // Logical, load and store operations clear this bit. VF = Bit1, // Carry: set if there was a carry from the bit 7 during last add // operation, or if there was a borrow from last subtract operation, // or if bit 7 of the A register was set during last MUL operation. CF = Bit0, }; mc6809(Bus& bus); Signal ExecutingInstruction; Signal ExecutedInstruction; virtual int execute(uint8_t opcode) final; virtual int step() final; virtual void powerOn() final; register16_t& D() { return m_d; } uint8_t& A() { return D().high; } uint8_t& B() { return D().low; } register16_t& X() { return m_x; } register16_t& Y() { return m_y; } register16_t& U() { return m_u; } register16_t& S() { return m_s; } uint8_t& DP() { return m_dp; } uint8_t& CC() { return m_cc; } PinLevel& IRQ() { return INT(); } PinLevel& FIRQ() { return m_firq; } protected: virtual void reset() final; private: const uint8_t RESETvector = 0xfe; const uint8_t NMIvector = 0xfc; const uint8_t SWIvector = 0xfa; const uint8_t IRQvector = 0xf8; const uint8_t FIRQvector = 0xf6; const uint8_t SWI2vector = 0xf4; const uint8_t SWI3vector = 0xf2; const uint8_t RESERVEDvector = 0xf0; // Register selection for "indexed" register16_t& RR(int which); // Addressing modes void Address_direct(); void Address_indexed(); void Address_extended(); // Addressing mode readers uint8_t AM_immediate_byte(); uint8_t AM_direct_byte(); uint8_t AM_indexed_byte(); uint8_t AM_extended_byte(); register16_t AM_immediate_word(); register16_t AM_direct_word(); register16_t AM_indexed_word(); register16_t AM_extended_word(); void adjustZero(uint8_t datum) { clearFlag(CC(), ZF, datum); } void adjustNegative(uint8_t datum) { setFlag(CC(), NF, datum & NF); } void adjustNZ(uint8_t datum) { adjustZero(datum); adjustNegative(datum); } void abx(); uint8_t adc(uint8_t operand, uint8_t data); uint8_t add(uint8_t operand, uint8_t data, int carry = 0); register16_t add(register16_t operand, register16_t data); uint8_t andr(uint8_t operand, uint8_t data); uint8_t asl(uint8_t operand); uint8_t asr(uint8_t operand); uint8_t neg(uint8_t operand); register16_t m_d; register16_t m_x; register16_t m_y; register16_t m_u; register16_t m_s; uint8_t m_dp; uint8_t m_cc; PinLevel m_firq; }; }