Skip to content

Commit

Permalink
Expand pre-loadable ROM space to include 32KB of spared WRAM space
Browse files Browse the repository at this point in the history
This is thanks to how the DSi WRAM is mapped, which causes the first 32KB of ARM7 code to be loaded to DSi WRAM instead of the shared WRAM, making the shared WRAM usable by ARM9

Total space increase is by 64KB, as DSi WRAM is no longer used for storing the DLDI driver
  • Loading branch information
RocketRobz committed Dec 16, 2024
1 parent 2d59ecf commit 15ef236
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 35 deletions.
25 changes: 18 additions & 7 deletions retail/bootloaderi/source/arm7/hook_arm9.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define b_slowSoftReset BIT(10)
#define b_dsiBios BIT(11)
#define b_asyncCardRead BIT(12)
#define b_useSharedRam BIT(13)
#define b_cloneboot BIT(14)
#define b_isDlp BIT(15)
#define b_bypassExceptionHandler BIT(16)
Expand Down Expand Up @@ -203,6 +204,7 @@ int hookNdsRetailArm9(
) {
nocashMessage("hookNdsRetailArm9");

extern bool sharedWramEnabled;
extern bool scfgBios9i(void);
extern u32 iUncompressedSize;
extern u32 overlaysSize;
Expand Down Expand Up @@ -247,6 +249,9 @@ int hookNdsRetailArm9(
if (asyncCardRead) {
ce9->valueBits |= b_asyncCardRead;
}
if (sharedWramEnabled) {
ce9->valueBits |= b_useSharedRam;
}
if (usesCloneboot) {
ce9->valueBits |= b_cloneboot;
}
Expand All @@ -258,7 +263,7 @@ int hookNdsRetailArm9(
}
if (!ROMinRAM && dsiWramAccess && !dsiWramMirrored && (ndsHeader->unitCode == 0 || !dsiModeConfirmed) && ndsHeader->fatSize != 0) {
const u32 fntFatSize = (ndsHeader->fatOffset-ndsHeader->filenameOffset)+ndsHeader->fatSize;
if (fntFatSize <= 0x78000) {
if (fntFatSize <= 0x80000) {
ce9->fntSrc = ndsHeader->filenameOffset;
ce9->fntFatSize = fntFatSize;
ce9->valueBits |= b_fntFatCached;
Expand All @@ -272,6 +277,7 @@ int hookNdsRetailArm9(

if (!ROMinRAM) {
//extern bool gbaRomFound;
extern u8 gameOnFlashcard;
bool runOverlayCheck = overlayPatch;
u32 dataToPreloadSizeAligned = 0;
ce9->cacheBlockSize = cacheBlockSize;
Expand All @@ -286,7 +292,6 @@ int hookNdsRetailArm9(
const bool cheatsEnabled = (cheatSizeTotal > 4 && cheatSizeTotal <= 0x8000);
const bool specialTitle = (strncmp(romTid, "V2G", 3) == 0 || strncmp(romTid, "DD3", 3) == 0);
const bool pkmnTitle = (strncmp(romTid, "IRB", 3) == 0 || strncmp(romTid, "IRA", 3) == 0 || strncmp(romTid, "IRE", 3) == 0 || strncmp(romTid, "IRD", 3) == 0);
extern u8 gameOnFlashcard;

ce9->cacheAddress = (consoleModel > 0 ? dev_CACHE_ADRESS_START_TWLSDK : (cheatsEnabled ? retail_CACHE_ADRESS_START_TWLSDK_CHEAT : retail_CACHE_ADRESS_START_TWLSDK));
if (consoleModel == 0 && !gameOnFlashcard) {
Expand All @@ -306,23 +311,29 @@ int hookNdsRetailArm9(
}
}
} else {
u32 size = 0;
if (strncmp(romTid, "UBR", 3) == 0) {
runOverlayCheck = false;
ce9->cacheAddress = CACHE_ADRESS_START;
ce9->romLocation = ce9->cacheAddress;
ce9->cacheSlots = retail_CACHE_ADRESS_SIZE_BROWSER/cacheBlockSize;
size = retail_CACHE_ADRESS_SIZE_BROWSER;
} else {
ce9->cacheAddress = (dsiMode ? CACHE_ADRESS_START_DSIMODE : CACHE_ADRESS_START);
if (!dsiMode && (ce9->valueBits & b_dsiBios) && !laterSdk) {
ce9->cacheAddress -= cacheBlockSize;
}
ce9->romLocation = ce9->cacheAddress;
if (dsiMode) {
ce9->cacheSlots = (consoleModel > 0 ? dev_CACHE_ADRESS_SIZE_DSIMODE : retail_CACHE_ADRESS_SIZE_DSIMODE)/cacheBlockSize;
size = (consoleModel > 0 ? dev_CACHE_ADRESS_SIZE_DSIMODE : retail_CACHE_ADRESS_SIZE_DSIMODE);
} else {
ce9->cacheSlots = (consoleModel > 0 ? dev_CACHE_ADRESS_SIZE : retail_CACHE_ADRESS_SIZE)/cacheBlockSize;
size = (consoleModel > 0 ? dev_CACHE_ADRESS_SIZE : retail_CACHE_ADRESS_SIZE);
}
}
extern u8 _io_dldi_size;
if (gameOnFlashcard && _io_dldi_size >= 0xF) {
ce9->cacheAddress += 0x8000;
size -= 0x8000;
}
ce9->romLocation = ce9->cacheAddress;
ce9->cacheSlots = size/cacheBlockSize;
}
if (dataToPreloadFound(ndsHeader)) {
//ce9->romLocation[1] = ce9->romLocation[0]+dataToPreloadSize[0];
Expand Down
11 changes: 7 additions & 4 deletions retail/bootloaderi/source/arm7/ips.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#include "locations.h"
#include "tonccpy.h"

extern u8 gameOnFlashcard;
extern u8 consoleModel;
extern u8 _io_dldi_size;
extern bool dsiModeConfirmed;
extern bool extendedMemoryConfirmed;
extern bool sharedWramEnabled;
extern bool overlaysInRam;

extern bool scfgBios9i(void);
Expand All @@ -25,6 +27,7 @@ bool applyIpsPatch(const tNDSHeader* ndsHeader, u8* ipsbyte, const bool arm9Only
bool armPatched = false;
const bool dsiBios = scfgBios9i();
const u32 romLocation = getRomLocation(ndsHeader, isESdk2, isSdk5, dsiBios);
const u32 wramLocation = sharedWramEnabled ? 0x036F8000 : 0x03700000;

int ipson = 5;
int totalrepeats = 0;
Expand Down Expand Up @@ -76,7 +79,7 @@ bool applyIpsPatch(const tNDSHeader* ndsHeader, u8* ipsbyte, const bool arm9Only
rombyte += 0x40000;
}
if ((u32)rombyte == (consoleModel > 0 ? 0x0E000000 : 0x0D000000)) {
rombyte = (void*)0x03708000;
rombyte = (void*)wramLocation;
}
} else {
rombyte = (void*)CACHE_ADRESS_START_DSIMODE;
Expand Down Expand Up @@ -118,7 +121,7 @@ bool applyIpsPatch(const tNDSHeader* ndsHeader, u8* ipsbyte, const bool arm9Only
rombyteOffset += 0x40000;
}
if ((u32)rombyteOffset == (consoleModel > 0 ? 0x0E000000 : 0x0D000000)) {
rombyteOffset = (u8*)0x03708000;
rombyteOffset = (u8*)wramLocation;
}
}
}
Expand Down Expand Up @@ -152,7 +155,7 @@ bool applyIpsPatch(const tNDSHeader* ndsHeader, u8* ipsbyte, const bool arm9Only
rombyteOffset += 0x40000;
}
if ((u32)rombyteOffset == (consoleModel > 0 ? 0x0E000000 : 0x0D000000)) {
rombyteOffset = (u8*)0x03708000;
rombyteOffset = (u8*)wramLocation;
}
}
}
Expand Down
60 changes: 39 additions & 21 deletions retail/bootloaderi/source/arm7/main.arm7.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ u32 baseChipID = 0;
u32 romPaddingSize = 0;
bool pkmnHeader = false;
bool ndmaDisabled = false;
bool sharedWramEnabled = false;

u32 newArm7binarySize = 0;
u32 newArm7ibinarySize = 0;
Expand Down Expand Up @@ -797,14 +798,14 @@ u32 getRomPartLocation(const tNDSHeader* ndsHeader, const bool isESdk2, const bo
if (ndsHeader->unitCode > 0 && dsiModeConfirmed) {
return ROM_LOCATION_TWLSDK;
}
return dsiModeConfirmed ? ROM_LOCATION_DSIMODE : (ROM_LOCATION - ((isESdk2 && dsiBios) ? cacheBlockSize : 0));
return (dsiModeConfirmed ? ROM_LOCATION_DSIMODE : (ROM_LOCATION - ((isESdk2 && dsiBios) ? cacheBlockSize : 0))) + ((gameOnFlashcard && _io_dldi_size >= 0xF) ? 0x8000 : 0);
}

u32 getRomLocation(const tNDSHeader* ndsHeader, const bool isESdk2, const bool isSdk5, const bool dsiBios) {
if (ndsHeader->unitCode > 0 && dsiModeConfirmed) {
return ROM_LOCATION_TWLSDK;
}
return (dsiModeConfirmed || strncmp(getRomTid(ndsHeader), "B6X", 3) == 0) ? ROM_LOCATION_DSIMODE : (ROM_LOCATION - ((isESdk2 && dsiBios) ? 0x4000 : 0));
return ((dsiModeConfirmed || strncmp(getRomTid(ndsHeader), "B6X", 3) == 0) ? ROM_LOCATION_DSIMODE : (ROM_LOCATION - ((isESdk2 && dsiBios) ? 0x4000 : 0))) + ((gameOnFlashcard && _io_dldi_size >= 0xF) ? 0x8000 : 0);
}

static bool isROMLoadableInRAM(const tDSiHeader* dsiHeader, const tNDSHeader* ndsHeader, const char* romTid, const module_params_t* moduleParams, const bool usesCloneboot) {
Expand All @@ -825,6 +826,21 @@ static bool isROMLoadableInRAM(const tDSiHeader* dsiHeader, const tNDSHeader* nd
const bool twlType = (ROMsupportsDsiMode(ndsHeader) && dsiModeConfirmed);
const bool cheatsEnabled = (cheatSizeTotal > 4 && cheatSizeTotal <= 0x8000);
const bool _8MBarea = (dsiModeConfirmed || strncmp(romTid, "B6X", 3) == 0);
u32 wramSize = 0x80000;
if (ce7Location == CARDENGINEI_ARM7_LOCATION) {
wramSize += 0x8000; // Shared 32KB of WRAM is available for ARM9 to use
sharedWramEnabled = true;
}
u32 romSizeLimit = (_8MBarea ? 0x00800000 : 0x00BC0000);
if (consoleModel > 0) {
romSizeLimit += 0x01000000;
}
if (dsiWramAccess && !dsiWramMirrored) {
romSizeLimit += wramSize;
}
if (gameOnFlashcard && _io_dldi_size >= 0xF) {
romSizeLimit -= 0x8000;
}

u32 romOffset = 0;
u32 romSize = baseRomSize;
Expand All @@ -843,12 +859,12 @@ static bool isROMLoadableInRAM(const tDSiHeader* dsiHeader, const tNDSHeader* nd
romSize -= romOffset;
}
res = ((consoleModel> 0 && twlType && ((u32)dsiHeader->arm9iromOffset - romOffset)+ioverlaysSize <= (cheatsEnabled ? dev_CACHE_ADRESS_SIZE_TWLSDK_CHEAT : dev_CACHE_ADRESS_SIZE_TWLSDK))
|| (consoleModel> 0 && !twlType && romSize <= (_8MBarea ? 0x01800000 : 0x01BC0000)+(dsiWramAccess&&!dsiWramMirrored ? 0x78000 : 0))
|| (consoleModel==0 && !twlType && romSize <= (_8MBarea ? 0x00800000 : 0x00BC0000)+(dsiWramAccess&&!dsiWramMirrored ? 0x78000 : 0)));

|| (!twlType && romSize <= romSizeLimit));
}
if (res) {
dbg_printf("ROM is loadable into RAM\n");
} else {
sharedWramEnabled = false;
}
return res;
}
Expand Down Expand Up @@ -1151,7 +1167,7 @@ static void buildRomMap(const tNDSHeader* ndsHeader, const module_params_t* modu
readRom = true;
}
if (romLocationChangePrep == (consoleModel > 0 ? 0x0E000000 : 0x0D000000)) {
romLocationChangePrep = 0x03708000;
romLocationChangePrep = sharedWramEnabled ? 0x036F8000 : 0x03700000;
}

if (readRom) {
Expand All @@ -1171,14 +1187,14 @@ static void loadNitroFileInfoIntoRAM(const tNDSHeader* ndsHeader, aFile* romFile
if (ndsHeader->fatSize == 0) return;

const u32 size = (ndsHeader->fatOffset-ndsHeader->filenameOffset)+ndsHeader->fatSize;
if (size > 0x78000) return;
if (size > 0x80000) return;

sdmmc_set_ndma_slot(0);
fileRead((char*)0x03708000, romFile, ndsHeader->filenameOffset, size);
fileRead((char*)0x03700000, romFile, ndsHeader->filenameOffset, size);
sdmmc_set_ndma_slot(4);

dbg_printf("Nitro file info pre-loaded into RAM at ");
dbg_hexa(0x03708000);
dbg_hexa(0x03700000);
dbg_printf("\n");
dbg_printf("\n");
}
Expand Down Expand Up @@ -2081,17 +2097,6 @@ int arm7_main(void) {
NTR_BIOS();
}

u32 clonebootFlag = 0;
const u32 clonebootOffset = ((romSize-0x88) <= baseRomSize) ? (romSize-0x88) : baseRomSize;
fileRead((char*)&clonebootFlag, romFile, clonebootOffset, sizeof(u32));
const bool usesCloneboot = (clonebootFlag == 0x16361);
if (usesCloneboot) {
dbg_printf("Cloneboot detected\n");
}

// If possible, set to load ROM into RAM
const u32 ROMinRAM = isROMLoadableInRAM(&dsiHeaderTemp, &dsiHeaderTemp.ndshdr, romTid, moduleParams, usesCloneboot);

// dbg_printf("Trying to patch the card...\n");

const u16 ce9size = 0x8000;
Expand Down Expand Up @@ -2158,7 +2163,9 @@ int arm7_main(void) {
tonccpy((u32*)ce9Location, ce9Src, ce9size);
}
if (gameOnFlashcard) {
if (!dldiPatchBinary((data_t*)ce9Location, ce9size, (data_t*)((ROMsupportsDsiMode(ndsHeader) && dsiModeConfirmed && _io_dldi_size < 0xF) ? ce9Location+0x3800 : CARDENGINEI_ARM9_LOCATION_DSI_WRAM))) {
const bool _8MBarea = (dsiModeConfirmed || strncmp(romTid, "B6X", 3) == 0);
const u32 ce9DldiOffset = _8MBarea ? CARDENGINEI_ARM9_LOCATION_DLDI_DRIVER_DSI : (CARDENGINEI_ARM9_LOCATION_DLDI_DRIVER - ((!laterSdk && scfgBios9i()) ? 0x4000 : 0));
if (!dldiPatchBinary((data_t*)ce9Location, ce9size, (data_t*)((ROMsupportsDsiMode(ndsHeader) && dsiModeConfirmed && _io_dldi_size < 0xF) ? ce9Location+0x3800 : (_io_dldi_size >= 0xF) ? ce9DldiOffset : ce9Location+0x4000))) {
dbg_printf("ce9 DLDI patch failed\n");
errorOutput();
}
Expand All @@ -2168,6 +2175,17 @@ int arm7_main(void) {
toncset((u32*)CARDENGINEI_ARM9_BUFFERED_LOCATION, 0, 0x10000);
toncset((u32*)CARDENGINEI_ARM7_BUFFERED_LOCATION, 0, 0x13400);

u32 clonebootFlag = 0;
const u32 clonebootOffset = ((romSize-0x88) <= baseRomSize) ? (romSize-0x88) : baseRomSize;
fileRead((char*)&clonebootFlag, romFile, clonebootOffset, sizeof(u32));
const bool usesCloneboot = (clonebootFlag == 0x16361);
if (usesCloneboot) {
dbg_printf("Cloneboot detected\n");
}

// If possible, set to load ROM into RAM
const u32 ROMinRAM = isROMLoadableInRAM(&dsiHeaderTemp, &dsiHeaderTemp.ndshdr, romTid, moduleParams, usesCloneboot);

errorCode = patchCardNds(
(cardengineArm7*)ce7Location,
(cardengineArm9*)ce9Location,
Expand Down
5 changes: 5 additions & 0 deletions retail/cardenginei/arm9/source/cardDma.thumb.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <nds/ndstypes.h>
#include <nds/arm9/exceptions.h>
#include <nds/arm9/cache.h>
#include <nds/arm9/video.h>
#include <nds/bios.h>
#include <nds/system.h>
#include <nds/dma.h>
Expand All @@ -45,6 +46,7 @@
#define cacheFlushFlag BIT(7)
#define cardReadFix BIT(8)
#define cacheDisabled BIT(9)
#define useSharedWram BIT(13)
#define waitForPreloadToFinish BIT(18)

//#ifdef DLDI
Expand Down Expand Up @@ -429,6 +431,9 @@ void cardSetDma(u32 * params) {
break;
}
}
if (ce9->valueBits & useSharedWram) {
WRAM_CR = 0; // Set shared WRAM to ARM9
}
while (len > 0) {
newSrc = (ce9->romMap[i][1]-ce9->romMap[i][0])+src;
newLen = len;
Expand Down
14 changes: 12 additions & 2 deletions retail/cardenginei/arm9/source/cardengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <nds/ndstypes.h>
#include <nds/arm9/exceptions.h>
#include <nds/arm9/cache.h>
#include <nds/arm9/video.h>
#include <nds/bios.h>
#include <nds/system.h>
#include <nds/dma.h>
Expand Down Expand Up @@ -50,7 +51,7 @@
#define slowSoftReset BIT(10)
#define dsiBios BIT(11)
#define asyncCardRead BIT(12)
#define softResetMb BIT(13)
#define useSharedWram BIT(13)
#define cloneboot BIT(14)
#define fntFatCached BIT(17)
#define waitForPreloadToFinish BIT(18)
Expand Down Expand Up @@ -640,6 +641,9 @@ static inline void cardReadRAM(u8* dst, u32 src, u32 len/*, int romPartNo*/) {
toncset(dst, 0, len); // Fill dst with 0 if ROM area is not within the map
return;
}
if (ce9->valueBits & useSharedWram) {
WRAM_CR = 0; // Set shared WRAM to ARM9
}
while (len > 0) {
newSrc = (ce9->romMap[i][1]-ce9->romMap[i][0])+src;
newLen = len;
Expand Down Expand Up @@ -856,7 +860,7 @@ void cardRead(u32* cacheStruct, u8* dst0, u32 src0, u32 len0) {
cardReadRAM(dst, src, len/*, romPartNo*/);
#ifndef TWLSDK
} else if ((ce9->valueBits & fntFatCached) && src >= ce9->fntSrc && src < ce9->fntSrc+ce9->fntFatSize) {
tonccpy(dst, (u8*)((0x03708000-ce9->fntSrc)+src), len);
tonccpy(dst, (u8*)((0x03700000-ce9->fntSrc)+src), len);
#endif
} else {
cardReadNormal(dst, src, len);
Expand Down Expand Up @@ -1348,6 +1352,12 @@ void inGameMenu(s32* exRegisters) {
while (REG_VCOUNT == 191) swiDelay(100);
}

#ifndef TWLSDK
if (ce9->valueBits & useSharedWram) {
WRAM_CR = 0; // Set shared WRAM to ARM9
}
#endif

*(u32*)(INGAME_MENU_LOCATION + IGM_TEXT_SIZE_ALIGNED) = (u32)sharedAddr;
#ifndef TWLSDK
*(u32*)((u32)INGAME_MENU_LOCATION + IGM_TEXT_SIZE_ALIGNED + 4) = 0x027FEFF4;
Expand Down
1 change: 1 addition & 0 deletions retail/common/include/cardengine_header_arm9.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ typedef struct cardengineArm9 {
10: slowSoftReset
11: dsiBios
12: asyncCardRead
13: useSharedWram
14: cloneboot
15: isDlp
16: bypassExceptionHandler
Expand Down
3 changes: 2 additions & 1 deletion retail/common/include/locations.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
#define CARDENGINEI_ARM9_LOCATION 0x027D8000
#define CARDENGINEI_ARM9_LOCATION2 0x027E0000
#define CARDENGINEI_ARM9_LOCATION_DLP 0x02800000
#define CARDENGINEI_ARM9_LOCATION_DSI_WRAM 0x03700000
#define CARDENGINEI_ARM9_LOCATION_DLDI_DRIVER 0x02400000
#define CARDENGINEI_ARM9_LOCATION_DLDI_DRIVER_DSI 0x02800000
#define CARDENGINEI_ARM9_TWLSDK_LOCATION 0x02FD8800 // Used for DSi-Enhanced games in DSi mode
#define CARDENGINEI_ARM9_TWLSDK_LOCATION3 0x02F80000 // Used for DSi-Exclusive games
#define CARDENGINEI_ARM9_DSIWARE_LOCATION CARDENGINEI_ARM9_TWLSDK_LOCATION
Expand Down

0 comments on commit 15ef236

Please sign in to comment.