all repos — mgba @ ad492cab49fecd0f6495b8b2d83456d8bba6cca7

mGBA Game Boy Advance Emulator

DS Memory: Add ITCM
Jeffrey Pfau jeffrey@endrift.com
Thu, 02 Jun 2016 23:12:50 -0700
commit

ad492cab49fecd0f6495b8b2d83456d8bba6cca7

parent

60d49b4860162405afdd488ee3dac11fe5e925ab

2 files changed, 63 insertions(+), 3 deletions(-)

jump to
M src/ds/memory.csrc/ds/memory.c

@@ -105,6 +105,8 @@ ds->memory.bios7 = NULL;

ds->memory.bios9 = NULL; ds->memory.wram = NULL; ds->memory.ram = NULL; + ds->memory.itcm = NULL; + ds->memory.dtcm = NULL; ds->memory.rom = NULL; ds->memory.activeRegion7 = -1;

@@ -130,6 +132,8 @@

void DSMemoryDeinit(struct DS* ds) { mappedMemoryFree(ds->memory.wram, DS_SIZE_WORKING_RAM); mappedMemoryFree(ds->memory.ram, DS_SIZE_RAM); + mappedMemoryFree(ds->memory.itcm, DS9_SIZE_ITCM); + mappedMemoryFree(ds->memory.dtcm, DS9_SIZE_DTCM); } void DSMemoryReset(struct DS* ds) {

@@ -143,6 +147,16 @@ mappedMemoryFree(ds->memory.ram, DS_SIZE_RAM);

} ds->memory.ram = anonymousMemoryMap(DS_SIZE_RAM); + if (ds->memory.itcm) { + mappedMemoryFree(ds->memory.itcm, DS9_SIZE_ITCM); + } + ds->memory.itcm = anonymousMemoryMap(DS9_SIZE_ITCM); + + if (ds->memory.dtcm) { + mappedMemoryFree(ds->memory.dtcm, DS9_SIZE_DTCM); + } + ds->memory.dtcm = anonymousMemoryMap(DS9_SIZE_DTCM); + memset(ds->memory.dma7, 0, sizeof(ds->memory.dma7)); memset(ds->memory.dma9, 0, sizeof(ds->memory.dma9)); ds->memory.activeDMA7 = -1;

@@ -150,7 +164,7 @@ ds->memory.activeDMA9 = -1;

ds->memory.nextDMA = INT_MAX; ds->memory.eventDiff = 0; - if (!ds->memory.wram || !ds->memory.ram) { + if (!ds->memory.wram || !ds->memory.ram || !ds->memory.itcm || !ds->memory.dtcm) { DSMemoryDeinit(ds); mLOG(DS_MEM, FATAL, "Could not map memory"); }

@@ -394,13 +408,21 @@ int newRegion = address >> DS_BASE_OFFSET;

memory->activeRegion9 = newRegion; switch (newRegion) { + case DS9_REGION_ITCM: + case DS9_REGION_ITCM_MIRROR: + if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) { + cpu->memory.activeRegion = memory->itcm; + cpu->memory.activeMask = DS9_SIZE_ITCM - 1; + return; + } + goto jump_error; case DS_REGION_RAM: if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) { cpu->memory.activeRegion = memory->ram; cpu->memory.activeMask = DS_SIZE_RAM - 1; return; } - break; + goto jump_error; case DS9_REGION_BIOS: // TODO: Mask properly if (memory->bios9) {

@@ -414,10 +436,11 @@ return;

default: break; } + +jump_error: cpu->memory.activeRegion = _deadbeef; cpu->memory.activeMask = 0; mLOG(DS_MEM, FATAL, "Jumped to invalid address: %08X", address); - return; } uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {

@@ -506,6 +529,14 @@ struct DSMemory* memory = &ds->memory;

int wait = 0; switch (address >> DS_BASE_OFFSET) { + case DS9_REGION_ITCM: + case DS9_REGION_ITCM_MIRROR: + if (address < (512 << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) { + STORE_32(value, address & (DS9_SIZE_ITCM - 1), memory->itcm); + break; + } + mLOG(DS_MEM, STUB, "Bad DS9 Store32: %08X:%08X", address, value); + break; case DS_REGION_RAM: if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) { STORE_32(value, address & (DS_SIZE_RAM - 1), memory->ram);

@@ -530,6 +561,14 @@ struct DSMemory* memory = &ds->memory;

int wait = 0; switch (address >> DS_BASE_OFFSET) { + case DS9_REGION_ITCM: + case DS9_REGION_ITCM_MIRROR: + if (address < (512 << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) { + STORE_16(value, address & (DS9_SIZE_ITCM - 1), memory->itcm); + break; + } + mLOG(DS_MEM, STUB, "Bad DS9 Store16: %08X:%04X", address, value); + break; case DS_REGION_RAM: if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) { STORE_16(value, address & (DS_SIZE_RAM - 1), memory->ram);

@@ -554,6 +593,14 @@ struct DSMemory* memory = &ds->memory;

int wait = 0; switch (address >> DS_BASE_OFFSET) { + case DS9_REGION_ITCM: + case DS9_REGION_ITCM_MIRROR: + if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) { + ((uint8_t*) memory->itcm)[address & (DS9_SIZE_ITCM - 1)] = value; + break; + } + mLOG(DS_MEM, STUB, "Bad DS9 Store8: %08X:%02X", address, value); + break; case DS_REGION_RAM: if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) { ((uint8_t*) memory->ram)[address & (DS_SIZE_RAM - 1)] = value;

@@ -647,6 +694,14 @@ uint32_t addressMisalign = address & 0x3;

address &= 0xFFFFFFFC; switch (address >> DS_BASE_OFFSET) { + case DS9_REGION_ITCM: + case DS9_REGION_ITCM_MIRROR: + STM_LOOP(if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) { + STORE_32(value, address & (DS9_SIZE_ITCM - 1), memory->itcm); + } else { + mLOG(DS_MEM, STUB, "Bad DS9 Store32: %08X:%08X", address, value); + }); + break; case DS_REGION_RAM: STM_LOOP(if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) { STORE_32(value, address & (DS_SIZE_RAM - 1), memory->ram);
M src/ds/memory.hsrc/ds/memory.h

@@ -14,6 +14,7 @@

enum DSMemoryRegion { DS7_REGION_BIOS = 0x0, DS9_REGION_ITCM = 0x0, + DS9_REGION_ITCM_MIRROR = 0x1, DS_REGION_RAM = 0x2, DS_REGION_WORKING_RAM = 0x3, DS_REGION_IO = 0x4,

@@ -41,6 +42,8 @@ DS9_BASE_BIOS = 0xFFFF0000,

}; enum { + DS9_SIZE_ITCM = 0x00008000, + DS9_SIZE_DTCM = 0x00004000, DS7_SIZE_BIOS = 0x00004000, DS9_SIZE_BIOS = 0x00008000, DS_SIZE_RAM = 0x00400000,

@@ -103,6 +106,8 @@

struct DSMemory { uint32_t* bios7; uint32_t* bios9; + uint32_t* itcm; + uint32_t* dtcm; uint32_t* ram; uint32_t* wram; uint32_t* rom;