Qt/Debugger: Invalidate blocks on manual memory edit
Ensures recompiler isn't executing stale code.
This commit is contained in:
parent
128d5254ca
commit
c633a6bacc
|
@ -6,9 +6,12 @@
|
|||
#include "qthost.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 "common/assert.h"
|
||||
|
||||
#include <QtCore/QSignalBlocker>
|
||||
#include <QtGui/QCursor>
|
||||
#include <QtGui/QFontDatabase>
|
||||
|
@ -568,10 +571,27 @@ void DebuggerWindow::setMemoryViewRegion(Bus::MemoryRegion 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 end = Bus::GetMemoryRegionEnd(region);
|
||||
m_ui.memoryView->setData(start, Bus::GetMemoryRegionPointer(region), end - start,
|
||||
Bus::IsMemoryRegionWritable(region));
|
||||
void* const mem_ptr = Bus::GetMemoryRegionPointer(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) \
|
||||
do \
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
MemoryViewWidget::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 */)
|
||||
: QAbstractScrollArea(parent)
|
||||
{
|
||||
m_bytes_per_line = 16;
|
||||
|
@ -19,7 +19,7 @@ MemoryViewWidget::MemoryViewWidget(QWidget* parent /* = nullptr */, size_t addre
|
|||
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &MemoryViewWidget::adjustContent);
|
||||
|
||||
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;
|
||||
|
@ -46,13 +46,15 @@ void MemoryViewWidget::updateMetrics()
|
|||
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_size = data_size;
|
||||
m_data_editable = data_editable;
|
||||
m_address_offset = address_offset;
|
||||
m_selected_address = INVALID_SELECTED_ADDRESS;
|
||||
m_edit_callback = edit_callback;
|
||||
m_last_data_start_offset = 0;
|
||||
m_last_data.clear();
|
||||
adjustContent();
|
||||
|
@ -137,7 +139,15 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
|||
if (m_selection_was_ascii)
|
||||
{
|
||||
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);
|
||||
forceRefresh();
|
||||
}
|
||||
|
@ -157,7 +167,14 @@ void MemoryViewWidget::keyPressEvent(QKeyEvent* event)
|
|||
expandCurrentDataToInclude(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)
|
||||
{
|
||||
|
|
|
@ -9,16 +9,18 @@
|
|||
|
||||
class MemoryViewWidget : public QAbstractScrollArea
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
|
||||
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,
|
||||
bool data_editable = false);
|
||||
bool data_editable = false, EditCallback edit_callback = nullptr);
|
||||
~MemoryViewWidget();
|
||||
|
||||
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 clearHighlightRange();
|
||||
void scrolltoOffset(size_t offset);
|
||||
|
@ -71,6 +73,7 @@ private:
|
|||
|
||||
int m_rows_visible;
|
||||
|
||||
EditCallback m_edit_callback = nullptr;
|
||||
std::vector<u8> m_last_data;
|
||||
size_t m_last_data_start_offset = 0;
|
||||
};
|
Loading…
Reference in New Issue