DS Memory: Improve TCM handling

This commit is contained in:
Vicki Pfau 2017-01-30 18:33:19 -08:00
parent e36732321d
commit d616cce6f5
3 changed files with 59 additions and 21 deletions

View File

@ -84,6 +84,10 @@ struct DSMemory {
size_t romSize;
size_t wramSize7;
size_t wramSize9;
uint32_t dtcmBase;
uint32_t dtcmSize;
uint32_t itcmSize;
};
struct DSCoreMemory {

View File

@ -526,13 +526,17 @@ static void _writeCache(struct ARMCore* cpu, int crm, int opcode2, uint32_t valu
static void _writeTCMControl(struct ARMCore* cpu, int crm, int opcode2, uint32_t value) {
uint32_t base = ARMTCMControlGetBase(value) << 12;
uint32_t size = 512 << ARMTCMControlGetVirtualSize(value);
struct DS* ds = (struct DS*) cpu->master;
mLOG(DS, DEBUG, "CP15 TCM control write: CRm: %i, Op2: %i, Base: %08X, Size: %08X", crm, opcode2, base, size);
switch (opcode2) {
case 0:
cpu->cp15.r9.d = value;
ds->memory.dtcmBase = base;
ds->memory.dtcmSize = size;
break;
case 1:
cpu->cp15.r9.i = value;
ds->memory.itcmSize = size;
break;
default:
mLOG(DS, GAME_ERROR, "CP15 TCM control bad op2: %i", opcode2);

View File

@ -624,7 +624,7 @@ static void DS9SetActiveRegion(struct ARMCore* cpu, uint32_t address) {
switch (newRegion) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < ds->memory.itcmSize) {
cpu->memory.activeRegion = ds->memory.itcm;
cpu->memory.activeMask = DS9_SIZE_ITCM - 1;
break;
@ -670,14 +670,14 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < memory->itcmSize) {
LOAD_32(value, address & (DS9_SIZE_ITCM - 1), memory->itcm);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load32: %08X:%08X", address, value);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
@ -696,6 +696,10 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
LOAD_32(value, address & (DS9_SIZE_BIOS - 1), memory->bios9);
break;
default:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
mLOG(DS_MEM, STUB, "Unimplemented DS9 Load32: %08X", address);
break;
}
@ -718,14 +722,14 @@ uint32_t DS9Load16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < memory->itcmSize) {
LOAD_16(value, address & (DS9_SIZE_ITCM - 1), memory->itcm);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load16: %08X:%08X", address, value);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_16(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
@ -743,6 +747,10 @@ uint32_t DS9Load16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
LOAD_16(value, address & (DS9_SIZE_BIOS - 1), memory->bios9);
break;
default:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_16(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
mLOG(DS_MEM, STUB, "Unimplemented DS9 Load16: %08X", address);
break;
}
@ -765,14 +773,14 @@ uint32_t DS9Load8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < memory->itcmSize) {
value = ((uint8_t*) memory->itcm)[address & (DS9_SIZE_ITCM - 1)];
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load8: %08X:%08X", address, value);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
value = ((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM- 1)];
break;
}
@ -787,6 +795,10 @@ uint32_t DS9Load8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
value = ((uint8_t*) memory->bios9)[address & (DS9_SIZE_BIOS - 1)];
break;
default:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
value = ((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM - 1)];
break;
}
mLOG(DS_MEM, STUB, "Unimplemented DS9 Load8: %08X", address);
break;
}
@ -806,14 +818,14 @@ void DS9Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < memory->itcmSize) {
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 & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
@ -827,6 +839,10 @@ void DS9Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
DS9IOWrite32(ds, address & 0x00FFFFFF, value);
break;
default:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
mLOG(DS_MEM, STUB, "Unimplemented DS9 Store32: %08X:%08X", address, value);
break;
}
@ -845,14 +861,14 @@ void DS9Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < memory->itcmSize) {
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 & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_16(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
@ -866,6 +882,10 @@ void DS9Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
DS9IOWrite(ds, address & 0x00FFFFFF, value);
break;
default:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_16(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
break;
}
mLOG(DS_MEM, STUB, "Unimplemented DS9 Store16: %08X:%04X", address, value);
break;
}
@ -884,14 +904,14 @@ void DS9Store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
if (address < memory->itcmSize) {
((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 & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM - 1)] = value;
break;
}
@ -904,6 +924,10 @@ void DS9Store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
DS9IOWrite8(ds, address & 0x00FFFFFF, value);
break;
default:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM - 1)] = value;
break;
}
mLOG(DS_MEM, STUB, "Unimplemented DS9 Store8: %08X:%02X", address, value);
break;
}
@ -939,7 +963,7 @@ uint32_t DS9LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
switch (address >> DS_BASE_OFFSET) {
case DS_REGION_RAM:
LDM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
LDM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
} else if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
LOAD_32(value, address & (DS_SIZE_RAM - 1), memory->ram);
@ -948,8 +972,11 @@ uint32_t DS9LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
});
break;
default:
LDM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
} else {
mLOG(DS_MEM, STUB, "Unimplemented DS9 LDM: %08X", address);
LDM_LOOP(value = 0);
});
break;
}
@ -996,14 +1023,14 @@ uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
switch (address >> DS_BASE_OFFSET) {
case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR:
STM_LOOP(if (address < (512U << ARMTCMControlGetVirtualSize(cpu->cp15.r9.i))) {
STM_LOOP(if (address < memory->itcmSize) {
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 & ~(DS9_SIZE_DTCM - 1)) == DS9_BASE_DTCM) {
STM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
} else if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
STORE_32(value, address & (DS_SIZE_RAM - 1), memory->ram);
@ -1012,8 +1039,11 @@ uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
});
break;
default:
STM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
} else {
mLOG(DS_MEM, STUB, "Unimplemented DS9 STM: %08X", address);
STM_LOOP();
});
break;
}