all repos — mgba @ 142940cc6945e18fba52d1cf3ea50f5ccb2f1017

mGBA Game Boy Advance Emulator

GBA Memory: Add GBAView* functions for viewing memory directly without bus issues
Jeffrey Pfau jeffrey@endrift.com
Wed, 11 Nov 2015 23:50:15 -0800
commit

142940cc6945e18fba52d1cf3ea50f5ccb2f1017

parent

4783e2eef6008b03516491b88b21724cfeaabd10

M CHANGESCHANGES

@@ -43,6 +43,7 @@ - GBA Audio: Implement missing flags on SOUNDCNT_X register

- 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:
M src/gba/memory.csrc/gba/memory.c

@@ -869,6 +869,117 @@ *cycleCounter += wait;

} } +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;
M src/gba/memory.hsrc/gba/memory.h

@@ -157,6 +157,10 @@ void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter);

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);
M src/platform/qt/IOViewer.cppsrc/platform/qt/IOViewer.cpp

@@ -779,7 +779,7 @@ m_value = 0;

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();
M src/platform/qt/MemoryModel.cppsrc/platform/qt/MemoryModel.cpp

@@ -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 @@ }

} 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 @@ }

} 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 @@ }

} 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 @@ break;

} 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]);
M src/platform/qt/MemoryView.cppsrc/platform/qt/MemoryView.cpp

@@ -94,17 +94,17 @@ int8_t i8;

} 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;