Add FAT image (.img) mounting

This commit is contained in:
RocketRobz 2020-02-21 02:14:37 -07:00
parent 2011b83be9
commit 2a43eb2370
7 changed files with 197 additions and 37 deletions

View File

@ -39,6 +39,8 @@
#define ENTRIES_START_ROW 1 #define ENTRIES_START_ROW 1
#define ENTRY_PAGE_LENGTH 10 #define ENTRY_PAGE_LENGTH 10
#define sizeOfdmAssignedOp 8
using namespace std; using namespace std;
//static bool ramDumped = false; //static bool ramDumped = false;
@ -47,7 +49,7 @@ bool flashcardMountSkipped = true;
static bool flashcardMountRan = true; static bool flashcardMountRan = true;
static bool dmTextPrinted = false; static bool dmTextPrinted = false;
static int dmCursorPosition = 0; static int dmCursorPosition = 0;
static int dmAssignedOp[7] = {-1}; static int dmAssignedOp[sizeOfdmAssignedOp] = {-1};
static int dmMaxCursors = -1; static int dmMaxCursors = -1;
static u8 gbaFixedValue = 0; static u8 gbaFixedValue = 0;
@ -118,7 +120,8 @@ void dm_drawTopScreen(void) {
|| (flashcardMounted && nitroCurrentDrive==1) || (flashcardMounted && nitroCurrentDrive==1)
|| (ramdrive1Mounted && nitroCurrentDrive==2) || (ramdrive1Mounted && nitroCurrentDrive==2)
|| (ramdrive2Mounted && nitroCurrentDrive==3) || (ramdrive2Mounted && nitroCurrentDrive==3)
|| (nandMounted && nitroCurrentDrive==4)) || (nandMounted && nitroCurrentDrive==4)
|| (imgMounted && nitroCurrentDrive==6))
{ {
// Do nothing // Do nothing
} }
@ -135,6 +138,23 @@ void dm_drawTopScreen(void) {
printf ("[ram2:] RAMDRIVE"); printf ("[ram2:] RAMDRIVE");
} else if (dmAssignedOp[i] == 7) { } else if (dmAssignedOp[i] == 7) {
printf ("[nand:] SYSNAND"); printf ("[nand:] SYSNAND");
} else if (dmAssignedOp[i] == 8) {
printf ("[img:] FAT IMAGE");
if ((sdMounted && imgCurrentDrive==0)
|| (flashcardMounted && imgCurrentDrive==1)
|| (ramdrive1Mounted && imgCurrentDrive==2)
|| (ramdrive2Mounted && imgCurrentDrive==3)
|| (nandMounted && imgCurrentDrive==4))
{
if (imgLabel[0] != '\0') {
iprintf (" (%s)", imgLabel);
}
}
else
{
iprintf ("\x1b[%d;29H", i + ENTRIES_START_ROW);
printf ("[x]");
}
} }
} }
} }
@ -207,6 +227,11 @@ void dm_drawBottomScreen(void) {
printf ("\n(SysNAND FAT, "); printf ("\n(SysNAND FAT, ");
printDriveBytes(nandSize); printDriveBytes(nandSize);
printf(")"); printf(")");
} else if (dmAssignedOp[dmCursorPosition] == 8) {
printf ("[img:] FAT IMAGE");
printf ("\n(Image FAT, ");
printDriveBytes(imgSize);
printf(")");
} }
} }
@ -219,7 +244,7 @@ void driveMenu (void) {
gbaFixedValue = *(u8*)(0x080000B2); gbaFixedValue = *(u8*)(0x080000B2);
} }
for (int i = 0; i < 6; i++) { for (int i = 0; i < sizeOfdmAssignedOp; i++) {
dmAssignedOp[i] = -1; dmAssignedOp[i] = -1;
} }
dmMaxCursors = -1; dmMaxCursors = -1;
@ -243,6 +268,10 @@ void driveMenu (void) {
dmMaxCursors++; dmMaxCursors++;
dmAssignedOp[dmMaxCursors] = 6; dmAssignedOp[dmMaxCursors] = 6;
} }
if (imgMounted) {
dmMaxCursors++;
dmAssignedOp[dmMaxCursors] = 8;
}
if (expansionPakFound if (expansionPakFound
|| (io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || (io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA)
|| (isDSiMode() && !arm7SCFGLocked && !(REG_SCFG_MC & BIT(0)))) { || (isDSiMode() && !arm7SCFGLocked && !(REG_SCFG_MC & BIT(0)))) {
@ -334,10 +363,11 @@ void driveMenu (void) {
|| (flashcardMounted && nitroCurrentDrive==1) || (flashcardMounted && nitroCurrentDrive==1)
|| (ramdrive1Mounted && nitroCurrentDrive==2) || (ramdrive1Mounted && nitroCurrentDrive==2)
|| (ramdrive2Mounted && nitroCurrentDrive==3) || (ramdrive2Mounted && nitroCurrentDrive==3)
|| (nandMounted && nitroCurrentDrive==4)) || (nandMounted && nitroCurrentDrive==4)
|| (imgMounted && nitroCurrentDrive==6))
{ {
dmTextPrinted = false; dmTextPrinted = false;
currentDrive = nitroCurrentDrive; currentDrive = 5;
chdir("nitro:/"); chdir("nitro:/");
screenMode = 1; screenMode = 1;
break; break;
@ -363,6 +393,19 @@ void driveMenu (void) {
chdir("nand:/"); chdir("nand:/");
screenMode = 1; screenMode = 1;
break; break;
} else if (dmAssignedOp[dmCursorPosition] == 8 && imgMounted) {
if ((sdMounted && imgCurrentDrive==0)
|| (flashcardMounted && imgCurrentDrive==1)
|| (ramdrive1Mounted && imgCurrentDrive==2)
|| (ramdrive2Mounted && imgCurrentDrive==3)
|| (nandMounted && imgCurrentDrive==4))
{
dmTextPrinted = false;
currentDrive = 6;
chdir("img:/");
screenMode = 1;
break;
}
} }
} }

View File

@ -11,6 +11,7 @@
#include "ramd.h" #include "ramd.h"
#include "ramdrive-include.h" #include "ramdrive-include.h"
#include "nandio.h" #include "nandio.h"
#include "imgio.h"
#include "tonccpy.h" #include "tonccpy.h"
static sNDSHeader nds; static sNDSHeader nds;
@ -20,23 +21,26 @@ u8 stored_SCFG_MC = 0;
static bool slot1Enabled = true; static bool slot1Enabled = true;
bool nandMounted = false; bool nandMounted = false;
bool nandMountedDone = false;
bool sdMounted = false; bool sdMounted = false;
bool sdMountedDone = false; // true if SD mount is successful once bool sdMountedDone = false; // true if SD mount is successful once
bool flashcardMounted = false; bool flashcardMounted = false;
bool ramdrive1Mounted = false; bool ramdrive1Mounted = false;
bool ramdrive2Mounted = false; bool ramdrive2Mounted = false;
bool imgMounted = false;
bool nitroMounted = false; bool nitroMounted = false;
int currentDrive = 0; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND int currentDrive = 0; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND, 5 == NitroFS, 6 == FAT IMG
int nitroCurrentDrive = 0; int nitroCurrentDrive = 0;
int imgCurrentDrive = 0;
char sdLabel[12]; char sdLabel[12];
char fatLabel[12]; char fatLabel[12];
char imgLabel[12];
u32 nandSize = 0; u32 nandSize = 0;
u64 sdSize = 0; u64 sdSize = 0;
u64 fatSize = 0; u64 fatSize = 0;
u64 imgSize = 0;
static int getGbNumber(u64 bytes) { static int getGbNumber(u64 bytes) {
int gbNumber = 0; int gbNumber = 0;
@ -87,28 +91,21 @@ const char* getDrivePath(void) {
return "ram2:/"; return "ram2:/";
case 4: case 4:
return "nand:/"; return "nand:/";
case 5:
return "nitro:/";
case 6:
return "img:/";
} }
return ""; return "";
} }
void fixLabel(bool fat) { void fixLabel(char* label) {
if (fat) { for (int i = 0; i < 12; i++) {
for (int i = 0; i < 12; i++) { if (((label[i] == ' ') && (label[i+1] == ' ') && (label[i+2] == ' '))
if (((fatLabel[i] == ' ') && (fatLabel[i+1] == ' ') && (fatLabel[i+2] == ' ')) || ((label[i] == ' ') && (label[i+1] == ' '))
|| ((fatLabel[i] == ' ') && (fatLabel[i+1] == ' ')) || (label[i] == ' ')) {
|| (fatLabel[i] == ' ')) { label[i] = '\0';
fatLabel[i] = '\0'; break;
break;
}
}
} else {
for (int i = 0; i < 12; i++) {
if (((sdLabel[i] == ' ') && (sdLabel[i+1] == ' ') && (sdLabel[i+2] == ' '))
|| ((sdLabel[i] == ' ') && (sdLabel[i+1] == ' '))
|| (sdLabel[i] == ' ')) {
sdLabel[i] = '\0';
break;
}
} }
} }
} }
@ -133,10 +130,13 @@ bool bothSDandFlashcard(void) {
} }
} }
bool imgFound(void) {
return (access("img:/", F_OK) == 0);
}
TWL_CODE bool nandMount(void) { TWL_CODE bool nandMount(void) {
fatMountSimple("nand", &io_dsi_nand); fatMountSimple("nand", &io_dsi_nand);
if (nandFound()) { if (nandFound()) {
nandMountedDone = true;
struct statvfs st; struct statvfs st;
if (statvfs("nand:/", &st) == 0) { if (statvfs("nand:/", &st) == 0) {
nandSize = st.f_bsize * st.f_blocks; nandSize = st.f_bsize * st.f_blocks;
@ -157,7 +157,7 @@ TWL_CODE bool sdMount(void) {
if (sdFound()) { if (sdFound()) {
sdMountedDone = true; sdMountedDone = true;
fatGetVolumeLabel("sd", sdLabel); fatGetVolumeLabel("sd", sdLabel);
fixLabel(false); fixLabel(&sdLabel[0]);
struct statvfs st; struct statvfs st;
if (statvfs("sd:/", &st) == 0) { if (statvfs("sd:/", &st) == 0) {
sdSize = st.f_bsize * st.f_blocks; sdSize = st.f_bsize * st.f_blocks;
@ -296,7 +296,7 @@ TWL_CODE bool twl_flashcardMount(void) {
if (flashcardFound()) { if (flashcardFound()) {
fatGetVolumeLabel("fat", fatLabel); fatGetVolumeLabel("fat", fatLabel);
fixLabel(true); fixLabel(&fatLabel[0]);
struct statvfs st; struct statvfs st;
if (statvfs("fat:/", &st) == 0) { if (statvfs("fat:/", &st) == 0) {
fatSize = st.f_bsize * st.f_blocks; fatSize = st.f_bsize * st.f_blocks;
@ -312,7 +312,7 @@ bool flashcardMount(void) {
fatInitDefault(); fatInitDefault();
if (flashcardFound()) { if (flashcardFound()) {
fatGetVolumeLabel("fat", fatLabel); fatGetVolumeLabel("fat", fatLabel);
fixLabel(true); fixLabel(&fatLabel[0]);
struct statvfs st; struct statvfs st;
if (statvfs("fat:/", &st) == 0) { if (statvfs("fat:/", &st) == 0) {
fatSize = st.f_bsize * st.f_blocks; fatSize = st.f_bsize * st.f_blocks;
@ -343,3 +343,27 @@ TWL_CODE void ramdrive2Mount(void) {
fatMountSimple("ram2", &io_ram_drive2); fatMountSimple("ram2", &io_ram_drive2);
ramdrive2Mounted = (access("ram2:/", F_OK) == 0); ramdrive2Mounted = (access("ram2:/", F_OK) == 0);
} }
bool imgMount(const char* imgName) {
extern const char* currentImgName;
currentImgName = imgName;
fatMountSimple("img", &io_img);
if (imgFound()) {
fatGetVolumeLabel("img", imgLabel);
fixLabel(&imgLabel[0]);
struct statvfs st;
if (statvfs("img:/", &st) == 0) {
imgSize = st.f_bsize * st.f_blocks;
}
return true;
}
return false;
}
void imgUnmount(void) {
fatUnmount("img");
imgLabel[0] = '\0';
imgSize = 0;
imgMounted = false;
}

View File

@ -4,23 +4,26 @@
extern u8 stored_SCFG_MC; extern u8 stored_SCFG_MC;
extern bool nandMounted; extern bool nandMounted;
extern bool nandMountedDone;
extern bool sdMounted; extern bool sdMounted;
extern bool sdMountedDone; // true if SD mount is successful once extern bool sdMountedDone; // true if SD mount is successful once
extern bool flashcardMounted; extern bool flashcardMounted;
extern bool ramdrive1Mounted; extern bool ramdrive1Mounted;
extern bool ramdrive2Mounted; extern bool ramdrive2Mounted;
extern bool imgMounted;
extern bool nitroMounted; extern bool nitroMounted;
extern int currentDrive; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND extern int currentDrive; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2, 4 == NAND, 5 == NitroFS, 6 == FAT IMG
extern int nitroCurrentDrive; extern int nitroCurrentDrive;
extern int imgCurrentDrive;
extern char sdLabel[12]; extern char sdLabel[12];
extern char fatLabel[12]; extern char fatLabel[12];
extern char imgLabel[12];
extern u32 nandSize; extern u32 nandSize;
extern u64 sdSize; extern u64 sdSize;
extern u64 fatSize; extern u64 fatSize;
extern u64 imgSize;
extern void printDriveBytes(u64 bytes); extern void printDriveBytes(u64 bytes);
extern const char* getDrivePath(void); extern const char* getDrivePath(void);
@ -29,6 +32,7 @@ extern bool nandFound(void);
extern bool sdFound(void); extern bool sdFound(void);
extern bool flashcardFound(void); extern bool flashcardFound(void);
extern bool bothSDandFlashcard(void); extern bool bothSDandFlashcard(void);
extern bool imgFound(void);
extern bool nandMount(void); extern bool nandMount(void);
extern void nandUnmount(void); extern void nandUnmount(void);
extern bool sdMount(void); extern bool sdMount(void);
@ -37,5 +41,7 @@ extern bool flashcardMount(void);
extern void flashcardUnmount(void); extern void flashcardUnmount(void);
extern void ramdrive1Mount(void); extern void ramdrive1Mount(void);
extern void ramdrive2Mount(void); extern void ramdrive2Mount(void);
extern bool imgMount(const char* imgName);
extern void imgUnmount(void);
#endif //FLASHCARD_H #endif //FLASHCARD_H

View File

@ -234,6 +234,16 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
assignedOp[maxCursors] = 3; assignedOp[maxCursors] = 3;
printf(" Mount NitroFS\n"); printf(" Mount NitroFS\n");
} }
else
if((entry->name.substr(entry->name.find_last_of(".") + 1) == "img")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "IMG")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "sd")
|| (entry->name.substr(entry->name.find_last_of(".") + 1) == "SD"))
{
maxCursors++;
assignedOp[maxCursors] = 5;
printf(" Mount as FAT image\n");
}
} }
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 4; assignedOp[maxCursors] = 4;
@ -328,9 +338,17 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
if (nitroMounted) { if (nitroMounted) {
chdir("nitro:/"); chdir("nitro:/");
nitroCurrentDrive = currentDrive; nitroCurrentDrive = currentDrive;
currentDrive = 5;
} }
} else if (assignedOp[optionOffset] == 4) { } else if (assignedOp[optionOffset] == 4) {
changeFileAttribs(entry); changeFileAttribs(entry);
} else if (assignedOp[optionOffset] == 5) {
imgMounted = imgMount(entry->name.c_str());
if (imgMounted) {
chdir("img:/");
imgCurrentDrive = currentDrive;
currentDrive = 6;
}
} }
return assignedOp[optionOffset]; return assignedOp[optionOffset];
} }
@ -550,8 +568,7 @@ string browseForFile (void) {
if ((!(held & KEY_R) && (pressed & KEY_A)) if ((!(held & KEY_R) && (pressed & KEY_A))
|| (!entry->isDirectory && (held & KEY_R) && (pressed & KEY_A))) { || (!entry->isDirectory && (held & KEY_R) && (pressed & KEY_A))) {
if (((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, getDrivePath()) == 0)) if ((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, getDrivePath()) == 0))
|| ((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, "nitro:/") == 0)))
{ {
screenMode = 0; screenMode = 0;
return "null"; return "null";
@ -567,9 +584,9 @@ string browseForFile (void) {
if (getOp == 0) { if (getOp == 0) {
// Return the chosen file // Return the chosen file
return entry->name; return entry->name;
} else if (getOp == 1 || getOp == 2 || (getOp == 3 && nitroMounted)) { } else if (getOp == 1 || getOp == 2 || (getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) {
getDirectoryContents (dirContents); // Refresh directory listing getDirectoryContents (dirContents); // Refresh directory listing
if (getOp == 3 && nitroMounted) { if ((getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) {
screenOffset = 0; screenOffset = 0;
fileOffset = 0; fileOffset = 0;
} }
@ -599,7 +616,7 @@ string browseForFile (void) {
} }
if (pressed & KEY_B) { if (pressed & KEY_B) {
if ((strcmp (path, getDrivePath()) == 0) || (strcmp (path, "nitro:/") == 0)) { if (strcmp (path, getDrivePath()) == 0) {
screenMode = 0; screenMode = 0;
return "null"; return "null";
} }

64
arm9/source/imgio.c Normal file
View File

@ -0,0 +1,64 @@
#include <nds.h>
#include <nds/disc_io.h>
#include <stdio.h>
#define SECTOR_SIZE 512
const char* currentImgName;
static FILE* imgFile[2];
bool img_startup() {
imgFile[0] = fopen(currentImgName, "rb");
if (imgFile[0]) {
//imgFile[1] = fopen(currentImgName, "wb");
return true;
}
return false;
}
bool img_is_inserted() {
if (imgFile[0]) {
return true;
}
return false;
}
bool img_read_sectors(sec_t sector, sec_t numSectors, void *buffer) {
if (!imgFile[0]) return false;
fseek(imgFile[0], (sector << 9), SEEK_SET);
fread(buffer, 1, (numSectors << 9), imgFile[0]);
return true;
}
bool img_write_sectors(sec_t sector, sec_t numSectors, const void *buffer) {
/*if (!imgFile[1]) return false;
fseek(imgFile[1], (sector << 9), SEEK_SET);
fwrite(buffer, 1, (numSectors << 9), imgFile[1]);
return true;*/
return false;
}
bool img_clear_status() {
return true;
}
bool img_shutdown() {
fclose(imgFile[0]);
fclose(imgFile[1]);
return true;
}
const DISC_INTERFACE io_img = {
('I' << 24) | ('M' << 16) | ('G' << 8) | 'F',
//FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE,
FEATURE_MEDIUM_CANREAD,
img_startup,
img_is_inserted,
img_read_sectors,
img_write_sectors,
img_clear_status,
img_shutdown
};

6
arm9/source/imgio.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#include <nds.h>
#include <nds/disc_io.h>
extern const DISC_INTERFACE io_img;

View File

@ -139,7 +139,7 @@ int main(int argc, char **argv) {
bool yHeld = false; bool yHeld = false;
sprintf(titleName, "GodMode9i v%i.%i.%i", 2, 2, 1); sprintf(titleName, "GodMode9i v%i.%i.%i", 2, 3, 0);
// initialize video mode // initialize video mode
videoSetMode(MODE_4_2D); videoSetMode(MODE_4_2D);