#ifndef OPCODES_H #define OPCODES_H #include "util.h" #include #include enum AddressMode { AM_InvalidOp, AM_Absolute, // a AM_AbsoluteIndexedIndirect, // (a,x) AM_AbsoluteIndexedWithX, // a,x AM_AbsoluteIndexedWithY, // a,y AM_AbsoluteIndirect, // (a) AM_Immediate, // # AM_Implied, // i AM_Accumulator, // A AM_ProgramCounterRelative, // r AM_ZeroPage, // zp AM_ZeroPageIndexedIndirect, // (zp,x) AM_ZeroPageIndexedWithX, // zp,x AM_ZeroPageIndexedWithY, // zp,y AM_ZeroPageIndirect, // (zp) AM_ZeroPageIndirectIndexedWithY // (zp),y }; class OpCodes { struct AssyInstruction { public: AssyInstruction(quint8 opcode = 0x00, QString mnemonic = "???", AddressMode am = AM_InvalidOp, bool reads = false, bool writes = false, bool stack = false); AddressMode addressMode() { return m_addressMode; } QString mnemonic() const { return m_mnemonic; } quint8 opcode() const { return m_opcode; } quint8 numArgs() const; bool readsMem() const { return m_reads; } bool writesMem() const { return m_writes; } bool modifiesStack() const { return m_stack; } // QString debugStr() { return QString("%1 %2 %3").arg(uint8ToHex(m_opcode)).arg(m_mnemonic).arg(m_addressMode); } private: QString m_mnemonic; quint8 m_opcode; AddressMode m_addressMode; bool m_reads; bool m_writes; bool m_stack; }; public: static QString getMnemonic(quint8 opcode) { return getAssyInstruction(opcode).mnemonic(); } static AssyInstruction &getAssyInstruction(quint8 id) { static QHash m_opcodeinfo; if (m_opcodeinfo.size() == 0) { makeOpcodeTable(&m_opcodeinfo); } return m_opcodeinfo[id]; } static AddressMode addressMode(quint8 opcode); static QString mnemonic(quint8 opcode); static quint8 numArgs(quint8 opcode); static bool isJump(quint8 id); static bool isIndirectJump(quint8 id); static bool isBranch(quint8 id); static bool isJsr(quint8 id); static bool isReturn(quint8 id); static bool isBreak(quint8 id); static bool readsMemoryLoc(quint8 id); static bool writesMemoryLoc(quint8 id); static bool modifiesStack(quint8 id); protected: OpCodes(); static void makeOpcodeTable(QHash* m_opcodeinfo); }; #endif // OPCODES_H