Skip to content

Commit

Permalink
B4DS: Only patch card read DMA for specific games
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketRobz committed Feb 24, 2025
1 parent 9526b4f commit ed0c18e
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 135 deletions.
142 changes: 78 additions & 64 deletions retail/bootloader/source/arm7/patch_arm9.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,17 +500,24 @@ static void patchCardReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, c
static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) {
const char* romTid = getRomTid(ndsHeader);

if (strncmp(romTid, "AWD", 3) == 0 // Diddy Kong Racing
|| strncmp(romTid, "CP3", 3) == 0 // Viva Pinata
/* if (strncmp(romTid, "AWD", 3) == 0 // Diddy Kong Racing
|| strncmp(romTid, "CP3", 3) == 0 // Viva Pinata
|| strncmp(romTid, "BO5", 3) == 0 // Golden Sun: Dark Dawn
|| strncmp(romTid, "Y8L", 3) == 0 // Golden Sun: Dark Dawn (Demo Version)
|| strncmp(romTid, "B8I", 3) == 0 // Spider-Man: Edge of Time
|| strncmp(romTid, "TAM", 3) == 0 // The Amazing Spider-Man
|| (strncmp(romTid, "V2G", 3) == 0 /* && !dsiModeConfirmed */) // Mario vs. Donkey Kong: Mini-Land Mayhem (DS mode)
|| !cardReadDMA) return false;

u32* offset = patchOffsetCache.cardEndReadDmaOffset;
u32 offsetDmaHandler = patchOffsetCache.dmaHandlerOffset;
|| strncmp(romTid, "V2G", 3) == 0 // Mario vs. Donkey Kong: Mini-Land Mayhem
|| !cardReadDMA) return false; */

if (strncmp(romTid, "CAY", 3) != 0 // Army Men: Soldiers of Misfortune
&& strncmp(romTid, "B5B", 3) != 0 // Call of Duty: Modern Warfare 3: Defiance
&& strncmp(romTid, "B7F", 3) != 0 // The Magic School Bus: Oceans
&& strncmp(romTid, "AH9", 3) != 0 // Tony Hawk's American Sk8land
&& strncmp(romTid, "YUT", 3) != 0 // Ultimate Mortal Kombat
) return false;

u32* offset = patchOffsetCache.cardEndReadDmaOffset;
u32 offsetDmaHandler = patchOffsetCache.dmaHandlerOffset;
if (!patchOffsetCache.cardEndReadDmaChecked) {
if (!patchOffsetCache.cardReadDmaEndOffset) {
u32* cardReadDmaEndOffset = findCardReadDmaEndOffset(ndsHeader, moduleParams);
Expand All @@ -528,49 +535,49 @@ static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader
}
patchOffsetCache.cardEndReadDmaChecked = true;
}
if(offset) {
dbg_printf("\nDMA CARD READ METHOD ACTIVE\n");
dbg_printf("cardEndReadDma location : ");
dbg_hexa((u32)offset);
dbg_printf("\n\n");
if(!isSdk5(moduleParams)) {
// SDK1-4
if(usesThumb) {
u16* thumbOffset = (u16*)offset;
u16* thumbOffsetStartFunc = (u16*)offset;
if(offset) {
dbg_printf("\nDMA CARD READ METHOD ACTIVE\n");
dbg_printf("cardEndReadDma location : ");
dbg_hexa((u32)offset);
dbg_printf("\n\n");
if(!isSdk5(moduleParams)) {
// SDK1-4
if(usesThumb) {
u16* thumbOffset = (u16*)offset;
u16* thumbOffsetStartFunc = (u16*)offset;
bool lrOnly = false;
for (int i = 0; i <= 18; i++) {
thumbOffsetStartFunc--;
for (int i = 0; i <= 18; i++) {
thumbOffsetStartFunc--;
if (*thumbOffsetStartFunc==0xB5F0) {
//dbg_printf("\nthumbOffsetStartFunc : ");
//dbg_hexa(*thumbOffsetStartFunc);
lrOnly = true;
break;
}
}
thumbOffset--;
}
thumbOffset--;
if (lrOnly) {
thumbOffset--;
thumbOffset[0] = *thumbOffsetStartFunc; // push {r4-r7, lr}
thumbOffset[1] = 0xB081; // SUB SP, SP, #4
} else {
*thumbOffset = 0xB5F8; // push {r3-r7, lr}
}
ce9->thumbPatches->cardEndReadDmaRef = (u32*)thumbOffset;
} else {
u32* armOffset = (u32*)offset;
u32* armOffsetStartFunc = (u32*)offset;
ce9->thumbPatches->cardEndReadDmaRef = (u32*)thumbOffset;
} else {
u32* armOffset = (u32*)offset;
u32* armOffsetStartFunc = (u32*)offset;
bool lrOnly = false;
for (int i = 0; i <= 16; i++) {
armOffsetStartFunc--;
for (int i = 0; i <= 16; i++) {
armOffsetStartFunc--;
if (*armOffsetStartFunc==0xE92D4000 || *armOffsetStartFunc==0xE92D4030 || *armOffsetStartFunc==0xE92D40F0) {
//dbg_printf("\narmOffsetStartFunc : ");
//dbg_hexa(*armOffsetStartFunc);
lrOnly = true;
break;
}
}
armOffset--;
}
armOffset--;
if (lrOnly) {
armOffset--;
armOffset[0] = *armOffsetStartFunc; // "STMFD SP!, {LR}", "STMFD SP!, {R4,R5,LR}", or "STMFD SP!, {R4-R7,LR}"
Expand All @@ -581,60 +588,67 @@ static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader
} else {
*armOffset = 0xE92D40F8; // STMFD SP!, {R3-R7,LR}
}
ce9->patches->cardEndReadDmaRef = offsetDmaHandler==0 ? armOffset : (u32*)offsetDmaHandler;
}
} else {
// SDK5
if(usesThumb) {
u16* thumbOffset = (u16*)offset;
while(*thumbOffset!=0xB508) { // push {r3, lr}
thumbOffset--;
}
ce9->thumbPatches->cardEndReadDmaRef = (u32*)thumbOffset;
thumbOffset[1] = 0x46C0; // NOP
thumbOffset[2] = 0x46C0; // NOP
thumbOffset[3] = 0x46C0; // NOP
thumbOffset[4] = 0x46C0; // NOP
} else {
u32* armOffset = (u32*)offset;
armOffset--;
ce9->patches->cardEndReadDmaRef = offsetDmaHandler==0 ? armOffset : (u32*)offsetDmaHandler;
}
} else {
// SDK5
if(usesThumb) {
u16* thumbOffset = (u16*)offset;
while(*thumbOffset!=0xB508) { // push {r3, lr}
thumbOffset--;
}
ce9->thumbPatches->cardEndReadDmaRef = (u32*)thumbOffset;
thumbOffset[1] = 0x46C0; // NOP
thumbOffset[2] = 0x46C0; // NOP
thumbOffset[3] = 0x46C0; // NOP
thumbOffset[4] = 0x46C0; // NOP
} else {
u32* armOffset = (u32*)offset;
armOffset--;
*armOffset = 0xE92D4008; // STMFD SP!, {R3,LR}
ce9->patches->cardEndReadDmaRef = armOffset;
}
ce9->patches->cardEndReadDmaRef = armOffset;
}
}
return true;
}
}
return false;
}

static bool patchCardSetDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) {
const char* romTid = getRomTid(ndsHeader);

if (strncmp(romTid, "AWD", 3) == 0 // Diddy Kong Racing
|| strncmp(romTid, "CP3", 3) == 0 // Viva Pinata
/* if (strncmp(romTid, "AWD", 3) == 0 // Diddy Kong Racing
|| strncmp(romTid, "CP3", 3) == 0 // Viva Pinata
|| strncmp(romTid, "BO5", 3) == 0 // Golden Sun: Dark Dawn
|| strncmp(romTid, "Y8L", 3) == 0 // Golden Sun: Dark Dawn (Demo Version)
|| strncmp(romTid, "B8I", 3) == 0 // Spider-Man: Edge of Time
|| strncmp(romTid, "TAM", 3) == 0 // The Amazing Spider-Man
|| (strncmp(romTid, "V2G", 3) == 0 /* && !dsiModeConfirmed */) // Mario vs. Donkey Kong: Mini-Land Mayhem (DS mode)
|| !cardReadDMA) return false;
|| strncmp(romTid, "V2G", 3) == 0 // Mario vs. Donkey Kong: Mini-Land Mayhem
|| !cardReadDMA) return false; */

if (strncmp(romTid, "CAY", 3) != 0 // Army Men: Soldiers of Misfortune
&& strncmp(romTid, "B5B", 3) != 0 // Call of Duty: Modern Warfare 3: Defiance
&& strncmp(romTid, "B7F", 3) != 0 // The Magic School Bus: Oceans
&& strncmp(romTid, "AH9", 3) != 0 // Tony Hawk's American Sk8land
&& strncmp(romTid, "YUT", 3) != 0 // Ultimate Mortal Kombat
) return false;

dbg_printf("\npatchCardSetDma\n");

u32* setDmaoffset = patchOffsetCache.cardSetDmaOffset;
if (!patchOffsetCache.cardSetDmaChecked) {
u32* setDmaoffset = patchOffsetCache.cardSetDmaOffset;
if (!patchOffsetCache.cardSetDmaChecked) {
setDmaoffset = findCardSetDma(ndsHeader,moduleParams,usesThumb);
if (setDmaoffset) {
patchOffsetCache.cardSetDmaOffset = setDmaoffset;
}
patchOffsetCache.cardSetDmaChecked = true;
}
if(setDmaoffset) {
dbg_printf("\nDMA CARD SET METHOD ACTIVE\n");
dbg_printf("cardSetDma location : ");
dbg_hexa((u32)setDmaoffset);
dbg_printf("\n\n");
const u32 newCardSetDma = (u32)ce9->patches->card_set_dma_arm9;
}
if(setDmaoffset) {
dbg_printf("\nDMA CARD SET METHOD ACTIVE\n");
dbg_printf("cardSetDma location : ");
dbg_hexa((u32)setDmaoffset);
dbg_printf("\n\n");
const u32 newCardSetDma = (u32)ce9->patches->card_set_dma_arm9;
if (usesThumb) {
u16* offsetThumb = (u16*)setDmaoffset;
offsetThumb[0] = 0xB540; // push {r6, lr}
Expand All @@ -647,8 +661,8 @@ static bool patchCardSetDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, co
setDmaoffset[1] = newCardSetDma;
}

return true;
}
return true;
}

return false;
}
Expand Down
Loading

0 comments on commit ed0c18e

Please sign in to comment.