mirror of https://github.com/mgba-emu/mgba.git
Qt: Memory viewer can now select segments
This commit is contained in:
parent
819062a9a5
commit
d23c993bbe
|
@ -107,13 +107,13 @@ struct mCore {
|
|||
void (*busWrite16)(struct mCore*, uint32_t address, uint16_t);
|
||||
void (*busWrite32)(struct mCore*, uint32_t address, uint32_t);
|
||||
|
||||
uint32_t (*rawRead8)(struct mCore*, uint32_t address);
|
||||
uint32_t (*rawRead16)(struct mCore*, uint32_t address);
|
||||
uint32_t (*rawRead32)(struct mCore*, uint32_t address);
|
||||
uint32_t (*rawRead8)(struct mCore*, uint32_t address, int segment);
|
||||
uint32_t (*rawRead16)(struct mCore*, uint32_t address, int segment);
|
||||
uint32_t (*rawRead32)(struct mCore*, uint32_t address, int segment);
|
||||
|
||||
void (*rawWrite8)(struct mCore*, uint32_t address, uint8_t);
|
||||
void (*rawWrite16)(struct mCore*, uint32_t address, uint16_t);
|
||||
void (*rawWrite32)(struct mCore*, uint32_t address, uint32_t);
|
||||
void (*rawWrite8)(struct mCore*, uint32_t address, int segment, uint8_t);
|
||||
void (*rawWrite16)(struct mCore*, uint32_t address, int segment, uint16_t);
|
||||
void (*rawWrite32)(struct mCore*, uint32_t address, int segment, uint32_t);
|
||||
|
||||
bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType);
|
||||
struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*);
|
||||
|
|
|
@ -317,34 +317,34 @@ static void _GBCoreBusWrite32(struct mCore* core, uint32_t address, uint32_t val
|
|||
cpu->memory.store8(cpu, address + 3, value >> 24);
|
||||
}
|
||||
|
||||
static uint32_t _GBCoreRawRead8(struct mCore* core, uint32_t address) {
|
||||
static uint32_t _GBCoreRawRead8(struct mCore* core, uint32_t address, int segment) {
|
||||
struct LR35902Core* cpu = core->cpu;
|
||||
return GBLoad8(cpu, address);
|
||||
return GBView8(cpu, address, segment);
|
||||
}
|
||||
|
||||
static uint32_t _GBCoreRawRead16(struct mCore* core, uint32_t address) {
|
||||
static uint32_t _GBCoreRawRead16(struct mCore* core, uint32_t address, int segment) {
|
||||
struct LR35902Core* cpu = core->cpu;
|
||||
return GBLoad8(cpu, address) | (GBLoad8(cpu, address + 1) << 8);
|
||||
return GBView8(cpu, address, segment) | (GBView8(cpu, address + 1, segment) << 8);
|
||||
}
|
||||
|
||||
static uint32_t _GBCoreRawRead32(struct mCore* core, uint32_t address) {
|
||||
static uint32_t _GBCoreRawRead32(struct mCore* core, uint32_t address, int segment) {
|
||||
struct LR35902Core* cpu = core->cpu;
|
||||
return GBLoad8(cpu, address) | (GBLoad8(cpu, address + 1) << 8) |
|
||||
(GBLoad8(cpu, address + 2) << 16) | (GBLoad8(cpu, address + 3) << 24);
|
||||
return GBView8(cpu, address, segment) | (GBView8(cpu, address + 1, segment) << 8) |
|
||||
(GBView8(cpu, address + 2, segment) << 16) | (GBView8(cpu, address + 3, segment) << 24);
|
||||
}
|
||||
|
||||
static void _GBCoreRawWrite8(struct mCore* core, uint32_t address, uint8_t value) {
|
||||
static void _GBCoreRawWrite8(struct mCore* core, uint32_t address, int segment, uint8_t value) {
|
||||
struct LR35902Core* cpu = core->cpu;
|
||||
GBPatch8(cpu, address, value, NULL);
|
||||
}
|
||||
|
||||
static void _GBCoreRawWrite16(struct mCore* core, uint32_t address, uint16_t value) {
|
||||
static void _GBCoreRawWrite16(struct mCore* core, uint32_t address, int segment, uint16_t value) {
|
||||
struct LR35902Core* cpu = core->cpu;
|
||||
GBPatch8(cpu, address, value, NULL);
|
||||
GBPatch8(cpu, address + 1, value >> 8, NULL);
|
||||
}
|
||||
|
||||
static void _GBCoreRawWrite32(struct mCore* core, uint32_t address, uint32_t value) {
|
||||
static void _GBCoreRawWrite32(struct mCore* core, uint32_t address, int segment, uint32_t value) {
|
||||
struct LR35902Core* cpu = core->cpu;
|
||||
GBPatch8(cpu, address, value, NULL);
|
||||
GBPatch8(cpu, address + 1, value >> 8, NULL);
|
||||
|
|
|
@ -229,9 +229,9 @@ uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) {
|
|||
case GB_REGION_EXTERNAL_RAM:
|
||||
case GB_REGION_EXTERNAL_RAM + 1:
|
||||
if (memory->rtcAccess) {
|
||||
return gb->memory.rtcRegs[memory->activeRtcReg];
|
||||
return memory->rtcRegs[memory->activeRtcReg];
|
||||
} else if (memory->sramAccess) {
|
||||
return gb->memory.sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)];
|
||||
return memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)];
|
||||
} else if (memory->mbcType == GB_MBC7) {
|
||||
return _GBMBC7Read(memory, address);
|
||||
} else if (memory->mbcType == GB_HuC3) {
|
||||
|
@ -290,11 +290,11 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
|
|||
case GB_REGION_EXTERNAL_RAM:
|
||||
case GB_REGION_EXTERNAL_RAM + 1:
|
||||
if (memory->rtcAccess) {
|
||||
gb->memory.rtcRegs[memory->activeRtcReg] = value;
|
||||
memory->rtcRegs[memory->activeRtcReg] = value;
|
||||
} else if (memory->sramAccess) {
|
||||
gb->memory.sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value;
|
||||
} else if (gb->memory.mbcType == GB_MBC7) {
|
||||
_GBMBC7Write(&gb->memory, address, value);
|
||||
memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value;
|
||||
} else if (memory->mbcType == GB_MBC7) {
|
||||
_GBMBC7Write(memory, address, value);
|
||||
}
|
||||
return;
|
||||
case GB_REGION_WORKING_RAM_BANK0:
|
||||
|
@ -322,6 +322,82 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) {
|
|||
}
|
||||
}
|
||||
}
|
||||
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment) {
|
||||
struct GB* gb = (struct GB*) cpu->master;
|
||||
struct GBMemory* memory = &gb->memory;
|
||||
switch (address >> 12) {
|
||||
case GB_REGION_CART_BANK0:
|
||||
case GB_REGION_CART_BANK0 + 1:
|
||||
case GB_REGION_CART_BANK0 + 2:
|
||||
case GB_REGION_CART_BANK0 + 3:
|
||||
return memory->romBase[address & (GB_SIZE_CART_BANK0 - 1)];
|
||||
case GB_REGION_CART_BANK1:
|
||||
case GB_REGION_CART_BANK1 + 1:
|
||||
case GB_REGION_CART_BANK1 + 2:
|
||||
case GB_REGION_CART_BANK1 + 3:
|
||||
if (segment < 0) {
|
||||
return memory->romBank[address & (GB_SIZE_CART_BANK0 - 1)];
|
||||
} else {
|
||||
if ((size_t) segment * GB_SIZE_CART_BANK0 > memory->romSize) {
|
||||
return 0xFF;
|
||||
}
|
||||
return memory->rom[(address & (GB_SIZE_CART_BANK0 - 1)) + segment * GB_SIZE_CART_BANK0];
|
||||
}
|
||||
case GB_REGION_VRAM:
|
||||
case GB_REGION_VRAM + 1:
|
||||
if (segment < 0) {
|
||||
return gb->video.vramBank[address & (GB_SIZE_VRAM_BANK0 - 1)];
|
||||
} else {
|
||||
return gb->video.vram[(address & (GB_SIZE_VRAM_BANK0 - 1)) + segment *GB_SIZE_VRAM_BANK0];
|
||||
}
|
||||
case GB_REGION_EXTERNAL_RAM:
|
||||
case GB_REGION_EXTERNAL_RAM + 1:
|
||||
if (memory->rtcAccess) {
|
||||
return memory->rtcRegs[memory->activeRtcReg];
|
||||
} else if (memory->sramAccess) {
|
||||
if (segment < 0) {
|
||||
return memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)];
|
||||
} else {
|
||||
return memory->sram[(address & (GB_SIZE_EXTERNAL_RAM - 1)) + segment *GB_SIZE_EXTERNAL_RAM];
|
||||
}
|
||||
} else if (memory->mbcType == GB_MBC7) {
|
||||
return _GBMBC7Read(memory, address);
|
||||
} else if (memory->mbcType == GB_HuC3) {
|
||||
return 0x01; // TODO: Is this supposed to be the current SRAM bank?
|
||||
}
|
||||
return 0xFF;
|
||||
case GB_REGION_WORKING_RAM_BANK0:
|
||||
case GB_REGION_WORKING_RAM_BANK0 + 2:
|
||||
return memory->wram[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)];
|
||||
case GB_REGION_WORKING_RAM_BANK1:
|
||||
if (segment < 0) {
|
||||
return memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)];
|
||||
} else {
|
||||
return memory->wram[(address & (GB_SIZE_WORKING_RAM_BANK0 - 1)) + segment *GB_SIZE_WORKING_RAM_BANK0];
|
||||
}
|
||||
default:
|
||||
if (address < GB_BASE_OAM) {
|
||||
return memory->wramBank[address & (GB_SIZE_WORKING_RAM_BANK0 - 1)];
|
||||
}
|
||||
if (address < GB_BASE_UNUSABLE) {
|
||||
if (gb->video.mode < 2) {
|
||||
return gb->video.oam.raw[address & 0xFF];
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
if (address < GB_BASE_IO) {
|
||||
mLOG(GB_MEM, GAME_ERROR, "Attempt to read from unusable memory: %04X", address);
|
||||
return 0xFF;
|
||||
}
|
||||
if (address < GB_BASE_HRAM) {
|
||||
return GBIORead(gb, address & (GB_SIZE_IO - 1));
|
||||
}
|
||||
if (address < GB_BASE_IE) {
|
||||
return memory->hram[address & GB_SIZE_HRAM];
|
||||
}
|
||||
return GBIORead(gb, REG_IE);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GBMemoryProcessEvents(struct GB* gb, int32_t cycles) {
|
||||
int nextEvent = INT_MAX;
|
||||
|
|
|
@ -165,6 +165,8 @@ void GBMemorySwitchWramBank(struct GBMemory* memory, int bank);
|
|||
uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address);
|
||||
void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value);
|
||||
|
||||
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment);
|
||||
|
||||
int32_t GBMemoryProcessEvents(struct GB* gb, int32_t cycles);
|
||||
void GBMemoryDMA(struct GB* gb, uint16_t base);
|
||||
void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value);
|
||||
|
|
|
@ -371,32 +371,38 @@ static void _GBACoreBusWrite32(struct mCore* core, uint32_t address, uint32_t va
|
|||
cpu->memory.store32(cpu, address, value, 0);
|
||||
}
|
||||
|
||||
static uint32_t _GBACoreRawRead8(struct mCore* core, uint32_t address) {
|
||||
static uint32_t _GBACoreRawRead8(struct mCore* core, uint32_t address, int segment) {
|
||||
UNUSED(segment);
|
||||
struct ARMCore* cpu = core->cpu;
|
||||
return GBAView8(cpu, address);
|
||||
}
|
||||
|
||||
static uint32_t _GBACoreRawRead16(struct mCore* core, uint32_t address) {
|
||||
static uint32_t _GBACoreRawRead16(struct mCore* core, uint32_t address, int segment) {
|
||||
UNUSED(segment);
|
||||
struct ARMCore* cpu = core->cpu;
|
||||
return GBAView16(cpu, address);
|
||||
}
|
||||
|
||||
static uint32_t _GBACoreRawRead32(struct mCore* core, uint32_t address) {
|
||||
static uint32_t _GBACoreRawRead32(struct mCore* core, uint32_t address, int segment) {
|
||||
UNUSED(segment);
|
||||
struct ARMCore* cpu = core->cpu;
|
||||
return GBAView32(cpu, address);
|
||||
}
|
||||
|
||||
static void _GBACoreRawWrite8(struct mCore* core, uint32_t address, uint8_t value) {
|
||||
static void _GBACoreRawWrite8(struct mCore* core, uint32_t address, int segment, uint8_t value) {
|
||||
UNUSED(segment);
|
||||
struct ARMCore* cpu = core->cpu;
|
||||
GBAPatch8(cpu, address, value, NULL);
|
||||
}
|
||||
|
||||
static void _GBACoreRawWrite16(struct mCore* core, uint32_t address, uint16_t value) {
|
||||
static void _GBACoreRawWrite16(struct mCore* core, uint32_t address, int segment, uint16_t value) {
|
||||
UNUSED(segment);
|
||||
struct ARMCore* cpu = core->cpu;
|
||||
GBAPatch16(cpu, address, value, NULL);
|
||||
}
|
||||
|
||||
static void _GBACoreRawWrite32(struct mCore* core, uint32_t address, uint32_t value) {
|
||||
static void _GBACoreRawWrite32(struct mCore* core, uint32_t address, int segment, uint32_t value) {
|
||||
UNUSED(segment);
|
||||
struct ARMCore* cpu = core->cpu;
|
||||
GBAPatch32(cpu, address, value, NULL);
|
||||
}
|
||||
|
|
|
@ -90,17 +90,23 @@ void MemoryModel::setController(GameController* controller) {
|
|||
m_core = controller->thread()->core;
|
||||
}
|
||||
|
||||
void MemoryModel::setRegion(uint32_t base, uint32_t size, const QString& name) {
|
||||
void MemoryModel::setRegion(uint32_t base, uint32_t size, const QString& name, int segment) {
|
||||
m_top = 0;
|
||||
m_base = base;
|
||||
m_size = size;
|
||||
m_regionName = name;
|
||||
m_regionName.prepare(QTransform(), m_font);
|
||||
m_currentBank = segment;
|
||||
verticalScrollBar()->setRange(0, (size >> 4) + 1 - viewport()->size().height() / m_cellHeight);
|
||||
verticalScrollBar()->setValue(0);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void MemoryModel::setSegment(int segment) {
|
||||
m_currentBank = segment;
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void MemoryModel::setAlignment(int width) {
|
||||
if (width != 1 && width != 2 && width != 4) {
|
||||
return;
|
||||
|
@ -169,17 +175,17 @@ void MemoryModel::serialize(QDataStream* stream) {
|
|||
switch (m_align) {
|
||||
case 1:
|
||||
for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) {
|
||||
*stream << m_core->rawRead8(m_core, i);
|
||||
*stream << m_core->rawRead8(m_core, i, m_currentBank);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) {
|
||||
*stream << m_core->rawRead16(m_core, i);
|
||||
*stream << m_core->rawRead16(m_core, i, m_currentBank);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) {
|
||||
*stream << m_core->rawRead32(m_core, i);
|
||||
*stream << m_core->rawRead32(m_core, i, m_currentBank);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -198,6 +204,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
static QChar c0('0');
|
||||
static QString arg("%0");
|
||||
static QString arg2("%0:%1");
|
||||
QSizeF letterSize = QSizeF(m_letterWidth, m_cellHeight);
|
||||
painter.drawStaticText(QPointF((m_margins.left() - m_regionName.size().width() - 1) / 2.0, 0), m_regionName);
|
||||
painter.drawText(
|
||||
|
@ -213,7 +220,12 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
if ((y + m_top) * 16 >= m_size) {
|
||||
break;
|
||||
}
|
||||
QString data = arg.arg((y + m_top) * 16 + m_base, 8, 16, c0).toUpper();
|
||||
QString data;
|
||||
if (m_currentBank >= 0) {
|
||||
data = arg2.arg(m_currentBank, 2, 16, c0).arg((y + m_top) * 16 + m_base, 4, 16, c0).toUpper();
|
||||
} else {
|
||||
data = arg.arg((y + m_top) * 16 + m_base, 8, 16, c0).toUpper();
|
||||
}
|
||||
painter.drawText(QRectF(QPointF(0, yp), QSizeF(m_margins.left(), m_cellHeight)), Qt::AlignHCenter, data);
|
||||
switch (m_align) {
|
||||
case 2:
|
||||
|
@ -236,7 +248,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
} else {
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
}
|
||||
uint16_t b = m_core->rawRead16(m_core, address);
|
||||
uint16_t b = m_core->rawRead16(m_core, address, m_currentBank);
|
||||
painter.drawStaticText(
|
||||
QPointF(m_cellSize.width() * (x + 1.0) - 2 * m_letterWidth + m_margins.left(), yp),
|
||||
m_staticNumbers[(b >> 8) & 0xFF]);
|
||||
|
@ -264,7 +276,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
} else {
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
}
|
||||
uint32_t b = m_core->rawRead32(m_core, address);
|
||||
uint32_t b = m_core->rawRead32(m_core, address, m_currentBank);
|
||||
painter.drawStaticText(
|
||||
QPointF(m_cellSize.width() * (x + 2.0) - 4 * m_letterWidth + m_margins.left(), yp),
|
||||
m_staticNumbers[(b >> 24) & 0xFF]);
|
||||
|
@ -297,7 +309,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
} else {
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
}
|
||||
uint8_t b = m_core->rawRead8(m_core, address);
|
||||
uint8_t b = m_core->rawRead8(m_core, address, m_currentBank);
|
||||
painter.drawStaticText(QPointF(m_cellSize.width() * (x + 0.5) - m_letterWidth + m_margins.left(), yp),
|
||||
m_staticNumbers[b]);
|
||||
}
|
||||
|
@ -305,7 +317,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
}
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
for (int x = 0; x < 16; ++x) {
|
||||
uint8_t b =m_core->rawRead8(m_core, (y + m_top) * 16 + x + m_base);
|
||||
uint8_t b =m_core->rawRead8(m_core, (y + m_top) * 16 + x + m_base, m_currentBank);
|
||||
painter.drawStaticText(
|
||||
QPointF(viewport()->size().width() - (16 - x) * m_margins.right() / 17.0 - m_letterWidth * 0.5, yp),
|
||||
b < 0x80 ? m_staticAscii[b] : m_staticAscii[0]);
|
||||
|
@ -422,13 +434,13 @@ void MemoryModel::keyPressEvent(QKeyEvent* event) {
|
|||
if (m_bufferedNybbles == m_align * 2) {
|
||||
switch (m_align) {
|
||||
case 1:
|
||||
m_core->rawWrite8(m_core, m_selection.first, m_buffer);
|
||||
m_core->rawWrite8(m_core, m_selection.first, m_buffer, m_currentBank);
|
||||
break;
|
||||
case 2:
|
||||
m_core->rawWrite16(m_core, m_selection.first, m_buffer);
|
||||
m_core->rawWrite16(m_core, m_selection.first, m_buffer, m_currentBank);
|
||||
break;
|
||||
case 4:
|
||||
m_core->rawWrite32(m_core, m_selection.first, m_buffer);
|
||||
m_core->rawWrite32(m_core, m_selection.first, m_buffer, m_currentBank);
|
||||
break;
|
||||
}
|
||||
m_bufferedNybbles = 0;
|
||||
|
|
|
@ -26,7 +26,8 @@ public:
|
|||
|
||||
void setController(GameController* controller);
|
||||
|
||||
void setRegion(uint32_t base, uint32_t size, const QString& name = QString());
|
||||
void setRegion(uint32_t base, uint32_t size, const QString& name = QString(), int segment = -1);
|
||||
void setSegment(int segment);
|
||||
|
||||
void setAlignment(int);
|
||||
int alignment() const { return m_align; }
|
||||
|
@ -77,6 +78,7 @@ private:
|
|||
uint32_t m_selectionAnchor;
|
||||
uint32_t m_buffer;
|
||||
int m_bufferedNybbles;
|
||||
int m_currentBank;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ struct IndexInfo {
|
|||
const char* longName;
|
||||
uint32_t base;
|
||||
uint32_t size;
|
||||
int maxSegment;
|
||||
};
|
||||
#ifdef M_CORE_GBA
|
||||
const static struct IndexInfo indexInfoGBA[] = {
|
||||
|
@ -40,20 +41,20 @@ const static struct IndexInfo indexInfoGBA[] = {
|
|||
{ "ROM WS1", "Game Pak (Waitstate 1)", BASE_CART1, SIZE_CART1 },
|
||||
{ "ROM WS2", "Game Pak (Waitstate 2)", BASE_CART2, SIZE_CART2 },
|
||||
{ "SRAM", "Static RAM (64kiB)", BASE_CART_SRAM, SIZE_CART_SRAM },
|
||||
{ nullptr, nullptr, 0, 0 }
|
||||
{ nullptr, nullptr, 0, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
const static struct IndexInfo indexInfoGB[] = {
|
||||
{ "All", "All", 0, 0x10000 },
|
||||
{ "ROM", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2 },
|
||||
{ "VRAM", "Video RAM (8kiB)", GB_BASE_VRAM, GB_SIZE_VRAM },
|
||||
{ "SRAM", "External RAM (8kiB)", GB_BASE_EXTERNAL_RAM, GB_SIZE_EXTERNAL_RAM },
|
||||
{ "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_SIZE_WORKING_RAM_BANK0 * 2 },
|
||||
{ "ROM", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 511 },
|
||||
{ "VRAM", "Video RAM (8kiB)", GB_BASE_VRAM, GB_SIZE_VRAM, 1 },
|
||||
{ "SRAM", "External RAM (8kiB)", GB_BASE_EXTERNAL_RAM, GB_SIZE_EXTERNAL_RAM, 3 },
|
||||
{ "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_SIZE_WORKING_RAM_BANK0 * 2, 7 },
|
||||
{ "OAM", "OBJ Attribute Memory", GB_BASE_OAM, GB_SIZE_OAM },
|
||||
{ "IO", "Memory-Mapped I/O", GB_BASE_IO, GB_SIZE_IO },
|
||||
{ "HRAM", "High RAM", GB_BASE_HRAM, GB_SIZE_HRAM },
|
||||
{ nullptr, nullptr, 0, 0 }
|
||||
{ nullptr, nullptr, 0, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -83,6 +84,8 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
|||
}
|
||||
|
||||
connect(m_ui.regions, SIGNAL(currentIndexChanged(int)), this, SLOT(setIndex(int)));
|
||||
connect(m_ui.segments, SIGNAL(valueChanged(int)), this, SLOT(setSegment(int)));
|
||||
|
||||
if (info) {
|
||||
for (size_t i = 0; info[i].name; ++i) {
|
||||
m_ui.regions->addItem(tr(info[i].longName));
|
||||
|
@ -93,7 +96,6 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
|||
connect(m_ui.width16, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(2); });
|
||||
connect(m_ui.width32, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(4); });
|
||||
connect(m_ui.setAddress, SIGNAL(valueChanged(const QString&)), m_ui.hexfield, SLOT(jumpToAddress(const QString&)));
|
||||
|
||||
connect(m_ui.hexfield, SIGNAL(selectionChanged(uint32_t, uint32_t)), this, SLOT(updateSelection(uint32_t, uint32_t)));
|
||||
|
||||
connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
|
||||
|
@ -121,9 +123,32 @@ void MemoryView::setIndex(int index) {
|
|||
default:
|
||||
return;
|
||||
}
|
||||
m_ui.segments->setValue(-1);
|
||||
m_ui.segments->setVisible(info.maxSegment > 0);
|
||||
m_ui.segments->setMaximum(info.maxSegment);
|
||||
m_ui.hexfield->setRegion(info.base, info.size, info.name);
|
||||
}
|
||||
|
||||
void MemoryView::setSegment(int segment) {
|
||||
mCore* core = m_controller->thread()->core;
|
||||
IndexInfo info;
|
||||
switch (core->platform(core)) {
|
||||
#ifdef M_CORE_GBA
|
||||
case PLATFORM_GBA:
|
||||
info = indexInfoGBA[m_ui.regions->currentIndex()];
|
||||
break;
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
case PLATFORM_GB:
|
||||
info = indexInfoGB[m_ui.regions->currentIndex()];
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_ui.hexfield->setSegment(info.maxSegment < segment ? info.maxSegment : segment);
|
||||
}
|
||||
|
||||
void MemoryView::update() {
|
||||
m_ui.hexfield->viewport()->update();
|
||||
updateStatus();
|
||||
|
@ -156,17 +181,17 @@ void MemoryView::updateStatus() {
|
|||
} value;
|
||||
switch (align) {
|
||||
case 1:
|
||||
value.u8 = core->rawRead8(core, m_selection.first);
|
||||
value.u8 = core->rawRead8(core, m_selection.first, m_ui.segments->value());
|
||||
m_ui.sintVal->setText(QString::number(value.i8));
|
||||
m_ui.uintVal->setText(QString::number(value.u8));
|
||||
break;
|
||||
case 2:
|
||||
value.u16 = core->rawRead16(core, m_selection.first);
|
||||
value.u16 = core->rawRead16(core, m_selection.first, m_ui.segments->value());
|
||||
m_ui.sintVal->setText(QString::number(value.i16));
|
||||
m_ui.uintVal->setText(QString::number(value.u16));
|
||||
break;
|
||||
case 4:
|
||||
value.u32 = core->rawRead32(core, m_selection.first);
|
||||
value.u32 = core->rawRead32(core, m_selection.first, m_ui.segments->value());
|
||||
m_ui.sintVal->setText(QString::number(value.i32));
|
||||
m_ui.uintVal->setText(QString::number(value.u32));
|
||||
break;
|
||||
|
|
|
@ -25,6 +25,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void setIndex(int);
|
||||
void setSegment(int);
|
||||
void updateSelection(uint32_t start, uint32_t end);
|
||||
void updateStatus();
|
||||
|
||||
|
|
|
@ -39,8 +39,24 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="segments">
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="displayIntegerBase">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="setAddress">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>0x</string>
|
||||
</property>
|
||||
|
|
Loading…
Reference in New Issue