From 142940cc6945e18fba52d1cf3ea50f5ccb2f1017 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 11 Nov 2015 23:50:15 -0800 Subject: [PATCH] GBA Memory: Add GBAView* functions for viewing memory directly without bus issues --- CHANGES | 1 + src/gba/memory.c | 111 ++++++++++++++++++++++++++++++++ src/gba/memory.h | 4 ++ src/platform/qt/IOViewer.cpp | 2 +- src/platform/qt/MemoryModel.cpp | 14 ++-- src/platform/qt/MemoryView.cpp | 6 +- 6 files changed, 127 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 4171d4824..ec2eac205 100644 --- a/CHANGES +++ b/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: diff --git a/src/gba/memory.c b/src/gba/memory.c index 834b54ae8..684412612 100644 --- a/src/gba/memory.c +++ b/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; diff --git a/src/gba/memory.h b/src/gba/memory.h index a70e3a1e6..68de048b9 100644 --- a/src/gba/memory.h +++ b/src/gba/memory.h @@ -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); diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index 0e6eee24c..e8e26972e 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -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(); diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index 343883f6a..aecde1356 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/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 @@ 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]); diff --git a/src/platform/qt/MemoryView.cpp b/src/platform/qt/MemoryView.cpp index 3b43592d2..b267ff2ea 100644 --- a/src/platform/qt/MemoryView.cpp +++ b/src/platform/qt/MemoryView.cpp @@ -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;