mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
Allow setting up a bonus drive on unused space
This commit is contained in:
parent
1348b7ca03
commit
e2c799ca5d
@ -38,7 +38,7 @@
|
||||
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
|
||||
|
||||
// GodMode9 version
|
||||
#define VERSION "0.9.9.2"
|
||||
#define VERSION "0.9.9.3"
|
||||
|
||||
// input / output paths
|
||||
#define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9"
|
||||
|
@ -13,20 +13,28 @@
|
||||
#include "nand.h"
|
||||
#include "sdmmc.h"
|
||||
|
||||
|
||||
#define FPDRV(pdrv) (((pdrv >= 7) && !nand_type_img) ? pdrv + 3 : pdrv)
|
||||
#define PART_TYPE(pdrv) (DriveInfo[FPDRV(pdrv)].type)
|
||||
#define PART_SUBTYPE(pdrv) (DriveInfo[FPDRV(pdrv)].subtype)
|
||||
#define NAND_TYPE(type) ((type == TYPE_SYSNAND) ? nand_type_sys : (type == TYPE_EMUNAND) ? nand_type_emu : (type == TYPE_IMGNAND) ? nand_type_img : 0)
|
||||
|
||||
#define TYPE_NONE 0
|
||||
#define TYPE_SYSNAND NAND_SYSNAND
|
||||
#define TYPE_EMUNAND NAND_EMUNAND
|
||||
#define TYPE_IMGNAND NAND_IMGNAND
|
||||
#define TYPE_SDCARD (1<<4)
|
||||
#define TYPE_IMAGE (1<<5)
|
||||
#define TYPE_RAMDRV (1<<6)
|
||||
#define TYPE_SDCARD (1UL<<4)
|
||||
#define TYPE_IMAGE (1UL<<5)
|
||||
#define TYPE_RAMDRV (1UL<<6)
|
||||
|
||||
#define SUBTYPE_CTRN 0
|
||||
#define SUBTYPE_CTRN_N 1
|
||||
#define SUBTYPE_CTRN_NO 2
|
||||
#define SUBTYPE_TWLN 3
|
||||
#define SUBTYPE_TWLP 4
|
||||
#define SUBTYPE_NONE 5
|
||||
#define SUBTYPE_FREE 5
|
||||
#define SUBTYPE_FREE_N 6
|
||||
#define SUBTYPE_NONE 7
|
||||
|
||||
typedef struct {
|
||||
BYTE type;
|
||||
@ -39,7 +47,7 @@ typedef struct {
|
||||
BYTE keyslot;
|
||||
} SubtypeDesc;
|
||||
|
||||
FATpartition DriveInfo[12] = {
|
||||
FATpartition DriveInfo[13] = {
|
||||
{ TYPE_SDCARD, SUBTYPE_NONE }, // 0 - SDCARD
|
||||
{ TYPE_SYSNAND, SUBTYPE_CTRN }, // 1 - SYSNAND CTRNAND
|
||||
{ TYPE_SYSNAND, SUBTYPE_TWLN }, // 2 - SYSNAND TWLN
|
||||
@ -51,15 +59,18 @@ FATpartition DriveInfo[12] = {
|
||||
{ TYPE_IMGNAND, SUBTYPE_TWLN }, // 8 - IMGNAND TWLN
|
||||
{ TYPE_IMGNAND, SUBTYPE_TWLP }, // 9 - IMGNAND TWLP
|
||||
{ TYPE_IMAGE, SUBTYPE_NONE }, // X - IMAGE
|
||||
{ TYPE_RAMDRV, SUBTYPE_NONE } // Y - RAMDRIVE
|
||||
{ TYPE_SYSNAND, SUBTYPE_FREE }, // Y - SYSNAND BONUS
|
||||
{ TYPE_RAMDRV, SUBTYPE_NONE } // Z - RAMDRIVE
|
||||
};
|
||||
|
||||
SubtypeDesc SubTypes[5] = {
|
||||
{ 0x05C980, 0x17AE80, 0x4 }, // O3DS CTRNAND
|
||||
{ 0x05C980, 0x20F680, 0x5 }, // N3DS CTRNAND
|
||||
{ 0x05C980, 0x20F680, 0x4 }, // N3DS CTRNAND (downgraded)
|
||||
{ 0x000097, 0x047DA9, 0x3 }, // TWLN
|
||||
{ 0x04808D, 0x0105B3, 0x3 } // TWLP
|
||||
SubtypeDesc SubTypes[7] = {
|
||||
{ 0x05C980, 0x17AE80, 0x04 }, // O3DS CTRNAND
|
||||
{ 0x05C980, 0x20F680, 0x05 }, // N3DS CTRNAND
|
||||
{ 0x05C980, 0x20F680, 0x04 }, // N3DS CTRNAND (downgraded)
|
||||
{ 0x000097, 0x047DA9, 0x03 }, // TWLN
|
||||
{ 0x04808D, 0x0105B3, 0x03 }, // TWLP
|
||||
{ 0x1D7800, 0x000000, 0xFF }, // O3DS FREE SPACE
|
||||
{ 0x26C000, 0x000000, 0xFF } // N3DS FREE SPACE
|
||||
};
|
||||
|
||||
static BYTE nand_type_sys = 0;
|
||||
@ -68,22 +79,6 @@ static BYTE nand_type_img = 0;
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get actual FAT partition type helper */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static inline BYTE get_partition_type(
|
||||
__attribute__((unused))
|
||||
BYTE pdrv /* Physical drive number to identify the drive */
|
||||
)
|
||||
{
|
||||
if ((pdrv >= 7) && !nand_type_img) // special handling for FAT images
|
||||
return (pdrv == 7) ? TYPE_IMAGE : (pdrv == 9) ? TYPE_RAMDRV : TYPE_NONE;
|
||||
return DriveInfo[pdrv].type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Subtype helper */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@ -93,15 +88,16 @@ static inline SubtypeDesc* get_subtype_desc(
|
||||
BYTE pdrv /* Physical drive number to identify the drive */
|
||||
)
|
||||
{
|
||||
BYTE type = get_partition_type(pdrv);
|
||||
BYTE subtype = (type) ? DriveInfo[pdrv].subtype : SUBTYPE_NONE;
|
||||
BYTE type = PART_TYPE(pdrv);
|
||||
BYTE subtype = PART_SUBTYPE(pdrv);
|
||||
BYTE nand_type = NAND_TYPE(type);
|
||||
|
||||
if (subtype == SUBTYPE_NONE) {
|
||||
return NULL;
|
||||
} else if (subtype == SUBTYPE_CTRN) {
|
||||
BYTE nand_type = (type == TYPE_SYSNAND) ? nand_type_sys : (type == TYPE_EMUNAND) ? nand_type_emu : nand_type_img;
|
||||
if (nand_type != NAND_TYPE_O3DS)
|
||||
} else if ((subtype == SUBTYPE_CTRN) && (nand_type != NAND_TYPE_O3DS)) {
|
||||
subtype = (nand_type == NAND_TYPE_N3DS) ? SUBTYPE_CTRN_N : SUBTYPE_CTRN_NO;
|
||||
} else if ((subtype == SUBTYPE_FREE) && (nand_type != NAND_TYPE_O3DS)) {
|
||||
subtype = SUBTYPE_FREE_N;
|
||||
}
|
||||
|
||||
return &(SubTypes[subtype]);
|
||||
@ -146,7 +142,7 @@ DSTATUS disk_initialize (
|
||||
nand_type_img = (mount_state & IMG_NAND) ? CheckNandType(NAND_IMGNAND) : 0;
|
||||
if (!nand_type_img) {
|
||||
if ((pdrv == 7) && !(mount_state & IMG_FAT)) return STA_NOINIT|STA_NODISK;
|
||||
else if (pdrv == 8) return STA_NOINIT|STA_NODISK;
|
||||
else if ((pdrv == 8) && !CheckNandType(NAND_SYSNAND)) return STA_NOINIT|STA_NODISK;
|
||||
else if (pdrv == 9) InitRamDrive();
|
||||
}
|
||||
}
|
||||
@ -167,7 +163,7 @@ DRESULT disk_read (
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
BYTE type = get_partition_type(pdrv);
|
||||
BYTE type = PART_TYPE(pdrv);
|
||||
|
||||
if (type == TYPE_NONE) {
|
||||
return RES_PARERR;
|
||||
@ -207,7 +203,7 @@ DRESULT disk_write (
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
BYTE type = get_partition_type(pdrv);
|
||||
BYTE type = PART_TYPE(pdrv);
|
||||
|
||||
if (type == TYPE_NONE) {
|
||||
return RES_PARERR;
|
||||
@ -249,7 +245,7 @@ DRESULT disk_ioctl (
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
BYTE type = get_partition_type(pdrv);
|
||||
BYTE type = PART_TYPE(pdrv);
|
||||
|
||||
switch (cmd) {
|
||||
case GET_SECTOR_SIZE:
|
||||
@ -262,6 +258,8 @@ DRESULT disk_ioctl (
|
||||
*((DWORD*) buff) = GetMountSize() / 0x200;
|
||||
} else if (type == TYPE_RAMDRV) { // RAM drive
|
||||
*((DWORD*) buff) = GetRamDriveSize() / 0x200;
|
||||
} else if ((type == TYPE_SYSNAND) && (PART_SUBTYPE(pdrv) == SUBTYPE_FREE)) { // SysNAND free area
|
||||
*((DWORD*) buff) = getMMCDevice(0)->total_size - get_subtype_desc(pdrv)->offset;
|
||||
} else if (type != TYPE_NONE) { // NAND
|
||||
*((DWORD*) buff) = get_subtype_desc(pdrv)->size;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_CHMOD 0
|
||||
#define _USE_CHMOD 1
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
@ -21,6 +21,8 @@ int DriveType(const char* path) {
|
||||
} else if ((pdrv >= 0) && (pdrv < NORM_FS)) {
|
||||
if (pdrv == 0) {
|
||||
type = DRV_FAT | DRV_SDCARD | DRV_STDFAT;
|
||||
} else if ((pdrv == 8) && !(GetMountState() & IMG_NAND)) {
|
||||
type = DRV_FAT | DRV_SYSNAND | DRV_BONUS | DRV_STDFAT;
|
||||
} else if ((pdrv == 9) && !(GetMountState() & IMG_NAND)) {
|
||||
type = DRV_FAT | DRV_RAMDRIVE | DRV_STDFAT;
|
||||
} else if (pdrv == 1) {
|
||||
@ -77,10 +79,11 @@ bool GetRootDirContentsWorker(DirStruct* contents) {
|
||||
if (!DriveType(drvnum[i])) continue; // drive not available
|
||||
memset(entry->path, 0x00, 64);
|
||||
snprintf(entry->path + 0, 4, drvnum[i]);
|
||||
if ((*(drvnum[i]) == '7') && (GetMountState() & IMG_FAT)) // FAT image handling
|
||||
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[i], "FAT IMAGE");
|
||||
else if ((*(drvnum[i]) == '9') && !(GetMountState() & IMG_NAND)) // RAM drive handling
|
||||
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[i], "RAMDRIVE");
|
||||
if ((*(drvnum[i]) >= '7') && (*(drvnum[i]) <= '9') && !(GetMountState() & IMG_NAND)) // Drive 7...9 handling
|
||||
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[i],
|
||||
(*(drvnum[i]) == '7') ? "FAT IMAGE" :
|
||||
(*(drvnum[i]) == '8') ? "BONUS DRIVE" :
|
||||
(*(drvnum[i]) == '9') ? "RAMDRIVE" : "UNK");
|
||||
else if (*(drvnum[i]) == 'G') // Game drive special handling
|
||||
snprintf(entry->path + 4, 32, "[%s] %s %s", drvnum[i],
|
||||
(GetMountState() & GAME_CIA ) ? "CIA" :
|
||||
|
@ -24,8 +24,9 @@
|
||||
#define DRV_GAME (1UL<<11)
|
||||
#define DRV_CART (1UL<<12)
|
||||
#define DRV_ALIAS (1UL<<13)
|
||||
#define DRV_SEARCH (1UL<<14)
|
||||
#define DRV_STDFAT (1UL<<15) // standard FAT drive without limitations
|
||||
#define DRV_BONUS (1UL<<14)
|
||||
#define DRV_SEARCH (1UL<<15)
|
||||
#define DRV_STDFAT (1UL<<16) // standard FAT drive without limitations
|
||||
|
||||
#define FS_DRVNAME \
|
||||
"SDCARD", \
|
||||
|
@ -77,6 +77,19 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SetupBonusDrive(void) {
|
||||
if (!ShowUnlockSequence(3, "Format the bonus drive?\nThis will irreversibly delete\nALL data on it.\n"))
|
||||
return false;
|
||||
ShowString("Formatting drive, please wait...");
|
||||
if (GetMountState() & IMG_NAND) InitImgFS(NULL);
|
||||
bool ret = (f_mkfs("8:", FM_ANY, 0, MAIN_BUFFER, MAIN_BUFFER_SIZE) == FR_OK);
|
||||
if (ret) {
|
||||
f_setlabel("8:BONUS");
|
||||
InitExtFS();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FileUnlock(const char* path) {
|
||||
FIL file;
|
||||
if (!(DriveType(path) & DRV_FAT)) return true; // can't really check this
|
||||
|
@ -17,6 +17,9 @@ uint64_t GetSDCardSize();
|
||||
/** Format the SD card **/
|
||||
bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label);
|
||||
|
||||
/** Format the bonus drive area **/
|
||||
bool SetupBonusDrive(void);
|
||||
|
||||
/** Check for file lock, offer to unlock if possible **/
|
||||
bool FileUnlock(const char* path);
|
||||
|
||||
|
@ -1355,8 +1355,8 @@ u32 GodMode() {
|
||||
exit_mode = GODMODE_EXIT_POWEROFF;
|
||||
break;
|
||||
} else if (pad_state & BUTTON_HOME) { // Home menu
|
||||
const char* optionstr[] = { "Poweroff system", "Reboot system", "SD format menu", "Switch EmuNAND" };
|
||||
u32 user_select = ShowSelectPrompt(CheckMultiEmuNand() ? 4 : 3, optionstr,
|
||||
const char* optionstr[] = { "Poweroff system", "Reboot system", "SD format menu", "Bonus drive setup", "Switch EmuNAND" };
|
||||
u32 user_select = ShowSelectPrompt(CheckMultiEmuNand() ? 5 : 4, optionstr,
|
||||
"HOME button pressed.\nSelect action:" );
|
||||
if (user_select == 1) {
|
||||
exit_mode = GODMODE_EXIT_POWEROFF;
|
||||
@ -1378,7 +1378,13 @@ u32 GodMode() {
|
||||
InitEmuNandBase(true);
|
||||
InitExtFS();
|
||||
GetDirContents(current_dir, current_path);
|
||||
} else if (user_select == 4) { // switch EmuNAND offset
|
||||
} else if (user_select == 4) { // setup bonus drive
|
||||
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_BONUS|DRV_IMAGE)))
|
||||
clipboard->n_entries = 0; // remove bonus drive clipboard entries
|
||||
if (!SetupBonusDrive()) ShowPrompt(false, "Setup failed!");
|
||||
ClearScreenF(true, true, COLOR_STD_BG);
|
||||
GetDirContents(current_dir, current_path);
|
||||
} else if (user_select == 5) { // switch EmuNAND offset
|
||||
while (ShowPrompt(true, "Current EmuNAND offset is %06X.\nSwitch to next offset?", GetEmuNandBase())) {
|
||||
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND))
|
||||
clipboard->n_entries = 0; // remove SD clipboard entries
|
||||
|
Loading…
x
Reference in New Issue
Block a user