Skip to content

Commit

Permalink
Expand RAM drive to use all 768KB of DSi WRAM + 32KB of shared WRAM
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketRobz committed Dec 30, 2024
1 parent 0bfc8fa commit 08433e7
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 52 deletions.
2 changes: 1 addition & 1 deletion arm7/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ CFLAGS := -g -Wall -O2\
CFLAGS += $(INCLUDE) -DARM7

ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,--nmagic -Wl,-Map,$(notdir $*).map
LDFLAGS = -specs=../ds_arm7.specs -g $(ARCH) -Wl,--nmagic -Wl,-Map,$(notdir $*).map


#---------------------------------------------------------------------------------
Expand Down
134 changes: 95 additions & 39 deletions arm7/ds_arm7_ram.ld → arm7/ds_arm7.ld
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
/*--------------------------------------------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/.
--------------------------------------------------------------------------------*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)


PHDRS {
crt0 PT_LOAD FLAGS(7);
arm7 PT_LOAD FLAGS(7);
arm7i PT_LOAD FLAGS(0x100007);
}


MEMORY {
rom : ORIGIN = 0x08000000, LENGTH = 32M
ram : ORIGIN = 0x2380000, LENGTH = 128K
iwram : ORIGIN = 0x037f8000, LENGTH = 96K
ewram : ORIGIN = 0x02380000, LENGTH = 12M - 512K
rom : ORIGIN = 0x08000000, LENGTH = 32M
iwram : ORIGIN = 0x03800000, LENGTH = 56K

twl_ewram : ORIGIN = 0x02e80000, LENGTH = 512K - 64K
twl_iwram : ORIGIN = 0x0380e000, LENGTH = 8K
}

__iwram_start = ORIGIN(iwram);
Expand All @@ -21,30 +37,59 @@ __irq_vector = 0x04000000 - 4;

SECTIONS
{
.init :

.twl :
{
__text_start = . ;
KEEP (*(.init))
__arm7i_lma__ = LOADADDR(.twl);
__arm7i_start__ = .;
*(.twl)
*.twl*(.text .stub .text.* .gnu.linkonce.t.*)
*.twl*(.rodata)
*.twl*(.roda)
*.twl*(.rodata.*)
*.twl*(.data)
*.twl*(.data.*)
*.twl*(.gnu.linkonce.d*)
. = ALIGN(4);
__arm7i_end__ = .;
} >twl_iwram AT>twl_ewram :arm7i

.twl_bss ALIGN(4) (NOLOAD) :
{
__twl_bss_start__ = .;
*(.twl_bss)
*.twl.*(.dynbss)
*.twl.*(.gnu.linkonce.b*)
*.twl.*(.bss*)
*.twl.*(COMMON)
. = ALIGN(4);
__twl_bss_end__ = .;
} >twl_iwram :NONE

.crt0 :
{
KEEP (*(.crt0))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
.plt : { *(.plt) } >ram = 0xff
} >ewram :crt0

.text : /* ALIGN (4): */
.text :
{
__arm7_lma__ = LOADADDR(.text);
__arm7_start__ = .;
KEEP (*(SORT_NONE(.init)))
*(.plt)
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
} >iwram AT>ewram :arm7

.fini :
{
KEEP (*(.fini))
} >ram =0xff

__text_end = . ;
} >iwram AT>ewram

.rodata :
{
Expand All @@ -55,27 +100,38 @@ SECTIONS
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
} >iwram AT>ewram

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >iwram AT>ewram

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ram
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ram
__exidx_end = .;
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} >iwram AT>ewram

/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { KEEP (*(.preinit_array)) } >ram = 0xff
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { KEEP (*(.init_array)) } >ram = 0xff
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { KEEP (*(.fini_array)) } >ram = 0xff
PROVIDE (__fini_array_end = .);
.preinit_array : {
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} >iwram AT>ewram

.init_array : {
PROVIDE (__init_array_start = .);
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
} >iwram AT>ewram

.fini_array : {
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
PROVIDE (__fini_array_end = .);
} >iwram AT>ewram

.ctors :
{
Expand All @@ -90,7 +146,7 @@ SECTIONS
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
} >iwram AT>ewram

.dtors :
{
Expand All @@ -99,21 +155,21 @@ SECTIONS
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
} >iwram AT>ewram

.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
} >iwram AT>ewram

.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
.jcr : { KEEP (*(.jcr)) } >ram = 0
.got : { *(.got.plt) *(.got) } >ram = 0
} >iwram AT>ewram
.jcr : { KEEP (*(.jcr)) } >iwram AT>ewram
.got : { *(.got.plt) *(.got) } >iwram AT>ewram

.data ALIGN(4) : {
__data_start = ABSOLUTE(.);
Expand All @@ -123,10 +179,11 @@ SECTIONS
CONSTRUCTORS
. = ALIGN(4);
__data_end = ABSOLUTE(.) ;
} >ram = 0xff
} >iwram AT>ewram

.bss ALIGN(4) :
.bss ALIGN(4) (NOLOAD) :
{
__arm7_end__ = .;
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
Expand All @@ -136,7 +193,7 @@ SECTIONS
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
__bss_end__ = ABSOLUTE(.);
__end__ = ABSOLUTE(.);
} >ram
} >iwram

/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
Expand Down Expand Up @@ -171,6 +228,5 @@ SECTIONS
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.stack 0x80000 : { _stack = .; *(.stack) }
/* These must appear regardless of . */
}
}
7 changes: 7 additions & 0 deletions arm7/ds_arm7.specs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
%include <sync-none.specs>

*link:
+ -T ../ds_arm7.ld%s --gc-sections --no-warn-rwx-segments

*startfile:
ds_arm7_crt0%O%s crti%O%s crtbegin%O%s
2 changes: 2 additions & 0 deletions arm7/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ int main() {
*(vu32*)0x400481C = 0; // Clear SD IRQ stat register
*(vu32*)0x4004820 = 0; // Clear SD IRQ mask register

REG_MBK9 = 0; // Allow full DSi WRAM access to ARM9

// clear sound registers
dmaFillWords(0, (void*)0x04000400, 0x100);

Expand Down
28 changes: 26 additions & 2 deletions arm9/source/driveOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,33 @@ void flashcardUnmount(void) {
}

void ramdriveMount(bool ram32MB) {
if(isDSiMode() || REG_SCFG_EXT != 0) {
ramdSectors = ram32MB ? 0xE000 : 0x6000;
if (isDSiMode() || REG_SCFG_EXT != 0) {
ramdSectors = ram32MB ? 0xE000 : 0x6000; // Main Memory
ramdSectors += 0x40; // Shared WRAM

WRAM_CR = 3;

// DSi WRAM
*(vu32*)0x03700000 = 0x49394D47;
if (*(vu32*)0x03700000 == 0x49394D47) {
if (*(vu32*)0x03700000 == 0x49394D47 && *(vu32*)0x03708000 == 0x49394D47) {
ramdSectors += 0x40;
} else {
ramdSectors += 0x400;

REG_MBK6=0x080037C0;
*((vu32*)REG_MBK1) = 0x8C888480;

*(vu32*)0x037C0000 = 0x49394D47;
if (*(vu32*)0x037C0000 == 0x49394D47) {
ramdSectors += 0x200;
}
}
}

WRAM_CR = 0;

ramd_setSize(ram32MB);
fatMountSimple("ram", &io_ram_drive);
} else if (isRegularDS) {
ramdSectors = 0x8 + 0x4000;
Expand Down
4 changes: 2 additions & 2 deletions arm9/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ int main(int argc, char **argv) {
scanKeys();
yHeld = (keysHeld() & KEY_Y);
*(vu32*)(0x0DFFFE0C) = 0x474D3969; // Check for 32MB of RAM
bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969;
const bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969;
ramdriveMount(ram32MB);
if (ram32MB) {
is3DS = fifoGetValue32(FIFO_USER_05) != 0xD2;
Expand All @@ -177,7 +177,7 @@ int main(int argc, char **argv) {
fclose(cidFile);*/
} else if (REG_SCFG_EXT != 0) {
*(vu32*)(0x0DFFFE0C) = 0x474D3969; // Check for 32MB of RAM
bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969;
const bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969;
ramdriveMount(ram32MB);
if (ram32MB) {
is3DS = fifoGetValue32(FIFO_USER_05) != 0xD2;
Expand Down
49 changes: 41 additions & 8 deletions arm9/source/ramd.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ const static u8 bootSector[] = {
'I', 'V', 'E', ' ', ' ', ' ', 'F', 'A', 'T'
};

static bool largeSize = false;
u32 ramdSectors = 0;
u8* ramdLoc = (u8*)NULL;
u8* ramdLocMep = (u8*)NULL;
const u16 bootSectorSignature = 0xAA55;

void ramd_setSize(const bool ram32MB) {
largeSize = ram32MB;
}

bool ramd_startup() {
if(isDSiMode() || REG_SCFG_EXT != 0) {
ramdLoc = (u8*)malloc(0x6000 * SECTOR_SIZE);
Expand All @@ -40,10 +45,24 @@ bool ramd_is_inserted() {
bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) {
for(int i = 0; i < numSectors; i++, sector++) {
if(isDSiMode() || REG_SCFG_EXT != 0) {
if(sector < 0x6000) {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector <= 0xE000) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), SECTOR_SIZE);
if (largeSize) {
if(sector >= 0xE440) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x037C0000 + ((sector - 0xE440) * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector >= 0xE000) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x036F8000 + ((sector - 0xE000) * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector >= 0x6000) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), SECTOR_SIZE);
} else {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE);
}
} else {
if(sector >= 0x6440) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x037C0000 + ((sector - 0x6440) * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector >= 0x6000) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x036F8000 + ((sector - 0x6000) * SECTOR_SIZE), SECTOR_SIZE);
} else {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE);
}
}
} else if(sector < 0x8) {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE);
Expand All @@ -60,10 +79,24 @@ bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) {
bool ramd_write_sectors(sec_t sector, sec_t numSectors, const void *buffer) {
for(int i = 0; i < numSectors; i++, sector++) {
if(isDSiMode() || REG_SCFG_EXT != 0) {
if(sector < 0x6000) {
tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector <= 0xE000) {
tonccpy((void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
if (largeSize) {
if(sector >= 0xE440) {
tonccpy((void*)0x037C0000 + ((sector - 0xE440) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector >= 0xE000) {
tonccpy((void*)0x036F8000 + ((sector - 0xE000) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector >= 0x6000) {
tonccpy((void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else {
tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
}
} else {
if(sector >= 0x6440) {
tonccpy((void*)0x037C0000 + ((sector - 0x6440) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector >= 0x6000) {
tonccpy((void*)0x036F8000 + ((sector - 0x6000) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else {
tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
}
}
} else if(sector < 0x8) {
tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
Expand Down
10 changes: 10 additions & 0 deletions arm9/source/ramd.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,14 @@
extern u32 ramdSectors;
extern u8* ramdLocMep;

#ifdef __cplusplus
extern "C" {
#endif

extern void ramd_setSize(const bool ram32MB);

#ifdef __cplusplus
}
#endif

extern const DISC_INTERFACE io_ram_drive;

0 comments on commit 08433e7

Please sign in to comment.