DS Memory: Add WRAM
@@ -78,6 +78,8 @@ uint32_t* itcm;
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];@@ -145,5 +147,7 @@ uint32_t DS9LoadMultiple(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
int* cycleCounter); uint32_t DS9StoreMultiple(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction, int* cycleCounter); + +void DSConfigureWRAM(struct DSMemory*, uint8_t config); #endif
@@ -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 @@ // VRAM control
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
@@ -172,7 +172,9 @@ ds->ds9.memory.activeDMA = -1;
// 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 @@ DSVideoConfigureVRAM(&ds->memory, 5, 0);
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ case DS_REGION_WORKING_RAM:
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 @@ if (address < memory->itcmSize) {
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 @@ if (address < memory->itcmSize) {
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 @@ 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); + 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) {@@ -868,6 +892,13 @@ case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR: if (address < memory->itcmSize) { STORE_32(value, address & (DS9_SIZE_ITCM - 4), memory->itcm); + break; + } + 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);@@ -925,6 +956,13 @@ break;
} 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);@@ -974,6 +1012,13 @@ case DS9_REGION_ITCM:
case DS9_REGION_ITCM_MIRROR: 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_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);@@ -1038,6 +1083,13 @@ } else {
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 @@ case DS9_REGION_ITCM_MIRROR:
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:@@ -1164,6 +1223,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) {