all repos — mgba @ 1326626777dacd7a7882e39c0f6dccc752549a1e

mGBA Game Boy Advance Emulator

src/platform/qt/MemoryView.cpp (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6
  7#include "MemoryView.h"
  8
  9#include "GameController.h"
 10
 11extern "C" {
 12#include "core/core.h"
 13#include "gba/memory.h"
 14}
 15
 16using namespace QGBA;
 17
 18MemoryView::MemoryView(GameController* controller, QWidget* parent)
 19	: QWidget(parent)
 20	, m_controller(controller)
 21{
 22	m_ui.setupUi(this);
 23
 24	m_ui.hexfield->setController(controller);
 25
 26	connect(m_ui.regions, SIGNAL(currentIndexChanged(int)), this, SLOT(setIndex(int)));
 27
 28	connect(m_ui.width8, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(1); });
 29	connect(m_ui.width16, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(2); });
 30	connect(m_ui.width32, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(4); });
 31	connect(m_ui.setAddress, SIGNAL(valueChanged(const QString&)), m_ui.hexfield, SLOT(jumpToAddress(const QString&)));
 32
 33	connect(m_ui.hexfield, SIGNAL(selectionChanged(uint32_t, uint32_t)), this, SLOT(updateSelection(uint32_t, uint32_t)));
 34
 35	connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
 36
 37	connect(controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(update()));
 38	connect(controller, SIGNAL(gamePaused(mCoreThread*)), this, SLOT(update()));
 39	connect(controller, SIGNAL(stateLoaded(mCoreThread*)), this, SLOT(update()));
 40	connect(controller, SIGNAL(rewound(mCoreThread*)), this, SLOT(update()));
 41}
 42
 43void MemoryView::setIndex(int index) {
 44	static struct {
 45		const char* name;
 46		uint32_t base;
 47		uint32_t size;
 48	} indexInfo[] = {
 49		{ "All", 0, 0x10000000 },
 50		{ "BIOS", BASE_BIOS, SIZE_BIOS },
 51		{ "EWRAM", BASE_WORKING_RAM, SIZE_WORKING_RAM },
 52		{ "IWRAM", BASE_WORKING_IRAM, SIZE_WORKING_IRAM },
 53		{ "MMIO", BASE_IO, SIZE_IO },
 54		{ "Palette", BASE_PALETTE_RAM, SIZE_PALETTE_RAM },
 55		{ "VRAM", BASE_VRAM, SIZE_VRAM },
 56		{ "OAM", BASE_OAM, SIZE_OAM },
 57		{ "ROM", BASE_CART0, SIZE_CART0 },
 58		{ "ROM WS1", BASE_CART1, SIZE_CART1 },
 59		{ "ROM WS2", BASE_CART2, SIZE_CART2 },
 60		{ "SRAM", BASE_CART_SRAM, SIZE_CART_SRAM },
 61	};
 62	const auto& info = indexInfo[index];
 63	m_ui.hexfield->setRegion(info.base, info.size, info.name);
 64}
 65
 66void MemoryView::update() {
 67	m_ui.hexfield->viewport()->update();
 68	updateStatus();
 69}
 70
 71void MemoryView::updateSelection(uint32_t start, uint32_t end) {
 72	m_selection.first = start;
 73	m_selection.second = end;
 74	updateStatus();
 75}
 76
 77void MemoryView::updateStatus() {
 78	int align = m_ui.hexfield->alignment();
 79	if (m_selection.first & (align - 1) || m_selection.second - m_selection.first != align) {
 80		m_ui.sintVal->clear();
 81		m_ui.uintVal->clear();
 82		return;
 83	}
 84	if (!m_controller->isLoaded()) {
 85		return;
 86	}
 87	ARMCore* cpu = static_cast<ARMCore*>(m_controller->thread()->core->cpu);
 88	union {
 89		uint32_t u32;
 90		int32_t i32;
 91		uint16_t u16;
 92		int16_t i16;
 93		uint8_t u8;
 94		int8_t i8;
 95	} value;
 96	switch (align) {
 97	case 1:
 98		value.u8 = GBAView8(cpu, m_selection.first);
 99		m_ui.sintVal->setText(QString::number(value.i8));
100		m_ui.uintVal->setText(QString::number(value.u8));
101		break;
102	case 2:
103		value.u16 = GBAView16(cpu, m_selection.first);
104		m_ui.sintVal->setText(QString::number(value.i16));
105		m_ui.uintVal->setText(QString::number(value.u16));
106		break;
107	case 4:
108		value.u32 = GBAView32(cpu, m_selection.first);
109		m_ui.sintVal->setText(QString::number(value.i32));
110		m_ui.uintVal->setText(QString::number(value.u32));
111		break;
112	}
113}