From 7f4ca94e9a227eb6042246caa04584b24c79aa3e Mon Sep 17 00:00:00 2001 From: mlong Date: Mon, 1 Feb 2021 20:19:16 -0600 Subject: [PATCH] Added memory role detection in disassembler for opcodes and operands --- AppleSAWS.pro | 2 + src/binaryfile/disassembler.cxx | 311 +++++++------ src/binaryfile/disassembler.h | 115 ++--- src/memory/attributedmemory.cpp | 14 + src/memory/attributedmemory.h | 3 +- src/memory/memorycell.cpp | 16 +- src/memory/memorycell.h | 1 + src/memory/memrole.cpp | 3 - src/memory/memrole.h | 13 +- src/memory/roles/role_asm_opcode.cpp | 16 +- src/memory/roles/role_asm_opcode.h | 17 +- src/memory/roles/role_asm_operand.cpp | 6 + src/memory/roles/role_asm_operand.h | 33 ++ src/ui/viewers/disassemblerviewer.cpp | 3 +- src/ui/viewers/disassemblerviewer.h | 1 - src/util/opcodes.cpp | 613 +++++++++++++++----------- src/util/opcodes.h | 66 ++- 17 files changed, 698 insertions(+), 535 deletions(-) create mode 100644 src/memory/roles/role_asm_operand.cpp create mode 100644 src/memory/roles/role_asm_operand.h diff --git a/AppleSAWS.pro b/AppleSAWS.pro index b1d519d..bbf9b26 100644 --- a/AppleSAWS.pro +++ b/AppleSAWS.pro @@ -46,6 +46,7 @@ SOURCES += \ src/memory/memorycell.cpp \ src/memory/memrole.cpp \ src/memory/roles/role_asm_opcode.cpp \ + src/memory/roles/role_asm_operand.cpp \ src/ui/startupdialog.cpp \ src/ui/viewers/intbasicfileviewer.cxx \ src/ui/widgets/notesdialog.cpp \ @@ -100,6 +101,7 @@ HEADERS += \ src/memory/memorycell.h \ src/memory/memrole.h \ src/memory/roles/role_asm_opcode.h \ + src/memory/roles/role_asm_operand.h \ src/ui/startupdialog.h \ src/ui/viewers/intbasicfileviewer.h \ src/ui/widgets/notesdialog.h \ diff --git a/src/binaryfile/disassembler.cxx b/src/binaryfile/disassembler.cxx index 4eefeff..4f6d92a 100644 --- a/src/binaryfile/disassembler.cxx +++ b/src/binaryfile/disassembler.cxx @@ -1,28 +1,27 @@ #include "opcodes.h" #include "disassembler.h" - - +#include "role_asm_opcode.h" +#include "role_asm_operand.h" +#include "util.h" #include #include #include #include -Disassembler::Disassembler(QByteArray memimage) +Disassembler::Disassembler(AttributedMemory &mem) { - m_memimage = memimage; + m_mem = &mem; m_memusagemap.clearData(); } - QList Disassembler::disassemble(quint16 from, quint16 to, QList entryPoints, bool processRecursively) { m_from = from; m_to = to; QList retval; - qDebug() << "\n\n*****************\n\nDisassemble: From"< Disassembler::disassemble(quint16 from, quint16 to, while (!stopping) { - // quint8 opcode = m_memimage[next]; - // qDebug() << "Opcode: " << uint8ToHex(opcode); DisassembledItem item; bool ok = false; @@ -107,13 +104,14 @@ QList Disassembler::disassemble(quint16 from, quint16 to, if (processRecursively) { - m_jumplines = m_jlm.buildJumpLines(); - qDebug() << "Num Channels: " << m_jlm.getNumJumpLineChannels(); + m_jumplines = m_jlm.buildJumpLines(); + qDebug() << "Num Channels: " << m_jlm.getNumJumpLineChannels(); } return retval; } + bool Disassembler::disassembleOp(quint16 address, DisassembledItem &retval, MemoryUsageMap *memuse) { @@ -122,11 +120,25 @@ bool Disassembler::disassembleOp(quint16 address, DisassembledItem &retval, Memo if ((*memuse)[address].testFlag(Operation)) return false; } - quint8 opcode = m_memimage[address]; - AssyInstruction op = OpCodes::getAssyInstruction(opcode); - retval.setInstruction(op); + quint8 opcode = m_mem->at(address); - if (opcode == 0x6C || opcode == 0x7c) // Indirect jumps + retval.setOpcode(opcode); + + + if (!m_mem->hasRoleAt(address,RoleAsmOpcode::RoleID)) + { + auto opRole = new RoleAsmOpcode(); + if (!m_mem->setRoleAt(address,opRole)) + { + qWarning("Cannot set role %s at address %s for opcode %s", + qPrintable(opRole->name()), + qPrintable(uint16ToHex(address)), + qPrintable(uint8ToHex(opcode))); + delete opRole; + } + } + + if (OpCodes::isIndirectJump(opcode)) // Indirect jumps { m_jlm.addJump(address,address,IsUnknownJump,m_from,m_to); retval.setCanNotFollow(true); @@ -139,136 +151,164 @@ bool Disassembler::disassembleOp(quint16 address, DisassembledItem &retval, Memo // Prepare Op Code arguments - for (int idx = 1; idx < op.numArgs()+1; idx++) { - quint8 val = m_memimage[address+idx]; + auto numArgs = OpCodes::numArgs(opcode); + for (int idx = 1; idx < numArgs+1; idx++) { + qDebug() << "Opcode at " << uint16ToHex(idx + address); + auto oprndRole = new RoleAsmOperand(); + if (numArgs == 1) + { + oprndRole->setOperandType(RoleAsmOperand::Type::Byte); + } + else { + if (idx == 1) + { + oprndRole->setOperandType(RoleAsmOperand::Type::WordLo); + } + else // idx == 2 + { + oprndRole->setOperandType(RoleAsmOperand::Type::WordHi); + } + } + if (!m_mem->setRoleAt(address+idx,oprndRole)) + { + qWarning(">> Cannot set role %s at address %s", + qPrintable(oprndRole->name()), + qPrintable(uint16ToHex(address))); + delete oprndRole; + } + + quint8 val = m_mem->at(address+idx); hexValues.append(val); } + if (memuse) { (*memuse)[address].setFlag(Operation); - for (int idx = 1; idx < op.numArgs()+1; idx++) + for (int idx = 1; idx < OpCodes::numArgs(opcode)+1; idx++) { (*memuse)[address+idx].setFlag(OperationArg); } } quint16 argval = 0; - if (op.numArgs() == 1) + if (numArgs == 1) + { argval = (quint8) hexValues[1]; - else if (op.numArgs() == 2) + } + else if (numArgs == 2) { argval = makeWord(hexValues[1],hexValues[2]); } - - for (int idx = 0; idx < hexValues.length(); idx++) { - hexValueString.append(QString("%1 ").arg((quint8) hexValues[idx],2,16,QChar('0'))); + hexValueString.append(QString("%1 ").arg(uint8ToHex(hexValues[idx]))); } - - retval.setNextContiguousAddress(address+1+op.numArgs()); - retval.setNextFlowAddress(address+1+op.numArgs()); + retval.setNextContiguousAddress(address+1+numArgs); + retval.setNextFlowAddress(address+1+numArgs); + + QString mnemonic = OpCodes::mnemonic(opcode); // Disassemble instruction - switch (op.addressMode()) { - case AM_InvalidOp: { - disassemblyLine = op.mnemonic(); - retval.setIsInvalidOp(true); - break; - } - case AM_Absolute:{ - disassemblyLine = QString("%1 _ARG16_").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_AbsoluteIndexedIndirect:{ - disassemblyLine = QString("%1 (_ARG16_,x)").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_AbsoluteIndexedWithX:{ - disassemblyLine = QString("%1 _ARG16_,x").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_AbsoluteIndexedWithY:{ - disassemblyLine = QString("%1 _ARG16_,y").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_AbsoluteIndirect:{ - disassemblyLine = QString("%1 (_ARG16_)").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_Immediate:{ - disassemblyLine = QString("%1 #%2").arg(op.mnemonic()).arg((quint8) hexValues[1],2,16,QChar('0')).toUpper(); - retval.setRawArgument(argval); - break; - } - case AM_Implied:{ - disassemblyLine = op.mnemonic(); - break; - } - case AM_Accumulator:{ - disassemblyLine = op.mnemonic(); - break; - } - case AM_ProgramCounterRelative:{ - qint8 offset = (qint8) hexValues[1]; - quint16 offsetAddress = address+2+offset; + switch (OpCodes::addressMode(opcode)) { + case AM_InvalidOp: { + disassemblyLine = OpCodes::mnemonic(opcode); + retval.setIsInvalidOp(true); + break; + } + case AM_Absolute:{ + disassemblyLine = QString("%1 _ARG16_").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_AbsoluteIndexedIndirect:{ + disassemblyLine = QString("%1 (_ARG16_,x)").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_AbsoluteIndexedWithX:{ + disassemblyLine = QString("%1 _ARG16_,x").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_AbsoluteIndexedWithY:{ + disassemblyLine = QString("%1 _ARG16_,y").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_AbsoluteIndirect:{ + disassemblyLine = QString("%1 (_ARG16_)").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_Immediate:{ + disassemblyLine = QString("%1 #%2").arg(mnemonic).arg((quint8) hexValues[1],2,16,QChar('0')).toUpper(); + retval.setRawArgument(argval); + break; + } + case AM_Implied:{ + disassemblyLine = mnemonic; + break; + } + case AM_Accumulator:{ + disassemblyLine = mnemonic; + break; + } + case AM_ProgramCounterRelative:{ + qint8 offset = (qint8) hexValues[1]; + quint16 offsetAddress = address+2+offset; - retval.setTargetAddress(offsetAddress); - if (opcode == 0x80) // BRA - m_jlm.addJump(address,offsetAddress,IsBRA,m_from,m_to); - else - m_jlm.addJump(address,offsetAddress,IsBranch,m_from,m_to); + retval.setTargetAddress(offsetAddress); + if (opcode == 0x80) // BRA + m_jlm.addJump(address,offsetAddress,IsBRA,m_from,m_to); + else + m_jlm.addJump(address,offsetAddress,IsBranch,m_from,m_to); - disassemblyLine = QString("%1 _ARG16_ {%2%3}").arg(op.mnemonic()) - .arg((offset<0)?"-":"+") - .arg(abs(offset)); - retval.setRawArgument(offsetAddress); - break; - } - case AM_ZeroPage:{ - disassemblyLine = QString("%1 _ARG8_").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_ZeroPageIndirectIndexedWithY:{ - disassemblyLine = QString("%1 (_ARG8_),Y").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_ZeroPageIndexedIndirect:{ - disassemblyLine = QString("%1 (_ARG8_,x)").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_ZeroPageIndexedWithX:{ - disassemblyLine = QString("%1 _ARG8_,x").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_ZeroPageIndexedWithY:{ - disassemblyLine = QString("%1 _ARG8_,y").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - case AM_ZeroPageIndirect:{ - disassemblyLine = QString("%1 (_ARG8_)").arg(op.mnemonic()); - retval.setRawArgument(argval); - break; - } - default:{ - disassemblyLine = op.mnemonic(); - retval.setIsInvalidOp(true); - qDebug() << "Unhandled Address Mode: " << op.addressMode(); - break; - } + disassemblyLine = QString("%1 _ARG16_ {%2%3}").arg(mnemonic) + .arg((offset<0)?"-":"+") + .arg(abs(offset)); + retval.setRawArgument(offsetAddress); + break; + } + case AM_ZeroPage:{ + disassemblyLine = QString("%1 _ARG8_").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_ZeroPageIndirectIndexedWithY:{ + disassemblyLine = QString("%1 (_ARG8_),Y").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_ZeroPageIndexedIndirect:{ + disassemblyLine = QString("%1 (_ARG8_,x)").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_ZeroPageIndexedWithX:{ + disassemblyLine = QString("%1 _ARG8_,x").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_ZeroPageIndexedWithY:{ + disassemblyLine = QString("%1 _ARG8_,y").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + case AM_ZeroPageIndirect:{ + disassemblyLine = QString("%1 (_ARG8_)").arg(mnemonic); + retval.setRawArgument(argval); + break; + } + default:{ + disassemblyLine = mnemonic; + retval.setIsInvalidOp(true); + qDebug() << "Unhandled Address Mode: " << mnemonic; + break; + } } - if (opcode == 0x20 || opcode == 0x4c) { + if (opcode == 0x20 || opcode == 0x4c) // JSR / JMP + { retval.setTargetAddress(makeWord(hexValues[1],hexValues[2])); if (opcode == 0x4c) // JMP @@ -294,6 +334,7 @@ bool Disassembler::disassembleOp(quint16 address, DisassembledItem &retval, Memo } + void Disassembler::setUnknownToData(quint16 from, quint16 to) { for (int idx = from; idx <= to; idx++) @@ -305,28 +346,14 @@ void Disassembler::setUnknownToData(quint16 from, quint16 to) } } -DisassembledItem::DisassembledItem(AssyInstruction instr) { - m_canNotFollow = false; - setInstruction(instr); -} +//DisassembledItem::DisassembledItem(AssyInstruction instr) { +// m_canNotFollow = false; +// setInstruction(instr); +//} -void DisassembledItem::setInstruction(AssyInstruction instr) { - m_instruction = instr; - // qDebug() << "Set instruction: " << uint8ToHex(instr.opcode()); - // qDebug() << " Copied instr:" << m_instruction.debugStr(); - if (instr.opcode() == 0x20) { m_is_jsr = true; } - if (instr.opcode() == 0x10) { m_is_branch = true; } // BPL - if (instr.opcode() == 0x30) { m_is_branch = true; } // BMI - if (instr.opcode() == 0x50) { m_is_branch = true; } // BVC - if (instr.opcode() == 0x70) { m_is_branch = true; } // BVS - if (instr.opcode() == 0x90) { m_is_branch = true; } // BCC - if (instr.opcode() == 0xB0) { m_is_branch = true; } // BCS - if (instr.opcode() == 0xD0) { m_is_branch = true; } // BNE - if (instr.opcode() == 0xF0) { m_is_branch = true; } // BEQ - if (instr.opcode() == 0x80) { m_is_jump = true; } // BRA - if (instr.opcode() == 0x4C) { m_is_jump = true; } // JMP a - if (instr.opcode() == 0x6C) { m_is_jump = true; } // JMP (a) - if (instr.opcode() == 0x7C) { m_is_jump = true; } // JMP (a,x) +DisassembledItem::DisassembledItem(quint8 opcode) { + m_canNotFollow = false; + m_opcode = opcode; } QString DisassembledItem::disassembledString() { @@ -345,11 +372,9 @@ void DisassembledItem::init() { m_address = m_target_address = 0; m_nextContiguousAddress = 0; m_nextFlowAddress = 0; - m_is_jump = m_is_branch = m_is_jsr = false; m_unknown_ta = true; m_raw_arg = 0; m_has_arg = false; m_canNotFollow = false; m_isInvalidOp = false; - } diff --git a/src/binaryfile/disassembler.h b/src/binaryfile/disassembler.h index 349499d..9d57565 100644 --- a/src/binaryfile/disassembler.h +++ b/src/binaryfile/disassembler.h @@ -5,6 +5,7 @@ #include "util.h" #include "JumpLineManager.h" #include "opcodes.h" +#include "attributedmemory.h" #include #include @@ -13,26 +14,6 @@ #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 AddressStack { public: @@ -41,7 +22,7 @@ class AddressStack bool push(quint16 address, bool force = false) { if (force || (!m_stack.contains(address))) { - qDebug() << " PUSH: " << uint16ToHex(address); + // qDebug() << " PUSH: " << uint16ToHex(address); m_stack.push(address); return true; } @@ -55,75 +36,46 @@ class AddressStack QStack m_stack; }; -////////////////////////////////////////////////////////////////////////////// - -//struct AssyInstruction { - -//public: - -// AssyInstruction(quint8 opcode = 0x00, QString mnemonic = "???", AddressMode am = AM_InvalidOp); - -// AddressMode addressMode() { return m_addressMode; } - -// QString mnemonic() { return m_mnemonic; } - -// quint8 opcode() { return m_opcode; } - -// quint8 numArgs(); - -// 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; -//}; -////////////////////////////////////////////////////////////////////////////// class DisassembledItem { public: DisassembledItem() { init(); } - DisassembledItem(AssyInstruction instr); + DisassembledItem(quint8 opcode); bool operator<(const DisassembledItem &other) const { return (address() < other.address()); } - void setInstruction(AssyInstruction instr); - + void setOpcode(quint8 opcode) { m_opcode = opcode; } void setAddress(quint16 add) { m_address = add; } void setDisassembledString(QString ds) { m_disassembly_text = ds; } void setHexValues(QByteArray hv) { m_hexvalues = hv; } void setHexString(QString hs) { m_hexstring = hs; } - void setBranch(bool branch) { m_is_branch = branch; } - void setJump(bool jump) { m_is_jump = jump; } - void setJsr(bool jsr) { m_is_jsr = jsr; } void setTargetAddress(quint16 ta) { m_unknown_ta = false; m_target_address = ta; } void setRawArgument(quint16 arg) { m_has_arg = true; m_raw_arg = arg; } void setCanNotFollow(bool canNotFollow) { m_canNotFollow = canNotFollow; } void setIsInvalidOp(bool isInvalid) { m_isInvalidOp = isInvalid; } - AssyInstruction assyInstruction() const { return m_instruction; } - QString rawDisassembledString() const { return m_disassembly_text; } - QString disassembledString(); + quint8 opcode() const { return m_opcode; } quint16 address() const { return m_address; } - QString hexAddress() const { return QString("%1").arg(m_address,4,16,QChar('0')).toUpper(); } + QString disassembledString(); + QString rawDisassembledString() const { return m_disassembly_text; } + QString hexAddress() const { return uint16ToHex(m_address); } QByteArray hexValues() const { return m_hexvalues; } QString hexString() const { return m_hexstring; } - bool isBranch() const { return m_is_branch; } - bool isJump() const { return m_is_jump; } - bool isJsr() const { return m_is_jsr; } - bool isReturn() { return (m_instruction.opcode() == 0x60) || m_instruction.opcode() == 0x40; } - bool isBreak() { return (m_instruction.opcode() == 0x00); } + + bool isBranch() const { return OpCodes::isBranch(m_opcode); } + bool isJump() const { return OpCodes::isJump(m_opcode); } + bool isJsr() const { return OpCodes::isJsr(m_opcode); } + bool isReturn() { return OpCodes::isReturn(m_opcode); } + bool isBreak() { return OpCodes::isBreak(m_opcode); } bool isInvalidOp() { return m_isInvalidOp; } bool canNotFollow() { return m_canNotFollow; } - bool stopsProcessing() { - if (isReturn()) qDebug() << "Is Return"; - if (isInvalidOp()) qDebug() << "Is Invalid Op" << uint8ToHex(m_instruction.opcode()); - if (canNotFollow()) qDebug() << "Not following jump"; - if (isBreak()) qDebug() << "Is Break"; - return isBreak() || isInvalidOp() || isReturn() || canNotFollow(); } + bool stopsProcessing() + { + return isBreak() || isInvalidOp() || isReturn() || canNotFollow(); + } quint16 nextContiguousAddress() { return m_nextContiguousAddress; } quint16 nextFlowAddress() { return m_nextFlowAddress; } @@ -133,14 +85,18 @@ public: quint16 targetAddress() const { return m_target_address; } bool hasArg() const { return m_has_arg; } - quint16 arg16() { return m_raw_arg; } + quint8 arg8() { return m_raw_arg % 256; } - QString arg16Str() { return QString("%1").arg(arg16(),4,16,QChar('0')).toUpper(); } - QString arg8Str() { return QString("%1").arg(arg8(),2,16,QChar('0')).toUpper(); } + QString arg8Str() { return uint8ToHex(arg8()); } + + quint16 arg16() { return m_raw_arg; } + QString arg16Str() { return uint16ToHex(arg16()); } private: void init(); + quint8 m_opcode; + quint16 m_address; quint16 m_nextContiguousAddress; quint16 m_nextFlowAddress; @@ -149,10 +105,7 @@ private: QByteArray m_hexvalues; QString m_disassembly_text; QString m_hexstring; - bool m_is_branch; - bool m_is_jump; - bool m_is_jsr; - AssyInstruction m_instruction; + bool m_unknown_ta; quint16 m_raw_arg; bool m_has_arg; @@ -166,16 +119,14 @@ private: class Disassembler { public: - - - - Disassembler(QByteArray memimage); + Disassembler(AttributedMemory &mem); enum ProcessorType { - P6502, - P65C02 + MOS6502, + MOS65C02 }; + QList disassemble(quint16 from, quint16 to, QList entryPoints, @@ -189,13 +140,15 @@ public: JumpLines getJumpLines() const { return m_jumplines; } private: - bool disassembleOp(quint16 address, DisassembledItem &retval, MemoryUsageMap *memuse = Q_NULLPTR); + bool disassembleOp(quint16 address, + DisassembledItem &retval, + MemoryUsageMap *memuse = Q_NULLPTR); quint16 m_from; quint16 m_to; - QByteArray m_memimage; + AttributedMemory *m_mem; AddressStack m_stack; diff --git a/src/memory/attributedmemory.cpp b/src/memory/attributedmemory.cpp index 749bed8..a73f6da 100644 --- a/src/memory/attributedmemory.cpp +++ b/src/memory/attributedmemory.cpp @@ -43,6 +43,15 @@ bool AttributedMemory::setRoleAt(quint16 address, return false; } +bool AttributedMemory::replaceRoleAt(quint16 address, + MemRole *withRole) +{ + if (!withRole) return false; + + removeRoleAt(address,withRole->id()); + return setRoleAt(address,withRole); +} + bool AttributedMemory::hasRoleAt(quint16 address, int withId) { return m_cells[address].hasRole(withId); @@ -58,6 +67,11 @@ QList AttributedMemory::getAllRolesAt(quint16 address) return m_cells[address].getAllRoles(); } +bool AttributedMemory::removeRoleAt(quint16 address, int withId) +{ + return m_cells[address].removeRole(withId); +} + QByteArray AttributedMemory::getAllValues() const { return getAllValuesInRange(0x0000,0x0ffff); diff --git a/src/memory/attributedmemory.h b/src/memory/attributedmemory.h index ae248a1..33736e8 100644 --- a/src/memory/attributedmemory.h +++ b/src/memory/attributedmemory.h @@ -22,6 +22,8 @@ public: bool hasRoleAt(quint16 address, int withId); MemRole *getRoleAt(quint16 address, int withId); QList getAllRolesAt(quint16 address); + bool removeRoleAt(quint16 address, int withId); + bool replaceRoleAt(quint16 address, MemRole *withRole); QByteArray getAllValues() const; QByteArray getAllValuesInExpectedRange() const; @@ -31,7 +33,6 @@ public: bool addFile(QByteArray data, quint16 start); // From Memory.h. Should be replaced? - protected: quint16 m_expected_bottom; diff --git a/src/memory/memorycell.cpp b/src/memory/memorycell.cpp index b07b021..a0aa3a1 100644 --- a/src/memory/memorycell.cpp +++ b/src/memory/memorycell.cpp @@ -17,10 +17,14 @@ MemoryCell::~MemoryCell() bool MemoryCell::setRole(MemRole *role) { - if (!role) return false; + if (!role) { + qWarning("No role given!"); + return false; + } if (hasRole(role->id())) { + qWarning("Address already has this role."); return false; } @@ -43,6 +47,16 @@ bool MemoryCell::hasRole(int id) const return m_roles.contains(id); } +bool MemoryCell::removeRole(int id) +{ + if (hasRole(id)) + { + m_roles.remove(id); + return true; + } + return false; +} + QList MemoryCell::getAllRoles() { return m_roles.values(); diff --git a/src/memory/memorycell.h b/src/memory/memorycell.h index 1f8eae7..1473066 100644 --- a/src/memory/memorycell.h +++ b/src/memory/memorycell.h @@ -18,6 +18,7 @@ public: bool setRole(MemRole *role); MemRole *getRole(int id); bool hasRole(int id) const; + bool removeRole(int id); void setValue(quint8 val) { m_value = val; } quint8 value() const { return m_value; } diff --git a/src/memory/memrole.cpp b/src/memory/memrole.cpp index abc2365..faa6b44 100644 --- a/src/memory/memrole.cpp +++ b/src/memory/memrole.cpp @@ -5,10 +5,7 @@ MemRole::MemRole() m_parent = nullptr; } -MemRole::~MemRole() -{ -} void MemRole::setParent(MemoryCell *parent) { diff --git a/src/memory/memrole.h b/src/memory/memrole.h index 20e774d..2811a4d 100644 --- a/src/memory/memrole.h +++ b/src/memory/memrole.h @@ -1,18 +1,25 @@ #ifndef MEMROLE_H #define MEMROLE_H +#include + +// IDs: +// 1: RoleAsmOpcode +// 2: RoleAsmOperand + class MemoryCell; class MemRole { public: MemRole(); - virtual ~MemRole(); + virtual ~MemRole() { } virtual int id() const = 0; + virtual QString name() const = 0; - void setParent(MemoryCell *parent); - MemoryCell *parent( ) const { return m_parent; } + virtual void setParent(MemoryCell *parent); + virtual MemoryCell *parent( ) const { return m_parent; } protected: MemoryCell *m_parent; diff --git a/src/memory/roles/role_asm_opcode.cpp b/src/memory/roles/role_asm_opcode.cpp index 70d5ee1..8afa7fe 100644 --- a/src/memory/roles/role_asm_opcode.cpp +++ b/src/memory/roles/role_asm_opcode.cpp @@ -2,17 +2,13 @@ #include "opcodes.h" #include "memorycell.h" -RoleAsmOpcode::RoleAsmOpcode() -{ -} - -RoleAsmOpcode::~RoleAsmOpcode() -{ - -} - -QString RoleAsmOpcode::getMnemonic() +QString RoleAsmOpcode::mnemonic() const { return OpCodes::getMnemonic(m_parent->value()); } + +AddressMode RoleAsmOpcode::addressMode() const +{ + return OpCodes::addressMode(m_parent->value()); +} diff --git a/src/memory/roles/role_asm_opcode.h b/src/memory/roles/role_asm_opcode.h index 3c1e690..8f53808 100644 --- a/src/memory/roles/role_asm_opcode.h +++ b/src/memory/roles/role_asm_opcode.h @@ -2,18 +2,27 @@ #define ROLE_ASM_OPCODE_H #include "memrole.h" +#include "opcodes.h" #include class RoleAsmOpcode : public MemRole { + public: - RoleAsmOpcode(); - virtual ~RoleAsmOpcode(); + static const int RoleID = 1; + RoleAsmOpcode() { m_am = AddressMode::AM_InvalidOp; } + virtual ~RoleAsmOpcode() { } - virtual int id() const { return 1; } + virtual int id() const override { return RoleID; } + virtual QString name() const override { return "RoleAsmOpcode"; } + + QString mnemonic() const; + AddressMode addressMode() const; + +protected: + AddressMode m_am; - QString getMnemonic(); }; #endif // ROLE_ASM_OPCODE_H diff --git a/src/memory/roles/role_asm_operand.cpp b/src/memory/roles/role_asm_operand.cpp new file mode 100644 index 0000000..65fd164 --- /dev/null +++ b/src/memory/roles/role_asm_operand.cpp @@ -0,0 +1,6 @@ +#include "role_asm_operand.h" + +RoleAsmOperand::RoleAsmOperand() +{ + +} diff --git a/src/memory/roles/role_asm_operand.h b/src/memory/roles/role_asm_operand.h new file mode 100644 index 0000000..c2f2396 --- /dev/null +++ b/src/memory/roles/role_asm_operand.h @@ -0,0 +1,33 @@ +#ifndef ROLEASMOPERAND_H +#define ROLEASMOPERAND_H + +#include +#include "memrole.h" + +class RoleAsmOperand : public MemRole +{ + +public: + static const int RoleID = 2; + + typedef enum + { + Byte, + WordLo, + WordHi, + } Type; + + RoleAsmOperand(); + + virtual int id() const override { return RoleID; } + virtual QString name() const override { return "RoleAsmOperand"; } + + void setOperandType(Type type) { m_optype = type; } + Type operandType() const { return m_optype; } + +protected: + Type m_optype; + +}; + +#endif // ROLEASMOPERAND_H diff --git a/src/ui/viewers/disassemblerviewer.cpp b/src/ui/viewers/disassemblerviewer.cpp index fdfe1b9..3510b0f 100644 --- a/src/ui/viewers/disassemblerviewer.cpp +++ b/src/ui/viewers/disassemblerviewer.cpp @@ -154,8 +154,7 @@ QStringList DisassemblerViewer::getDisassemblyStrings() { void DisassemblerViewer::disassemble(QList entryPoints) { - //Disassembler dis(m_mem.values()); - Disassembler dis(m_mem.getAllValues()); + Disassembler dis(m_mem); int length = m_file->length(); qDebug() << "DV: from: << " << m_file->address() << " to " << length; int end = m_file->address()+length; diff --git a/src/ui/viewers/disassemblerviewer.h b/src/ui/viewers/disassemblerviewer.h index eb7693c..a0bfda3 100644 --- a/src/ui/viewers/disassemblerviewer.h +++ b/src/ui/viewers/disassemblerviewer.h @@ -61,7 +61,6 @@ private: BinaryFileMetadata *m_bfm; - //Memory m_mem; AttributedMemory m_mem; bool m_isRelo; diff --git a/src/util/opcodes.cpp b/src/util/opcodes.cpp index 0989b99..eb475a7 100644 --- a/src/util/opcodes.cpp +++ b/src/util/opcodes.cpp @@ -4,15 +4,92 @@ OpCodes::OpCodes() { } +AddressMode OpCodes::addressMode(quint8 opcode) +{ + return getAssyInstruction(opcode).addressMode(); +} + +QString OpCodes::mnemonic(quint8 opcode) +{ + return getAssyInstruction(opcode).mnemonic(); +} + +quint8 OpCodes::numArgs(quint8 opcode) +{ + return getAssyInstruction(opcode).numArgs(); +} + +bool OpCodes::isJump(quint8 id) +{ + if (id == 0x80) return true; // BRA + if (id == 0x4C) return true; // JMP a + if (id == 0x6C) return true; // JMP (a) + if (id == 0x7C) return true; // JMP (a,x); + return false; +} + +bool OpCodes::isIndirectJump(quint8 id) +{ + if (id == 0x6C) return true; // JMP (a) + if (id == 0x7C) return true; // JMP (a,x); + return false; +} + +bool OpCodes::isBranch(quint8 id) +{ + if (id == 0x10) return true; // BPL + if (id == 0x30) return true; // BMI + if (id == 0x50) return true; // BVC + if (id == 0x70) return true; // BVS + if (id == 0x90) return true; // BCC + if (id == 0xB0) return true; // BCS + if (id == 0xD0) return true; // BNE + if (id == 0xF0) return true; // BEQ + return false; +} + +bool OpCodes::isJsr(quint8 id) +{ + return (id == 0x20); // JSR +} + +bool OpCodes::isReturn(quint8 id) +{ + if (id == 0x40) return true; // RTI + if (id == 0x60) return true; // RTS + return false; +} + +bool OpCodes::isBreak(quint8 id) +{ + return (id = 0x00); // BRK +} + +bool OpCodes::readsMemoryLoc(quint8 opcode) +{ + return getAssyInstruction(opcode).readsMem(); +} + +bool OpCodes::writesMemoryLoc(quint8 opcode) +{ + return getAssyInstruction(opcode).writesMem(); +} + +bool OpCodes::modifiesStack(quint8 opcode) +{ + return getAssyInstruction(opcode).modifiesStack(); +} + + void OpCodes::makeOpcodeTable(QHash* opcode_table) { opcode_table->insert(0x00,AssyInstruction(0x00, "BRK", AM_Implied)); opcode_table->insert(0x10,AssyInstruction(0x10, "BPL", AM_ProgramCounterRelative)); - opcode_table->insert(0x20,AssyInstruction(0x20, "JSR", AM_Absolute)); + opcode_table->insert(0x20,AssyInstruction(0x20, "JSR", AM_Absolute, false, false, true)); opcode_table->insert(0x30,AssyInstruction(0x30, "BMI", AM_ProgramCounterRelative)); - opcode_table->insert(0x40,AssyInstruction(0x40, "RTI", AM_Implied)); + opcode_table->insert(0x40,AssyInstruction(0x40, "RTI", AM_Implied, false, false, true)); opcode_table->insert(0x50,AssyInstruction(0x50, "BVC", AM_ProgramCounterRelative)); - opcode_table->insert(0x60,AssyInstruction(0x60, "RTS", AM_Implied)); + opcode_table->insert(0x60,AssyInstruction(0x60, "RTS", AM_Implied, false, false, true)); opcode_table->insert(0x70,AssyInstruction(0x70, "BVS", AM_ProgramCounterRelative)); opcode_table->insert(0x80,AssyInstruction(0x80, "BRA", AM_ProgramCounterRelative)); //65C02 opcode_table->insert(0x90,AssyInstruction(0x90, "BCC", AM_ProgramCounterRelative)); @@ -23,39 +100,39 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) opcode_table->insert(0xe0,AssyInstruction(0xe0, "CPX", AM_Immediate)); opcode_table->insert(0xf0,AssyInstruction(0xf0, "BEQ", AM_ProgramCounterRelative)); - opcode_table->insert(0x01,AssyInstruction(0x01, "ORA", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0x11,AssyInstruction(0x11, "ORA", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0x21,AssyInstruction(0x21, "AND", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0x31,AssyInstruction(0x31, "AND", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0x41,AssyInstruction(0x41, "EOR", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0x51,AssyInstruction(0x51, "EOR", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0x61,AssyInstruction(0x61, "ADC", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0x71,AssyInstruction(0x71, "ADC", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0x81,AssyInstruction(0x81, "STA", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0x91,AssyInstruction(0x91, "STA", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0xa1,AssyInstruction(0xa1, "LDA", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0xb1,AssyInstruction(0xb1, "LDA", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0xc1,AssyInstruction(0xc1, "CMP", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0xd1,AssyInstruction(0xd1, "CMP", AM_ZeroPageIndirectIndexedWithY)); - opcode_table->insert(0xe1,AssyInstruction(0xe1, "SBC", AM_ZeroPageIndexedIndirect)); - opcode_table->insert(0xf1,AssyInstruction(0xff, "SBC", AM_ZeroPageIndirectIndexedWithY)); + opcode_table->insert(0x01,AssyInstruction(0x01, "ORA", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0x11,AssyInstruction(0x11, "ORA", AM_ZeroPageIndirectIndexedWithY, true, false, false)); + opcode_table->insert(0x21,AssyInstruction(0x21, "AND", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0x31,AssyInstruction(0x31, "AND", AM_ZeroPageIndirectIndexedWithY, true, false, false)); + opcode_table->insert(0x41,AssyInstruction(0x41, "EOR", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0x51,AssyInstruction(0x51, "EOR", AM_ZeroPageIndirectIndexedWithY, true, false, false)); + opcode_table->insert(0x61,AssyInstruction(0x61, "ADC", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0x71,AssyInstruction(0x71, "ADC", AM_ZeroPageIndirectIndexedWithY, true, false, false)); + opcode_table->insert(0x81,AssyInstruction(0x81, "STA", AM_ZeroPageIndexedIndirect, false, true, false)); + opcode_table->insert(0x91,AssyInstruction(0x91, "STA", AM_ZeroPageIndirectIndexedWithY, false, true, false)); + opcode_table->insert(0xa1,AssyInstruction(0xa1, "LDA", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0xb1,AssyInstruction(0xb1, "LDA", AM_ZeroPageIndirectIndexedWithY, true, false, false)); + opcode_table->insert(0xc1,AssyInstruction(0xc1, "CMP", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0xd1,AssyInstruction(0xd1, "CMP", AM_ZeroPageIndirectIndexedWithY, true, false, false)); + opcode_table->insert(0xe1,AssyInstruction(0xe1, "SBC", AM_ZeroPageIndexedIndirect, true, false, false)); + opcode_table->insert(0xf1,AssyInstruction(0xff, "SBC", AM_ZeroPageIndirectIndexedWithY, true, false, false)); opcode_table->insert(0x02,AssyInstruction(0x02, "???", AM_InvalidOp)); - opcode_table->insert(0x12,AssyInstruction(0x12, "ORA", AM_ZeroPageIndirect)); + opcode_table->insert(0x12,AssyInstruction(0x12, "ORA", AM_ZeroPageIndirect, true, false, false)); opcode_table->insert(0x22,AssyInstruction(0x22, "???", AM_InvalidOp)); - opcode_table->insert(0x32,AssyInstruction(0x32, "AND", AM_ZeroPageIndirect)); + opcode_table->insert(0x32,AssyInstruction(0x32, "AND", AM_ZeroPageIndirect, true, false, false)); opcode_table->insert(0x42,AssyInstruction(0x42, "???", AM_InvalidOp)); - opcode_table->insert(0x52,AssyInstruction(0x52, "EOR", AM_ZeroPageIndirect)); + opcode_table->insert(0x52,AssyInstruction(0x52, "EOR", AM_ZeroPageIndirect, true, false, false)); opcode_table->insert(0x62,AssyInstruction(0x62, "???", AM_InvalidOp)); - opcode_table->insert(0x72,AssyInstruction(0x72, "ADC", AM_ZeroPageIndirect)); + opcode_table->insert(0x72,AssyInstruction(0x72, "ADC", AM_ZeroPageIndirect, true, false, false)); opcode_table->insert(0x82,AssyInstruction(0x82, "???", AM_InvalidOp)); - opcode_table->insert(0x92,AssyInstruction(0x92, "STA", AM_ZeroPageIndirect)); //65C02 + opcode_table->insert(0x92,AssyInstruction(0x92, "STA", AM_ZeroPageIndirect, false, true, false)); //65C02 opcode_table->insert(0xa2,AssyInstruction(0xa2, "LDX", AM_Immediate)); - opcode_table->insert(0xb2,AssyInstruction(0xb2, "LDA", AM_ZeroPageIndirect)); //65C02 + opcode_table->insert(0xb2,AssyInstruction(0xb2, "LDA", AM_ZeroPageIndirect, true, false, false)); //65C02 opcode_table->insert(0xc2,AssyInstruction(0xc2, "???", AM_InvalidOp)); - opcode_table->insert(0xd2,AssyInstruction(0xd2, "CMP", AM_ZeroPageIndirect)); + opcode_table->insert(0xd2,AssyInstruction(0xd2, "CMP", AM_ZeroPageIndirect, true, false, false)); opcode_table->insert(0xe2,AssyInstruction(0xe2, "???", AM_InvalidOp)); - opcode_table->insert(0xf2,AssyInstruction(0xf2, "SBC", AM_ZeroPageIndirect)); + opcode_table->insert(0xf2,AssyInstruction(0xf2, "SBC", AM_ZeroPageIndirect, true, false, false)); opcode_table->insert(0x03,AssyInstruction(0x03, "???", AM_InvalidOp)); opcode_table->insert(0x13,AssyInstruction(0x13, "???", AM_InvalidOp)); @@ -74,56 +151,56 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) opcode_table->insert(0xe3,AssyInstruction(0xe3, "???", AM_InvalidOp)); opcode_table->insert(0xf3,AssyInstruction(0xf3, "???", AM_InvalidOp)); - opcode_table->insert(0x04,AssyInstruction(0x04, "TSB", AM_ZeroPage)); //65C02 - opcode_table->insert(0x14,AssyInstruction(0x14, "TRB", AM_ZeroPage)); //65C02 - opcode_table->insert(0x24,AssyInstruction(0x24, "BIT", AM_ZeroPage)); - opcode_table->insert(0x34,AssyInstruction(0x34, "BIT", AM_ZeroPageIndexedWithX)); //65C02 + opcode_table->insert(0x04,AssyInstruction(0x04, "TSB", AM_ZeroPage, true, false, false)); //65C02 + opcode_table->insert(0x14,AssyInstruction(0x14, "TRB", AM_ZeroPage, true, false, false)); //65C02 + opcode_table->insert(0x24,AssyInstruction(0x24, "BIT", AM_ZeroPage, true, false, false)); + opcode_table->insert(0x34,AssyInstruction(0x34, "BIT", AM_ZeroPageIndexedWithX, true, false, false)); //65C02 opcode_table->insert(0x44,AssyInstruction(0x44, "???", AM_InvalidOp)); opcode_table->insert(0x54,AssyInstruction(0x54, "???", AM_InvalidOp)); - opcode_table->insert(0x64,AssyInstruction(0x64, "STZ", AM_ZeroPage)); //65C02 - opcode_table->insert(0x74,AssyInstruction(0x74, "STZ", AM_ZeroPageIndexedWithX)); //65C02 - opcode_table->insert(0x84,AssyInstruction(0x84, "STY", AM_ZeroPage)); - opcode_table->insert(0x94,AssyInstruction(0x94, "STY", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0xa4,AssyInstruction(0xa4, "LDY", AM_ZeroPage)); - opcode_table->insert(0xb4,AssyInstruction(0xb4, "LDY", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0xc4,AssyInstruction(0xc4, "CPY", AM_ZeroPage)); + opcode_table->insert(0x64,AssyInstruction(0x64, "STZ", AM_ZeroPage, false, true, false)); //65C02 + opcode_table->insert(0x74,AssyInstruction(0x74, "STZ", AM_ZeroPageIndexedWithX, false, true, false)); //65C02 + opcode_table->insert(0x84,AssyInstruction(0x84, "STY", AM_ZeroPage, false, true, false)); + opcode_table->insert(0x94,AssyInstruction(0x94, "STY", AM_ZeroPageIndexedWithX, false, true, false)); + opcode_table->insert(0xa4,AssyInstruction(0xa4, "LDY", AM_ZeroPage, true, false, false)); + opcode_table->insert(0xb4,AssyInstruction(0xb4, "LDY", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0xc4,AssyInstruction(0xc4, "CPY", AM_ZeroPage, true, false, false)); opcode_table->insert(0xd4,AssyInstruction(0xd4, "???", AM_InvalidOp)); - opcode_table->insert(0xe4,AssyInstruction(0xe4, "CPX", AM_ZeroPage)); + opcode_table->insert(0xe4,AssyInstruction(0xe4, "CPX", AM_ZeroPage, true, false, false)); opcode_table->insert(0xf4,AssyInstruction(0xf4, "???", AM_InvalidOp)); - opcode_table->insert(0x05,AssyInstruction(0x05, "ORA", AM_ZeroPage)); - opcode_table->insert(0x15,AssyInstruction(0x15, "ORA", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x25,AssyInstruction(0x25, "AND", AM_ZeroPage)); - opcode_table->insert(0x35,AssyInstruction(0x35, "AND", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x45,AssyInstruction(0x45, "EOR", AM_ZeroPage)); - opcode_table->insert(0x55,AssyInstruction(0x55, "EOR", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x65,AssyInstruction(0x65, "ADC", AM_ZeroPage)); - opcode_table->insert(0x75,AssyInstruction(0x75, "ADC", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x85,AssyInstruction(0x85, "STA", AM_ZeroPage)); - opcode_table->insert(0x95,AssyInstruction(0x95, "STA", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0xa5,AssyInstruction(0xa5, "LDA", AM_ZeroPage)); - opcode_table->insert(0xb5,AssyInstruction(0xb5, "LDA", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0xc5,AssyInstruction(0xc5, "CMP", AM_ZeroPage)); - opcode_table->insert(0xd5,AssyInstruction(0xd5, "CMP", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0xe5,AssyInstruction(0xe5, "SEC", AM_ZeroPage)); - opcode_table->insert(0xf5,AssyInstruction(0xf5, "SEC", AM_ZeroPageIndexedWithX)); + opcode_table->insert(0x05,AssyInstruction(0x05, "ORA", AM_ZeroPage, true, false, false)); + opcode_table->insert(0x15,AssyInstruction(0x15, "ORA", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0x25,AssyInstruction(0x25, "AND", AM_ZeroPage, true, false, false)); + opcode_table->insert(0x35,AssyInstruction(0x35, "AND", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0x45,AssyInstruction(0x45, "EOR", AM_ZeroPage, true, false, false)); + opcode_table->insert(0x55,AssyInstruction(0x55, "EOR", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0x65,AssyInstruction(0x65, "ADC", AM_ZeroPage, true, false, false)); + opcode_table->insert(0x75,AssyInstruction(0x75, "ADC", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0x85,AssyInstruction(0x85, "STA", AM_ZeroPage, false, true, false)); + opcode_table->insert(0x95,AssyInstruction(0x95, "STA", AM_ZeroPageIndexedWithX, false, true, false)); + opcode_table->insert(0xa5,AssyInstruction(0xa5, "LDA", AM_ZeroPage, true, false, false)); + opcode_table->insert(0xb5,AssyInstruction(0xb5, "LDA", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0xc5,AssyInstruction(0xc5, "CMP", AM_ZeroPage, true, false, false)); + opcode_table->insert(0xd5,AssyInstruction(0xd5, "CMP", AM_ZeroPageIndexedWithX, true, false, false)); + opcode_table->insert(0xe5,AssyInstruction(0xe5, "SBC", AM_ZeroPage, true, false, false)); + opcode_table->insert(0xf5,AssyInstruction(0xf5, "SBC", AM_ZeroPageIndexedWithX, true, false, false)); - opcode_table->insert(0x06,AssyInstruction(0x06, "ASL", AM_ZeroPage)); - opcode_table->insert(0x16,AssyInstruction(0x16, "ASL", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x26,AssyInstruction(0x26, "ROL", AM_ZeroPage)); - opcode_table->insert(0x36,AssyInstruction(0x36, "ROL", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x46,AssyInstruction(0x46, "LSR", AM_ZeroPage)); - opcode_table->insert(0x56,AssyInstruction(0x56, "LSR", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x66,AssyInstruction(0x66, "ROR", AM_ZeroPage)); - opcode_table->insert(0x76,AssyInstruction(0x76, "ROR", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0x86,AssyInstruction(0x86, "STX", AM_ZeroPage)); - opcode_table->insert(0x96,AssyInstruction(0x96, "STX", AM_ZeroPageIndexedWithY)); - opcode_table->insert(0xa6,AssyInstruction(0xa6, "LDX", AM_ZeroPage)); - opcode_table->insert(0xb6,AssyInstruction(0xb6, "LDX", AM_ZeroPageIndexedWithY)); - opcode_table->insert(0xc6,AssyInstruction(0xc6, "DEC", AM_ZeroPage)); - opcode_table->insert(0xd6,AssyInstruction(0xd6, "DEC", AM_ZeroPageIndexedWithX)); - opcode_table->insert(0xe6,AssyInstruction(0xe6, "INC", AM_ZeroPage)); - opcode_table->insert(0xf6,AssyInstruction(0xf6, "INC", AM_ZeroPageIndexedWithX)); + opcode_table->insert(0x06,AssyInstruction(0x06, "ASL", AM_ZeroPage, true, true, false)); + opcode_table->insert(0x16,AssyInstruction(0x16, "ASL", AM_ZeroPageIndexedWithX, true, true, false)); + opcode_table->insert(0x26,AssyInstruction(0x26, "ROL", AM_ZeroPage, true, true, false)); + opcode_table->insert(0x36,AssyInstruction(0x36, "ROL", AM_ZeroPageIndexedWithX, true, true, false)); + opcode_table->insert(0x46,AssyInstruction(0x46, "LSR", AM_ZeroPage, true, true, false)); + opcode_table->insert(0x56,AssyInstruction(0x56, "LSR", AM_ZeroPageIndexedWithX, true, true, false)); + opcode_table->insert(0x66,AssyInstruction(0x66, "ROR", AM_ZeroPage, true, true, false)); + opcode_table->insert(0x76,AssyInstruction(0x76, "ROR", AM_ZeroPageIndexedWithX, true, true, false)); + opcode_table->insert(0x86,AssyInstruction(0x86, "STX", AM_ZeroPage, false, true, false)); + opcode_table->insert(0x96,AssyInstruction(0x96, "STX", AM_ZeroPageIndexedWithY, false, true, false)); + opcode_table->insert(0xa6,AssyInstruction(0xa6, "LDX", AM_ZeroPage, true, false, false)); + opcode_table->insert(0xb6,AssyInstruction(0xb6, "LDX", AM_ZeroPageIndexedWithY, true, false, false)); + opcode_table->insert(0xc6,AssyInstruction(0xc6, "DEC", AM_ZeroPage, true, true, false)); + opcode_table->insert(0xd6,AssyInstruction(0xd6, "DEC", AM_ZeroPageIndexedWithX, true, true, false)); + opcode_table->insert(0xe6,AssyInstruction(0xe6, "INC", AM_ZeroPage, true, true, false)); + opcode_table->insert(0xf6,AssyInstruction(0xf6, "INC", AM_ZeroPageIndexedWithX, true, true, false)); opcode_table->insert(0x07,AssyInstruction(0x07, "???", AM_InvalidOp)); opcode_table->insert(0x17,AssyInstruction(0x17, "???", AM_InvalidOp)); @@ -160,21 +237,21 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) opcode_table->insert(0xf8,AssyInstruction(0xf8, "SED", AM_Implied)); opcode_table->insert(0x09,AssyInstruction(0x09, "ORA", AM_Immediate)); - opcode_table->insert(0x19,AssyInstruction(0x19, "ORA", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0x19,AssyInstruction(0x19, "ORA", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0x29,AssyInstruction(0x29, "AND", AM_Immediate)); - opcode_table->insert(0x39,AssyInstruction(0x39, "AND", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0x39,AssyInstruction(0x39, "AND", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0x49,AssyInstruction(0x49, "EOR", AM_Immediate)); - opcode_table->insert(0x59,AssyInstruction(0x59, "EOR", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0x59,AssyInstruction(0x59, "EOR", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0x69,AssyInstruction(0x69, "ADC", AM_Immediate)); - opcode_table->insert(0x79,AssyInstruction(0x79, "ADC", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0x79,AssyInstruction(0x79, "ADC", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0x89,AssyInstruction(0x89, "BIT", AM_Immediate)); //65C02 - opcode_table->insert(0x99,AssyInstruction(0x99, "STA", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0x99,AssyInstruction(0x99, "STA", AM_AbsoluteIndexedWithY, false, true, false)); opcode_table->insert(0xa9,AssyInstruction(0xa9, "LDA", AM_Immediate)); - opcode_table->insert(0xb9,AssyInstruction(0xb9, "LDA", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0xb9,AssyInstruction(0xb9, "LDA", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0xc9,AssyInstruction(0xc9, "CMP", AM_Immediate)); - opcode_table->insert(0xd9,AssyInstruction(0xd9, "CMP", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0xd9,AssyInstruction(0xd9, "CMP", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0xe9,AssyInstruction(0xe9, "SBC", AM_Immediate)); - opcode_table->insert(0xf9,AssyInstruction(0xf9, "SBC", AM_AbsoluteIndexedWithY)); + opcode_table->insert(0xf9,AssyInstruction(0xf9, "SBC", AM_AbsoluteIndexedWithY, true, false, false)); opcode_table->insert(0x0a,AssyInstruction(0x0a, "ASL", AM_Accumulator)); opcode_table->insert(0x1a,AssyInstruction(0x1a, "INA", AM_Accumulator)); //65C02 @@ -210,56 +287,56 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) opcode_table->insert(0xeb,AssyInstruction(0xeb, "???", AM_InvalidOp)); opcode_table->insert(0xfb,AssyInstruction(0xfb, "???", AM_InvalidOp)); - opcode_table->insert(0x0c,AssyInstruction(0x0c, "TSB", AM_Absolute)); //65C02 - opcode_table->insert(0x1c,AssyInstruction(0x1c, "TRB", AM_Absolute)); //65C02 - opcode_table->insert(0x2c,AssyInstruction(0x2c, "BIT", AM_Absolute)); - opcode_table->insert(0x3c,AssyInstruction(0x3c, "BIT", AM_AbsoluteIndexedWithX)); //65C02 + opcode_table->insert(0x0c,AssyInstruction(0x0c, "TSB", AM_Absolute, true, true, false)); //65C02 + opcode_table->insert(0x1c,AssyInstruction(0x1c, "TRB", AM_Absolute, true, true, false)); //65C02 + opcode_table->insert(0x2c,AssyInstruction(0x2c, "BIT", AM_Absolute, true, false, false)); + opcode_table->insert(0x3c,AssyInstruction(0x3c, "BIT", AM_AbsoluteIndexedWithX, true, false, false)); //65C02 opcode_table->insert(0x4c,AssyInstruction(0x4c, "JMP", AM_Absolute)); opcode_table->insert(0x5c,AssyInstruction(0x5c, "???", AM_InvalidOp)); - opcode_table->insert(0x6c,AssyInstruction(0x6c, "JMP", AM_AbsoluteIndirect)); - opcode_table->insert(0x7c,AssyInstruction(0x7c, "JMP", AM_AbsoluteIndexedIndirect)); //65C02 - opcode_table->insert(0x8c,AssyInstruction(0x8c, "STY", AM_Absolute)); - opcode_table->insert(0x9c,AssyInstruction(0x9c, "STZ", AM_Absolute)); - opcode_table->insert(0xac,AssyInstruction(0xac, "LDY", AM_Absolute)); - opcode_table->insert(0xbc,AssyInstruction(0xbc, "LDY", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0xcc,AssyInstruction(0xcc, "CPY", AM_Absolute)); + opcode_table->insert(0x6c,AssyInstruction(0x6c, "JMP", AM_AbsoluteIndirect, true, false, false)); + opcode_table->insert(0x7c,AssyInstruction(0x7c, "JMP", AM_AbsoluteIndexedIndirect, true, false, false)); //65C02 + opcode_table->insert(0x8c,AssyInstruction(0x8c, "STY", AM_Absolute, false, true, false)); + opcode_table->insert(0x9c,AssyInstruction(0x9c, "STZ", AM_Absolute, false, true, false)); + opcode_table->insert(0xac,AssyInstruction(0xac, "LDY", AM_Absolute, true, false, false)); + opcode_table->insert(0xbc,AssyInstruction(0xbc, "LDY", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0xcc,AssyInstruction(0xcc, "CPY", AM_Absolute, true, false, false)); opcode_table->insert(0xdc,AssyInstruction(0xdc, "???", AM_InvalidOp)); - opcode_table->insert(0xec,AssyInstruction(0xec, "CPX", AM_Absolute)); + opcode_table->insert(0xec,AssyInstruction(0xec, "CPX", AM_Absolute, true, false, false)); opcode_table->insert(0xfc,AssyInstruction(0xfc, "???", AM_InvalidOp)); - opcode_table->insert(0x0d,AssyInstruction(0x0d, "ORA", AM_Absolute)); - opcode_table->insert(0x1d,AssyInstruction(0x1d, "ORA", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x2d,AssyInstruction(0x2d, "AND", AM_Absolute)); - opcode_table->insert(0x3d,AssyInstruction(0x3d, "AND", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x4d,AssyInstruction(0x4d, "EOR", AM_Absolute)); - opcode_table->insert(0x5d,AssyInstruction(0x5d, "EOR", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x6d,AssyInstruction(0x6d, "ADC", AM_Absolute)); - opcode_table->insert(0x7d,AssyInstruction(0x7d, "ADC", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x8d,AssyInstruction(0x8d, "STA", AM_Absolute)); - opcode_table->insert(0x9d,AssyInstruction(0x9d, "STA", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0xad,AssyInstruction(0xad, "LDA", AM_Absolute)); - opcode_table->insert(0xbd,AssyInstruction(0xbd, "LDA", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0xcd,AssyInstruction(0xcd, "CMP", AM_Absolute)); - opcode_table->insert(0xdd,AssyInstruction(0xdd, "CMP", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0xed,AssyInstruction(0xed, "SBC", AM_Absolute)); - opcode_table->insert(0xfd,AssyInstruction(0xfd, "SBC", AM_AbsoluteIndexedWithX)); + opcode_table->insert(0x0d,AssyInstruction(0x0d, "ORA", AM_Absolute, true, false, false)); + opcode_table->insert(0x1d,AssyInstruction(0x1d, "ORA", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0x2d,AssyInstruction(0x2d, "AND", AM_Absolute, true, false, false)); + opcode_table->insert(0x3d,AssyInstruction(0x3d, "AND", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0x4d,AssyInstruction(0x4d, "EOR", AM_Absolute, true, false, false)); + opcode_table->insert(0x5d,AssyInstruction(0x5d, "EOR", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0x6d,AssyInstruction(0x6d, "ADC", AM_Absolute, true, false, false)); + opcode_table->insert(0x7d,AssyInstruction(0x7d, "ADC", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0x8d,AssyInstruction(0x8d, "STA", AM_Absolute, false, true, false)); + opcode_table->insert(0x9d,AssyInstruction(0x9d, "STA", AM_AbsoluteIndexedWithX, false, true, false)); + opcode_table->insert(0xad,AssyInstruction(0xad, "LDA", AM_Absolute, true, false, false)); + opcode_table->insert(0xbd,AssyInstruction(0xbd, "LDA", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0xcd,AssyInstruction(0xcd, "CMP", AM_Absolute, true, false, false)); + opcode_table->insert(0xdd,AssyInstruction(0xdd, "CMP", AM_AbsoluteIndexedWithX, true, false, false)); + opcode_table->insert(0xed,AssyInstruction(0xed, "SBC", AM_Absolute, true, false, false)); + opcode_table->insert(0xfd,AssyInstruction(0xfd, "SBC", AM_AbsoluteIndexedWithX, true, false, false)); - opcode_table->insert(0x0e,AssyInstruction(0x0e, "ASL", AM_Absolute)); - opcode_table->insert(0x1e,AssyInstruction(0x1e, "ASL", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x2e,AssyInstruction(0x2e, "ROL", AM_Absolute)); - opcode_table->insert(0x3e,AssyInstruction(0x3e, "ROL", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x4e,AssyInstruction(0x4e, "LSR", AM_Absolute)); - opcode_table->insert(0x5e,AssyInstruction(0x5e, "LSR", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x6e,AssyInstruction(0x6e, "ROR", AM_Absolute)); - opcode_table->insert(0x7e,AssyInstruction(0x7e, "ROR", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0x8e,AssyInstruction(0x8e, "STX", AM_Absolute)); - opcode_table->insert(0x9e,AssyInstruction(0x9e, "STZ", AM_AbsoluteIndexedWithX)); //65C02 - opcode_table->insert(0xae,AssyInstruction(0xae, "LDX", AM_Absolute)); - opcode_table->insert(0xbe,AssyInstruction(0xbe, "LDX", AM_AbsoluteIndexedWithY)); - opcode_table->insert(0xce,AssyInstruction(0xce, "DEC", AM_Absolute)); - opcode_table->insert(0xde,AssyInstruction(0xde, "DEC", AM_AbsoluteIndexedWithX)); - opcode_table->insert(0xee,AssyInstruction(0xee, "INC", AM_Absolute)); - opcode_table->insert(0xfe,AssyInstruction(0xfe, "INC", AM_AbsoluteIndexedWithX)); + opcode_table->insert(0x0e,AssyInstruction(0x0e, "ASL", AM_Absolute, true, true, false)); + opcode_table->insert(0x1e,AssyInstruction(0x1e, "ASL", AM_AbsoluteIndexedWithX, true, true, false)); + opcode_table->insert(0x2e,AssyInstruction(0x2e, "ROL", AM_Absolute, true, true, false)); + opcode_table->insert(0x3e,AssyInstruction(0x3e, "ROL", AM_AbsoluteIndexedWithX, true, true, false)); + opcode_table->insert(0x4e,AssyInstruction(0x4e, "LSR", AM_Absolute, true, true, false)); + opcode_table->insert(0x5e,AssyInstruction(0x5e, "LSR", AM_AbsoluteIndexedWithX, true, true, false)); + opcode_table->insert(0x6e,AssyInstruction(0x6e, "ROR", AM_Absolute, true, true, false)); + opcode_table->insert(0x7e,AssyInstruction(0x7e, "ROR", AM_AbsoluteIndexedWithX, true, true, false)); + opcode_table->insert(0x8e,AssyInstruction(0x8e, "STX", AM_Absolute, false, true, false)); + opcode_table->insert(0x9e,AssyInstruction(0x9e, "STZ", AM_AbsoluteIndexedWithX, false, true, false)); //65C02 + opcode_table->insert(0xae,AssyInstruction(0xae, "LDX", AM_Absolute, true, false, false)); + opcode_table->insert(0xbe,AssyInstruction(0xbe, "LDX", AM_AbsoluteIndexedWithY, true, false, false)); + opcode_table->insert(0xce,AssyInstruction(0xce, "DEC", AM_Absolute, true, true, false)); + opcode_table->insert(0xde,AssyInstruction(0xde, "DEC", AM_AbsoluteIndexedWithX, true, true, false)); + opcode_table->insert(0xee,AssyInstruction(0xee, "INC", AM_Absolute, true, true, false)); + opcode_table->insert(0xfe,AssyInstruction(0xfe, "INC", AM_AbsoluteIndexedWithX, true, true, false)); opcode_table->insert(0x0f,AssyInstruction(0x0f, "???", AM_InvalidOp)); opcode_table->insert(0x1f,AssyInstruction(0x1f, "???", AM_InvalidOp)); @@ -287,7 +364,7 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) m_opcodeinfo->insert(0x50,AssyInstruction(0x50, "BVC", AM_ProgramCounterRelative); m_opcodeinfo->insert(0x60,AssyInstruction(0x60, "RTS", AM_Implied)); m_opcodeinfo->insert(0x70,AssyInstruction(0x70, "BVS", AM_ProgramCounterRelative); - m_opcodeinfo->insert(0x80,AssyInstruction(0x80, "nop", AM_ZeroPage)); + m_opcodeinfo->insert(0x80,AssyInstruction(0x80, "nop", AM_ZeroPage, false, false, false)); m_opcodeinfo->insert(0x90,AssyInstruction(0x90, "BCC", AM_ProgramCounterRelative); m_opcodeinfo->insert(0xa0,AssyInstruction(0xa0, "LDY", AM_Immediate)); m_opcodeinfo->insert(0xb0,AssyInstruction(0xb0, "BCC", AM_ProgramCounterRelative); @@ -296,26 +373,26 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) m_opcodeinfo->insert(0xe0,AssyInstruction(0xe0, "CPX", AM_Immediate)); m_opcodeinfo->insert(0xf0,AssyInstruction(0xf0, "BEQ", AM_ProgramCounterRelative); - m_opcodeinfo->insert(0x01,AssyInstruction(0x01, "ORA", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0x11,AssyInstruction(0x11, "ORA", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0x21,AssyInstruction(0x21, "AND", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0x31,AssyInstruction(0x31, "AND", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0x41,AssyInstruction(0x41, "EOR", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0x51,AssyInstruction(0x51, "EOR", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0x61,AssyInstruction(0x61, "ADC", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0x71,AssyInstruction(0x71, "ADC", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0x81,AssyInstruction(0x81, "STA", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0x91,AssyInstruction(0x91, "STA", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0xa1,AssyInstruction(0xa1, "LDA", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0xb1,AssyInstruction(0xb1, "LDA", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0xc1,AssyInstruction(0xc1, "CMP", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0xd1,AssyInstruction(0xd1, "CMP", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0xe1,AssyInstruction(0xe1, "SBC", AM_AbsoluteIndexedIndirect)); - m_opcodeinfo->insert(0xf1,AssyInstruction(0xff, "SBC", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x01,AssyInstruction(0x01, "ORA", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x11,AssyInstruction(0x11, "ORA", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x21,AssyInstruction(0x21, "AND", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x31,AssyInstruction(0x31, "AND", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x41,AssyInstruction(0x41, "EOR", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x51,AssyInstruction(0x51, "EOR", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x61,AssyInstruction(0x61, "ADC", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x71,AssyInstruction(0x71, "ADC", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x81,AssyInstruction(0x81, "STA", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x91,AssyInstruction(0x91, "STA", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xa1,AssyInstruction(0xa1, "LDA", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0xb1,AssyInstruction(0xb1, "LDA", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xc1,AssyInstruction(0xc1, "CMP", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0xd1,AssyInstruction(0xd1, "CMP", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xe1,AssyInstruction(0xe1, "SBC", AM_AbsoluteIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0xf1,AssyInstruction(0xff, "SBC", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x02,AssyInstruction(0x02, "halt", AM_Immediate)); - m_opcodeinfo->insert(0x12,AssyInstruction(0x12, "asl-ora", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0x22,AssyInstruction(0x22, "and", AM_ZeroPageIndexedWithX)); + m_opcodeinfo->insert(0x12,AssyInstruction(0x12, "asl-ora", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x22,AssyInstruction(0x22, "and", AM_ZeroPageIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x32,AssyInstruction(0x32, "halt", AM_Immediate)); m_opcodeinfo->insert(0x42,AssyInstruction(0x42, "halt", AM_Immediate)); m_opcodeinfo->insert(0x52,AssyInstruction(0x52, "halt", AM_Immediate)); @@ -330,90 +407,90 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) m_opcodeinfo->insert(0xe2,AssyInstruction(0xe2, "halt", AM_Immediate)); m_opcodeinfo->insert(0xf2,AssyInstruction(0xf2, "halt", AM_Immediate)); - m_opcodeinfo->insert(0x03,AssyInstruction(0x03, "asl/ora", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0x13,AssyInstruction(0x13, "asl/ora", AM_ZeroPageIndirect)); - m_opcodeinfo->insert(0x23,AssyInstruction(0x23, "rol/and", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0x33,AssyInstruction(0x33, "rol/and", AM_ZeroPageIndexedWithY)); - m_opcodeinfo->insert(0x43,AssyInstruction(0x43, "lsr/eor", AM_ZeroPage)); - m_opcodeinfo->insert(0x53,AssyInstruction(0x53, "lsr/eor", AM_ZeroPageIndirectIndexedWithY)); - m_opcodeinfo->insert(0x63,AssyInstruction(0x63, "ror/adc", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0x73,AssyInstruction(0x73, "ror/adc", AM_ZeroPageIndirectIndexedWithY)); - m_opcodeinfo->insert(0x83,AssyInstruction(0x83, "sta/stx", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0x93,AssyInstruction(0x93, "sta/stx", AM_ZeroPageIndirectIndexedWithY)); - m_opcodeinfo->insert(0xa3,AssyInstruction(0xa3, "lda/ldx", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0xb3,AssyInstruction(0xb3, "lda/ldx", AM_ZeroPageIndirectIndexedWithY)); - m_opcodeinfo->insert(0xc3,AssyInstruction(0xc3, "dec/cmp", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0xd3,AssyInstruction(0xd3, "dec/cmp", AM_ZeroPageIndirectIndexedWithY)); - m_opcodeinfo->insert(0xe3,AssyInstruction(0xe3, "inc/sbc", AM_ZeroPageIndexedIndirect)); - m_opcodeinfo->insert(0xf3,AssyInstruction(0xf3, "inc/sbc", AM_ZeroPageIndirectIndexedWithY)); + m_opcodeinfo->insert(0x03,AssyInstruction(0x03, "asl/ora", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x13,AssyInstruction(0x13, "asl/ora", AM_ZeroPageIndirect, false, false, false)); + m_opcodeinfo->insert(0x23,AssyInstruction(0x23, "rol/and", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x33,AssyInstruction(0x33, "rol/and", AM_ZeroPageIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x43,AssyInstruction(0x43, "lsr/eor", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x53,AssyInstruction(0x53, "lsr/eor", AM_ZeroPageIndirectIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x63,AssyInstruction(0x63, "ror/adc", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x73,AssyInstruction(0x73, "ror/adc", AM_ZeroPageIndirectIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x83,AssyInstruction(0x83, "sta/stx", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0x93,AssyInstruction(0x93, "sta/stx", AM_ZeroPageIndirectIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xa3,AssyInstruction(0xa3, "lda/ldx", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0xb3,AssyInstruction(0xb3, "lda/ldx", AM_ZeroPageIndirectIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xc3,AssyInstruction(0xc3, "dec/cmp", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0xd3,AssyInstruction(0xd3, "dec/cmp", AM_ZeroPageIndirectIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xe3,AssyInstruction(0xe3, "inc/sbc", AM_ZeroPageIndexedIndirect, false, false, false)); + m_opcodeinfo->insert(0xf3,AssyInstruction(0xf3, "inc/sbc", AM_ZeroPageIndirectIndexedWithY, false, false, false)); - m_opcodeinfo->insert(0x04,AssyInstruction(0x04, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x14,AssyInstruction(0x14, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x24,AssyInstruction(0x24, "BIT", AM_ZeroPage)); - m_opcodeinfo->insert(0x34,AssyInstruction(0x34, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x44,AssyInstruction(0x44, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x54,AssyInstruction(0x54, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x64,AssyInstruction(0x64, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x74,AssyInstruction(0x74, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x84,AssyInstruction(0x84, "STY", AM_ZeroPage)); - m_opcodeinfo->insert(0x94,AssyInstruction(0x94, "STY", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0xa4,AssyInstruction(0xa4, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0xb4,AssyInstruction(0xb4, "LDY", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0xc4,AssyInstruction(0xc4, "CPY", AM_ZeroPage)); - m_opcodeinfo->insert(0xd4,AssyInstruction(0xd4, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0xe4,AssyInstruction(0xe4, "CPX", AM_ZeroPage)); - m_opcodeinfo->insert(0xf4,AssyInstruction(0xf4, "nop", AM_ZeroPage)); + m_opcodeinfo->insert(0x04,AssyInstruction(0x04, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x14,AssyInstruction(0x14, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x24,AssyInstruction(0x24, "BIT", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x34,AssyInstruction(0x34, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x44,AssyInstruction(0x44, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x54,AssyInstruction(0x54, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x64,AssyInstruction(0x64, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x74,AssyInstruction(0x74, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x84,AssyInstruction(0x84, "STY", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x94,AssyInstruction(0x94, "STY", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xa4,AssyInstruction(0xa4, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xb4,AssyInstruction(0xb4, "LDY", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xc4,AssyInstruction(0xc4, "CPY", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xd4,AssyInstruction(0xd4, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xe4,AssyInstruction(0xe4, "CPX", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xf4,AssyInstruction(0xf4, "nop", AM_ZeroPage, false, false, false)); - m_opcodeinfo->insert(0x05,AssyInstruction(0x05, "ORA", AM_ZeroPage)); - m_opcodeinfo->insert(0x15,AssyInstruction(0x15, "ORA", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x25,AssyInstruction(0x25, "AND", AM_ZeroPage)); - m_opcodeinfo->insert(0x35,AssyInstruction(0x35, "AND", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x45,AssyInstruction(0x45, "EOR", AM_ZeroPage)); - m_opcodeinfo->insert(0x55,AssyInstruction(0x55, "EOR", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x65,AssyInstruction(0x65, "ADC", AM_ZeroPage)); - m_opcodeinfo->insert(0x75,AssyInstruction(0x75, "ADC", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x85,AssyInstruction(0x85, "STA", AM_ZeroPage)); - m_opcodeinfo->insert(0x95,AssyInstruction(0x95, "STA", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0xa5,AssyInstruction(0xa5, "LDA", AM_ZeroPage)); - m_opcodeinfo->insert(0xb5,AssyInstruction(0xb5, "LDA", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0xc5,AssyInstruction(0xc5, "CMP", AM_ZeroPage)); - m_opcodeinfo->insert(0xd5,AssyInstruction(0xd5, "CMP", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0xe5,AssyInstruction(0xe5, "SEC", AM_ZeroPage)); - m_opcodeinfo->insert(0xf5,AssyInstruction(0xf5, "SEC", AM_ZeroPageIndexedWithX)); + m_opcodeinfo->insert(0x05,AssyInstruction(0x05, "ORA", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x15,AssyInstruction(0x15, "ORA", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x25,AssyInstruction(0x25, "AND", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x35,AssyInstruction(0x35, "AND", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x45,AssyInstruction(0x45, "EOR", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x55,AssyInstruction(0x55, "EOR", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x65,AssyInstruction(0x65, "ADC", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x75,AssyInstruction(0x75, "ADC", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x85,AssyInstruction(0x85, "STA", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x95,AssyInstruction(0x95, "STA", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xa5,AssyInstruction(0xa5, "LDA", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xb5,AssyInstruction(0xb5, "LDA", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xc5,AssyInstruction(0xc5, "CMP", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xd5,AssyInstruction(0xd5, "CMP", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xe5,AssyInstruction(0xe5, "SEC", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xf5,AssyInstruction(0xf5, "SEC", AM_ZeroPageIndexedWithX, false, false, false)); - m_opcodeinfo->insert(0x06,AssyInstruction(0x06, "ASL", AM_ZeroPage)); - m_opcodeinfo->insert(0x16,AssyInstruction(0x16, "ASL", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x26,AssyInstruction(0x26, "ROL", AM_ZeroPage)); - m_opcodeinfo->insert(0x36,AssyInstruction(0x36, "ROL", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x46,AssyInstruction(0x46, "LSR", AM_ZeroPage)); - m_opcodeinfo->insert(0x56,AssyInstruction(0x56, "LSR", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x66,AssyInstruction(0x66, "ROR", AM_ZeroPage)); - m_opcodeinfo->insert(0x76,AssyInstruction(0x76, "ROR", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x86,AssyInstruction(0x86, "STX", AM_ZeroPage)); - m_opcodeinfo->insert(0x96,AssyInstruction(0x96, "STX", AM_ZeroPageIndexedWithY)); - m_opcodeinfo->insert(0xa6,AssyInstruction(0xa6, "LDX", AM_ZeroPage)); - m_opcodeinfo->insert(0xb6,AssyInstruction(0xb6, "LDX", AM_ZeroPageIndexedWithY)); - m_opcodeinfo->insert(0xc6,AssyInstruction(0xc6, "DEC", AM_ZeroPage)); - m_opcodeinfo->insert(0xd6,AssyInstruction(0xd6, "DEC", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0xe6,AssyInstruction(0xe6, "INC", AM_ZeroPage)); - m_opcodeinfo->insert(0xf6,AssyInstruction(0xf6, "INC", AM_ZeroPageIndexedWithX)); + m_opcodeinfo->insert(0x06,AssyInstruction(0x06, "ASL", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x16,AssyInstruction(0x16, "ASL", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x26,AssyInstruction(0x26, "ROL", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x36,AssyInstruction(0x36, "ROL", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x46,AssyInstruction(0x46, "LSR", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x56,AssyInstruction(0x56, "LSR", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x66,AssyInstruction(0x66, "ROR", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x76,AssyInstruction(0x76, "ROR", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x86,AssyInstruction(0x86, "STX", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x96,AssyInstruction(0x96, "STX", AM_ZeroPageIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xa6,AssyInstruction(0xa6, "LDX", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xb6,AssyInstruction(0xb6, "LDX", AM_ZeroPageIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xc6,AssyInstruction(0xc6, "DEC", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xd6,AssyInstruction(0xd6, "DEC", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xe6,AssyInstruction(0xe6, "INC", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xf6,AssyInstruction(0xf6, "INC", AM_ZeroPageIndexedWithX, false, false, false)); - m_opcodeinfo->insert(0x07,AssyInstruction(0x07, "asl/ora", AM_ZeroPage)); - m_opcodeinfo->insert(0x17,AssyInstruction(0x17, "asl/ora", AM_ZeroPageIndirectIndexedWithY)); - m_opcodeinfo->insert(0x27,AssyInstruction(0x27, "rol/and", AM_ZeroPage)); - m_opcodeinfo->insert(0x37,AssyInstruction(0x37, "rol/and", AM_ZeroPageIndexedWithX)); - m_opcodeinfo->insert(0x47,AssyInstruction(0x47, "lsr/eor", AM_ZeroPage)); - m_opcodeinfo->insert(0x57,AssyInstruction(0x57, "lsr/eor", AM_AbsoluteIndexedWithX)); - m_opcodeinfo->insert(0x67,AssyInstruction(0x67, "ror/adc", AM_ZeroPage)); - m_opcodeinfo->insert(0x77,AssyInstruction(0x77, "ror/adc", AM_AbsoluteIndexedWithX)); - m_opcodeinfo->insert(0x87,AssyInstruction(0x87, "sta/stx", AM_ZeroPage)); - m_opcodeinfo->insert(0x97,AssyInstruction(0x97, "sta/stx", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0xa7,AssyInstruction(0xa7, "lda/ldx", AM_ZeroPage)); - m_opcodeinfo->insert(0xb7,AssyInstruction(0xb7, "ldx/ldx", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0xc7,AssyInstruction(0xc7, "dec/cmp", AM_ZeroPage)); - m_opcodeinfo->insert(0xd7,AssyInstruction(0xd7, "dec/cmp", AM_AbsoluteIndexedWithX)); - m_opcodeinfo->insert(0xe7,AssyInstruction(0xe7, "inc/sbc", AM_ZeroPage)); - m_opcodeinfo->insert(0xf7,AssyInstruction(0xf7, "inc/sbc", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x07,AssyInstruction(0x07, "asl/ora", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x17,AssyInstruction(0x17, "asl/ora", AM_ZeroPageIndirectIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x27,AssyInstruction(0x27, "rol/and", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x37,AssyInstruction(0x37, "rol/and", AM_ZeroPageIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x47,AssyInstruction(0x47, "lsr/eor", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x57,AssyInstruction(0x57, "lsr/eor", AM_AbsoluteIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x67,AssyInstruction(0x67, "ror/adc", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x77,AssyInstruction(0x77, "ror/adc", AM_AbsoluteIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0x87,AssyInstruction(0x87, "sta/stx", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x97,AssyInstruction(0x97, "sta/stx", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xa7,AssyInstruction(0xa7, "lda/ldx", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xb7,AssyInstruction(0xb7, "ldx/ldx", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0xc7,AssyInstruction(0xc7, "dec/cmp", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xd7,AssyInstruction(0xd7, "dec/cmp", AM_AbsoluteIndexedWithX, false, false, false)); + m_opcodeinfo->insert(0xe7,AssyInstruction(0xe7, "inc/sbc", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0xf7,AssyInstruction(0xf7, "inc/sbc", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x08,AssyInstruction(0x08, "PHP", AM_Implied)); m_opcodeinfo->insert(0x18,AssyInstruction(0x18, "CLC", AM_Implied)); @@ -433,21 +510,21 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) m_opcodeinfo->insert(0xf8,AssyInstruction(0xf8, "SED", AM_Implied)); m_opcodeinfo->insert(0x09,AssyInstruction(0x09, "ORA", AM_Immediate)); - m_opcodeinfo->insert(0x19,AssyInstruction(0x19, "ORA", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x19,AssyInstruction(0x19, "ORA", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x29,AssyInstruction(0x29, "AND", AM_Immediate)); - m_opcodeinfo->insert(0x39,AssyInstruction(0x39, "AND", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x39,AssyInstruction(0x39, "AND", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x49,AssyInstruction(0x49, "EOR", AM_Immediate)); - m_opcodeinfo->insert(0x59,AssyInstruction(0x59, "EOR", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x59,AssyInstruction(0x59, "EOR", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x69,AssyInstruction(0x69, "ADC", AM_Immediate)); - m_opcodeinfo->insert(0x79,AssyInstruction(0x79, "ADC", AM_AbsoluteIndexedWithY)); - m_opcodeinfo->insert(0x89,AssyInstruction(0x89, "nop", AM_ZeroPage)); - m_opcodeinfo->insert(0x99,AssyInstruction(0x99, "STA", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x79,AssyInstruction(0x79, "ADC", AM_AbsoluteIndexedWithY, false, false, false)); + m_opcodeinfo->insert(0x89,AssyInstruction(0x89, "nop", AM_ZeroPage, false, false, false)); + m_opcodeinfo->insert(0x99,AssyInstruction(0x99, "STA", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0xa9,AssyInstruction(0xa9, "LDA", AM_Immediate)); - m_opcodeinfo->insert(0xb9,AssyInstruction(0xb9, "LDA", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0xb9,AssyInstruction(0xb9, "LDA", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0xc9,AssyInstruction(0xc9, "CMP", AM_Immediate)); - m_opcodeinfo->insert(0xd9,AssyInstruction(0xd9, "CMP", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0xd9,AssyInstruction(0xd9, "CMP", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0xe9,AssyInstruction(0xe9, "SBC", AM_Immediate)); - m_opcodeinfo->insert(0xf9,AssyInstruction(0xf9, "SBC", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0xf9,AssyInstruction(0xf9, "SBC", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x0a,AssyInstruction(0x0a, "ASL", AM_Accumulator)); m_opcodeinfo->insert(0x1a,AssyInstruction(0x1a, "nop", AM_Implied)); @@ -467,15 +544,15 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) m_opcodeinfo->insert(0xfa,AssyInstruction(0xfa, "nop", AM_Implied)); m_opcodeinfo->insert(0x0b,AssyInstruction(0x0b, "and/mov bit7->Cy", AM_Immediate)); - m_opcodeinfo->insert(0x1b,AssyInstruction(0x1b, "asl/ora", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x1b,AssyInstruction(0x1b, "asl/ora", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x2b,AssyInstruction(0x2b, "and/mov bit7->Cy", AM_Immediate)); - m_opcodeinfo->insert(0x3b,AssyInstruction(0x3b, "asl/ora", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x3b,AssyInstruction(0x3b, "asl/ora", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x4b,AssyInstruction(0x4b, "and/lsr A", AM_Immediate)); - m_opcodeinfo->insert(0x5b,AssyInstruction(0x5b, "lsr/eor", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x5b,AssyInstruction(0x5b, "lsr/eor", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x6b,AssyInstruction(0x6b, "and/ror A", AM_Immediate)); - m_opcodeinfo->insert(0x7b,AssyInstruction(0x7b, "ror/adc", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x7b,AssyInstruction(0x7b, "ror/adc", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0x8b,AssyInstruction(0x8b, "txa/and", AM_Immediate)); - m_opcodeinfo->insert(0x9b,AssyInstruction(0x9b, "sta/stx", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0x9b,AssyInstruction(0x9b, "sta/stx", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0xab,AssyInstruction(0xab, "lda/ldx", AM_Implied)); m_opcodeinfo->insert(0xbb,AssyInstruction(0xbb, "lda/ldx", AM_Implied)); m_opcodeinfo->insert(0xcb,AssyInstruction(0xcb, "sbx", AM_Immediate)); @@ -489,78 +566,84 @@ void OpCodes::makeOpcodeTable(QHash* opcode_table) m_opcodeinfo->insert(0x3c,AssyInstruction(0x3c, "nop", AM_Absolute)); m_opcodeinfo->insert(0x4c,AssyInstruction(0x4c, "JMP", AM_Absolute)); m_opcodeinfo->insert(0x5c,AssyInstruction(0x5c, "nop", AM_Absolute)); - m_opcodeinfo->insert(0x6c,AssyInstruction(0x6c, "JMP", AM_AbsoluteIndirect)); + m_opcodeinfo->insert(0x6c,AssyInstruction(0x6c, "JMP", AM_AbsoluteIndirect, false, false, false)); m_opcodeinfo->insert(0x7c,AssyInstruction(0x7c, "nop", AM_Absolute)); m_opcodeinfo->insert(0x8c,AssyInstruction(0x8c, "STY", AM_Absolute)); - m_opcodeinfo->insert(0x9c,AssyInstruction(0x9c, "sta/stx", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x9c,AssyInstruction(0x9c, "sta/stx", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xac,AssyInstruction(0xac, "LDY", AM_Absolute)); - m_opcodeinfo->insert(0xbc,AssyInstruction(0xbc, "LDY", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xbc,AssyInstruction(0xbc, "LDY", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xcc,AssyInstruction(0xcc, "CPY", AM_Absolute)); m_opcodeinfo->insert(0xdc,AssyInstruction(0xdc, "???", AM_InvalidOp)); m_opcodeinfo->insert(0xec,AssyInstruction(0xec, "CPX", AM_Absolute)); m_opcodeinfo->insert(0xfc,AssyInstruction(0xfc, "???", AM_InvalidOp)); m_opcodeinfo->insert(0x0d,AssyInstruction(0x0d, "ORA", AM_Absolute)); - m_opcodeinfo->insert(0x1d,AssyInstruction(0x1d, "ORA", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x1d,AssyInstruction(0x1d, "ORA", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x2d,AssyInstruction(0x2d, "AND", AM_Absolute)); - m_opcodeinfo->insert(0x3d,AssyInstruction(0x3d, "AND", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x3d,AssyInstruction(0x3d, "AND", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x4d,AssyInstruction(0x4d, "EOR", AM_Absolute)); - m_opcodeinfo->insert(0x5d,AssyInstruction(0x5d, "EOR", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x5d,AssyInstruction(0x5d, "EOR", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x6d,AssyInstruction(0x6d, "ADC", AM_Absolute)); - m_opcodeinfo->insert(0x7d,AssyInstruction(0x7d, "ADC", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x7d,AssyInstruction(0x7d, "ADC", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x8d,AssyInstruction(0x8d, "STA", AM_Absolute)); - m_opcodeinfo->insert(0x9d,AssyInstruction(0x9d, "STA", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x9d,AssyInstruction(0x9d, "STA", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xad,AssyInstruction(0xad, "LDA", AM_Absolute)); - m_opcodeinfo->insert(0xbd,AssyInstruction(0xbd, "LDA", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xbd,AssyInstruction(0xbd, "LDA", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xcd,AssyInstruction(0xcd, "CMP", AM_Absolute)); - m_opcodeinfo->insert(0xdd,AssyInstruction(0xdd, "CMP", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xdd,AssyInstruction(0xdd, "CMP", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xed,AssyInstruction(0xed, "SBC", AM_Absolute)); - m_opcodeinfo->insert(0xfd,AssyInstruction(0xfd, "SBC", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xfd,AssyInstruction(0xfd, "SBC", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x0e,AssyInstruction(0x0e, "ASL", AM_Absolute)); - m_opcodeinfo->insert(0x1e,AssyInstruction(0x1e, "ASL", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x1e,AssyInstruction(0x1e, "ASL", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x2e,AssyInstruction(0x2e, "ROL", AM_Absolute)); - m_opcodeinfo->insert(0x3e,AssyInstruction(0x3e, "ROL", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x3e,AssyInstruction(0x3e, "ROL", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x4e,AssyInstruction(0x4e, "LSR", AM_Absolute)); - m_opcodeinfo->insert(0x5e,AssyInstruction(0x5e, "LSR", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x5e,AssyInstruction(0x5e, "LSR", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x6e,AssyInstruction(0x6e, "ROR", AM_Absolute)); - m_opcodeinfo->insert(0x7e,AssyInstruction(0x7e, "ROR", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x7e,AssyInstruction(0x7e, "ROR", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x8e,AssyInstruction(0x8e, "STX", AM_Absolute)); - m_opcodeinfo->insert(0x9e,AssyInstruction(0x9e, "sta/stx", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x9e,AssyInstruction(0x9e, "sta/stx", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xae,AssyInstruction(0xae, "LDX", AM_Absolute)); - m_opcodeinfo->insert(0xbe,AssyInstruction(0xbe, "LDX", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0xbe,AssyInstruction(0xbe, "LDX", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0xce,AssyInstruction(0xce, "DEC", AM_Absolute)); - m_opcodeinfo->insert(0xde,AssyInstruction(0xde, "DEC", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xde,AssyInstruction(0xde, "DEC", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xee,AssyInstruction(0xee, "INC", AM_Absolute)); - m_opcodeinfo->insert(0xfe,AssyInstruction(0xfe, "INC", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xfe,AssyInstruction(0xfe, "INC", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x0f,AssyInstruction(0x0f, "asl/ora", AM_Absolute)); - m_opcodeinfo->insert(0x1f,AssyInstruction(0x1f, "asl/ora", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x1f,AssyInstruction(0x1f, "asl/ora", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x2f,AssyInstruction(0x2f, "rol/and", AM_Absolute)); - m_opcodeinfo->insert(0x3f,AssyInstruction(0x3f, "rol/and", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x3f,AssyInstruction(0x3f, "rol/and", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x4f,AssyInstruction(0x4f, "lsr/eor", AM_Absolute)); - m_opcodeinfo->insert(0x5f,AssyInstruction(0x5f, "lsr/eor", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x5f,AssyInstruction(0x5f, "lsr/eor", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x6f,AssyInstruction(0x6f, "ror/adc", AM_Absolute)); - m_opcodeinfo->insert(0x7f,AssyInstruction(0x7f, "ror/adc", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x7f,AssyInstruction(0x7f, "ror/adc", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0x8f,AssyInstruction(0x8f, "sta/stx", AM_Absolute)); - m_opcodeinfo->insert(0x9f,AssyInstruction(0x9f, "sta/stx", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0x9f,AssyInstruction(0x9f, "sta/stx", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xaf,AssyInstruction(0xaf, "lda/ldx", AM_Absolute)); - m_opcodeinfo->insert(0xbf,AssyInstruction(0xbf, "ldx/ldx", AM_AbsoluteIndexedWithY)); + m_opcodeinfo->insert(0xbf,AssyInstruction(0xbf, "ldx/ldx", AM_AbsoluteIndexedWithY, false, false, false)); m_opcodeinfo->insert(0xcf,AssyInstruction(0xcf, "dec/cmp", AM_Absolute)); - m_opcodeinfo->insert(0xdf,AssyInstruction(0xdf, "dec/cmp", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xdf,AssyInstruction(0xdf, "dec/cmp", AM_AbsoluteIndexedWithX, false, false, false)); m_opcodeinfo->insert(0xef,AssyInstruction(0xef, "inc/sbc", AM_Absolute)); - m_opcodeinfo->insert(0xff,AssyInstruction(0xff, "inc/sbc", AM_AbsoluteIndexedWithX)); + m_opcodeinfo->insert(0xff,AssyInstruction(0xff, "inc/sbc", AM_AbsoluteIndexedWithX, false, false, false)); #endif } -AssyInstruction::AssyInstruction(quint8 opcode, QString mnemonic, AddressMode am) { + +OpCodes::AssyInstruction::AssyInstruction(quint8 opcode, QString mnemonic, AddressMode am, bool reads, bool writes, bool stack) +{ m_opcode = opcode; m_mnemonic = mnemonic; m_addressMode = am; + m_reads = reads; + m_writes = writes; + m_stack = stack; } -quint8 AssyInstruction::numArgs() { +quint8 OpCodes::AssyInstruction::numArgs() const +{ switch (m_addressMode) { case AM_Absolute: case AM_AbsoluteIndexedIndirect: diff --git a/src/util/opcodes.h b/src/util/opcodes.h index 9697805..b2544b9 100644 --- a/src/util/opcodes.h +++ b/src/util/opcodes.h @@ -26,30 +26,39 @@ enum AddressMode { AM_ZeroPageIndirectIndexedWithY // (zp),y }; -struct AssyInstruction { - -public: - - AssyInstruction(quint8 opcode = 0x00, QString mnemonic = "???", AddressMode am = AM_InvalidOp); - - AddressMode addressMode() { return m_addressMode; } - - QString mnemonic() { return m_mnemonic; } - - quint8 opcode() { return m_opcode; } - - quint8 numArgs(); - - 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; -}; 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) @@ -67,6 +76,21 @@ public: 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);