Skip to content

Commit

Permalink
Expand DLDI space to 32KB
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketRobz committed Nov 11, 2024
1 parent 5926219 commit bf79b1c
Show file tree
Hide file tree
Showing 17 changed files with 310 additions and 169 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "libnds32"]
path = libnds32
url = https://github.com/lifehackerhansol/libnds32
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ arm7/$(TARGET).elf:

#---------------------------------------------------------------------------------
arm9/$(TARGET).elf:
@$(MAKE) -C libnds32 release
@$(MAKE) -C arm9

#---------------------------------------------------------------------------------
Expand All @@ -50,6 +51,7 @@ clean:
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds
@rm -fr $(TARGET).arm7.elf
@rm -fr $(TARGET).arm9.elf
@$(MAKE) -C libnds32 clean
@$(MAKE) -C bootloader clean
@$(MAKE) -C bootstub clean
@$(MAKE) -C arm9 clean
Expand Down
49 changes: 25 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,29 +57,30 @@ GodMode9i uses the same FRF font files as [GodMode9](https://github.com/d0k3/God
When loading GodMode9i will try to load `/gm9i/font.frf` on your SD card and if that fails will load the default font. To change the default font when building GodMode9i, replace `data/font_default.frf` with your font.

## Credits
* [RocketRobz](https://github.com/RocketRobz): Main Developer.
* [Evie/Pk11](https://github.com/Epicpkmn11): Contributor.
* [zacchi4k](https://github.com/zacchi4k): Logo designer.
* [Edo9300](https://github.com/edo9300): Save reading code from his save manager tool.
* [endrift](https://github.com/endrift): GBA ROM dumping code from [duplo](https://github.com/endrift/duplo), used for 64MB ROMs.
* [JimmyZ](https://github.com/JimmyZ): NAND code from twlnf (with writing code stripped for safety reasons).
* [zoogie](https://github.com/zoogie): ConsoleID code (originating from dumpTool).
* [devkitPro](https://github.com/devkitPro): devkitARM, libnds, original nds-hb-menu code, and screenshot code.
* [d0k3](https://github.com/d0k3): Developer of GodMode9 for the Nintendo 3DS, which this is inspired by.
* [門真 なむ (Num Kadoma)](https://littlelimit.net): k6x8 font used for the default font's Kanji and 美咲ゴシック font in resources folder
* Additional Chinese is from [Angelic47/FontChinese7x7](https://github.com/Angelic47/FontChinese7x7)
- [RocketRobz](https://github.com/RocketRobz): Main Developer.
- [Evie/Pk11](https://github.com/Epicpkmn11): Contributor.
- [lifehackerhansol](https://github.com/lifehackerhansol): [libnds32](https://github.com/lifehackerhansol/libnds32) fork for 32KB DLDI driver support
- [zacchi4k](https://github.com/zacchi4k): Logo designer.
- [Edo9300](https://github.com/edo9300): Save reading code from his save manager tool.
- [endrift](https://github.com/endrift): GBA ROM dumping code from [duplo](https://github.com/endrift/duplo), used for 64MB ROMs.
- [JimmyZ](https://github.com/JimmyZ): NAND code from twlnf (with writing code stripped for safety reasons).
- [zoogie](https://github.com/zoogie): ConsoleID code (originating from dumpTool).
- [devkitPro](https://github.com/devkitPro): devkitARM, libnds, original nds-hb-menu code, and screenshot code.
- [d0k3](https://github.com/d0k3): Developer of GodMode9 for the Nintendo 3DS, which this is inspired by.
- [門真 なむ (Num Kadoma)](https://littlelimit.net): k6x8 font used for the default font's Kanji and 美咲ゴシック font in resources folder
- Additional Chinese is from [Angelic47/FontChinese7x7](https://github.com/Angelic47/FontChinese7x7)

### Translators
* Chinese (Simplified): [cai_miao](https://crowdin.com/profile/cai_miao), [James-Makoto](https://crowdin.com/profile/vcmod55)
* Dutch: [Minionguyjpro](https://crowdin.com/profile/minionguyjpro)
* French: [Benjamin](https://crowdin.com/profile/sombrabsol), [Dhalian.](https://crowdin.com/profile/dhalian3630)
* German: [redstonekasi](https://crowdin.com/profile/redstonekasi)
* Hebrew: [Yaniv Levin](https://crowdin.com/profile/y4niv)
* Hungarian: [Viktor Varga](http://github.com/vargaviktor)
* Italian: [Malick](https://crowdin.com/profile/malick1160), [TM-47](https://crowdin.com/profile/-tm-), [zacchi4k](https://crowdin.com/profile/zacchi4k)
* Japanese: [Cloud0835](https://crowdin.com/profile/cloud0835), [Pk11](https://github.com/Epicpkmn11)
* Romanian: [Tescu](https://crowdin.com/profile/tescu48)
* Russian: [Ckau](https://crowdin.com/profile/ckau), [Молодая Кукуруза](https://crowdin.com/profile/bessmertnyi_mikhail)
* Spanish: [Allinxter](https://crowdin.com/profile/allinxter), [beta215](https://crowdin.com/profile/beta215)
* Turkish: [Egehan.TWL](https://crowdin.com/profile/egehan.twl), [Grandmaquil](https://crowdin.com/profile/grandmaquil), [rewold20](https://crowdin.com/profile/rewold20)
* Ukrainian: [GriShafir](https://crowdin.com/profile/grishafir)
- Chinese (Simplified): [cai_miao](https://crowdin.com/profile/cai_miao), [James-Makoto](https://crowdin.com/profile/vcmod55)
- Dutch: [Minionguyjpro](https://crowdin.com/profile/minionguyjpro)
- French: [Benjamin](https://crowdin.com/profile/sombrabsol), [Dhalian.](https://crowdin.com/profile/dhalian3630)
- German: [redstonekasi](https://crowdin.com/profile/redstonekasi)
- Hebrew: [Yaniv Levin](https://crowdin.com/profile/y4niv)
- Hungarian: [Viktor Varga](http://github.com/vargaviktor)
- Italian: [Malick](https://crowdin.com/profile/malick1160), [TM-47](https://crowdin.com/profile/-tm-), [zacchi4k](https://crowdin.com/profile/zacchi4k)
- Japanese: [Cloud0835](https://crowdin.com/profile/cloud0835), [Pk11](https://github.com/Epicpkmn11)
- Romanian: [Tescu](https://crowdin.com/profile/tescu48)
- Russian: [Ckau](https://crowdin.com/profile/ckau), [Молодая Кукуруза](https://crowdin.com/profile/bessmertnyi_mikhail)
- Spanish: [Allinxter](https://crowdin.com/profile/allinxter), [beta215](https://crowdin.com/profile/beta215)
- Turkish: [Egehan.TWL](https://crowdin.com/profile/egehan.twl), [Grandmaquil](https://crowdin.com/profile/grandmaquil), [rewold20](https://crowdin.com/profile/rewold20)
- Ukrainian: [GriShafir](https://crowdin.com/profile/grishafir)
6 changes: 4 additions & 2 deletions arm9/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ LDFLAGS = -specs=../ds_arm9_hi.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS := -lfat -lnds9
LIBS := -lfat -lnds329

#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR) ../ $(LIBNDS)
LIBDIRS32 := $(CURDIR)/../libnds32

#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
Expand Down Expand Up @@ -114,7 +115,8 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)

export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
$(foreach dir,$(LIBDIRS32),-L$(dir)/lib)


export OUTPUT := $(CURDIR)/$(TARGET)
Expand Down
8 changes: 8 additions & 0 deletions arm9/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,14 @@ int main(int argc, char **argv) {
swiWaitForVBlank();
}

if (nitroMounted && (strcmp(io_dldi_data->friendlyName, "NAND FLASH CARD LIBFATNRIO") == 0) && (*(u32*)0x02FF8000 != 0x53535A4C)) {
FILE* file = fopen("nitro:/dldi/nrio.lz77", "rb");
fread((void*)0x02FF8004, 1, 0x3FFC, file);
fclose(file);

*(u32*)0x02FF8000 = 0x53535A4C;
}

// Ensure gm9i folder exists
char folderPath[10];
sprintf(folderPath, "%s:/gm9i", (sdMounted ? "sd" : "fat"));
Expand Down
92 changes: 44 additions & 48 deletions arm9/source/nds_loader_arm9.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@
#include "tonccpy.h"

#ifndef _NO_BOOTSTUB_
struct __my_bootstub {
u64 bootsig;
VoidFn arm9reboot;
VoidFn arm7reboot;
u32 bootaddr;
u32 bootsize;
};

#include "bootstub_bin.h"
#endif

#include "nds_loader_arm9.h"
#define LCDC_BANK_C (u16*)0x06840000
#define LCDC_BANK_C (u16*)0x06848000
#define STORED_FILE_CLUSTER (*(((u32*)LCDC_BANK_C) + 1))
#define INIT_DISC (*(((u32*)LCDC_BANK_C) + 2))
#define WANT_TO_PATCH_DLDI (*(((u32*)LCDC_BANK_C) + 3))
Expand Down Expand Up @@ -120,7 +128,7 @@ static void writeAddr (data_t *mem, addr_t offset, addr_t value) {
((addr_t*)mem)[offset/sizeof(addr_t)] = value;
}

static addr_t quickFind (const data_t* data, const data_t* search, size_t dataLen, size_t searchLen) {
/* static addr_t quickFind (const data_t* data, const data_t* search, size_t dataLen, size_t searchLen) {
const int* dataChunk = (const int*) data;
int searchChunk = ((const int*)search)[0];
addr_t i;
Expand All @@ -138,18 +146,17 @@ static addr_t quickFind (const data_t* data, const data_t* search, size_t dataLe
}
return -1;
}
} */

// Normal DLDI uses "\xED\xA5\x8D\xBF Chishm"
// Bootloader string is different to avoid being patched
static const data_t dldiMagicLoaderString[] = "\xEE\xA5\x8D\xBF Chishm"; // Different to a normal DLDI file
// static const data_t dldiMagicLoaderString[] = "\xEE\xA5\x8D\xBF Chishm"; // Different to a normal DLDI file

#define DEVICE_TYPE_DLDI 0x49444C44

static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)
static bool dldiPatchLoader (void)
{
addr_t memOffset; // Offset of DLDI after the file is loaded into memory
addr_t patchOffset; // Position of patch destination in the file
addr_t relocationOffset; // Value added to all offsets within the patch to fix it properly
addr_t ddmemOffset; // Original offset used in the DLDI file
addr_t ddmemStart; // Start of range that offsets can be in the DLDI file
Expand All @@ -158,39 +165,28 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)

addr_t addrIter;

data_t *pDH;
data_t *pAH;

size_t dldiFileSize = 0;

// Find the DLDI reserved space in the file
patchOffset = quickFind (binData, dldiMagicLoaderString, binSize, sizeof(dldiMagicLoaderString));

if (patchOffset < 0) {
// does not have a DLDI section
return false;
}
data_t *pDH = (data_t*)(io_dldi_data);

pDH = (data_t*)(io_dldi_data);

pAH = &(binData[patchOffset]);
data_t *pAH = (data_t*)0x02FF8000;

if (*((u32*)(pDH + DO_ioType)) == DEVICE_TYPE_DLDI) {
// No DLDI patch
return false;
}

if (pDH[DO_driverSize] > pAH[DO_allocatedSpace]) {
// Not enough space for patch
return false;
if (*(u32*)0x02FF8004 == 0x69684320 || *(u32*)0x02FF8000 == 0x53535A4C) {
return true; // Skip patching for existing or compressed DLDI file
}

dldiFileSize = 1 << pDH[DO_driverSize];

memOffset = readAddr (pAH, DO_text_start);
/* memOffset = readAddr (pAH, DO_text_start);
if (memOffset == 0) {
memOffset = readAddr (pAH, DO_startup) - DO_code;
}
} */
memOffset = 0x06000000;
ddmemOffset = readAddr (pDH, DO_text_start);
relocationOffset = memOffset - ddmemOffset;

Expand All @@ -201,7 +197,7 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)
// Remember how much space is actually reserved
pDH[DO_allocatedSpace] = pAH[DO_allocatedSpace];
// Copy the DLDI patch into the application
tonccpy (pAH, pDH, dldiFileSize);
tonccpy (pAH, pDH, (dldiFileSize > 0x4000) ? 0x4000 : dldiFileSize);

// Fix the section pointers in the header
writeAddr (pAH, DO_text_start, readAddr (pAH, DO_text_start) + relocationOffset);
Expand All @@ -220,7 +216,7 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)
writeAddr (pAH, DO_clearStatus, readAddr (pAH, DO_clearStatus) + relocationOffset);
writeAddr (pAH, DO_shutdown, readAddr (pAH, DO_shutdown) + relocationOffset);

if (pDH[DO_fixSections] & FIX_ALL) {
if (pDH[DO_fixSections] & FIX_ALL) {
// Search through and fix pointers within the data section of the file
for (addrIter = (readAddr(pDH, DO_text_start) - ddmemStart); addrIter < (readAddr(pDH, DO_data_end) - ddmemStart); addrIter++) {
if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) {
Expand All @@ -229,7 +225,7 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)
}
}

if (pDH[DO_fixSections] & FIX_GLUE) {
if (pDH[DO_fixSections] & FIX_GLUE) {
// Search through and fix pointers within the glue section of the file
for (addrIter = (readAddr(pDH, DO_glue_start) - ddmemStart); addrIter < (readAddr(pDH, DO_glue_end) - ddmemStart); addrIter++) {
if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) {
Expand All @@ -238,7 +234,7 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)
}
}

if (pDH[DO_fixSections] & FIX_GOT) {
if (pDH[DO_fixSections] & FIX_GOT) {
// Search through and fix pointers within the Global Offset Table section of the file
for (addrIter = (readAddr(pDH, DO_got_start) - ddmemStart); addrIter < (readAddr(pDH, DO_got_end) - ddmemStart); addrIter++) {
if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) {
Expand All @@ -247,7 +243,7 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS)
}
}

if (clearBSS && (pDH[DO_fixSections] & FIX_BSS)) {
if (/* clearBSS && */ (pDH[DO_fixSections] & FIX_BSS) && dldiFileSize <= 0x4000) {
// Initialise the BSS to 0, only if the disc is being re-inited
toncset (&pAH[readAddr(pDH, DO_bss_start) - ddmemStart] , 0, readAddr(pDH, DO_bss_end) - readAddr(pDH, DO_bss_start));
}
Expand Down Expand Up @@ -321,7 +317,7 @@ int runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool

if(dldiPatchNds) {
// Patch the loader with a DLDI for the card
if (!dldiPatchLoader ((data_t*)LCDC_BANK_C, loaderSize, initDisc)) {
if (!dldiPatchLoader()) {
return 3;
}
}
Expand All @@ -348,7 +344,7 @@ int runNdsFile (const char* filename, int argc, const char** argv) {
int pathLen;
const char* args[1];


if (stat (filename, &st) < 0) {
return 1;
}
Expand All @@ -372,8 +368,10 @@ int runNdsFile (const char* filename, int argc, const char** argv) {
bool havedsiSD = false;

if(argv[0][0]=='s' && argv[0][1]=='d') havedsiSD = true;


#ifndef _NO_BOOTSTUB_
installBootStub(havedsiSD);
#endif

return runNds (load_bin, load_bin_size, st.st_ino, true, true, argc, argv);
}
Expand All @@ -398,34 +396,32 @@ int runNdsFile (const char* filename, int argc, const char** argv) {
.word 0
*/

bool installBootStub(bool havedsiSD) {
#ifndef _NO_BOOTSTUB_
bool installBootStub(const bool havedsiSD) {
extern char *fake_heap_end;
struct __bootstub *bootstub = (struct __bootstub *)fake_heap_end;
struct __my_bootstub *bootstub = (struct __my_bootstub *)fake_heap_end;
u32 *bootloader = (u32*)(fake_heap_end+bootstub_bin_size);

memcpy(bootstub,bootstub_bin,bootstub_bin_size);
memcpy(bootloader,load_bin,load_bin_size);
bool ret = false;
tonccpy(bootstub,bootstub_bin,bootstub_bin_size);
tonccpy(bootloader,load_bin,load_bin_size);

bootloader[8] = isDSiMode();
if( havedsiSD) {
ret = true;
bootloader[3] = 0; // don't dldi patch
if (havedsiSD) {
if (memcmp(io_dldi_data->friendlyName, "Default", 7) != 0) {
dldiPatchLoader ();
} else {
bootloader[3] = 0; // don't dldi patch
}
bootloader[7] = 1; // use internal dsi SD code
} else {
ret = dldiPatchLoader((data_t*)bootloader, load_bin_size,false);
dldiPatchLoader ();
}
bootstub->arm9reboot = (VoidFn)(((u32)bootstub->arm9reboot)+fake_heap_end);
bootstub->arm7reboot = (VoidFn)(((u32)bootstub->arm7reboot)+fake_heap_end);
bootstub->bootaddr += (u32)fake_heap_end;
bootstub->bootsize = load_bin_size;

DC_FlushAll();

return ret;
#else
return true;
#endif

}
#endif

2 changes: 1 addition & 1 deletion arm9/source/nds_loader_arm9.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool

int runNdsFile (const char* filename, int argc, const char** argv);

bool installBootStub(bool havedsiSD);
void installBootStub(const bool havedsiSD);

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion bootloader/load.ld
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ENTRY(_start)

MEMORY {

vram : ORIGIN = 0x06000000, LENGTH = 128K
vram : ORIGIN = 0x06008000, LENGTH = 128K - 32K
}

__vram_start = ORIGIN(vram);
Expand Down
24 changes: 22 additions & 2 deletions bootloader/source/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ void passArgs_ARM7 (void) {

argDst = (u32*)((ARM9_DST + ARM9_LEN + 3) & ~3); // Word aligned

if (dsiMode && (*(u8*)(NDS_HEAD + 0x012) & BIT(1)))
{
if (ARM9_LEN > 0x380000) {
argDst = (u32*)(TEMP_MEM - ((argSize/4)*4));
} else if (dsiMode && (*(u8*)(NDS_HEAD + 0x012) & BIT(1))) {
u32 ARM9i_DST = *((u32*)(TWL_HEAD + 0x1C8));
u32 ARM9i_LEN = *((u32*)(TWL_HEAD + 0x1CC));
if (ARM9i_LEN)
Expand Down Expand Up @@ -334,6 +335,25 @@ int main (void) {
#ifndef NO_SDMMC
sdRead = (dsiSD && dsiMode);
#endif
if (wantToPatchDLDI) {
toncset((u32*)0x06000000, 0, 0x8000);
if (*(u32*)0x02FF4184 == 0x69684320) { // DLDI ' Chi' string in bootstub space + bootloader in DLDI driver space
const u16 dldiFileSize = 1 << *(u8*)0x02FF418D;
tonccpy((u32*)0x06000000, (u32*)0x02FF4180, dldiFileSize);
dldiRelocateBinary();

toncset((u32*)0x02FF4000, 0, 0x8180); // Clear bootstub + DLDI driver
} else if (*(u32*)0x02FF8004 == 0x69684320) { // DLDI ' Chi' string
const u16 dldiFileSize = 1 << *(u8*)0x02FF800D;
tonccpy((u32*)0x06000000, (u32*)0x02FF8000, (dldiFileSize > 0x4000) ? 0x4000 : dldiFileSize);
dldiClearBss();
} else if (*(u32*)0x02FF8000 == 0x53535A4C) { // LZ77 flag
dldiDecompressBinary();
} else {
return -1;
}
}

u32 fileCluster = storedFileCluster;
// Init card
if(!FAT_InitFiles(initDisc))
Expand Down
Loading

0 comments on commit bf79b1c

Please sign in to comment.