1818#include < fat.h>
1919#include < easysave/ini.hpp>
2020#include " myDSiMode.h"
21+ #include " blz.h"
2122#include " lzss.h"
2223#include " lzx.h"
2324#include " text.h"
@@ -107,6 +108,30 @@ off_t getFileSize(FILE* fp) {
107108 return fsize;
108109}
109110
111+ void s2RamAccess (bool open) {
112+ if (io_dldi_data->ioInterface .features & FEATURE_SLOT_NDS) return ;
113+
114+ const u16 s2FlashcardId = *(u16 *)0x020000C0 ;
115+
116+ if (open) {
117+ if (s2FlashcardId == 0x334D ) {
118+ _M3_changeMode (M3_MODE_RAM);
119+ } else if (s2FlashcardId == 0x3647 ) {
120+ _G6_SelectOperation (G6_MODE_RAM);
121+ } else if (s2FlashcardId == 0x4353 ) {
122+ _SC_changeMode (SC_MODE_RAM);
123+ }
124+ } else {
125+ if (s2FlashcardId == 0x334D ) {
126+ _M3_changeMode (M3_MODE_MEDIA);
127+ } else if (s2FlashcardId == 0x3647 ) {
128+ _G6_SelectOperation (G6_MODE_MEDIA);
129+ } else if (s2FlashcardId == 0x4353 ) {
130+ _SC_changeMode (SC_MODE_MEDIA);
131+ }
132+ }
133+ }
134+
110135char sdmcText[4 ] = {' s' ,' d' ,' m' ,' c' };
111136
112137void addTwlDevice (const char letter, u8 flags, u8 accessRights, const char * name, const char * path) {
@@ -713,6 +738,8 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
713738 return -1 ;
714739 }
715740
741+ bool expansionPakFound = false ;
742+
716743 if (*(u16 *)0x02FFFC30 == 0 ) {
717744 sysSetCartOwner (BUS_OWNER_ARM9); // Allow arm9 to access GBA ROM
718745 if (*(u16 *)(0x020000C0 ) != 0x334D && *(u16 *)(0x020000C0 ) != 0x3647 && *(u16 *)(0x020000C0 ) != 0x4353 && *(u16 *)(0x020000C0 ) != 0x5A45 ) {
@@ -747,6 +774,7 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
747774 if (*(vu16*)(0x08000000 ) != 0x4D54 ) {
748775 *(u16 *)(0x020000C0 ) = 0 ;
749776 }
777+ sysSetCartOwner (BUS_OWNER_ARM7);
750778 } else if (io_dldi_data->ioInterface .features & FEATURE_SLOT_GBA) {
751779 if (memcmp (io_dldi_data->friendlyName , " M3 Adapter" , 10 ) == 0 ) {
752780 *(u16 *)(0x020000C0 ) = 0x334D ;
@@ -762,6 +790,15 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
762790 }
763791 }
764792 }
793+ expansionPakFound = (*(u16 *)(0x020000C0 ) != 0 );
794+ if (!expansionPakFound) {
795+ sysSetCartOwner (BUS_OWNER_ARM9);
796+
797+ *(vu16*)0x08240000 = 1 ;
798+ expansionPakFound = (*(vu16*)0x08240000 == 1 );
799+
800+ sysSetCartOwner (BUS_OWNER_ARM7);
801+ }
765802 } else if (!conf->forceSleepPatch ) {
766803 conf->forceSleepPatch = (
767804 (memcmp (io_dldi_data->friendlyName , " Ace3DS+" , 7 ) == 0 )
@@ -2133,7 +2170,7 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
21332170
21342171 if (accessControl & BIT (4 )) {
21352172 romFSInited = (romFSInit (conf->ndsPath ));
2136- startMultibootSrl = (strncmp (romTid, " KCX" , 3 ) == 0 || (!b4dsDebugRam && strncmp (romTid, " KAV " , 3 ) == 0 ) || strncmp (romTid, " KNK" , 3 ) == 0 );
2173+ startMultibootSrl = (strncmp (romTid, " KCX" , 3 ) == 0 || strncmp (romTid, " KNK" , 3 ) == 0 );
21372174 }
21382175
21392176 const char * donorNdsPath = " " ;
@@ -2550,6 +2587,105 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
25502587 }
25512588 fclose (sdatFile);
25522589 }
2590+ } else if (!b4dsDebugRam && expansionPakFound && (strncmp (romTid, " KAV" , 3 ) == 0 )) {
2591+ // Load overlay 1 for DIGIDRIVE + Sound data from multiboot SRL
2592+ sysSetCartOwner (BUS_OWNER_ARM9); // Allow arm9 to access GBA ROM
2593+
2594+ const u32 mepAddr = (*(u16 *)0x020000C0 == 0x5A45 ) ? 0x08000000 : 0x09000000 ;
2595+
2596+ u32 overlayOffset = 0x021BC7A0 ;
2597+ u32 sdatOffsetMB = 0x11D040 ;
2598+ u32 sdatSizeMB = 0x87540 ;
2599+ u32 sdatSize = 0x44C2C0 ;
2600+ switch (romTid[3 ]) {
2601+ case ' V' :
2602+ sdatSize = 0x44CD80 ;
2603+ break ;
2604+ case ' J' :
2605+ overlayOffset = 0x021BBB20 ;
2606+ sdatOffsetMB = 0x11CCC0 ;
2607+ sdatSizeMB = 0x7C2C0 ;
2608+ sdatSize = 0x44F880 ;
2609+ break ;
2610+ }
2611+ u32 ndsArm9Size = 0 ;
2612+ u32 overlayStart = 0 ;
2613+ u32 overlayEnd = 0 ;
2614+
2615+ // Load ARM9 binary from multiboot SRL
2616+ FILE* ndsFile = fopen (multibootSrl, " rb" );
2617+
2618+ fseek (ndsFile, 0x20 , SEEK_SET);
2619+ fread (&ndsArm9BinOffset, sizeof (u32 ), 1 , ndsFile);
2620+ fseek (ndsFile, 0x2C , SEEK_SET);
2621+ fread (&ndsArm9Size, sizeof (u32 ), 1 , ndsFile);
2622+
2623+ fseek (ndsFile, ndsArm9BinOffset, SEEK_SET);
2624+ if (io_dldi_data->ioInterface .features & FEATURE_SLOT_GBA) {
2625+ u32 pos = 0 ;
2626+ u32 currentLen = ndsArm9Size;
2627+ while (currentLen > 0 ) {
2628+ const u16 readLen = currentLen > sizeof_lz77ImageBuffer ? sizeof_lz77ImageBuffer : currentLen;
2629+ s2RamAccess (false );
2630+ fread (lz77ImageBuffer, 1 , readLen, ndsFile);
2631+ s2RamAccess (true );
2632+ tonccpy ((u8 *)mepAddr+pos, lz77ImageBuffer, readLen);
2633+ pos += readLen;
2634+ currentLen -= readLen;
2635+ }
2636+ s2RamAccess (false );
2637+ } else {
2638+ fread ((void *)mepAddr, 1 , ndsArm9Size, ndsFile);
2639+ }
2640+
2641+ fclose (ndsFile);
2642+
2643+ s2RamAccess (true );
2644+ decompressLZ77Backwards ((u8 *)mepAddr+0x4000 , ndsArm9Size-0x4000 );
2645+ tonccpy ((u8 *)overlayOffset+0x18E0 , (u8 *)mepAddr+sdatOffsetMB, sdatSizeMB); // Grab sound data from ARM9 binary
2646+ s2RamAccess (false );
2647+
2648+ // Load overlay
2649+ ndsFile = fopen (conf->ndsPath , " rb" );
2650+
2651+ fseek (ndsFile, 0x48 , SEEK_SET);
2652+ fread (&fatAddr, sizeof (u32 ), 1 , ndsFile);
2653+ fseek (ndsFile, fatAddr+8 , SEEK_SET);
2654+ fread (&overlayStart, sizeof (u32 ), 1 , ndsFile);
2655+ fread (&overlayEnd, sizeof (u32 ), 1 , ndsFile);
2656+ const u32 overlaySize = overlayEnd - overlayStart;
2657+
2658+ fseek (ndsFile, overlayStart, SEEK_SET);
2659+ if (io_dldi_data->ioInterface .features & FEATURE_SLOT_GBA) {
2660+ u32 pos = 0 ;
2661+ u32 currentLen = overlaySize;
2662+ while (currentLen > 0 ) {
2663+ const u16 readLen = currentLen > sizeof_lz77ImageBuffer ? sizeof_lz77ImageBuffer : currentLen;
2664+ s2RamAccess (false );
2665+ fread (lz77ImageBuffer, 1 , readLen, ndsFile);
2666+ s2RamAccess (true );
2667+ tonccpy ((u8 *)mepAddr+pos, lz77ImageBuffer, readLen);
2668+ pos += readLen;
2669+ currentLen -= readLen;
2670+ }
2671+ s2RamAccess (false );
2672+ } else {
2673+ fread ((void *)mepAddr, 1 , overlaySize, ndsFile);
2674+ }
2675+
2676+ fclose (ndsFile);
2677+
2678+ s2RamAccess (true );
2679+ const u32 len = decompressLZ77Backwards ((u8 *)mepAddr, overlaySize);
2680+ tonccpy ((u8 *)overlayOffset, (u8 *)mepAddr, 0x18E0 ); // Load the overlay, but skip it's sound data
2681+ tonccpy ((u8 *)overlayOffset+0x18E0 +sdatSize, (u8 *)mepAddr+0x18E0 +sdatSize, len-(0x18E0 +sdatSize)); // Overwrites a sample used in music (which will be disabled anyway)
2682+ s2RamAccess (false );
2683+
2684+ if (io_dldi_data->ioInterface .features & FEATURE_SLOT_NDS) {
2685+ sysSetCartOwner (BUS_OWNER_ARM7);
2686+ }
2687+
2688+ *(u32 *)((romTid[3 ] == ' J' ) ? 0x021BBFD4 : 0x021BCC54 ) = 0xE8BD80F8 ; // ldmfd sp!, {r3-r7,pc} (Disable music)
25532689 } else if (!b4dsDebugRam && (strncmp (romTid, " KEG" , 3 ) == 0 )) {
25542690 // Convert stereo title intro music to mono in Electroplankton: Lumiloop
25552691 const u32 sdatSize = getFileSize (" rom:/sound_data_hw.sdat" );
0 commit comments