forked from Mirror/GodMode9
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))
|
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
|
||||||
|
|
||||||
// GodMode9 version
|
// GodMode9 version
|
||||||
#define VERSION "0.9.9.2"
|
#define VERSION "0.9.9.3"
|
||||||
|
|
||||||
// input / output paths
|
// input / output paths
|
||||||
#define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9"
|
#define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9"
|
||||||
|
@ -13,20 +13,28 @@
|
|||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
#include "sdmmc.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_NONE 0
|
||||||
#define TYPE_SYSNAND NAND_SYSNAND
|
#define TYPE_SYSNAND NAND_SYSNAND
|
||||||
#define TYPE_EMUNAND NAND_EMUNAND
|
#define TYPE_EMUNAND NAND_EMUNAND
|
||||||
#define TYPE_IMGNAND NAND_IMGNAND
|
#define TYPE_IMGNAND NAND_IMGNAND
|
||||||
#define TYPE_SDCARD (1<<4)
|
#define TYPE_SDCARD (1UL<<4)
|
||||||
#define TYPE_IMAGE (1<<5)
|
#define TYPE_IMAGE (1UL<<5)
|
||||||
#define TYPE_RAMDRV (1<<6)
|
#define TYPE_RAMDRV (1UL<<6)
|
||||||
|
|
||||||
#define SUBTYPE_CTRN 0
|
#define SUBTYPE_CTRN 0
|
||||||
#define SUBTYPE_CTRN_N 1
|
#define SUBTYPE_CTRN_N 1
|
||||||
#define SUBTYPE_CTRN_NO 2
|
#define SUBTYPE_CTRN_NO 2
|
||||||
#define SUBTYPE_TWLN 3
|
#define SUBTYPE_TWLN 3
|
||||||
#define SUBTYPE_TWLP 4
|
#define SUBTYPE_TWLP 4
|
||||||
#define SUBTYPE_NONE 5
|
#define SUBTYPE_FREE 5
|
||||||
|
#define SUBTYPE_FREE_N 6
|
||||||
|
#define SUBTYPE_NONE 7
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BYTE type;
|
BYTE type;
|
||||||
@ -39,7 +47,7 @@ typedef struct {
|
|||||||
BYTE keyslot;
|
BYTE keyslot;
|
||||||
} SubtypeDesc;
|
} SubtypeDesc;
|
||||||
|
|
||||||
FATpartition DriveInfo[12] = {
|
FATpartition DriveInfo[13] = {
|
||||||
{ TYPE_SDCARD, SUBTYPE_NONE }, // 0 - SDCARD
|
{ TYPE_SDCARD, SUBTYPE_NONE }, // 0 - SDCARD
|
||||||
{ TYPE_SYSNAND, SUBTYPE_CTRN }, // 1 - SYSNAND CTRNAND
|
{ TYPE_SYSNAND, SUBTYPE_CTRN }, // 1 - SYSNAND CTRNAND
|
||||||
{ TYPE_SYSNAND, SUBTYPE_TWLN }, // 2 - SYSNAND TWLN
|
{ TYPE_SYSNAND, SUBTYPE_TWLN }, // 2 - SYSNAND TWLN
|
||||||
@ -51,15 +59,18 @@ FATpartition DriveInfo[12] = {
|
|||||||
{ TYPE_IMGNAND, SUBTYPE_TWLN }, // 8 - IMGNAND TWLN
|
{ TYPE_IMGNAND, SUBTYPE_TWLN }, // 8 - IMGNAND TWLN
|
||||||
{ TYPE_IMGNAND, SUBTYPE_TWLP }, // 9 - IMGNAND TWLP
|
{ TYPE_IMGNAND, SUBTYPE_TWLP }, // 9 - IMGNAND TWLP
|
||||||
{ TYPE_IMAGE, SUBTYPE_NONE }, // X - IMAGE
|
{ 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] = {
|
SubtypeDesc SubTypes[7] = {
|
||||||
{ 0x05C980, 0x17AE80, 0x4 }, // O3DS CTRNAND
|
{ 0x05C980, 0x17AE80, 0x04 }, // O3DS CTRNAND
|
||||||
{ 0x05C980, 0x20F680, 0x5 }, // N3DS CTRNAND
|
{ 0x05C980, 0x20F680, 0x05 }, // N3DS CTRNAND
|
||||||
{ 0x05C980, 0x20F680, 0x4 }, // N3DS CTRNAND (downgraded)
|
{ 0x05C980, 0x20F680, 0x04 }, // N3DS CTRNAND (downgraded)
|
||||||
{ 0x000097, 0x047DA9, 0x3 }, // TWLN
|
{ 0x000097, 0x047DA9, 0x03 }, // TWLN
|
||||||
{ 0x04808D, 0x0105B3, 0x3 } // TWLP
|
{ 0x04808D, 0x0105B3, 0x03 }, // TWLP
|
||||||
|
{ 0x1D7800, 0x000000, 0xFF }, // O3DS FREE SPACE
|
||||||
|
{ 0x26C000, 0x000000, 0xFF } // N3DS FREE SPACE
|
||||||
};
|
};
|
||||||
|
|
||||||
static BYTE nand_type_sys = 0;
|
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 */
|
/* Get Drive Subtype helper */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
@ -93,15 +88,16 @@ static inline SubtypeDesc* get_subtype_desc(
|
|||||||
BYTE pdrv /* Physical drive number to identify the drive */
|
BYTE pdrv /* Physical drive number to identify the drive */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BYTE type = get_partition_type(pdrv);
|
BYTE type = PART_TYPE(pdrv);
|
||||||
BYTE subtype = (type) ? DriveInfo[pdrv].subtype : SUBTYPE_NONE;
|
BYTE subtype = PART_SUBTYPE(pdrv);
|
||||||
|
BYTE nand_type = NAND_TYPE(type);
|
||||||
|
|
||||||
if (subtype == SUBTYPE_NONE) {
|
if (subtype == SUBTYPE_NONE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (subtype == SUBTYPE_CTRN) {
|
} else if ((subtype == SUBTYPE_CTRN) && (nand_type != NAND_TYPE_O3DS)) {
|
||||||
BYTE nand_type = (type == TYPE_SYSNAND) ? nand_type_sys : (type == TYPE_EMUNAND) ? nand_type_emu : nand_type_img;
|
subtype = (nand_type == NAND_TYPE_N3DS) ? SUBTYPE_CTRN_N : SUBTYPE_CTRN_NO;
|
||||||
if (nand_type != NAND_TYPE_O3DS)
|
} else if ((subtype == SUBTYPE_FREE) && (nand_type != NAND_TYPE_O3DS)) {
|
||||||
subtype = (nand_type == NAND_TYPE_N3DS) ? SUBTYPE_CTRN_N : SUBTYPE_CTRN_NO;
|
subtype = SUBTYPE_FREE_N;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &(SubTypes[subtype]);
|
return &(SubTypes[subtype]);
|
||||||
@ -146,7 +142,7 @@ DSTATUS disk_initialize (
|
|||||||
nand_type_img = (mount_state & IMG_NAND) ? CheckNandType(NAND_IMGNAND) : 0;
|
nand_type_img = (mount_state & IMG_NAND) ? CheckNandType(NAND_IMGNAND) : 0;
|
||||||
if (!nand_type_img) {
|
if (!nand_type_img) {
|
||||||
if ((pdrv == 7) && !(mount_state & IMG_FAT)) return STA_NOINIT|STA_NODISK;
|
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();
|
else if (pdrv == 9) InitRamDrive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +163,7 @@ DRESULT disk_read (
|
|||||||
UINT count /* Number of sectors to read */
|
UINT count /* Number of sectors to read */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BYTE type = get_partition_type(pdrv);
|
BYTE type = PART_TYPE(pdrv);
|
||||||
|
|
||||||
if (type == TYPE_NONE) {
|
if (type == TYPE_NONE) {
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
@ -207,7 +203,7 @@ DRESULT disk_write (
|
|||||||
UINT count /* Number of sectors to write */
|
UINT count /* Number of sectors to write */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BYTE type = get_partition_type(pdrv);
|
BYTE type = PART_TYPE(pdrv);
|
||||||
|
|
||||||
if (type == TYPE_NONE) {
|
if (type == TYPE_NONE) {
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
@ -249,7 +245,7 @@ DRESULT disk_ioctl (
|
|||||||
void *buff /* Buffer to send/receive control data */
|
void *buff /* Buffer to send/receive control data */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BYTE type = get_partition_type(pdrv);
|
BYTE type = PART_TYPE(pdrv);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case GET_SECTOR_SIZE:
|
case GET_SECTOR_SIZE:
|
||||||
@ -262,6 +258,8 @@ DRESULT disk_ioctl (
|
|||||||
*((DWORD*) buff) = GetMountSize() / 0x200;
|
*((DWORD*) buff) = GetMountSize() / 0x200;
|
||||||
} else if (type == TYPE_RAMDRV) { // RAM drive
|
} else if (type == TYPE_RAMDRV) { // RAM drive
|
||||||
*((DWORD*) buff) = GetRamDriveSize() / 0x200;
|
*((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
|
} else if (type != TYPE_NONE) { // NAND
|
||||||
*((DWORD*) buff) = get_subtype_desc(pdrv)->size;
|
*((DWORD*) buff) = get_subtype_desc(pdrv)->size;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
/* 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().
|
/* 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. */
|
/ (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)) {
|
} else if ((pdrv >= 0) && (pdrv < NORM_FS)) {
|
||||||
if (pdrv == 0) {
|
if (pdrv == 0) {
|
||||||
type = DRV_FAT | DRV_SDCARD | DRV_STDFAT;
|
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)) {
|
} else if ((pdrv == 9) && !(GetMountState() & IMG_NAND)) {
|
||||||
type = DRV_FAT | DRV_RAMDRIVE | DRV_STDFAT;
|
type = DRV_FAT | DRV_RAMDRIVE | DRV_STDFAT;
|
||||||
} else if (pdrv == 1) {
|
} else if (pdrv == 1) {
|
||||||
@ -77,10 +79,11 @@ bool GetRootDirContentsWorker(DirStruct* contents) {
|
|||||||
if (!DriveType(drvnum[i])) continue; // drive not available
|
if (!DriveType(drvnum[i])) continue; // drive not available
|
||||||
memset(entry->path, 0x00, 64);
|
memset(entry->path, 0x00, 64);
|
||||||
snprintf(entry->path + 0, 4, drvnum[i]);
|
snprintf(entry->path + 0, 4, drvnum[i]);
|
||||||
if ((*(drvnum[i]) == '7') && (GetMountState() & IMG_FAT)) // FAT image handling
|
if ((*(drvnum[i]) >= '7') && (*(drvnum[i]) <= '9') && !(GetMountState() & IMG_NAND)) // Drive 7...9 handling
|
||||||
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[i], "FAT IMAGE");
|
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[i],
|
||||||
else if ((*(drvnum[i]) == '9') && !(GetMountState() & IMG_NAND)) // RAM drive handling
|
(*(drvnum[i]) == '7') ? "FAT IMAGE" :
|
||||||
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[i], "RAMDRIVE");
|
(*(drvnum[i]) == '8') ? "BONUS DRIVE" :
|
||||||
|
(*(drvnum[i]) == '9') ? "RAMDRIVE" : "UNK");
|
||||||
else if (*(drvnum[i]) == 'G') // Game drive special handling
|
else if (*(drvnum[i]) == 'G') // Game drive special handling
|
||||||
snprintf(entry->path + 4, 32, "[%s] %s %s", drvnum[i],
|
snprintf(entry->path + 4, 32, "[%s] %s %s", drvnum[i],
|
||||||
(GetMountState() & GAME_CIA ) ? "CIA" :
|
(GetMountState() & GAME_CIA ) ? "CIA" :
|
||||||
|
@ -24,8 +24,9 @@
|
|||||||
#define DRV_GAME (1UL<<11)
|
#define DRV_GAME (1UL<<11)
|
||||||
#define DRV_CART (1UL<<12)
|
#define DRV_CART (1UL<<12)
|
||||||
#define DRV_ALIAS (1UL<<13)
|
#define DRV_ALIAS (1UL<<13)
|
||||||
#define DRV_SEARCH (1UL<<14)
|
#define DRV_BONUS (1UL<<14)
|
||||||
#define DRV_STDFAT (1UL<<15) // standard FAT drive without limitations
|
#define DRV_SEARCH (1UL<<15)
|
||||||
|
#define DRV_STDFAT (1UL<<16) // standard FAT drive without limitations
|
||||||
|
|
||||||
#define FS_DRVNAME \
|
#define FS_DRVNAME \
|
||||||
"SDCARD", \
|
"SDCARD", \
|
||||||
|
@ -77,6 +77,19 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) {
|
|||||||
return ret;
|
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) {
|
bool FileUnlock(const char* path) {
|
||||||
FIL file;
|
FIL file;
|
||||||
if (!(DriveType(path) & DRV_FAT)) return true; // can't really check this
|
if (!(DriveType(path) & DRV_FAT)) return true; // can't really check this
|
||||||
|
@ -17,6 +17,9 @@ uint64_t GetSDCardSize();
|
|||||||
/** Format the SD card **/
|
/** Format the SD card **/
|
||||||
bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label);
|
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 **/
|
/** Check for file lock, offer to unlock if possible **/
|
||||||
bool FileUnlock(const char* path);
|
bool FileUnlock(const char* path);
|
||||||
|
|
||||||
|
@ -1355,8 +1355,8 @@ u32 GodMode() {
|
|||||||
exit_mode = GODMODE_EXIT_POWEROFF;
|
exit_mode = GODMODE_EXIT_POWEROFF;
|
||||||
break;
|
break;
|
||||||
} else if (pad_state & BUTTON_HOME) { // Home menu
|
} else if (pad_state & BUTTON_HOME) { // Home menu
|
||||||
const char* optionstr[] = { "Poweroff system", "Reboot system", "SD format menu", "Switch EmuNAND" };
|
const char* optionstr[] = { "Poweroff system", "Reboot system", "SD format menu", "Bonus drive setup", "Switch EmuNAND" };
|
||||||
u32 user_select = ShowSelectPrompt(CheckMultiEmuNand() ? 4 : 3, optionstr,
|
u32 user_select = ShowSelectPrompt(CheckMultiEmuNand() ? 5 : 4, optionstr,
|
||||||
"HOME button pressed.\nSelect action:" );
|
"HOME button pressed.\nSelect action:" );
|
||||||
if (user_select == 1) {
|
if (user_select == 1) {
|
||||||
exit_mode = GODMODE_EXIT_POWEROFF;
|
exit_mode = GODMODE_EXIT_POWEROFF;
|
||||||
@ -1378,7 +1378,13 @@ u32 GodMode() {
|
|||||||
InitEmuNandBase(true);
|
InitEmuNandBase(true);
|
||||||
InitExtFS();
|
InitExtFS();
|
||||||
GetDirContents(current_dir, current_path);
|
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())) {
|
while (ShowPrompt(true, "Current EmuNAND offset is %06X.\nSwitch to next offset?", GetEmuNandBase())) {
|
||||||
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND))
|
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND))
|
||||||
clipboard->n_entries = 0; // remove SD clipboard entries
|
clipboard->n_entries = 0; // remove SD clipboard entries
|
||||||
|
Loading…
x
Reference in New Issue
Block a user