Skip to content

Commit

Permalink
Read DSiWare saves in .pub/.prv format on flashcards without copy…
Browse files Browse the repository at this point in the history
…ing to console SD first
  • Loading branch information
RocketRobz committed Dec 8, 2024
1 parent 3678edf commit f1c821c
Show file tree
Hide file tree
Showing 19 changed files with 153 additions and 100 deletions.
12 changes: 9 additions & 3 deletions imageview/arm7/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ int main() {
*(u16*)0x02FFFC36 = *(u16*)0x0800015E; // Header CRC16
*(u32*)0x02FFFC38 = *(u32*)0x0800000C; // Game Code

*(u32*)0x02FFFDF0 = REG_SCFG_EXT;

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

Expand Down Expand Up @@ -127,22 +129,26 @@ int main() {

// 01: Fade Out
// 02: Return
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgSdmmcEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)


// 03: Status: Init/Volume/Battery/SD
// https://problemkaputt.de/gbatek.htm#dsii2cdevice4ahbptwlchip
// Battery is 7 bits -- bits 0-7
// Volume is 00h to 1Fh = 5 bits -- bits 8-12
// SD status -- bits 13-14
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgSdmmcEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)

*(vu32*)0x4004820 = 0x8B7F0305;

u8 initStatus = (BIT_SET(!!(REG_SNDEXTCNT), SNDEXTCNT_BIT)
| BIT_SET(!!(REG_SCFG_EXT), REGSCFG_BIT)
| BIT_SET(*(vu32*)0x4004820, SCFGSDMMC_BIT)
| BIT_SET(!!(pmBacklight & BIT(4) || pmBacklight & BIT(5) || pmBacklight & BIT(6) || pmBacklight & BIT(7)), BACKLIGHT_BIT)
| BIT_SET(isPhat(), DSPHAT_BIT)
| BIT_SET(i2cBricked, I2CBRICKED_BIT));

*(vu32*)0x4004820 = 0;

status = (status & ~INIT_MASK) | ((initStatus << INIT_OFF) & INIT_MASK);
fifoSendValue32(FIFO_USER_03, status);

Expand Down
12 changes: 9 additions & 3 deletions manual/arm7/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ int main() {
*(u16*)0x02FFFC36 = *(u16*)0x0800015E; // Header CRC16
*(u32*)0x02FFFC38 = *(u32*)0x0800000C; // Game Code

*(u32*)0x02FFFDF0 = REG_SCFG_EXT;

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

Expand Down Expand Up @@ -125,22 +127,26 @@ int main() {

// 01: Fade Out
// 02: Return
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgSdmmcEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)


// 03: Status: Init/Volume/Battery/SD
// https://problemkaputt.de/gbatek.htm#dsii2cdevice4ahbptwlchip
// Battery is 7 bits -- bits 0-7
// Volume is 00h to 1Fh = 5 bits -- bits 8-12
// SD status -- bits 13-14
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgSdmmcEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)

*(vu32*)0x4004820 = 0x8B7F0305;

u8 initStatus = (BIT_SET(!!(REG_SNDEXTCNT), SNDEXTCNT_BIT)
| BIT_SET(!!(REG_SCFG_EXT), REGSCFG_BIT)
| BIT_SET(*(vu32*)0x4004820, SCFGSDMMC_BIT)
| BIT_SET(!!(pmBacklight & BIT(4) || pmBacklight & BIT(5) || pmBacklight & BIT(6) || pmBacklight & BIT(7)), BACKLIGHT_BIT)
| BIT_SET(isPhat(), DSPHAT_BIT)
| BIT_SET(i2cBricked, I2CBRICKED_BIT));

*(vu32*)0x4004820 = 0;

status = (status & ~INIT_MASK) | ((initStatus << INIT_OFF) & INIT_MASK);
fifoSendValue32(FIFO_USER_03, status);

Expand Down
16 changes: 11 additions & 5 deletions quickmenu/arm7/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void changeBacklightLevel(void) {
// if the backlight is regulable and the console is a phat the range will be 0 - 4 (with 4 being backlight off)
// if the backlight is not regulable the only possible values will be 0 and 4 (with 4 being backlight off)
backlightLevel += 1 + (3 * !hasRegulableBacklight);

if (backlightLevel > (3 + isDSPhat)) {
backlightLevel = 0;
}
Expand Down Expand Up @@ -205,6 +205,8 @@ int main() {
*(u16*)0x02FFFC36 = *(u16*)0x0800015E; // Header CRC16
*(u32*)0x02FFFC38 = *(u32*)0x0800000C; // Game Code

*(u32*)0x02FFFDF0 = REG_SCFG_EXT;

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

Expand Down Expand Up @@ -260,29 +262,33 @@ int main() {

// 01: Fade Out
// 02: Return
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgSdmmcEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)


// 03: Status: Init/Volume/Battery/SD
// https://problemkaputt.de/gbatek.htm#dsii2cdevice4ahbptwlchip
// Battery is 7 bits -- bits 0-7
// Volume is 00h to 1Fh = 5 bits -- bits 8-12
// SD status -- bits 13-14
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgSdmmcEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)

*(vu32*)0x4004820 = 0x8B7F0305;

u8 initStatus = (BIT_SET(!!(REG_SNDEXTCNT), SNDEXTCNT_BIT)
| BIT_SET(!!(REG_SCFG_EXT), REGSCFG_BIT)
| BIT_SET(*(vu32*)0x4004820, SCFGSDMMC_BIT)
| BIT_SET(hasRegulableBacklight, BACKLIGHT_BIT)
| BIT_SET(isDSPhat, DSPHAT_BIT)
| BIT_SET(i2cBricked, I2CBRICKED_BIT));

*(vu32*)0x4004820 = 0;

status = (status & ~INIT_MASK) | ((initStatus << INIT_OFF) & INIT_MASK);
fifoSendValue32(FIFO_USER_03, status);

if (REG_SNDEXTCNT == 0) {
if (hasRegulableBacklight)
backlightLevel = pmBacklight & 3; // Brightness

if((readPowerManagement(PM_CONTROL_REG) & 0xC) == 0) // DS Phat backlight off
backlightLevel = 4;
}
Expand Down
44 changes: 22 additions & 22 deletions quickmenu/arm9/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ int SetDonorSDK() {
void SetMPUSettings() {
scanKeys();
int pressed = keysHeld();

if (pressed & KEY_B) {
mpuregion = 1;
} else if (pressed & KEY_X) {
Expand Down Expand Up @@ -338,7 +338,7 @@ void dsCardLaunch() {
*(u32*)(0x02000318) = 0x00000013;
*(u32*)(0x0200031C) = 0x00000000;
*(u16*)(0x02000306) = swiCRC16(0xFFFF, (void*)0x02000308, 0x18);

unlaunchSetHiyaBoot();

DC_FlushAll(); // Make reboot not fail
Expand All @@ -359,7 +359,7 @@ void SetWidescreen(const char *filename) {
|| !useWidescreen || !externalFirmsModules || ms().macroMode) {
return;
}

if (isHomebrew[ms().secondaryDevice] && ms().homebrewHasWide && (access("sd:/_nds/TWiLightMenu/TwlBg/Widescreen.cxi", F_OK) == 0)) {
if (access("sd:/luma/sysmodules/TwlBg.cxi", F_OK) == 0) {
rename("sd:/luma/sysmodules/TwlBg.cxi", "sd:/_nds/TWiLightMenu/TwlBg/TwlBg.cxi.bak");
Expand Down Expand Up @@ -550,7 +550,7 @@ mm_sound_effect snd_hour;

void InitSound() {
mmInitDefaultMem((mm_addr)soundbank_bin);

mmLoadEffect(SFX_LAUNCH);
mmLoadEffect(SFX_SELECT);
mmLoadEffect(SFX_STOP);
Expand Down Expand Up @@ -1041,11 +1041,11 @@ void customSleep() {
static void getFiletypeFromFilename(std::string_view filename, eROMType& rom_type, int& box_art_type) {
rom_type = ROM_TYPE_UNK;
box_art_type = -1;

auto pos = filename.find_last_of('.');
if(pos == filename.npos)
return;

if (extension(filename, {".nds", ".dsi", ".ids", ".app", ".srl", ".argv"})) {
rom_type = ROM_TYPE_NDS;
box_art_type = 0;
Expand Down Expand Up @@ -1177,14 +1177,14 @@ void findPictochatAndDownladPlay() {
logPrint("DS Download Play found\n");
return;
}

auto mountNand = [nandInited = false]() mutable {
if (!nandInited) {
fatMountSimple("nand", &io_dsi_nand);
nandInited = true;
}
};

char srcPath[256];
u8 regions[3] = {0x41, 0x43, 0x4B};

Expand Down Expand Up @@ -1222,7 +1222,7 @@ void findPictochatAndDownladPlay() {
strncpy(dlplayPath, "/_nds/dlplay.nds", sizeof(dlplayPath));
return;
}

if (ms().consoleModel == 0) {
for (int i = 0; i < 3; i++) {
snprintf(dlplayPath, sizeof(dlplayPath), "/title/00030005/484e44%x/content/00000000.app", regions[i]);
Expand Down Expand Up @@ -1278,7 +1278,7 @@ int dsClassicMenu(void) {
//---------------------------------------------------------------------------------
// Read user name
/*char *username = (char*)PersonalData->name;
// text
for (int i = 0; i < 10; i++) {
if (username[i*2] == 0x00)
Expand All @@ -1298,7 +1298,7 @@ int dsClassicMenu(void) {
externalFirmsModules = (lumaConfig.GetInt("boot", "enable_external_firm_and_modules", 0) == true);
logPrint((access("sd:/_nds/TWiLightMenu/TwlBg/Widescreen.cxi", F_OK) == 0) && externalFirmsModules ? "Widescreen found\n" : "Widescreen not found\n");
}

logPrint("\n");

ms().gbaR3Test = (access(sys().isRunFromSD() ? "sd:/_nds/TWiLightMenu/emulators/GBARunner3.nds" : "fat:/_nds/TWiLightMenu/emulators/GBARunner3.nds", F_OK) == 0);
Expand Down Expand Up @@ -1358,9 +1358,9 @@ int dsClassicMenu(void) {
keysSetRepeat(25,5);

srand(time(NULL));

bool menuButtonPressed = false;

sysSetCartOwner(BUS_OWNER_ARM9); // Allow arm9 to access GBA ROM

if (ms().previousUsedDevice && bothSDandFlashcard() && ms().launchType[ms().previousUsedDevice] == 3
Expand Down Expand Up @@ -1398,7 +1398,7 @@ int dsClassicMenu(void) {
// SD card
if (sdFound() && ms().romPath[0] != "" && access(ms().romPath[0].c_str(), F_OK) == 0) {
romFound[0] = true;

parseRomInformationForDevice(0, filename[0], boxArtPath[0]);
}

Expand Down Expand Up @@ -1450,7 +1450,7 @@ int dsClassicMenu(void) {
gbaUseBottomScreen = (gbarunner2ini.GetString("emulation", "useBottomScreen", "false")=="false" ? false : true);
}
gbaModeIconLoad(gbaUseBottomScreen);

whiteScreen = false;
fadeType = true; // Fade in from white
while (!screenFadedIn()) {
Expand Down Expand Up @@ -1668,9 +1668,9 @@ int dsClassicMenu(void) {
mmEffectEx(&snd_select);
}
}

auto selectedPosition = cursorPosition;

auto getTouchedElement = [](const auto& touchPoint){
if (touchPoint.px >= 33 && touchPoint.px <= 221 && touchPoint.py >= 25 && touchPoint.py <= 69) {
return MenuEntry::CART;
Expand Down Expand Up @@ -1724,7 +1724,7 @@ int dsClassicMenu(void) {

if (menuButtonPressed) {
menuButtonPressed = false;

switch (selectedPosition) {
case MenuEntry::INVALID:
break;
Expand Down Expand Up @@ -2039,7 +2039,7 @@ int dsClassicMenu(void) {
gbaSwitch();
} else {
mmEffectEx(&snd_wrong);
}
}
break;
case MenuEntry::BRIGHTNESS:
// Adjust backlight level
Expand Down Expand Up @@ -2188,7 +2188,7 @@ int dsClassicMenu(void) {
mkdir("saves", 0777);
}
ms().dsiWarePrvPath = ms().dsiWarePubPath;
bool savFormat = (ms().secondaryDevice && (!sdFound() || !ms().dsiWareToSD || bs().b4dsMode));
const bool savFormat = (ms().secondaryDevice && (!isDSiMode() || !sys().scfgSdmmcEnabled() || bs().b4dsMode));
if (savFormat) {
ms().dsiWarePubPath = replaceAll(ms().dsiWarePubPath, typeToReplace, getSavExtension());
ms().dsiWarePrvPath = ms().dsiWarePubPath;
Expand Down Expand Up @@ -2397,7 +2397,7 @@ int dsClassicMenu(void) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "GAME_SOFT_RESET", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", 0);
bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", 0);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
|| (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !sys().isRegularDS())
|| (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !sys().isRegularDS())
Expand Down Expand Up @@ -2615,7 +2615,7 @@ int dsClassicMenu(void) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "DONOR_SDK_VER", SetDonorSDK());
bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", mpuregion);
bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", mpusize);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
|| (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !sys().isRegularDS())
|| (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !sys().isRegularDS())
Expand Down
22 changes: 14 additions & 8 deletions romsel_aktheme/arm7/source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void changeBacklightLevel(void) {
// if the backlight is regulable and the console is a phat the range will be 0 - 4 (with 4 being backlight off)
// if the backlight is not regulable the only possible values will be 0 and 4 (with 4 being backlight off)
backlightLevel += 1 + (3 * !hasRegulableBacklight);

if (backlightLevel > (3 + isDSPhat)) {
backlightLevel = 0;
}
Expand Down Expand Up @@ -146,6 +146,8 @@ int main() {
*(u16*)0x02FFFC36 = *(u16*)0x0800015E; // Header CRC16
*(u32*)0x02FFFC38 = *(u32*)0x0800000C; // Game Code

*(u32*)0x02FFFDF0 = REG_SCFG_EXT;

REG_SOUNDCNT |= SOUND_ENABLE;
writePowerManagement(PM_CONTROL_REG, ( readPowerManagement(PM_CONTROL_REG) & ~PM_SOUND_MUTE ) | PM_SOUND_AMP );
powerOn(POWER_SOUND);
Expand All @@ -161,7 +163,7 @@ int main() {
fifoInit();

SetYtrigger(80);

my_installSystemFIFO();

irqSet(IRQ_VCOUNT, VcountHandler);
Expand Down Expand Up @@ -192,29 +194,33 @@ int main() {

// 01: Fade Out
// 02: Return
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)
// 03: status (Bit 0: hasRegulableBacklight, Bit 1: scfgSdmmcEnabled, Bit 2: REG_SNDEXTCNT, Bit 3: isDSPhat, Bit 4: i2cBricked)


// 03: Status: Init/Volume/Battery/SD
// https://problemkaputt.de/gbatek.htm#dsii2cdevice4ahbptwlchip
// Battery is 7 bits -- bits 0-7
// Volume is 00h to 1Fh = 5 bits -- bits 8-12
// SD status -- bits 13-14
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)
// Init status -- bits 15-18 (Bit 0 (15): hasRegulableBacklight, Bit 1 (16): scfgSdmmcEnabled, Bit 2 (17): REG_SNDEXTCNT, Bit 3 (18): isDSPhat, Bit 4 (19): i2cBricked)

*(vu32*)0x4004820 = 0x8B7F0305;

u8 initStatus = (BIT_SET(!!(REG_SNDEXTCNT), SNDEXTCNT_BIT)
| BIT_SET(!!(REG_SCFG_EXT), REGSCFG_BIT)
| BIT_SET(*(vu32*)0x4004820, SCFGSDMMC_BIT)
| BIT_SET(hasRegulableBacklight, BACKLIGHT_BIT)
| BIT_SET(isDSPhat, DSPHAT_BIT)
| BIT_SET(i2cBricked, I2CBRICKED_BIT));

*(vu32*)0x4004820 = 0;

status = (status & ~INIT_MASK) | ((initStatus << INIT_OFF) & INIT_MASK);
fifoSendValue32(FIFO_USER_03, status);

if (REG_SNDEXTCNT == 0) {
if (hasRegulableBacklight)
backlightLevel = pmBacklight & 3; // Brightness

if((readPowerManagement(PM_CONTROL_REG) & 0xC) == 0) // DS Phat backlight off
backlightLevel = 4;
}
Expand All @@ -233,12 +239,12 @@ int main() {
gotCartHeader = true;
}*/


timeTilVolumeLevelRefresh++;
if (timeTilVolumeLevelRefresh == 8) {
if ((isDSiMode() || REG_SCFG_EXT != 0) && !i2cBricked) { //vol
status = (status & ~VOL_MASK) | ((my_i2cReadRegister(I2C_PM, I2CREGPM_VOL) << VOL_OFF) & VOL_MASK);
status = (status & ~BAT_MASK) | ((my_i2cReadRegister(I2C_PM, I2CREGPM_BATTERY) << BAT_OFF) & BAT_MASK);
status = (status & ~BAT_MASK) | ((my_i2cReadRegister(I2C_PM, I2CREGPM_BATTERY) << BAT_OFF) & BAT_MASK);
} else {
int battery = (readPowerManagement(PM_BATTERY_REG) & 1)?3:15;
int backlight = readPowerManagement(PM_BACKLIGHT_LEVEL);
Expand Down
Loading

0 comments on commit f1c821c

Please sign in to comment.