diff --git a/src/binaryfile/disassembler.cxx b/src/binaryfile/disassembler.cxx index f57e616..888de1b 100644 --- a/src/binaryfile/disassembler.cxx +++ b/src/binaryfile/disassembler.cxx @@ -4,14 +4,14 @@ #include -QList Disassembler::disassemble(quint16 from, quint16 to) { - QList retval; +QList Disassembler::disassemble(quint16 from, quint16 to) { + QList retval; quint16 next = 0; for (int idx = from; idx <= to; ) { - QStringList line = disassembleOp(quint16(idx), &next); - retval.append(line); + DisassembledItem item = disassembleOp(quint16(idx), &next); + retval.append(item); idx = next ; if (idx > 0xffff || (next < from)) { qDebug() << "Breaking."; @@ -23,8 +23,10 @@ QList Disassembler::disassemble(quint16 from, quint16 to) { } -QStringList Disassembler::disassembleOp(quint16 address, quint16 *nextAddress) +DisassembledItem Disassembler::disassembleOp(quint16 address, quint16 *nextAddress) { + DisassembledItem retval; + quint8 opcode = m_memimage[address]; AssyInstruction op = m_opcodeinfo[opcode]; @@ -38,7 +40,7 @@ QStringList Disassembler::disassembleOp(quint16 address, quint16 *nextAddress) hexValues.append(val); } - QString addressStr = QString("%1 ").arg(address,4,16,QChar('0')).toUpper(); + for (int idx = 0; idx < hexValues.length(); idx++) { hexValueString.append(QString("%1 ").arg((quint8) hexValues[idx],2,16,QChar('0'))); @@ -100,6 +102,8 @@ QStringList Disassembler::disassembleOp(quint16 address, quint16 *nextAddress) qint8 offset = (qint8) hexValues[1]; quint16 offsetAddress = address+2+offset; + retval.setTargetAddress(offsetAddress); + disassemblyLine = QString("%1 $%2 {%3%4}").arg(op.mnemonic()) .arg((quint16) offsetAddress,4,16,QChar('0')) .arg((offset<0)?"-":"+") @@ -143,10 +147,14 @@ QStringList Disassembler::disassembleOp(quint16 address, quint16 *nextAddress) } } - QStringList retval; - retval.append(addressStr.trimmed()); - retval.append(hexValueString.trimmed().toUpper().leftJustified(12,' ')); - retval.append(disassemblyLine.toUpper()); + if (opcode == 0x20 || opcode == 0x4c) { + retval.setTargetAddress(hexValues[2]*256 + hexValues[1]); + } + + retval.setAddress(address); + retval.setDisassembledString(disassemblyLine.toUpper()); + retval.setHexString(hexValueString.trimmed().toUpper().leftJustified(12,' ')); + retval.setHexValues(hexValues); return retval; } diff --git a/src/binaryfile/disassembler.h b/src/binaryfile/disassembler.h index 826c3d0..fa004a3 100644 --- a/src/binaryfile/disassembler.h +++ b/src/binaryfile/disassembler.h @@ -23,6 +23,7 @@ enum AddressMode { AM_ZeroPageIndirect, // (zp) AM_ZeroPageIndirectIndexedWithY // (zp),y }; +////////////////////////////////////////////////////////////////////////////// struct AssyInstruction { @@ -69,6 +70,73 @@ private: quint8 m_opcode; AddressMode m_addressMode; }; +////////////////////////////////////////////////////////////////////////////// + +class DisassembledItem { +public: + DisassembledItem() { init(); } + + DisassembledItem(AssyInstruction instr) { + setInstruction(instr); + } + + + void setInstruction(AssyInstruction instr) { + m_instruction = instr; + 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) + } + + 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; } + + AssyInstruction assyInstruction() const { return m_instruction; } + QString disassembledString() const { return m_disassembly_text; } + quint16 address() const { return m_address; } + QString hexAddress() const { return QString("%1").arg(m_address,4,16,QChar('0')).toUpper(); } + 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; } + quint16 targetAddress() const { return m_target_address; } + +private: + void init() { + m_address = m_target_address = 0; + m_is_jump = m_is_branch = m_is_jsr = false; + m_unknown_ta = true; + } + + quint16 m_address; + QByteArray m_hexvalues; + QString m_disassembly_text; + QString m_hexstring; + bool m_is_branch; + bool m_is_jump; + bool m_is_jsr; + quint16 m_target_address; + AssyInstruction m_instruction; + bool m_unknown_ta; +}; + ////////////////////////////////////////////////////////////////////////////// @@ -82,11 +150,11 @@ public: P65C02 }; - QList disassemble(quint16 from, quint16 to); + QList disassemble(quint16 from, quint16 to); private: - QStringList disassembleOp(quint16 address, quint16 *nextAddress = 0); + DisassembledItem disassembleOp(quint16 address, quint16 *nextAddress = 0); void makeOpcodeTable(); QHash m_opcodeinfo; diff --git a/src/ui/viewers/disassemblerviewer.cpp b/src/ui/viewers/disassemblerviewer.cpp index 37a01d2..fde4976 100644 --- a/src/ui/viewers/disassemblerviewer.cpp +++ b/src/ui/viewers/disassemblerviewer.cpp @@ -29,12 +29,12 @@ void DisassemblerViewer::setFile(BinaryFile *file) { mem.addFile(file->data(), address); Disassembler dis(mem.values()); - QList lines = dis.disassemble(file->address(), file->address()+file->length()); + QList lines = dis.disassemble(file->address(), file->address()+file->length()); QStringList formattedLines; - foreach (QStringList line, lines) { - QString newline = QString("%1: %2 %3").arg(line[0]).arg(line[1]).arg(line[2]); + foreach (DisassembledItem di, lines) { + QString newline = QString("%1: %2 %3").arg(di.hexAddress()).arg(di.hexString()).arg(di.disassembledString()); formattedLines.append(newline); }