Skip to content

fix scfg_ext_7 handling with direct boot - #2701

Open
edo9300 wants to merge 3 commits into
melonDS-emu:masterfrom
edo9300:fix-direct-boot
Open

edo9300 wants to merge 3 commits into
melonDS-emu:masterfrom
edo9300:fix-direct-boot

Conversation

@edo9300

@edo9300 edo9300 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

With the scfg permissions update, melonds changed the default scfg flags when direct booting, but as default it disabled access to the scmc registers, breaking direct booting homebrews and software that required nand access.
Properly handle this case by using the appropriate dsi header field in the rom containing the arm7 scfg settings (as stated on gbatek, only bit 0,1,2,10,18 and 31 are to be considered).

Comment thread src/DSi.cpp Outdated
edo9300 added 2 commits July 26, 2026 13:13
the code worked before because some sdk5 games have a routine that checks if scfg7 is unlocked, and in case automatically populated these values themselves, by disabling it according to the header in the previous commit, this was no longer the case
@edo9300

edo9300 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

After the initial commit, I noticed that retail games failed to boot, this came down to the fact that before they were being booted with unlocked scfg, and sdk5 games have a routine that checks for that, and, if it's unlocked, automatically populate the ram values used by the sdk to determine the environment it's being run on, which should instead be taken care of by the launcher.
The routine in question is this (here taken from pokemon black at arm7 address 0x238018c):

void setup_scfg(void) {
	if((REG_SCFG_EXT & SCFG_EXT_SCFG_MBK_REG) == 0)
		return;
	REG_SCFG_WL |= 1;
	REG_SCFG_CLK |= SCFG_CLK_TOUCH;
	REG_SCFG_EXT |= SCFG_EXT_NDMA;
	*(unsigned*)0x380FFC4 = REG_SCFG_EXT;
	unsigned r0 = REG_SCFG_OP & 0xFF;
	r0 |= (REG_SCFG_A9ROM & 0x03) << 2;
	r0 |= (REG_SCFG_A7ROM & 0x06) << 4;
	r0 |= (REG_SCFG_WL & 0x01) << 7;
	*(unsigned char*)0x380FFC8 = r0;
	
	r0 = REG_SCFG_JTAG;
	unsigned r12 = r0 & SCFG_JTAG_DSP_ENABLE;
	r0 |= r12 >> 6;
	
	unsigned r1 = REG_SCFG_CLK;
	r12 = r1 & 0x7;
	r0 |= r12 << 3;
	r12 = r1 & (SCFG_CLK_TOUCH | SCFG_CLK_NWRAM);
	r0 |= r12 >> 1;
	*(unsigned char*)0x380FFC9 = r0;
	REG_SCFG_EXT &= ~SCFG_EXT_SCFG_MBK_REG;
}

Specifically the games seems to only need the values of SCFG_ROM to be placed in ram so that they can detect if they're run on a ds or on a dsi

@AntonioND

Copy link
Copy Markdown
Contributor

Also, this branch fixes a hang that I get in the examples of BlocksDS that initialize NAND, like. https://codeberg.org/blocksds/sdk/src/branch/master/examples/filesystem/all_filesystems

AntonioND added a commit to blocksds/libnds that referenced this pull request Sep 9, 2026
The current location of this code isn't the right one. The idea of this
code is to enable access to the SD/NAND in loaders that don't set the right
SCFG bits, which confuses libnds. However, the ARM7 version of irqInit()
calls TMIO_init() much earlier than SDMMC_init() is called, which means
TMIO has already decided that it can't access SD/NAND and it hangs when
nandInit() is called.

This has been discovered thanks to Edoardo Lolletti <edoardo762@gmail.com>
and his work on a potential fix for melonDS [1]. The fix hasn't been
merged yet and, even if it gets merged, there will be many users of
melonDS with buggy versions of the emulator, so it's important to add a
workaround to libnds.

[1] melonDS-emu/melonDS#2701
@AntonioND

AntonioND commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

I've ended up adding a workaround to libnds because, even if this PR gets merged, there will be lots of people with old versions of melonDS and I'd rather have a workaround for them: https://codeberg.org/blocksds/libnds/commit/8d80f2a7aeed7ff0440bc9bc8b46f92756a48fcb

AntonioND added a commit to blocksds/libnds that referenced this pull request Sep 9, 2026
The current location of this code isn't the right one. The idea of this
code is to enable access to the SD/NAND in loaders that don't set the right
SCFG bits, which confuses libnds. However, the ARM7 version of irqInit()
calls TMIO_init() much earlier than SDMMC_init() is called, which means
TMIO has already decided that it can't access SD/NAND and it hangs when
nandInit() is called.

This has been discovered thanks to @edo9300 and his work on a potential
fix for melonDS [1]. The fix hasn't been merged yet and, even if it gets
merged, there will be many users of melonDS with buggy versions of the
emulator, so it's important to add a workaround to libnds.

[1] melonDS-emu/melonDS#2701
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants