DS Memory: Add WRAM

This commit is contained in:
Vicki Pfau 2017-02-20 17:51:33 -08:00
parent 7b13335caf
commit 2c3a1c6f71
3 changed files with 115 additions and 19 deletions

View File

@ -78,6 +78,8 @@ struct DSMemory {
uint32_t* dtcm;
uint32_t* ram;
uint32_t* wram;
uint32_t* wramBase7;
uint32_t* wramBase9;
uint32_t* wram7;
uint32_t* rom;
uint16_t io7[DS7_REG_MAX >> 1];
@ -146,4 +148,6 @@ uint32_t DS9LoadMultiple(struct ARMCore*, uint32_t baseAddress, int mask, enum L
uint32_t DS9StoreMultiple(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
int* cycleCounter);
void DSConfigureWRAM(struct DSMemory*, uint8_t config);
#endif

View File

@ -324,6 +324,7 @@ void DS9IOInit(struct DS* ds) {
memset(ds->memory.io9, 0, sizeof(ds->memory.io9));
ds->memory.io9[DS_REG_IPCFIFOCNT >> 1] = 0x0101;
ds->memory.io9[DS_REG_POSTFLG >> 1] = 0x0001;
ds->memory.io9[DS9_REG_VRAMCNT_G >> 1] = 0x0300;
}
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
@ -332,16 +333,19 @@ void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
case DS9_REG_VRAMCNT_A:
case DS9_REG_VRAMCNT_C:
case DS9_REG_VRAMCNT_E:
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A + 1, value & 0xFF);
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A, value >> 8);
value &= 0x9F9F;
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A, value & 0xFF);
DSVideoConfigureVRAM(&ds->memory, address - DS9_REG_VRAMCNT_A + 1, value >> 8);
break;
case DS9_REG_VRAMCNT_G:
DSVideoConfigureVRAM(&ds->memory, 6, value >> 8);
mLOG(DS_IO, STUB, "Stub DS9 I/O register write: %06X:%04X", address + 1, value);
value &= 0x9F03;
DSVideoConfigureVRAM(&ds->memory, 6, value & 0xFF);
DSConfigureWRAM(&ds->memory, value >> 8);
break;
case DS9_REG_VRAMCNT_H:
DSVideoConfigureVRAM(&ds->memory, 7, value >> 8);
DSVideoConfigureVRAM(&ds->memory, 8, value & 0xFF);
value &= 0x9F9F;
DSVideoConfigureVRAM(&ds->memory, 7, value & 0xFF);
DSVideoConfigureVRAM(&ds->memory, 8, value >> 8);
break;
// Math

View File

@ -172,7 +172,9 @@ void DSMemoryReset(struct DS* ds) {
// TODO: Correct size
ds->memory.wramSize7 = 0x8000;
ds->memory.wramBase7 = ds->memory.wram;
ds->memory.wramSize9 = 0;
ds->memory.wramBase9 = NULL;
DSVideoConfigureVRAM(&ds->memory, 0, 0);
DSVideoConfigureVRAM(&ds->memory, 1, 0);
@ -183,6 +185,7 @@ void DSMemoryReset(struct DS* ds) {
DSVideoConfigureVRAM(&ds->memory, 6, 0);
DSVideoConfigureVRAM(&ds->memory, 7, 0);
DSVideoConfigureVRAM(&ds->memory, 8, 0);
DSConfigureWRAM(&ds->memory, 3);
if (!ds->memory.wram || !ds->memory.wram7 || !ds->memory.ram || !ds->memory.itcm || !ds->memory.dtcm) {
DSMemoryDeinit(ds);
@ -250,7 +253,7 @@ uint32_t DS7Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
LOAD_32(value, address & (DS7_SIZE_WORKING_RAM - 4), memory->wram7);
} else {
LOAD_32(value, address & (ds->memory.wramSize7 - 4), memory->wram);
LOAD_32(value, address & (ds->memory.wramSize7 - 4), memory->wramBase7);
}
break;
case DS_REGION_RAM:
@ -291,7 +294,7 @@ uint32_t DS7Load16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
LOAD_16(value, address & (DS7_SIZE_WORKING_RAM - 2), memory->wram7);
} else {
LOAD_16(value, address & (ds->memory.wramSize7 - 2), memory->wram);
LOAD_16(value, address & (ds->memory.wramSize7 - 2), memory->wramBase7);
}
break;
case DS_REGION_RAM:
@ -328,7 +331,7 @@ uint32_t DS7Load8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
value = ((uint8_t*) memory->wram7)[address & (DS7_SIZE_WORKING_RAM - 1)];
} else {
value = ((uint8_t*) memory->wram)[address & (ds->memory.wramSize7 - 1)];
value = ((uint8_t*) memory->wramBase7)[address & (ds->memory.wramSize7 - 1)];
}
break;
case DS_REGION_RAM:
@ -359,7 +362,7 @@ void DS7Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
STORE_32(value, address & (DS7_SIZE_WORKING_RAM - 4), memory->wram7);
} else {
STORE_32(value, address & (ds->memory.wramSize7 - 4), memory->wram);
STORE_32(value, address & (ds->memory.wramSize7 - 4), memory->wramBase7);
}
break;
case DS_REGION_RAM:
@ -393,7 +396,7 @@ void DS7Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
STORE_16(value, address & (DS7_SIZE_WORKING_RAM - 2), memory->wram7);
} else {
STORE_16(value, address & (ds->memory.wramSize7 - 2), memory->wram);
STORE_16(value, address & (ds->memory.wramSize7 - 2), memory->wramBase7);
}
break;
case DS_REGION_RAM:
@ -427,7 +430,7 @@ void DS7Store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
((uint8_t*) memory->wram7)[address & (DS7_SIZE_WORKING_RAM - 1)] = value;
} else {
((uint8_t*) memory->wram)[address & (ds->memory.wramSize7 - 1)] = value;
((uint8_t*) memory->wramBase7)[address & (ds->memory.wramSize7 - 1)] = value;
}
break;
case DS_REGION_RAM:
@ -544,7 +547,7 @@ uint32_t DS7LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
LDM_LOOP(if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
LOAD_32(value, address & (DS7_SIZE_WORKING_RAM - 1), memory->wram7);
} else {
LOAD_32(value, address & (ds->memory.wramSize7 - 1), memory->wram);
LOAD_32(value, address & (ds->memory.wramSize7 - 1), memory->wramBase7);
});
break;
case DS_REGION_RAM:
@ -607,7 +610,7 @@ uint32_t DS7StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
STM_LOOP(if (address >= DS7_BASE_WORKING_RAM || !ds->memory.wramSize7) {
STORE_32(value, address & (DS7_SIZE_WORKING_RAM - 1), memory->wram7);
} else {
STORE_32(value, address & (ds->memory.wramSize7 - 1), memory->wram);
STORE_32(value, address & (ds->memory.wramSize7 - 1), memory->wramBase7);
});
break;
case DS_REGION_RAM:
@ -698,7 +701,14 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
LOAD_32(value, address & (DS9_SIZE_ITCM - 4), memory->itcm);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load32: %08X:%08X", address, value);
mLOG(DS_MEM, STUB, "Bad DS9 Load32: %08X", address);
break;
case DS_REGION_WORKING_RAM:
if (ds->memory.wramSize9) {
LOAD_32(value, address & (ds->memory.wramSize9 - 4), memory->wramBase9);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load32: %08X", address);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
@ -762,7 +772,14 @@ uint32_t DS9Load16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
LOAD_16(value, address & (DS9_SIZE_ITCM - 2), memory->itcm);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load16: %08X:%08X", address, value);
mLOG(DS_MEM, STUB, "Bad DS9 Load16: %08X", address);
break;
case DS_REGION_WORKING_RAM:
if (ds->memory.wramSize9) {
LOAD_16(value, address & (ds->memory.wramSize9 - 2), memory->wramBase9);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load16: %08X", address);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
@ -825,11 +842,18 @@ uint32_t DS9Load8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
value = ((uint8_t*) memory->itcm)[address & (DS9_SIZE_ITCM - 1)];
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load8: %08X:%08X", address, value);
mLOG(DS_MEM, STUB, "Bad DS9 Load8: %08X", address);
break;
case DS_REGION_WORKING_RAM:
if (ds->memory.wramSize9) {
value = ((uint8_t*) memory->wramBase9)[address & (memory->wramSize9 - 1)];
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Load8: %08X", address);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
value = ((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM- 1)];
value = ((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM - 1)];
break;
}
if ((address & (DS_SIZE_RAM - 1)) < DS_SIZE_RAM) {
@ -872,6 +896,13 @@ void DS9Store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycle
}
mLOG(DS_MEM, STUB, "Bad DS9 Store32: %08X:%08X", address, value);
break;
case DS_REGION_WORKING_RAM:
if (ds->memory.wramSize9) {
STORE_32(value, address & (ds->memory.wramSize9 - 4), memory->wramBase9);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Store32: %08X:%08X", address, value);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_32(value, address & (DS9_SIZE_DTCM - 4), memory->dtcm);
@ -925,6 +956,13 @@ void DS9Store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
}
mLOG(DS_MEM, STUB, "Bad DS9 Store16: %08X:%04X", address, value);
break;
case DS_REGION_WORKING_RAM:
if (ds->memory.wramSize9) {
STORE_16(value, address & (ds->memory.wramSize9 - 2), memory->wramBase9);
break;
}
mLOG(DS_MEM, STUB, "Bad DS9 Store16: %08X:%04X", address, value);
break;
case DS_REGION_RAM:
if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
STORE_16(value, address & (DS9_SIZE_DTCM - 2), memory->dtcm);
@ -978,6 +1016,13 @@ void DS9Store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
}
mLOG(DS_MEM, STUB, "Bad DS9 Store8: %08X:%02X", address, value);
break;
case DS_REGION_WORKING_RAM:
if (ds->memory.wramSize9) {
((uint8_t*) memory->wramBase9)[address & (ds->memory.wramSize9 - 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)) == memory->dtcmBase) {
((uint8_t*) memory->dtcm)[address & (DS9_SIZE_DTCM - 1)] = value;
@ -1038,6 +1083,13 @@ uint32_t DS9LoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
mLOG(DS_MEM, STUB, "Bad DS9 LDM: %08X:%08X", address, value);
});
break;
case DS_REGION_WORKING_RAM:
LDM_LOOP(if (ds->memory.wramSize9) {
LOAD_32(value, address & (ds->memory.wramSize9 - 4), memory->wramBase9);
} else {
mLOG(DS_MEM, STUB, "Bad DS9 STM: %08X", address);
});
break;
case DS_REGION_RAM:
LDM_LOOP(if ((address & ~(DS9_SIZE_DTCM - 1)) == memory->dtcmBase) {
LOAD_32(value, address & (DS9_SIZE_DTCM - 1), memory->dtcm);
@ -1117,7 +1169,14 @@ uint32_t DS9StoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum
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);
mLOG(DS_MEM, STUB, "Bad DS9 STM: %08X:%08X", address, value);
});
break;
case DS_REGION_WORKING_RAM:
STM_LOOP(if (ds->memory.wramSize9) {
STORE_32(value, address & (ds->memory.wramSize9 - 4), memory->wramBase9);
} else {
mLOG(DS_MEM, STUB, "Bad DS9 STM: %08X", address);
});
break;
case DS_REGION_RAM:
@ -1166,6 +1225,35 @@ int32_t DSMemoryStall(struct ARMCore* cpu, int32_t wait) {
return wait;
}
void DSConfigureWRAM(struct DSMemory* memory, uint8_t config) {
switch (config & 3) {
case 0:
memory->wramSize7 = 0;
memory->wramBase7 = NULL;
memory->wramSize9 = DS_SIZE_WORKING_RAM;
memory->wramBase9 = memory->wram;
break;
case 1:
memory->wramSize7 = DS_SIZE_WORKING_RAM >> 1;
memory->wramBase7 = memory->wram;
memory->wramSize9 = DS_SIZE_WORKING_RAM >> 1;
memory->wramBase9 = &memory->wram[DS_SIZE_WORKING_RAM >> 3];
break;
case 2:
memory->wramSize7 = DS_SIZE_WORKING_RAM >> 1;
memory->wramBase7 = &memory->wram[DS_SIZE_WORKING_RAM >> 3];
memory->wramSize9 = DS_SIZE_WORKING_RAM >> 1;
memory->wramBase9 = memory->wram;
break;
case 3:
memory->wramSize7 = DS_SIZE_WORKING_RAM;
memory->wramBase7 = memory->wram;
memory->wramSize9 = 0;
memory->wramBase9 = NULL;
break;
}
}
static unsigned _selectVRAM(struct DSMemory* memory, uint32_t offset) {
unsigned mask = 0;
offset &= 0x3FF;