mirror of https://github.com/mgba-emu/mgba.git
Core: List memory segments in the core
This commit is contained in:
parent
89a4b427a1
commit
202b7b1509
1
CHANGES
1
CHANGES
|
@ -124,6 +124,7 @@ Misc:
|
||||||
- Util: Tune patch-fast extent sizes
|
- Util: Tune patch-fast extent sizes
|
||||||
- Qt: Relax hard dependency on OpenGL
|
- Qt: Relax hard dependency on OpenGL
|
||||||
- GB Video: Improved video timings
|
- GB Video: Improved video timings
|
||||||
|
- Core: List memory segments in the core
|
||||||
|
|
||||||
0.5.2: (2016-12-31)
|
0.5.2: (2016-12-31)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -131,6 +131,9 @@ struct mCore {
|
||||||
void (*rawWrite16)(struct mCore*, uint32_t address, int segment, uint16_t);
|
void (*rawWrite16)(struct mCore*, uint32_t address, int segment, uint16_t);
|
||||||
void (*rawWrite32)(struct mCore*, uint32_t address, int segment, uint32_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
|
#ifdef USE_DEBUGGERS
|
||||||
bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType);
|
bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType);
|
||||||
struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*);
|
struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*);
|
||||||
|
|
|
@ -112,6 +112,27 @@ struct mCoreChannelInfo {
|
||||||
const char* visibleType;
|
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
|
CXX_GUARD_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,28 @@ const static struct LR35902Segment _GBCSegments[] = {
|
||||||
{ 0 }
|
{ 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 mVideoLogContext;
|
||||||
struct GBCore {
|
struct GBCore {
|
||||||
struct mCore d;
|
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);
|
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
|
#ifdef USE_DEBUGGERS
|
||||||
static bool _GBCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
|
static bool _GBCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
|
||||||
UNUSED(core);
|
UNUSED(core);
|
||||||
|
@ -762,6 +826,8 @@ struct mCore* GBCoreCreate(void) {
|
||||||
core->rawWrite8 = _GBCoreRawWrite8;
|
core->rawWrite8 = _GBCoreRawWrite8;
|
||||||
core->rawWrite16 = _GBCoreRawWrite16;
|
core->rawWrite16 = _GBCoreRawWrite16;
|
||||||
core->rawWrite32 = _GBCoreRawWrite32;
|
core->rawWrite32 = _GBCoreRawWrite32;
|
||||||
|
core->listMemoryBlocks = _GBListMemoryBlocks;
|
||||||
|
core->getMemoryBlock = _GBGetMemoryBlock;
|
||||||
#ifdef USE_DEBUGGERS
|
#ifdef USE_DEBUGGERS
|
||||||
core->supportsDebuggerType = _GBCoreSupportsDebuggerType;
|
core->supportsDebuggerType = _GBCoreSupportsDebuggerType;
|
||||||
core->debuggerPlatform = _GBCoreDebuggerPlatform;
|
core->debuggerPlatform = _GBCoreDebuggerPlatform;
|
||||||
|
|
137
src/gba/core.c
137
src/gba/core.c
|
@ -41,6 +41,80 @@ const static struct mCoreChannelInfo _GBAAudioChannels[] = {
|
||||||
{ 5, "chB", "FIFO Channel B", NULL },
|
{ 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 mVideoLogContext;
|
||||||
struct GBACore {
|
struct GBACore {
|
||||||
struct mCore d;
|
struct mCore d;
|
||||||
|
@ -520,6 +594,67 @@ static void _GBACoreRawWrite32(struct mCore* core, uint32_t address, int segment
|
||||||
GBAPatch32(cpu, address, value, NULL);
|
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
|
#ifdef USE_DEBUGGERS
|
||||||
static bool _GBACoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
|
static bool _GBACoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) {
|
||||||
UNUSED(core);
|
UNUSED(core);
|
||||||
|
@ -749,6 +884,8 @@ struct mCore* GBACoreCreate(void) {
|
||||||
core->rawWrite8 = _GBACoreRawWrite8;
|
core->rawWrite8 = _GBACoreRawWrite8;
|
||||||
core->rawWrite16 = _GBACoreRawWrite16;
|
core->rawWrite16 = _GBACoreRawWrite16;
|
||||||
core->rawWrite32 = _GBACoreRawWrite32;
|
core->rawWrite32 = _GBACoreRawWrite32;
|
||||||
|
core->listMemoryBlocks = _GBAListMemoryBlocks;
|
||||||
|
core->getMemoryBlock = _GBAGetMemoryBlock;
|
||||||
#ifdef USE_DEBUGGERS
|
#ifdef USE_DEBUGGERS
|
||||||
core->supportsDebuggerType = _GBACoreSupportsDebuggerType;
|
core->supportsDebuggerType = _GBACoreSupportsDebuggerType;
|
||||||
core->debuggerPlatform = _GBACoreDebuggerPlatform;
|
core->debuggerPlatform = _GBACoreDebuggerPlatform;
|
||||||
|
|
|
@ -9,53 +9,9 @@
|
||||||
#include "GameController.h"
|
#include "GameController.h"
|
||||||
|
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
#ifdef M_CORE_GBA
|
|
||||||
#include <mgba/internal/gba/memory.h>
|
|
||||||
#endif
|
|
||||||
#ifdef M_CORE_GB
|
|
||||||
#include <mgba/internal/gb/memory.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace QGBA;
|
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)
|
MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_controller(controller)
|
, m_controller(controller)
|
||||||
|
@ -65,21 +21,8 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
||||||
m_ui.hexfield->setController(controller);
|
m_ui.hexfield->setController(controller);
|
||||||
|
|
||||||
mCore* core = m_controller->thread()->core;
|
mCore* core = m_controller->thread()->core;
|
||||||
const IndexInfo* info = nullptr;
|
const mCoreMemoryBlock* info;
|
||||||
switch (core->platform(core)) {
|
size_t nBlocks = core->listMemoryBlocks(core, &info);
|
||||||
#ifdef M_CORE_GBA
|
|
||||||
case PLATFORM_GBA:
|
|
||||||
info = indexInfoGBA;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef M_CORE_GB
|
|
||||||
case PLATFORM_GB:
|
|
||||||
info = indexInfoGB;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(m_ui.regions, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
connect(m_ui.regions, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
this, &MemoryView::setIndex);
|
this, &MemoryView::setIndex);
|
||||||
|
@ -87,7 +30,10 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
||||||
this, &MemoryView::setSegment);
|
this, &MemoryView::setSegment);
|
||||||
|
|
||||||
if (info) {
|
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));
|
m_ui.regions->addItem(tr(info[i].longName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,44 +62,22 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
||||||
|
|
||||||
void MemoryView::setIndex(int index) {
|
void MemoryView::setIndex(int index) {
|
||||||
mCore* core = m_controller->thread()->core;
|
mCore* core = m_controller->thread()->core;
|
||||||
IndexInfo info;
|
const mCoreMemoryBlock* blocks;
|
||||||
switch (core->platform(core)) {
|
size_t nBlocks = core->listMemoryBlocks(core, &blocks);
|
||||||
#ifdef M_CORE_GBA
|
const mCoreMemoryBlock& info = blocks[index];
|
||||||
case PLATFORM_GBA:
|
|
||||||
info = indexInfoGBA[index];
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef M_CORE_GB
|
|
||||||
case PLATFORM_GB:
|
|
||||||
info = indexInfoGB[index];
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_ui.segments->setValue(-1);
|
m_ui.segments->setValue(-1);
|
||||||
m_ui.segments->setVisible(info.maxSegment > 0);
|
m_ui.segments->setVisible(info.maxSegment > 0);
|
||||||
m_ui.segments->setMaximum(info.maxSegment);
|
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) {
|
void MemoryView::setSegment(int segment) {
|
||||||
mCore* core = m_controller->thread()->core;
|
mCore* core = m_controller->thread()->core;
|
||||||
IndexInfo info;
|
const mCoreMemoryBlock* blocks;
|
||||||
switch (core->platform(core)) {
|
size_t nBlocks = core->listMemoryBlocks(core, &blocks);
|
||||||
#ifdef M_CORE_GBA
|
const mCoreMemoryBlock& info = blocks[m_ui.regions->currentIndex()];
|
||||||
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);
|
m_ui.hexfield->setSegment(info.maxSegment < segment ? info.maxSegment : segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue