mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	citra-qt: Remove disassembler widget
It has performance problems, a very misleading UI, and is broken in general. It has essentially been superceded by the GDB stub, but if we wanted a built-in disassembler in the future it'd essentially need to be rewritten from scratch anyway. Closes #427, #1480
This commit is contained in:
		
							parent
							
								
									e33558c6ce
								
							
						
					
					
						commit
						47e806b084
					
				@ -12,7 +12,6 @@ set(SRCS
 | 
				
			|||||||
            configuration/configure_input.cpp
 | 
					            configuration/configure_input.cpp
 | 
				
			||||||
            configuration/configure_system.cpp
 | 
					            configuration/configure_system.cpp
 | 
				
			||||||
            debugger/callstack.cpp
 | 
					            debugger/callstack.cpp
 | 
				
			||||||
            debugger/disassembler.cpp
 | 
					 | 
				
			||||||
            debugger/graphics/graphics.cpp
 | 
					            debugger/graphics/graphics.cpp
 | 
				
			||||||
            debugger/graphics/graphics_breakpoint_observer.cpp
 | 
					            debugger/graphics/graphics_breakpoint_observer.cpp
 | 
				
			||||||
            debugger/graphics/graphics_breakpoints.cpp
 | 
					            debugger/graphics/graphics_breakpoints.cpp
 | 
				
			||||||
@ -44,7 +43,6 @@ set(HEADERS
 | 
				
			|||||||
            configuration/configure_input.h
 | 
					            configuration/configure_input.h
 | 
				
			||||||
            configuration/configure_system.h
 | 
					            configuration/configure_system.h
 | 
				
			||||||
            debugger/callstack.h
 | 
					            debugger/callstack.h
 | 
				
			||||||
            debugger/disassembler.h
 | 
					 | 
				
			||||||
            debugger/graphics/graphics.h
 | 
					            debugger/graphics/graphics.h
 | 
				
			||||||
            debugger/graphics/graphics_breakpoint_observer.h
 | 
					            debugger/graphics/graphics_breakpoint_observer.h
 | 
				
			||||||
            debugger/graphics/graphics_breakpoints.h
 | 
					            debugger/graphics/graphics_breakpoints.h
 | 
				
			||||||
@ -75,7 +73,6 @@ set(UIS
 | 
				
			|||||||
            configuration/configure_input.ui
 | 
					            configuration/configure_input.ui
 | 
				
			||||||
            configuration/configure_system.ui
 | 
					            configuration/configure_system.ui
 | 
				
			||||||
            debugger/callstack.ui
 | 
					            debugger/callstack.ui
 | 
				
			||||||
            debugger/disassembler.ui
 | 
					 | 
				
			||||||
            debugger/registers.ui
 | 
					            debugger/registers.ui
 | 
				
			||||||
            hotkeys.ui
 | 
					            hotkeys.ui
 | 
				
			||||||
            main.ui
 | 
					            main.ui
 | 
				
			||||||
 | 
				
			|||||||
@ -1,272 +0,0 @@
 | 
				
			|||||||
// Copyright 2014 Citra Emulator Project
 | 
					 | 
				
			||||||
// Licensed under GPLv2 or any later version
 | 
					 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <QShortcut>
 | 
					 | 
				
			||||||
#include "citra_qt/bootmanager.h"
 | 
					 | 
				
			||||||
#include "citra_qt/debugger/disassembler.h"
 | 
					 | 
				
			||||||
#include "citra_qt/hotkeys.h"
 | 
					 | 
				
			||||||
#include "citra_qt/util/util.h"
 | 
					 | 
				
			||||||
#include "common/break_points.h"
 | 
					 | 
				
			||||||
#include "common/symbols.h"
 | 
					 | 
				
			||||||
#include "core/arm/arm_interface.h"
 | 
					 | 
				
			||||||
#include "core/arm/disassembler/arm_disasm.h"
 | 
					 | 
				
			||||||
#include "core/core.h"
 | 
					 | 
				
			||||||
#include "core/memory.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DisassemblerModel::DisassemblerModel(QObject* parent)
 | 
					 | 
				
			||||||
    : QAbstractListModel(parent), base_address(0), code_size(0), program_counter(0),
 | 
					 | 
				
			||||||
      selection(QModelIndex()) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int DisassemblerModel::columnCount(const QModelIndex& parent) const {
 | 
					 | 
				
			||||||
    return 3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int DisassemblerModel::rowCount(const QModelIndex& parent) const {
 | 
					 | 
				
			||||||
    return code_size;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QVariant DisassemblerModel::data(const QModelIndex& index, int role) const {
 | 
					 | 
				
			||||||
    switch (role) {
 | 
					 | 
				
			||||||
    case Qt::DisplayRole: {
 | 
					 | 
				
			||||||
        u32 address = base_address + index.row() * 4;
 | 
					 | 
				
			||||||
        u32 instr = Memory::Read32(address);
 | 
					 | 
				
			||||||
        std::string disassembly = ARM_Disasm::Disassemble(address, instr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (index.column() == 0) {
 | 
					 | 
				
			||||||
            return QString("0x%1").arg((uint)(address), 8, 16, QLatin1Char('0'));
 | 
					 | 
				
			||||||
        } else if (index.column() == 1) {
 | 
					 | 
				
			||||||
            return QString::fromStdString(disassembly);
 | 
					 | 
				
			||||||
        } else if (index.column() == 2) {
 | 
					 | 
				
			||||||
            if (Symbols::HasSymbol(address)) {
 | 
					 | 
				
			||||||
                TSymbol symbol = Symbols::GetSymbol(address);
 | 
					 | 
				
			||||||
                return QString("%1 - Size:%2")
 | 
					 | 
				
			||||||
                    .arg(QString::fromStdString(symbol.name))
 | 
					 | 
				
			||||||
                    .arg(symbol.size / 4); // divide by 4 to get instruction count
 | 
					 | 
				
			||||||
            } else if (ARM_Disasm::Decode(instr) == OP_BL) {
 | 
					 | 
				
			||||||
                u32 offset = instr & 0xFFFFFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Sign-extend the 24-bit offset
 | 
					 | 
				
			||||||
                if ((offset >> 23) & 1)
 | 
					 | 
				
			||||||
                    offset |= 0xFF000000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Pre-compute the left-shift and the prefetch offset
 | 
					 | 
				
			||||||
                offset <<= 2;
 | 
					 | 
				
			||||||
                offset += 8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                TSymbol symbol = Symbols::GetSymbol(address + offset);
 | 
					 | 
				
			||||||
                return QString("    --> %1").arg(QString::fromStdString(symbol.name));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case Qt::BackgroundRole: {
 | 
					 | 
				
			||||||
        unsigned int address = base_address + 4 * index.row();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (breakpoints.IsAddressBreakPoint(address))
 | 
					 | 
				
			||||||
            return QBrush(QColor(0xFF, 0xC0, 0xC0));
 | 
					 | 
				
			||||||
        else if (address == program_counter)
 | 
					 | 
				
			||||||
            return QBrush(QColor(0xC0, 0xC0, 0xFF));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case Qt::FontRole: {
 | 
					 | 
				
			||||||
        if (index.column() == 0 || index.column() == 1) { // 2 is the symbols column
 | 
					 | 
				
			||||||
            return GetMonospaceFont();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return QVariant();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QModelIndex DisassemblerModel::IndexFromAbsoluteAddress(unsigned int address) const {
 | 
					 | 
				
			||||||
    return index((address - base_address) / 4, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const BreakPoints& DisassemblerModel::GetBreakPoints() const {
 | 
					 | 
				
			||||||
    return breakpoints;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerModel::ParseFromAddress(unsigned int address) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // NOTE: A too large value causes lagging when scrolling the disassembly
 | 
					 | 
				
			||||||
    const unsigned int chunk_size = 1000 * 500;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // If we haven't loaded anything yet, initialize base address to the parameter address
 | 
					 | 
				
			||||||
    if (code_size == 0)
 | 
					 | 
				
			||||||
        base_address = address;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // If the new area is already loaded, just continue
 | 
					 | 
				
			||||||
    if (base_address + code_size > address + chunk_size && base_address <= address)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Insert rows before currently loaded data
 | 
					 | 
				
			||||||
    if (base_address > address) {
 | 
					 | 
				
			||||||
        unsigned int num_rows = (address - base_address) / 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        beginInsertRows(QModelIndex(), 0, num_rows);
 | 
					 | 
				
			||||||
        code_size += num_rows;
 | 
					 | 
				
			||||||
        base_address = address;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        endInsertRows();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Insert rows after currently loaded data
 | 
					 | 
				
			||||||
    if (base_address + code_size < address + chunk_size) {
 | 
					 | 
				
			||||||
        unsigned int num_rows = (base_address + chunk_size - code_size - address) / 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        beginInsertRows(QModelIndex(), 0, num_rows);
 | 
					 | 
				
			||||||
        code_size += num_rows;
 | 
					 | 
				
			||||||
        endInsertRows();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SetNextInstruction(address);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerModel::OnSelectionChanged(const QModelIndex& new_selection) {
 | 
					 | 
				
			||||||
    selection = new_selection;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerModel::OnSetOrUnsetBreakpoint() {
 | 
					 | 
				
			||||||
    if (!selection.isValid())
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unsigned int address = base_address + selection.row() * 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (breakpoints.IsAddressBreakPoint(address)) {
 | 
					 | 
				
			||||||
        breakpoints.Remove(address);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        breakpoints.Add(address);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    emit dataChanged(selection, selection);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerModel::SetNextInstruction(unsigned int address) {
 | 
					 | 
				
			||||||
    QModelIndex cur_index = IndexFromAbsoluteAddress(program_counter);
 | 
					 | 
				
			||||||
    QModelIndex prev_index = IndexFromAbsoluteAddress(address);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    program_counter = address;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    emit dataChanged(cur_index, cur_index);
 | 
					 | 
				
			||||||
    emit dataChanged(prev_index, prev_index);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread)
 | 
					 | 
				
			||||||
    : QDockWidget(parent), base_addr(0), emu_thread(emu_thread) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    disasm_ui.setupUi(this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    RegisterHotkey("Disassembler", "Start/Stop", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut);
 | 
					 | 
				
			||||||
    RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut);
 | 
					 | 
				
			||||||
    RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut);
 | 
					 | 
				
			||||||
    RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9),
 | 
					 | 
				
			||||||
                   Qt::ApplicationShortcut);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep()));
 | 
					 | 
				
			||||||
    connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause()));
 | 
					 | 
				
			||||||
    connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this,
 | 
					 | 
				
			||||||
            SLOT(OnToggleStartStop()));
 | 
					 | 
				
			||||||
    connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep()));
 | 
					 | 
				
			||||||
    connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this,
 | 
					 | 
				
			||||||
            SLOT(OnStepInto()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    setEnabled(false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::Init() {
 | 
					 | 
				
			||||||
    model->ParseFromAddress(Core::CPU().GetPC());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    disasm_ui.treeView->resizeColumnToContents(0);
 | 
					 | 
				
			||||||
    disasm_ui.treeView->resizeColumnToContents(1);
 | 
					 | 
				
			||||||
    disasm_ui.treeView->resizeColumnToContents(2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    QModelIndex model_index = model->IndexFromAbsoluteAddress(Core::CPU().GetPC());
 | 
					 | 
				
			||||||
    disasm_ui.treeView->scrollTo(model_index);
 | 
					 | 
				
			||||||
    disasm_ui.treeView->selectionModel()->setCurrentIndex(
 | 
					 | 
				
			||||||
        model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnContinue() {
 | 
					 | 
				
			||||||
    emu_thread->SetRunning(true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnStep() {
 | 
					 | 
				
			||||||
    OnStepInto(); // change later
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnStepInto() {
 | 
					 | 
				
			||||||
    emu_thread->SetRunning(false);
 | 
					 | 
				
			||||||
    emu_thread->ExecStep();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnPause() {
 | 
					 | 
				
			||||||
    emu_thread->SetRunning(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO: By now, the CPU might not have actually stopped...
 | 
					 | 
				
			||||||
    if (Core::System::GetInstance().IsPoweredOn()) {
 | 
					 | 
				
			||||||
        model->SetNextInstruction(Core::CPU().GetPC());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnToggleStartStop() {
 | 
					 | 
				
			||||||
    emu_thread->SetRunning(!emu_thread->IsRunning());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnDebugModeEntered() {
 | 
					 | 
				
			||||||
    u32 next_instr = Core::CPU().GetPC();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (model->GetBreakPoints().IsAddressBreakPoint(next_instr))
 | 
					 | 
				
			||||||
        emu_thread->SetRunning(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    model->SetNextInstruction(next_instr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    QModelIndex model_index = model->IndexFromAbsoluteAddress(next_instr);
 | 
					 | 
				
			||||||
    disasm_ui.treeView->scrollTo(model_index);
 | 
					 | 
				
			||||||
    disasm_ui.treeView->selectionModel()->setCurrentIndex(
 | 
					 | 
				
			||||||
        model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnDebugModeLeft() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int DisassemblerWidget::SelectedRow() {
 | 
					 | 
				
			||||||
    QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex();
 | 
					 | 
				
			||||||
    if (!index.isValid())
 | 
					 | 
				
			||||||
        return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return disasm_ui.treeView->selectionModel()->currentIndex().row();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnEmulationStarting(EmuThread* emu_thread) {
 | 
					 | 
				
			||||||
    this->emu_thread = emu_thread;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    model = new DisassemblerModel(this);
 | 
					 | 
				
			||||||
    disasm_ui.treeView->setModel(model);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    connect(disasm_ui.treeView->selectionModel(),
 | 
					 | 
				
			||||||
            SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), model,
 | 
					 | 
				
			||||||
            SLOT(OnSelectionChanged(const QModelIndex&)));
 | 
					 | 
				
			||||||
    connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), model, SLOT(OnSetOrUnsetBreakpoint()));
 | 
					 | 
				
			||||||
    connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), model,
 | 
					 | 
				
			||||||
            SLOT(OnSetOrUnsetBreakpoint()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Init();
 | 
					 | 
				
			||||||
    setEnabled(true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DisassemblerWidget::OnEmulationStopping() {
 | 
					 | 
				
			||||||
    disasm_ui.treeView->setModel(nullptr);
 | 
					 | 
				
			||||||
    delete model;
 | 
					 | 
				
			||||||
    emu_thread = nullptr;
 | 
					 | 
				
			||||||
    setEnabled(false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,76 +0,0 @@
 | 
				
			|||||||
// Copyright 2014 Citra Emulator Project
 | 
					 | 
				
			||||||
// Licensed under GPLv2 or any later version
 | 
					 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <QAbstractListModel>
 | 
					 | 
				
			||||||
#include <QDockWidget>
 | 
					 | 
				
			||||||
#include "common/break_points.h"
 | 
					 | 
				
			||||||
#include "common/common_types.h"
 | 
					 | 
				
			||||||
#include "ui_disassembler.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class QAction;
 | 
					 | 
				
			||||||
class EmuThread;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DisassemblerModel : public QAbstractListModel {
 | 
					 | 
				
			||||||
    Q_OBJECT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    explicit DisassemblerModel(QObject* parent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int columnCount(const QModelIndex& parent = QModelIndex()) const override;
 | 
					 | 
				
			||||||
    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
 | 
					 | 
				
			||||||
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    QModelIndex IndexFromAbsoluteAddress(unsigned int address) const;
 | 
					 | 
				
			||||||
    const BreakPoints& GetBreakPoints() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public slots:
 | 
					 | 
				
			||||||
    void ParseFromAddress(unsigned int address);
 | 
					 | 
				
			||||||
    void OnSelectionChanged(const QModelIndex&);
 | 
					 | 
				
			||||||
    void OnSetOrUnsetBreakpoint();
 | 
					 | 
				
			||||||
    void SetNextInstruction(unsigned int address);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
    unsigned int base_address;
 | 
					 | 
				
			||||||
    unsigned int code_size;
 | 
					 | 
				
			||||||
    unsigned int program_counter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    QModelIndex selection;
 | 
					 | 
				
			||||||
    BreakPoints breakpoints;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DisassemblerWidget : public QDockWidget {
 | 
					 | 
				
			||||||
    Q_OBJECT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    DisassemblerWidget(QWidget* parent, EmuThread* emu_thread);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public slots:
 | 
					 | 
				
			||||||
    void OnContinue();
 | 
					 | 
				
			||||||
    void OnStep();
 | 
					 | 
				
			||||||
    void OnStepInto();
 | 
					 | 
				
			||||||
    void OnPause();
 | 
					 | 
				
			||||||
    void OnToggleStartStop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void OnDebugModeEntered();
 | 
					 | 
				
			||||||
    void OnDebugModeLeft();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void OnEmulationStarting(EmuThread* emu_thread);
 | 
					 | 
				
			||||||
    void OnEmulationStopping();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
    // returns -1 if no row is selected
 | 
					 | 
				
			||||||
    int SelectedRow();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Ui::DockWidget disasm_ui;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DisassemblerModel* model;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    u32 base_addr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    EmuThread* emu_thread;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -1,81 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<ui version="4.0">
 | 
					 | 
				
			||||||
 <class>DockWidget</class>
 | 
					 | 
				
			||||||
 <widget class="QDockWidget" name="DockWidget">
 | 
					 | 
				
			||||||
  <property name="geometry">
 | 
					 | 
				
			||||||
   <rect>
 | 
					 | 
				
			||||||
    <x>0</x>
 | 
					 | 
				
			||||||
    <y>0</y>
 | 
					 | 
				
			||||||
    <width>430</width>
 | 
					 | 
				
			||||||
    <height>401</height>
 | 
					 | 
				
			||||||
   </rect>
 | 
					 | 
				
			||||||
  </property>
 | 
					 | 
				
			||||||
  <property name="windowTitle">
 | 
					 | 
				
			||||||
   <string>Disassembly</string>
 | 
					 | 
				
			||||||
  </property>
 | 
					 | 
				
			||||||
  <widget class="QWidget" name="dockWidgetContents">
 | 
					 | 
				
			||||||
   <layout class="QVBoxLayout" name="verticalLayout">
 | 
					 | 
				
			||||||
    <item>
 | 
					 | 
				
			||||||
     <layout class="QHBoxLayout" name="horizontalLayout">
 | 
					 | 
				
			||||||
      <item>
 | 
					 | 
				
			||||||
       <widget class="QPushButton" name="button_step">
 | 
					 | 
				
			||||||
        <property name="text">
 | 
					 | 
				
			||||||
         <string>Step</string>
 | 
					 | 
				
			||||||
        </property>
 | 
					 | 
				
			||||||
       </widget>
 | 
					 | 
				
			||||||
      </item>
 | 
					 | 
				
			||||||
      <item>
 | 
					 | 
				
			||||||
       <widget class="QPushButton" name="button_pause">
 | 
					 | 
				
			||||||
        <property name="text">
 | 
					 | 
				
			||||||
         <string>Pause</string>
 | 
					 | 
				
			||||||
        </property>
 | 
					 | 
				
			||||||
       </widget>
 | 
					 | 
				
			||||||
      </item>
 | 
					 | 
				
			||||||
      <item>
 | 
					 | 
				
			||||||
       <widget class="QPushButton" name="button_continue">
 | 
					 | 
				
			||||||
        <property name="text">
 | 
					 | 
				
			||||||
         <string>Continue</string>
 | 
					 | 
				
			||||||
        </property>
 | 
					 | 
				
			||||||
       </widget>
 | 
					 | 
				
			||||||
      </item>
 | 
					 | 
				
			||||||
      <item>
 | 
					 | 
				
			||||||
       <widget class="QPushButton" name="pushButton">
 | 
					 | 
				
			||||||
        <property name="text">
 | 
					 | 
				
			||||||
         <string>Step Into</string>
 | 
					 | 
				
			||||||
        </property>
 | 
					 | 
				
			||||||
       </widget>
 | 
					 | 
				
			||||||
      </item>
 | 
					 | 
				
			||||||
      <item>
 | 
					 | 
				
			||||||
       <widget class="QPushButton" name="button_breakpoint">
 | 
					 | 
				
			||||||
        <property name="text">
 | 
					 | 
				
			||||||
         <string>Set Breakpoint</string>
 | 
					 | 
				
			||||||
        </property>
 | 
					 | 
				
			||||||
       </widget>
 | 
					 | 
				
			||||||
      </item>
 | 
					 | 
				
			||||||
     </layout>
 | 
					 | 
				
			||||||
    </item>
 | 
					 | 
				
			||||||
    <item>
 | 
					 | 
				
			||||||
     <widget class="QTreeView" name="treeView">
 | 
					 | 
				
			||||||
      <property name="alternatingRowColors">
 | 
					 | 
				
			||||||
       <bool>true</bool>
 | 
					 | 
				
			||||||
      </property>
 | 
					 | 
				
			||||||
      <property name="indentation">
 | 
					 | 
				
			||||||
       <number>20</number>
 | 
					 | 
				
			||||||
      </property>
 | 
					 | 
				
			||||||
      <property name="rootIsDecorated">
 | 
					 | 
				
			||||||
       <bool>false</bool>
 | 
					 | 
				
			||||||
      </property>
 | 
					 | 
				
			||||||
      <property name="uniformRowHeights">
 | 
					 | 
				
			||||||
       <bool>true</bool>
 | 
					 | 
				
			||||||
      </property>
 | 
					 | 
				
			||||||
      <attribute name="headerVisible">
 | 
					 | 
				
			||||||
       <bool>false</bool>
 | 
					 | 
				
			||||||
      </attribute>
 | 
					 | 
				
			||||||
     </widget>
 | 
					 | 
				
			||||||
    </item>
 | 
					 | 
				
			||||||
   </layout>
 | 
					 | 
				
			||||||
  </widget>
 | 
					 | 
				
			||||||
 </widget>
 | 
					 | 
				
			||||||
 <resources/>
 | 
					 | 
				
			||||||
 <connections/>
 | 
					 | 
				
			||||||
</ui>
 | 
					 | 
				
			||||||
@ -17,7 +17,6 @@
 | 
				
			|||||||
#include "citra_qt/configuration/config.h"
 | 
					#include "citra_qt/configuration/config.h"
 | 
				
			||||||
#include "citra_qt/configuration/configure_dialog.h"
 | 
					#include "citra_qt/configuration/configure_dialog.h"
 | 
				
			||||||
#include "citra_qt/debugger/callstack.h"
 | 
					#include "citra_qt/debugger/callstack.h"
 | 
				
			||||||
#include "citra_qt/debugger/disassembler.h"
 | 
					 | 
				
			||||||
#include "citra_qt/debugger/graphics/graphics.h"
 | 
					#include "citra_qt/debugger/graphics/graphics.h"
 | 
				
			||||||
#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
 | 
					#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
 | 
				
			||||||
#include "citra_qt/debugger/graphics/graphics_cmdlists.h"
 | 
					#include "citra_qt/debugger/graphics/graphics_cmdlists.h"
 | 
				
			||||||
@ -130,15 +129,6 @@ void GMainWindow::InitializeDebugWidgets() {
 | 
				
			|||||||
    debug_menu->addAction(microProfileDialog->toggleViewAction());
 | 
					    debug_menu->addAction(microProfileDialog->toggleViewAction());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    disasmWidget = new DisassemblerWidget(this, emu_thread.get());
 | 
					 | 
				
			||||||
    addDockWidget(Qt::BottomDockWidgetArea, disasmWidget);
 | 
					 | 
				
			||||||
    disasmWidget->hide();
 | 
					 | 
				
			||||||
    debug_menu->addAction(disasmWidget->toggleViewAction());
 | 
					 | 
				
			||||||
    connect(this, &GMainWindow::EmulationStarting, disasmWidget,
 | 
					 | 
				
			||||||
            &DisassemblerWidget::OnEmulationStarting);
 | 
					 | 
				
			||||||
    connect(this, &GMainWindow::EmulationStopping, disasmWidget,
 | 
					 | 
				
			||||||
            &DisassemblerWidget::OnEmulationStopping);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    registersWidget = new RegistersWidget(this);
 | 
					    registersWidget = new RegistersWidget(this);
 | 
				
			||||||
    addDockWidget(Qt::RightDockWidgetArea, registersWidget);
 | 
					    addDockWidget(Qt::RightDockWidgetArea, registersWidget);
 | 
				
			||||||
    registersWidget->hide();
 | 
					    registersWidget->hide();
 | 
				
			||||||
@ -391,16 +381,12 @@ void GMainWindow::BootGame(const QString& filename) {
 | 
				
			|||||||
    connect(render_window, SIGNAL(Closed()), this, SLOT(OnStopGame()));
 | 
					    connect(render_window, SIGNAL(Closed()), this, SLOT(OnStopGame()));
 | 
				
			||||||
    // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
 | 
					    // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
 | 
				
			||||||
    // before the CPU continues
 | 
					    // before the CPU continues
 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()),
 | 
					 | 
				
			||||||
            Qt::BlockingQueuedConnection);
 | 
					 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), registersWidget,
 | 
					    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), registersWidget,
 | 
				
			||||||
            SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
 | 
					            SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), callstackWidget,
 | 
					    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), callstackWidget,
 | 
				
			||||||
            SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
 | 
					            SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), waitTreeWidget,
 | 
					    connect(emu_thread.get(), SIGNAL(DebugModeEntered()), waitTreeWidget,
 | 
				
			||||||
            SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
 | 
					            SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection);
 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeLeft()), disasmWidget, SLOT(OnDebugModeLeft()),
 | 
					 | 
				
			||||||
            Qt::BlockingQueuedConnection);
 | 
					 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()),
 | 
					    connect(emu_thread.get(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()),
 | 
				
			||||||
            Qt::BlockingQueuedConnection);
 | 
					            Qt::BlockingQueuedConnection);
 | 
				
			||||||
    connect(emu_thread.get(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()),
 | 
					    connect(emu_thread.get(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()),
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CallstackWidget;
 | 
					class CallstackWidget;
 | 
				
			||||||
class Config;
 | 
					class Config;
 | 
				
			||||||
class DisassemblerWidget;
 | 
					 | 
				
			||||||
class EmuThread;
 | 
					class EmuThread;
 | 
				
			||||||
class GameList;
 | 
					class GameList;
 | 
				
			||||||
class GImageInfo;
 | 
					class GImageInfo;
 | 
				
			||||||
@ -152,7 +151,6 @@ private:
 | 
				
			|||||||
    // Debugger panes
 | 
					    // Debugger panes
 | 
				
			||||||
    ProfilerWidget* profilerWidget;
 | 
					    ProfilerWidget* profilerWidget;
 | 
				
			||||||
    MicroProfileDialog* microProfileDialog;
 | 
					    MicroProfileDialog* microProfileDialog;
 | 
				
			||||||
    DisassemblerWidget* disasmWidget;
 | 
					 | 
				
			||||||
    RegistersWidget* registersWidget;
 | 
					    RegistersWidget* registersWidget;
 | 
				
			||||||
    CallstackWidget* callstackWidget;
 | 
					    CallstackWidget* callstackWidget;
 | 
				
			||||||
    GPUCommandStreamWidget* graphicsWidget;
 | 
					    GPUCommandStreamWidget* graphicsWidget;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user