mirror of https://github.com/mgba-emu/mgba.git
GBA Memory: Add GBAView* functions for viewing memory directly without bus issues
This commit is contained in:
parent
4783e2eef6
commit
142940cc69
1
CHANGES
1
CHANGES
|
@ -43,6 +43,7 @@ Misc:
|
|||
- Util: Use VFile for configuration
|
||||
- GBA Memory: Implement several unimplemented memory access types
|
||||
- GBA: Implement bad I/O register loading
|
||||
- GBA Memory: Add GBAView* functions for viewing memory directly without bus issues
|
||||
|
||||
0.3.1: (2015-10-24)
|
||||
Bugfixes:
|
||||
|
|
111
src/gba/memory.c
111
src/gba/memory.c
|
@ -869,6 +869,117 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t GBAView32(struct ARMCore* cpu, uint32_t address) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
uint32_t value = 0;
|
||||
address &= ~3;
|
||||
switch (address >> BASE_OFFSET) {
|
||||
case REGION_BIOS:
|
||||
if (address < SIZE_BIOS) {
|
||||
LOAD_32(value, address, gba->memory.bios);
|
||||
}
|
||||
break;
|
||||
case REGION_WORKING_RAM:
|
||||
case REGION_WORKING_IRAM:
|
||||
case REGION_PALETTE_RAM:
|
||||
case REGION_VRAM:
|
||||
case REGION_OAM:
|
||||
case REGION_CART0:
|
||||
case REGION_CART0_EX:
|
||||
case REGION_CART1:
|
||||
case REGION_CART1_EX:
|
||||
case REGION_CART2:
|
||||
case REGION_CART2_EX:
|
||||
value = GBALoad32(cpu, address, 0);
|
||||
break;
|
||||
case REGION_IO:
|
||||
if ((address & OFFSET_MASK) < REG_MAX) {
|
||||
value = gba->memory.io[(address & OFFSET_MASK) >> 1];
|
||||
value |= gba->memory.io[((address & OFFSET_MASK) >> 1) + 1] << 16;
|
||||
}
|
||||
break;
|
||||
case REGION_CART_SRAM:
|
||||
value = GBALoad8(cpu, address, 0);
|
||||
value |= GBALoad8(cpu, address + 1, 0) << 8;
|
||||
value |= GBALoad8(cpu, address + 2, 0) << 16;
|
||||
value |= GBALoad8(cpu, address + 3, 0) << 24;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t GBAView16(struct ARMCore* cpu, uint32_t address) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
uint16_t value = 0;
|
||||
address &= ~1;
|
||||
switch (address >> BASE_OFFSET) {
|
||||
case REGION_BIOS:
|
||||
if (address < SIZE_BIOS) {
|
||||
LOAD_16(value, address, gba->memory.bios);
|
||||
}
|
||||
break;
|
||||
case REGION_WORKING_RAM:
|
||||
case REGION_WORKING_IRAM:
|
||||
case REGION_PALETTE_RAM:
|
||||
case REGION_VRAM:
|
||||
case REGION_OAM:
|
||||
case REGION_CART0:
|
||||
case REGION_CART0_EX:
|
||||
case REGION_CART1:
|
||||
case REGION_CART1_EX:
|
||||
case REGION_CART2:
|
||||
case REGION_CART2_EX:
|
||||
value = GBALoad16(cpu, address, 0);
|
||||
break;
|
||||
case REGION_IO:
|
||||
if ((address & OFFSET_MASK) < REG_MAX) {
|
||||
value = gba->memory.io[(address & OFFSET_MASK) >> 1];
|
||||
}
|
||||
break;
|
||||
case REGION_CART_SRAM:
|
||||
value = GBALoad8(cpu, address, 0);
|
||||
value |= GBALoad8(cpu, address + 1, 0) << 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint8_t GBAView8(struct ARMCore* cpu, uint32_t address) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
uint8_t value = 0;
|
||||
switch (address >> BASE_OFFSET) {
|
||||
case REGION_BIOS:
|
||||
if (address < SIZE_BIOS) {
|
||||
value = ((uint8_t*) gba->memory.bios)[address];
|
||||
}
|
||||
break;
|
||||
case REGION_WORKING_RAM:
|
||||
case REGION_WORKING_IRAM:
|
||||
case REGION_CART0:
|
||||
case REGION_CART0_EX:
|
||||
case REGION_CART1:
|
||||
case REGION_CART1_EX:
|
||||
case REGION_CART2:
|
||||
case REGION_CART2_EX:
|
||||
case REGION_CART_SRAM:
|
||||
value = GBALoad8(cpu, address, 0);
|
||||
break;
|
||||
case REGION_IO:
|
||||
case REGION_PALETTE_RAM:
|
||||
case REGION_VRAM:
|
||||
case REGION_OAM:
|
||||
value = GBAView16(cpu, address) >> ((address & 1) * 8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* old) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
|
|
|
@ -157,6 +157,10 @@ void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
|
|||
void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter);
|
||||
void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter);
|
||||
|
||||
uint32_t GBAView32(struct ARMCore* cpu, uint32_t address);
|
||||
uint16_t GBAView16(struct ARMCore* cpu, uint32_t address);
|
||||
uint8_t GBAView8(struct ARMCore* cpu, uint32_t address);
|
||||
|
||||
void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* old);
|
||||
void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* old);
|
||||
void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old);
|
||||
|
|
|
@ -779,7 +779,7 @@ void IOViewer::updateRegister() {
|
|||
uint16_t value = 0;
|
||||
m_controller->threadInterrupt();
|
||||
if (m_controller->isLoaded()) {
|
||||
value = GBAIORead(m_controller->thread()->gba, m_register);
|
||||
value = GBAView16(m_controller->thread()->cpu, BASE_IO | m_register);
|
||||
}
|
||||
m_controller->threadContinue();
|
||||
|
||||
|
|
|
@ -169,17 +169,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 << (quint8) m_cpu->memory.load8(m_cpu, i, nullptr);
|
||||
*stream << GBAView8(m_cpu, i);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) {
|
||||
*stream << (quint16) m_cpu->memory.load16(m_cpu, i, nullptr);
|
||||
*stream << GBAView16(m_cpu, i);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) {
|
||||
*stream << (quint32) m_cpu->memory.load32(m_cpu, i, nullptr);
|
||||
*stream << GBAView32(m_cpu, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
} else {
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
}
|
||||
uint16_t b = m_cpu->memory.load16(m_cpu, address, nullptr);
|
||||
uint16_t b = GBAView16(m_cpu, address);
|
||||
painter.drawStaticText(
|
||||
QPointF(m_cellSize.width() * (x + 1.0) - 2 * m_letterWidth + m_margins.left(), yp),
|
||||
m_staticNumbers[(b >> 8) & 0xFF]);
|
||||
|
@ -255,7 +255,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
} else {
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
}
|
||||
uint32_t b = m_cpu->memory.load32(m_cpu, address, nullptr);
|
||||
uint32_t b = GBAView32(m_cpu, address);
|
||||
painter.drawStaticText(
|
||||
QPointF(m_cellSize.width() * (x + 2.0) - 4 * m_letterWidth + m_margins.left(), yp),
|
||||
m_staticNumbers[(b >> 24) & 0xFF]);
|
||||
|
@ -285,7 +285,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
} else {
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
}
|
||||
uint8_t b = m_cpu->memory.load8(m_cpu, address, nullptr);
|
||||
uint8_t b = GBAView8(m_cpu, address);
|
||||
painter.drawStaticText(QPointF(m_cellSize.width() * (x + 0.5) - m_letterWidth + m_margins.left(), yp),
|
||||
m_staticNumbers[b]);
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
|||
}
|
||||
painter.setPen(palette.color(QPalette::WindowText));
|
||||
for (int x = 0; x < 16; ++x) {
|
||||
uint8_t b = m_cpu->memory.load8(m_cpu, (y + m_top) * 16 + x + m_base, nullptr);
|
||||
uint8_t b = GBAView8(m_cpu, (y + m_top) * 16 + x + m_base);
|
||||
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]);
|
||||
|
|
|
@ -94,17 +94,17 @@ void MemoryView::updateStatus() {
|
|||
} value;
|
||||
switch (align) {
|
||||
case 1:
|
||||
value.u8 = cpu->memory.load8(cpu, m_selection.first, nullptr);
|
||||
value.u8 = GBAView8(cpu, m_selection.first);
|
||||
m_ui.sintVal->setText(QString::number(value.i8));
|
||||
m_ui.uintVal->setText(QString::number(value.u8));
|
||||
break;
|
||||
case 2:
|
||||
value.u16 = cpu->memory.load16(cpu, m_selection.first, nullptr);
|
||||
value.u16 = GBAView16(cpu, m_selection.first);
|
||||
m_ui.sintVal->setText(QString::number(value.i16));
|
||||
m_ui.uintVal->setText(QString::number(value.u16));
|
||||
break;
|
||||
case 4:
|
||||
value.u32 = cpu->memory.load32(cpu, m_selection.first, nullptr);
|
||||
value.u32 = GBAView32(cpu, m_selection.first);
|
||||
m_ui.sintVal->setText(QString::number(value.i32));
|
||||
m_ui.uintVal->setText(QString::number(value.u32));
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue