mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 23:25:41 +00:00
Qt/Debugger: Invalidate blocks on manual memory edit
Ensures recompiler isn't executing stale code.
This commit is contained in:
parent
830e0ad3ad
commit
eeca12467c
|
@ -6,9 +6,12 @@
|
||||||
#include "qthost.h"
|
#include "qthost.h"
|
||||||
#include "qtutils.h"
|
#include "qtutils.h"
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "core/bus.h"
|
||||||
|
#include "core/cpu_code_cache.h"
|
||||||
#include "core/cpu_core_private.h"
|
#include "core/cpu_core_private.h"
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
|
||||||
#include <QtCore/QSignalBlocker>
|
#include <QtCore/QSignalBlocker>
|
||||||
#include <QtGui/QCursor>
|
#include <QtGui/QCursor>
|
||||||
#include <QtGui/QFontDatabase>
|
#include <QtGui/QFontDatabase>
|
||||||
|
@ -568,10 +571,27 @@ void DebuggerWindow::setMemoryViewRegion(Bus::MemoryRegion region)
|
||||||
|
|
||||||
m_active_memory_region = region;
|
m_active_memory_region = region;
|
||||||
|
|
||||||
|
static constexpr auto edit_ram_callback = [](size_t offset, size_t count) {
|
||||||
|
// shouldn't happen
|
||||||
|
if (offset > Bus::g_ram_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const u32 start_page = static_cast<u32>(offset) / HOST_PAGE_SIZE;
|
||||||
|
const u32 end_page = static_cast<u32>(offset + count - 1) / HOST_PAGE_SIZE;
|
||||||
|
for (u32 i = start_page; i <= end_page; i++)
|
||||||
|
{
|
||||||
|
if (Bus::g_ram_code_bits[i])
|
||||||
|
CPU::CodeCache::InvalidateBlocksWithPageIndex(i);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const PhysicalMemoryAddress start = Bus::GetMemoryRegionStart(region);
|
const PhysicalMemoryAddress start = Bus::GetMemoryRegionStart(region);
|
||||||
const PhysicalMemoryAddress end = Bus::GetMemoryRegionEnd(region);
|
const PhysicalMemoryAddress end = Bus::GetMemoryRegionEnd(region);
|
||||||
m_ui.memoryView->setData(start, Bus::GetMemoryRegionPointer(region), end - start,
|
void* const mem_ptr = Bus::GetMemoryRegionPointer(region);
|
||||||
Bus::IsMemoryRegionWritable(region));
|
const bool mem_writable = Bus::IsMemoryRegionWritable(region);
|
||||||
|
const MemoryViewWidget::EditCallback edit_callback =
|
||||||
|
((region == Bus::MemoryRegion::RAM) ? edit_ram_callback : nullptr);
|
||||||
|
m_ui.memoryView->setData(start, mem_ptr, end - start, mem_writable, edit_callback);
|
||||||
|
|
||||||
#define SET_REGION_RADIO_BUTTON(name, rb_region) \
|
#define SET_REGION_RADIO_BUTTON(name, rb_region) \
|
||||||
do \
|
do \
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
MemoryViewWidget::MemoryViewWidget(QWidget* parent /* = nullptr */, size_t address_offset /* = 0 */,
|
MemoryViewWidget::MemoryViewWidget(QWidget* parent /* = nullptr */, size_t address_offset /* = 0 */,
|
||||||
void* data_ptr /* = nullptr */, size_t data_size /* = 0 */,
|
void* data_ptr /* = nullptr */, size_t data_size /* = 0 */,
|
||||||
bool data_editable /* = false */)
|
bool data_editable /* = false */, EditCallback edit_callback /* = nullptr */)
|
||||||
: QAbstractScrollArea(parent)
|
: QAbstractScrollArea(parent)
|
||||||
{
|
{
|
||||||
m_bytes_per_line = 16;
|
m_bytes_per_line = 16;
|
||||||
|
@ -19,7 +19,7 @@ MemoryViewWidget::MemoryViewWidget(QWidget* parent /* = nullptr */, size_t addre
|
||||||
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &MemoryViewWidget::adjustContent);
|
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &MemoryViewWidget::adjustContent);
|
||||||
|
|
||||||
if (data_ptr)
|
if (data_ptr)
|
||||||
setData(address_offset, data_ptr, data_size, data_editable);
|
setData(address_offset, data_ptr, data_size, data_editable, edit_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryViewWidget::~MemoryViewWidget() = default;
|
MemoryViewWidget::~MemoryViewWidget() = default;
|
||||||
|
@ -46,13 +46,15 @@ void MemoryViewWidget::updateMetrics()
|
||||||
m_char_height = fm.height();
|
m_char_height = fm.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryViewWidget::setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable)
|
void MemoryViewWidget::setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable,
|
||||||
|
EditCallback edit_callback)
|
||||||
{
|
{
|
||||||
m_data = data_ptr;
|
m_data = data_ptr;
|
||||||
m_data_size = data_size;
|
m_data_size = data_size;
|
||||||
m_data_editable = data_editable;
|
m_data_editable = data_editable;
|
||||||
m_address_offset = address_offset;
|
m_address_offset = address_offset;
|
||||||
m_selected_address = INVALID_SELECTED_ADDRESS;
|
m_selected_address = INVALID_SELECTED_ADDRESS;
|
||||||
|
m_edit_callback = edit_callback;
|
||||||
m_last_data_start_offset = 0;
|
m_last_data_start_offset = 0;
|
||||||
m_last_data.clear();
|
m_last_data.clear();
|
||||||
adjustContent();
|
adjustContent();
|
||||||
|
@ -137,7 +139,15 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
||||||
if (m_selection_was_ascii)
|
if (m_selection_was_ascii)
|
||||||
{
|
{
|
||||||
expandCurrentDataToInclude(m_selected_address);
|
expandCurrentDataToInclude(m_selected_address);
|
||||||
std::memcpy(static_cast<unsigned char*>(m_data) + m_selected_address, &ch, sizeof(unsigned char));
|
|
||||||
|
unsigned char* pdata = static_cast<unsigned char*>(m_data) + m_selected_address;
|
||||||
|
if (static_cast<unsigned char>(ch) != *pdata)
|
||||||
|
{
|
||||||
|
*pdata = static_cast<unsigned char>(ch);
|
||||||
|
if (m_edit_callback)
|
||||||
|
m_edit_callback(m_selected_address, 1);
|
||||||
|
}
|
||||||
|
|
||||||
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
|
m_selected_address = std::min(m_selected_address + 1, m_data_size - 1);
|
||||||
forceRefresh();
|
forceRefresh();
|
||||||
}
|
}
|
||||||
|
@ -157,7 +167,14 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
||||||
expandCurrentDataToInclude(m_selected_address);
|
expandCurrentDataToInclude(m_selected_address);
|
||||||
|
|
||||||
unsigned char* pdata = static_cast<unsigned char*>(m_data) + m_selected_address;
|
unsigned char* pdata = static_cast<unsigned char*>(m_data) + m_selected_address;
|
||||||
*pdata = (*pdata & ~(0xf0 >> (m_editing_nibble * 4))) | (nibble << ((1 - m_editing_nibble) * 4));
|
const unsigned char new_value =
|
||||||
|
(*pdata & ~(0xf0 >> (m_editing_nibble * 4))) | (nibble << ((1 - m_editing_nibble) * 4));
|
||||||
|
if (*pdata != new_value)
|
||||||
|
{
|
||||||
|
*pdata = new_value;
|
||||||
|
if (m_edit_callback)
|
||||||
|
m_edit_callback(m_selected_address, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_editing_nibble == 1)
|
if (m_editing_nibble == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,16 +9,18 @@
|
||||||
|
|
||||||
class MemoryViewWidget : public QAbstractScrollArea
|
class MemoryViewWidget : public QAbstractScrollArea
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using EditCallback = void (*)(size_t offset, size_t bytes);
|
||||||
|
|
||||||
MemoryViewWidget(QWidget* parent = nullptr, size_t address_offset = 0, void* data_ptr = nullptr, size_t data_size = 0,
|
MemoryViewWidget(QWidget* parent = nullptr, size_t address_offset = 0, void* data_ptr = nullptr, size_t data_size = 0,
|
||||||
bool data_editable = false);
|
bool data_editable = false, EditCallback edit_callback = nullptr);
|
||||||
~MemoryViewWidget();
|
~MemoryViewWidget();
|
||||||
|
|
||||||
size_t addressOffset() const { return m_address_offset; }
|
size_t addressOffset() const { return m_address_offset; }
|
||||||
|
|
||||||
void setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable);
|
void setData(size_t address_offset, void* data_ptr, size_t data_size, bool data_editable, EditCallback edit_callback);
|
||||||
void setHighlightRange(size_t start, size_t end);
|
void setHighlightRange(size_t start, size_t end);
|
||||||
void clearHighlightRange();
|
void clearHighlightRange();
|
||||||
void scrolltoOffset(size_t offset);
|
void scrolltoOffset(size_t offset);
|
||||||
|
@ -71,6 +73,7 @@ private:
|
||||||
|
|
||||||
int m_rows_visible;
|
int m_rows_visible;
|
||||||
|
|
||||||
|
EditCallback m_edit_callback = nullptr;
|
||||||
std::vector<u8> m_last_data;
|
std::vector<u8> m_last_data;
|
||||||
size_t m_last_data_start_offset = 0;
|
size_t m_last_data_start_offset = 0;
|
||||||
};
|
};
|
Loading…
Reference in a new issue