From b88f8b1d2c98edcbcb2b294c5c9d71957f156a43 Mon Sep 17 00:00:00 2001 From: RocketRobz Date: Wed, 1 Jan 2025 18:21:33 -0700 Subject: [PATCH] Fix *Luminous Arc 2* crashing on first boot after initializing save data --- retail/bootloader/source/arm7/hook_arm7.c | 4 ++++ retail/bootloaderi/source/arm7/hook_arm7.c | 5 ++++- retail/cardengine/arm7/source/cardengine.c | 19 +++++++++++++++++++ retail/cardenginei/arm7/source/cardengine.c | 9 ++++++++- .../common/include/cardengine_header_arm7.h | 3 ++- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/retail/bootloader/source/arm7/hook_arm7.c b/retail/bootloader/source/arm7/hook_arm7.c index d212f8e08..42303fb54 100644 --- a/retail/bootloader/source/arm7/hook_arm7.c +++ b/retail/bootloader/source/arm7/hook_arm7.c @@ -34,6 +34,7 @@ #include "nocashMessage.h" #define b_a9IrqHooked BIT(7) +#define b_delayWrites BIT(8) #define b_sleepMode BIT(17) extern u32 newArm7binarySize; @@ -224,6 +225,9 @@ int hookNdsRetailArm7( if (patchedCardIrqEnable) { ce7->valueBits |= b_a9IrqHooked; } + if (strncmp(romTid, "YL2", 3) == 0) { // Luminous Arc 2 + ce7->valueBits |= b_delayWrites; // Delay save writes by 1 frame for the first 2 seconds to fix crash on first boot + } if (sleepMode) { ce7->valueBits |= b_sleepMode; } diff --git a/retail/bootloaderi/source/arm7/hook_arm7.c b/retail/bootloaderi/source/arm7/hook_arm7.c index a68701fb2..11d276b7b 100644 --- a/retail/bootloaderi/source/arm7/hook_arm7.c +++ b/retail/bootloaderi/source/arm7/hook_arm7.c @@ -43,7 +43,7 @@ #define b_dsiSD BIT(5) #define b_preciseVolumeControl BIT(6) #define b_powerCodeOnVBlank BIT(7) -#define b_runCardEngineCheck BIT(8) +#define b_delayWrites BIT(8) #define b_igmAccessible BIT(9) #define b_hiyaCfwFound BIT(10) #define b_slowSoftReset BIT(11) @@ -391,6 +391,9 @@ int hookNdsRetailArm7( if (consoleModel < 2 && preciseVolumeControl) { ce7->valueBits |= b_preciseVolumeControl; } + if (strncmp(romTid, "YL2", 3) == 0) { // Luminous Arc 2 + ce7->valueBits |= b_delayWrites; // Delay save writes by 1 frame for the first 2 seconds to fix crash on first boot + } if (hiyaCfwFound) { ce7->valueBits |= b_hiyaCfwFound; } diff --git a/retail/cardengine/arm7/source/cardengine.c b/retail/cardengine/arm7/source/cardengine.c index f0e215784..1ac90981e 100644 --- a/retail/cardengine/arm7/source/cardengine.c +++ b/retail/cardengine/arm7/source/cardengine.c @@ -38,6 +38,7 @@ #include "tonccpy.h" #define a9IrqHooked BIT(7) +#define delayWrites BIT(8) #define RUMBLE_PAK (*(vuint16 *)0x08000000) #define WARIOWARE_PAK (*(vuint16 *)0x080000C4) @@ -128,6 +129,14 @@ static PERSONAL_DATA* personalData = NULL; } }*/ +// Alternative to swiWaitForVBlank() +static inline void waitFrames(int count) { + for (int i = 0; i < count; i++) { + while (REG_VCOUNT != 191); + while (REG_VCOUNT == 191); + } +} + static void waitForArm9(void) { IPC_SendSync(0x4); while (sharedAddr[3] != (vu32)0); @@ -584,6 +593,16 @@ bool eepromPageWrite(u32 dst, const void *src, u32 len) { return false; } +#ifndef MUSIC + if (valueBits & delayWrites) { + if (*(int*)((valueBits & isSdk5Set) ? 0x02FFFC3C : 0x027FFC3C) >= 60*2) { + valueBits &= ~delayWrites; + } else { + waitFrames(1); + } + } +#endif + // Send a command to the ARM9 to write the save const u32 commandSaveWrite = 0x53415657; diff --git a/retail/cardenginei/arm7/source/cardengine.c b/retail/cardenginei/arm7/source/cardengine.c index 65fb52181..0c3917722 100644 --- a/retail/cardenginei/arm7/source/cardengine.c +++ b/retail/cardenginei/arm7/source/cardengine.c @@ -63,7 +63,7 @@ #define b_dsiSD BIT(5) #define preciseVolumeControl BIT(6) #define powerCodeOnVBlank BIT(7) -#define b_runCardEngineCheck BIT(8) +#define delayWrites BIT(8) #define igmAccessible BIT(9) #define hiyaCfwFound BIT(10) #define slowSoftReset BIT(11) @@ -2105,6 +2105,13 @@ bool eepromPageWrite(u32 dst, const void *src, u32 len) { /*if (saveInRam) { tonccpy((char*)0x02440000 + dst, src, len); }*/ + if (valueBits & delayWrites) { + if (*(int*)((valueBits & isSdk5) ? 0x02FFFC3C : 0x027FFC3C) >= 60*2) { + valueBits &= ~delayWrites; + } else { + waitFrames(1); + } + } sdmmc_set_ndma_slot(4); if ((dst % saveSize)+len > saveSize) { u32 len2 = len; diff --git a/retail/common/include/cardengine_header_arm7.h b/retail/common/include/cardengine_header_arm7.h index cd4f10d06..191030af6 100644 --- a/retail/common/include/cardengine_header_arm7.h +++ b/retail/common/include/cardengine_header_arm7.h @@ -90,7 +90,7 @@ typedef struct cardengineArm7 { 5: dsiSD 6: preciseVolumeControl 7: powerCodeOnVBlank - 8: runCardEngineCheck + 8: delayWrites 9: igmAccessible 10: hiyaCfwFound 11: slowSoftReset @@ -140,6 +140,7 @@ typedef struct cardengineArm7B4DS { u32 valueBits; /* 7: a9IrqHooked + 8: delayWrites 17: sleepMode */ s32 mainScreen;