From 202b7b15090056587950f9bcd91d21cebd60ae76 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 5 Jun 2017 15:20:58 -0700 Subject: [PATCH] Core: List memory segments in the core --- CHANGES | 1 + include/mgba/core/core.h | 3 + include/mgba/core/interface.h | 21 +++++ src/gb/core.c | 66 ++++++++++++++++ src/gba/core.c | 137 +++++++++++++++++++++++++++++++++ src/platform/qt/MemoryView.cpp | 106 ++++--------------------- 6 files changed, 243 insertions(+), 91 deletions(-) diff --git a/CHANGES b/CHANGES index db620fc67..a871d8693 100644 --- a/CHANGES +++ b/CHANGES @@ -124,6 +124,7 @@ Misc: - Util: Tune patch-fast extent sizes - Qt: Relax hard dependency on OpenGL - GB Video: Improved video timings + - Core: List memory segments in the core 0.5.2: (2016-12-31) Bugfixes: diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 99c57a037..768f5d889 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -131,6 +131,9 @@ struct mCore { void (*rawWrite16)(struct mCore*, uint32_t address, int segment, uint16_t); void (*rawWrite32)(struct mCore*, uint32_t address, int segment, uint32_t); + size_t (*listMemoryBlocks)(const struct mCore*, const struct mCoreMemoryBlock**); + void* (*getMemoryBlock)(struct mCore*, size_t id, size_t* sizeOut); + #ifdef USE_DEBUGGERS bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType); struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 7f0515a60..2d538d0c3 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -112,6 +112,27 @@ struct mCoreChannelInfo { const char* visibleType; }; +enum mCoreMemoryBlockFlags { + mCORE_MEMORY_READ = 0x01, + mCORE_MEMORY_WRITE = 0x02, + mCORE_MEMORY_RW = 0x03, + mCORE_MEMORY_MAPPED = 0x10, + mCORE_MEMORY_VIRTUAL = 0x20, +}; + +struct mCoreMemoryBlock { + size_t id; + const char* internalName; + const char* shortName; + const char* longName; + uint32_t start; + uint32_t end; + uint32_t size; + uint32_t flags; + uint16_t maxSegment; + uint32_t segmentStart; +}; + CXX_GUARD_END #endif diff --git a/src/gb/core.c b/src/gb/core.c index 1a5e0475d..bae061cdb 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -51,6 +51,28 @@ const static struct LR35902Segment _GBCSegments[] = { { 0 } }; +const static struct mCoreMemoryBlock _GBMemoryBlocks[] = { + { -1, "mem", "All", "All", 0, 0x10000, 0x10000, mCORE_MEMORY_VIRTUAL }, + { GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511 }, + { GB_REGION_VRAM, "vram", "VRAM", "Video RAM (8kiB)", GB_BASE_VRAM, GB_BASE_VRAM + GB_SIZE_VRAM, GB_SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { GB_REGION_EXTERNAL_RAM, "sram", "SRAM", "External RAM (8kiB)", GB_BASE_EXTERNAL_RAM, GB_BASE_EXTERNAL_RAM + GB_SIZE_EXTERNAL_RAM, GB_SIZE_EXTERNAL_RAM * 4, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 3 }, + { GB_REGION_WORKING_RAM_BANK0, "wram", "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2 , GB_SIZE_WORKING_RAM_BANK0 * 2, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { GB_BASE_OAM, "oam", "OAM", "OBJ Attribute Memory", GB_BASE_OAM, GB_BASE_OAM + GB_SIZE_OAM, GB_SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { GB_BASE_IO, "io", "MMIO", "Memory-Mapped I/O", GB_BASE_IO, GB_BASE_IO + GB_SIZE_IO, GB_SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { GB_BASE_HRAM, "hram", "HRAM", "High RAM", GB_BASE_HRAM, GB_BASE_HRAM + GB_SIZE_HRAM, GB_SIZE_HRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, +}; + +const static struct mCoreMemoryBlock _GBCMemoryBlocks[] = { + { -1, "mem", "All", "All", 0, 0x10000, 0x10000, mCORE_MEMORY_VIRTUAL }, + { GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511 }, + { GB_REGION_VRAM, "vram", "VRAM", "Video RAM (8kiB)", GB_BASE_VRAM, GB_BASE_VRAM + GB_SIZE_VRAM, GB_SIZE_VRAM * 2, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 1 }, + { GB_REGION_EXTERNAL_RAM, "sram", "SRAM", "External RAM (8kiB)", GB_BASE_EXTERNAL_RAM, GB_BASE_EXTERNAL_RAM + GB_SIZE_EXTERNAL_RAM, GB_SIZE_EXTERNAL_RAM * 4, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 3 }, + { GB_REGION_WORKING_RAM_BANK0, "wram", "WRAM", "Working RAM (8kiB)", GB_BASE_WORKING_RAM_BANK0, GB_BASE_WORKING_RAM_BANK0 + GB_SIZE_WORKING_RAM_BANK0 * 2, GB_SIZE_WORKING_RAM_BANK0 * 8, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 7 }, + { GB_BASE_OAM, "oam", "OAM", "OBJ Attribute Memory", GB_BASE_OAM, GB_BASE_OAM + GB_SIZE_OAM, GB_SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { GB_BASE_IO, "io", "MMIO", "Memory-Mapped I/O", GB_BASE_IO, GB_BASE_IO + GB_SIZE_IO, GB_SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { GB_BASE_HRAM, "hram", "HRAM", "High RAM", GB_BASE_HRAM, GB_BASE_HRAM + GB_SIZE_HRAM, GB_SIZE_HRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, +}; + struct mVideoLogContext; struct GBCore { struct mCore d; @@ -530,6 +552,48 @@ static void _GBCoreRawWrite32(struct mCore* core, uint32_t address, int segment, GBPatch8(cpu, address + 3, value >> 24, NULL, segment); } +size_t _GBListMemoryBlocks(const struct mCore* core, const struct mCoreMemoryBlock** blocks) { + const struct GB* gb = core->board; + switch (gb->model) { + case GB_MODEL_DMG: + case GB_MODEL_SGB: + default: + *blocks = _GBMemoryBlocks; + return sizeof(_GBMemoryBlocks) / sizeof(*_GBMemoryBlocks); + case GB_MODEL_CGB: + case GB_MODEL_AGB: + *blocks = _GBCMemoryBlocks; + return sizeof(_GBCMemoryBlocks) / sizeof(*_GBCMemoryBlocks); + } +} + +void* _GBGetMemoryBlock(struct mCore* core, size_t id, size_t* sizeOut) { + struct GB* gb = core->board; + bool isCgb = gb->model >= GB_MODEL_CGB; + switch (id) { + default: + return NULL; + case GB_REGION_CART_BANK0: + *sizeOut = gb->memory.romSize; + return gb->memory.rom; + case GB_REGION_VRAM: + *sizeOut = GB_SIZE_WORKING_RAM_BANK0 * (isCgb ? 1 : 2); + return gb->video.vram; + case GB_REGION_EXTERNAL_RAM: + *sizeOut = gb->sramSize; + return gb->memory.sram; + case GB_REGION_WORKING_RAM_BANK0: + *sizeOut = GB_SIZE_VRAM * (isCgb ? 8 : 2); + return gb->memory.wram; + case GB_BASE_OAM: + *sizeOut = GB_SIZE_OAM; + return gb->video.oam.raw; + case GB_BASE_HRAM: + *sizeOut = GB_SIZE_HRAM; + return gb->memory.hram; + } +} + #ifdef USE_DEBUGGERS static bool _GBCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) { UNUSED(core); @@ -762,6 +826,8 @@ struct mCore* GBCoreCreate(void) { core->rawWrite8 = _GBCoreRawWrite8; core->rawWrite16 = _GBCoreRawWrite16; core->rawWrite32 = _GBCoreRawWrite32; + core->listMemoryBlocks = _GBListMemoryBlocks; + core->getMemoryBlock = _GBGetMemoryBlock; #ifdef USE_DEBUGGERS core->supportsDebuggerType = _GBCoreSupportsDebuggerType; core->debuggerPlatform = _GBCoreDebuggerPlatform; diff --git a/src/gba/core.c b/src/gba/core.c index 32272bb50..53b3375e5 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -41,6 +41,80 @@ const static struct mCoreChannelInfo _GBAAudioChannels[] = { { 5, "chB", "FIFO Channel B", NULL }, }; +const static struct mCoreMemoryBlock _GBAMemoryBlocks[] = { + { -1, "mem", "All", "All", 0, 0x10000000, 0x10000000, mCORE_MEMORY_VIRTUAL }, + { REGION_BIOS, "bios", "BIOS", "BIOS (16kiB)", BASE_BIOS, SIZE_BIOS, SIZE_BIOS, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_RAM, "wram", "EWRAM", "Working RAM (256kiB)", BASE_WORKING_RAM, BASE_WORKING_RAM + SIZE_WORKING_RAM, SIZE_WORKING_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_IRAM, "iwram", "IWRAM", "Internal Working RAM (32kiB)", BASE_WORKING_IRAM, BASE_WORKING_IRAM + SIZE_WORKING_IRAM, SIZE_WORKING_IRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_IO, "io", "MMIO", "Memory-Mapped I/O", BASE_IO, BASE_IO + SIZE_IO, SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_PALETTE_RAM, "palette", "Palette", "Palette RAM (1kiB)", BASE_PALETTE_RAM, BASE_PALETTE_RAM + SIZE_PALETTE_RAM, SIZE_PALETTE_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_VRAM, "vram", "VRAM", "Video RAM (96kiB)", BASE_VRAM, BASE_VRAM + SIZE_VRAM, SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_OAM, "oam", "OAM", "OBJ Attribute Memory (1kiB)", BASE_OAM, BASE_OAM + SIZE_OAM, SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_CART0, "cart0", "ROM", "Game Pak (32MiB)", BASE_CART0, BASE_CART0 + SIZE_CART0, SIZE_CART0, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART1, "cart1", "ROM WS1", "Game Pak (Waitstate 1)", BASE_CART1, BASE_CART1 + SIZE_CART1, SIZE_CART1, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART2, "cart2", "ROM WS2", "Game Pak (Waitstate 2)", BASE_CART2, BASE_CART2 + SIZE_CART2, SIZE_CART2, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, +}; + +const static struct mCoreMemoryBlock _GBAMemoryBlocksSRAM[] = { + { -1, "mem", "All", "All", 0, 0x10000000, 0x10000000, mCORE_MEMORY_VIRTUAL }, + { REGION_BIOS, "bios", "BIOS", "BIOS (16kiB)", BASE_BIOS, SIZE_BIOS, SIZE_BIOS, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_RAM, "wram", "EWRAM", "Working RAM (256kiB)", BASE_WORKING_RAM, BASE_WORKING_RAM + SIZE_WORKING_RAM, SIZE_WORKING_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_IRAM, "iwram", "IWRAM", "Internal Working RAM (32kiB)", BASE_WORKING_IRAM, BASE_WORKING_IRAM + SIZE_WORKING_IRAM, SIZE_WORKING_IRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_IO, "io", "MMIO", "Memory-Mapped I/O", BASE_IO, BASE_IO + SIZE_IO, SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_PALETTE_RAM, "palette", "Palette", "Palette RAM (1kiB)", BASE_PALETTE_RAM, BASE_PALETTE_RAM + SIZE_PALETTE_RAM, SIZE_PALETTE_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_VRAM, "vram", "VRAM", "Video RAM (96kiB)", BASE_VRAM, BASE_VRAM + SIZE_VRAM, SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_OAM, "oam", "OAM", "OBJ Attribute Memory (1kiB)", BASE_OAM, BASE_OAM + SIZE_OAM, SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_CART0, "cart0", "ROM", "Game Pak (32MiB)", BASE_CART0, BASE_CART0 + SIZE_CART0, SIZE_CART0, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART1, "cart1", "ROM WS1", "Game Pak (Waitstate 1)", BASE_CART1, BASE_CART1 + SIZE_CART1, SIZE_CART1, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART2, "cart2", "ROM WS2", "Game Pak (Waitstate 2)", BASE_CART2, BASE_CART2 + SIZE_CART2, SIZE_CART2, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART_SRAM, "sram", "SRAM", "Static RAM (64kiB)", BASE_CART_SRAM, BASE_CART_SRAM + SIZE_CART_SRAM, SIZE_CART_SRAM, true }, +}; + +const static struct mCoreMemoryBlock _GBAMemoryBlocksFlash512[] = { + { -1, "mem", "All", "All", 0, 0x10000000, 0x10000000, mCORE_MEMORY_VIRTUAL }, + { REGION_BIOS, "bios", "BIOS", "BIOS (16kiB)", BASE_BIOS, SIZE_BIOS, SIZE_BIOS, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_RAM, "wram", "EWRAM", "Working RAM (256kiB)", BASE_WORKING_RAM, BASE_WORKING_RAM + SIZE_WORKING_RAM, SIZE_WORKING_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_IRAM, "iwram", "IWRAM", "Internal Working RAM (32kiB)", BASE_WORKING_IRAM, BASE_WORKING_IRAM + SIZE_WORKING_IRAM, SIZE_WORKING_IRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_IO, "io", "MMIO", "Memory-Mapped I/O", BASE_IO, BASE_IO + SIZE_IO, SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_PALETTE_RAM, "palette", "Palette", "Palette RAM (1kiB)", BASE_PALETTE_RAM, BASE_PALETTE_RAM + SIZE_PALETTE_RAM, SIZE_PALETTE_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_VRAM, "vram", "VRAM", "Video RAM (96kiB)", BASE_VRAM, BASE_VRAM + SIZE_VRAM, SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_OAM, "oam", "OAM", "OBJ Attribute Memory (1kiB)", BASE_OAM, BASE_OAM + SIZE_OAM, SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_CART0, "cart0", "ROM", "Game Pak (32MiB)", BASE_CART0, BASE_CART0 + SIZE_CART0, SIZE_CART0, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART1, "cart1", "ROM WS1", "Game Pak (Waitstate 1)", BASE_CART1, BASE_CART1 + SIZE_CART1, SIZE_CART1, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART2, "cart2", "ROM WS2", "Game Pak (Waitstate 2)", BASE_CART2, BASE_CART2 + SIZE_CART2, SIZE_CART2, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART_SRAM, "sram", "Flash", "Flash Memory (64kiB)", BASE_CART_SRAM, BASE_CART_SRAM + SIZE_CART_FLASH512, SIZE_CART_FLASH512, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, +}; + +const static struct mCoreMemoryBlock _GBAMemoryBlocksFlash1M[] = { + { -1, "mem", "All", "All", 0, 0x10000000, 0x10000000, mCORE_MEMORY_VIRTUAL }, + { REGION_BIOS, "bios", "BIOS", "BIOS (16kiB)", BASE_BIOS, SIZE_BIOS, SIZE_BIOS, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_RAM, "wram", "EWRAM", "Working RAM (256kiB)", BASE_WORKING_RAM, BASE_WORKING_RAM + SIZE_WORKING_RAM, SIZE_WORKING_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_IRAM, "iwram", "IWRAM", "Internal Working RAM (32kiB)", BASE_WORKING_IRAM, BASE_WORKING_IRAM + SIZE_WORKING_IRAM, SIZE_WORKING_IRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_IO, "io", "MMIO", "Memory-Mapped I/O", BASE_IO, BASE_IO + SIZE_IO, SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_PALETTE_RAM, "palette", "Palette", "Palette RAM (1kiB)", BASE_PALETTE_RAM, BASE_PALETTE_RAM + SIZE_PALETTE_RAM, SIZE_PALETTE_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_VRAM, "vram", "VRAM", "Video RAM (96kiB)", BASE_VRAM, BASE_VRAM + SIZE_VRAM, SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_OAM, "oam", "OAM", "OBJ Attribute Memory (1kiB)", BASE_OAM, BASE_OAM + SIZE_OAM, SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_CART0, "cart0", "ROM", "Game Pak (32MiB)", BASE_CART0, BASE_CART0 + SIZE_CART0, SIZE_CART0, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART1, "cart1", "ROM WS1", "Game Pak (Waitstate 1)", BASE_CART1, BASE_CART1 + SIZE_CART1, SIZE_CART1, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART2, "cart2", "ROM WS2", "Game Pak (Waitstate 2)", BASE_CART2, BASE_CART2 + SIZE_CART2, SIZE_CART2, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART_SRAM, "sram", "Flash", "Flash Memory (64kiB)", BASE_CART_SRAM, BASE_CART_SRAM + SIZE_CART_FLASH512, SIZE_CART_FLASH1M, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED, 1 }, +}; + +const static struct mCoreMemoryBlock _GBAMemoryBlocksEEPROM[] = { + { -1, "mem", "All", "All", 0, 0x10000000, 0x10000000, mCORE_MEMORY_VIRTUAL }, + { REGION_BIOS, "bios", "BIOS", "BIOS (16kiB)", BASE_BIOS, SIZE_BIOS, SIZE_BIOS, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_RAM, "wram", "EWRAM", "Working RAM (256kiB)", BASE_WORKING_RAM, BASE_WORKING_RAM + SIZE_WORKING_RAM, SIZE_WORKING_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_WORKING_IRAM, "iwram", "IWRAM", "Internal Working RAM (32kiB)", BASE_WORKING_IRAM, BASE_WORKING_IRAM + SIZE_WORKING_IRAM, SIZE_WORKING_IRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_IO, "io", "MMIO", "Memory-Mapped I/O", BASE_IO, BASE_IO + SIZE_IO, SIZE_IO, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_PALETTE_RAM, "palette", "Palette", "Palette RAM (1kiB)", BASE_PALETTE_RAM, BASE_PALETTE_RAM + SIZE_PALETTE_RAM, SIZE_PALETTE_RAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_VRAM, "vram", "VRAM", "Video RAM (96kiB)", BASE_VRAM, BASE_VRAM + SIZE_VRAM, SIZE_VRAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_OAM, "oam", "OAM", "OBJ Attribute Memory (1kiB)", BASE_OAM, BASE_OAM + SIZE_OAM, SIZE_OAM, mCORE_MEMORY_RW | mCORE_MEMORY_MAPPED }, + { REGION_CART0, "cart0", "ROM", "Game Pak (32MiB)", BASE_CART0, BASE_CART0 + SIZE_CART0, SIZE_CART0, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART1, "cart1", "ROM WS1", "Game Pak (Waitstate 1)", BASE_CART1, BASE_CART1 + SIZE_CART1, SIZE_CART1, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART2, "cart2", "ROM WS2", "Game Pak (Waitstate 2)", BASE_CART2, BASE_CART2 + SIZE_CART2, SIZE_CART2, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED }, + { REGION_CART_SRAM_MIRROR, "eeprom", "EEPROM", "EEPROM (8kiB)", 0, SIZE_CART_EEPROM, SIZE_CART_EEPROM, mCORE_MEMORY_RW }, +}; + struct mVideoLogContext; struct GBACore { struct mCore d; @@ -520,6 +594,67 @@ static void _GBACoreRawWrite32(struct mCore* core, uint32_t address, int segment GBAPatch32(cpu, address, value, NULL); } +size_t _GBAListMemoryBlocks(const struct mCore* core, const struct mCoreMemoryBlock** blocks) { + const struct GBA* gba = core->board; + switch (gba->memory.savedata.type) { + case SAVEDATA_SRAM: + *blocks = _GBAMemoryBlocksSRAM; + return sizeof(_GBAMemoryBlocksSRAM) / sizeof(*_GBAMemoryBlocksSRAM); + case SAVEDATA_FLASH512: + *blocks = _GBAMemoryBlocksFlash512; + return sizeof(_GBAMemoryBlocksFlash512) / sizeof(*_GBAMemoryBlocksFlash512); + case SAVEDATA_FLASH1M: + *blocks = _GBAMemoryBlocksFlash1M; + return sizeof(_GBAMemoryBlocksFlash1M) / sizeof(*_GBAMemoryBlocksFlash1M); + case SAVEDATA_EEPROM: + *blocks = _GBAMemoryBlocksEEPROM; + return sizeof(_GBAMemoryBlocksEEPROM) / sizeof(*_GBAMemoryBlocksEEPROM); + default: + *blocks = _GBAMemoryBlocks; + return sizeof(_GBAMemoryBlocks) / sizeof(*_GBAMemoryBlocks); + } +} + +void* _GBAGetMemoryBlock(struct mCore* core, size_t id, size_t* sizeOut) { + struct GBA* gba = core->board; + switch (id) { + default: + return NULL; + case REGION_BIOS: + *sizeOut = SIZE_BIOS; + return gba->memory.bios; + case REGION_WORKING_RAM: + *sizeOut = SIZE_WORKING_RAM; + return gba->memory.wram; + case REGION_WORKING_IRAM: + *sizeOut = SIZE_WORKING_IRAM; + return gba->memory.iwram; + case REGION_PALETTE_RAM: + *sizeOut = SIZE_PALETTE_RAM; + return gba->video.palette; + case REGION_VRAM: + *sizeOut = SIZE_VRAM; + return gba->video.vram; + case REGION_OAM: + *sizeOut = SIZE_OAM; + return gba->video.oam.raw; + case REGION_CART0: + case REGION_CART1: + case REGION_CART2: + *sizeOut = gba->memory.romSize; + return gba->memory.rom; + case REGION_CART_SRAM: + if (gba->memory.savedata.type == SAVEDATA_FLASH1M) { + *sizeOut = SIZE_CART_FLASH1M; + return gba->memory.savedata.currentBank; + } + // Fall through + case REGION_CART_SRAM_MIRROR: + *sizeOut = GBASavedataSize(&gba->memory.savedata); + return gba->memory.savedata.data; + } +} + #ifdef USE_DEBUGGERS static bool _GBACoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) { UNUSED(core); @@ -749,6 +884,8 @@ struct mCore* GBACoreCreate(void) { core->rawWrite8 = _GBACoreRawWrite8; core->rawWrite16 = _GBACoreRawWrite16; core->rawWrite32 = _GBACoreRawWrite32; + core->listMemoryBlocks = _GBAListMemoryBlocks; + core->getMemoryBlock = _GBAGetMemoryBlock; #ifdef USE_DEBUGGERS core->supportsDebuggerType = _GBACoreSupportsDebuggerType; core->debuggerPlatform = _GBACoreDebuggerPlatform; diff --git a/src/platform/qt/MemoryView.cpp b/src/platform/qt/MemoryView.cpp index b343060fa..543dbe6bf 100644 --- a/src/platform/qt/MemoryView.cpp +++ b/src/platform/qt/MemoryView.cpp @@ -9,53 +9,9 @@ #include "GameController.h" #include -#ifdef M_CORE_GBA -#include -#endif -#ifdef M_CORE_GB -#include -#endif using namespace QGBA; -struct IndexInfo { - const char* name; - const char* longName; - uint32_t base; - uint32_t size; - int maxSegment; -}; -#ifdef M_CORE_GBA -const static struct IndexInfo indexInfoGBA[] = { - { "All", "All", 0, 0x10000000 }, - { "BIOS", "BIOS (16kiB)", BASE_BIOS, SIZE_BIOS }, - { "EWRAM", "Working RAM (256kiB)", BASE_WORKING_RAM, SIZE_WORKING_RAM }, - { "IWRAM", "Internal Working RAM (32kiB)", BASE_WORKING_IRAM, SIZE_WORKING_IRAM }, - { "MMIO", "Memory-Mapped I/O", BASE_IO, SIZE_IO }, - { "Palette", "Palette RAM (1kiB)", BASE_PALETTE_RAM, SIZE_PALETTE_RAM }, - { "VRAM", "Video RAM (96kiB)", BASE_VRAM, SIZE_VRAM }, - { "OAM", "OBJ Attribute Memory (1kiB)", BASE_OAM, SIZE_OAM }, - { "ROM", "Game Pak (32MiB)", BASE_CART0, SIZE_CART0 }, - { "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, 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, 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, 0 } -}; -#endif - MemoryView::MemoryView(GameController* controller, QWidget* parent) : QWidget(parent) , m_controller(controller) @@ -65,21 +21,8 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent) m_ui.hexfield->setController(controller); mCore* core = m_controller->thread()->core; - const IndexInfo* info = nullptr; - switch (core->platform(core)) { -#ifdef M_CORE_GBA - case PLATFORM_GBA: - info = indexInfoGBA; - break; -#endif -#ifdef M_CORE_GB - case PLATFORM_GB: - info = indexInfoGB; - break; -#endif - default: - break; - } + const mCoreMemoryBlock* info; + size_t nBlocks = core->listMemoryBlocks(core, &info); connect(m_ui.regions, static_cast(&QComboBox::currentIndexChanged), this, &MemoryView::setIndex); @@ -87,7 +30,10 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent) this, &MemoryView::setSegment); if (info) { - for (size_t i = 0; info[i].name; ++i) { + for (size_t i = 0; i < nBlocks; ++i) { + if (!(info[i].flags & (mCORE_MEMORY_MAPPED | mCORE_MEMORY_VIRTUAL))) { + continue; + } m_ui.regions->addItem(tr(info[i].longName)); } } @@ -116,44 +62,22 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent) void MemoryView::setIndex(int index) { mCore* core = m_controller->thread()->core; - IndexInfo info; - switch (core->platform(core)) { -#ifdef M_CORE_GBA - case PLATFORM_GBA: - info = indexInfoGBA[index]; - break; -#endif -#ifdef M_CORE_GB - case PLATFORM_GB: - info = indexInfoGB[index]; - break; -#endif - default: - return; - } + const mCoreMemoryBlock* blocks; + size_t nBlocks = core->listMemoryBlocks(core, &blocks); + const mCoreMemoryBlock& info = blocks[index]; + 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); + m_ui.hexfield->setRegion(info.start, info.end - info.start, info.shortName); } 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; - } + const mCoreMemoryBlock* blocks; + size_t nBlocks = core->listMemoryBlocks(core, &blocks); + const mCoreMemoryBlock& info = blocks[m_ui.regions->currentIndex()]; + m_ui.hexfield->setSegment(info.maxSegment < segment ? info.maxSegment : segment); }