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 ENTRY_PAGE_LENGTH 10
#define sizeOfdmAssignedOp 8
using namespace std;
//static bool ramDumped = false;
@ -47,7 +49,7 @@ bool flashcardMountSkipped = true;
static bool flashcardMountRan = true;
static bool dmTextPrinted = false;
static int dmCursorPosition = 0;
static int dmAssignedOp[7] = {-1};
static int dmAssignedOp[sizeOfdmAssignedOp] = {-1};
static int dmMaxCursors = -1;
static u8 gbaFixedValue = 0;
@ -118,7 +120,8 @@ void dm_drawTopScreen(void) {
|| (flashcardMounted && nitroCurrentDrive==1)
|| (ramdrive1Mounted && nitroCurrentDrive==2)
|| (ramdrive2Mounted && nitroCurrentDrive==3)
|| (nandMounted && nitroCurrentDrive==4))
|| (nandMounted && nitroCurrentDrive==4)
|| (imgMounted && nitroCurrentDrive==6))
{
// Do nothing
}
@ -135,6 +138,23 @@ void dm_drawTopScreen(void) {
printf ("[ram2:] RAMDRIVE");
} else if (dmAssignedOp[i] == 7) {
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, ");
printDriveBytes(nandSize);
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);
}
for (int i = 0; i < 6; i++) {
for (int i = 0; i < sizeOfdmAssignedOp; i++) {
dmAssignedOp[i] = -1;
}
dmMaxCursors = -1;
@ -243,6 +268,10 @@ void driveMenu (void) {
dmMaxCursors++;
dmAssignedOp[dmMaxCursors] = 6;
}
if (imgMounted) {
dmMaxCursors++;
dmAssignedOp[dmMaxCursors] = 8;
}
if (expansionPakFound
|| (io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA)
|| (isDSiMode() && !arm7SCFGLocked && !(REG_SCFG_MC & BIT(0)))) {
@ -334,10 +363,11 @@ void driveMenu (void) {
|| (flashcardMounted && nitroCurrentDrive==1)
|| (ramdrive1Mounted && nitroCurrentDrive==2)
|| (ramdrive2Mounted && nitroCurrentDrive==3)
|| (nandMounted && nitroCurrentDrive==4))
|| (nandMounted && nitroCurrentDrive==4)
|| (imgMounted && nitroCurrentDrive==6))
{
dmTextPrinted = false;
currentDrive = nitroCurrentDrive;
currentDrive = 5;
chdir("nitro:/");
screenMode = 1;
break;
@ -363,6 +393,19 @@ void driveMenu (void) {
chdir("nand:/");
screenMode = 1;
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 "ramdrive-include.h"
#include "nandio.h"
#include "imgio.h"
#include "tonccpy.h"
static sNDSHeader nds;
@ -20,23 +21,26 @@ u8 stored_SCFG_MC = 0;
static bool slot1Enabled = true;
bool nandMounted = false;
bool nandMountedDone = false;
bool sdMounted = false;
bool sdMountedDone = false; // true if SD mount is successful once
bool flashcardMounted = false;
bool ramdrive1Mounted = false;
bool ramdrive2Mounted = false;
bool imgMounted = 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 imgCurrentDrive = 0;
char sdLabel[12];
char fatLabel[12];
char imgLabel[12];
u32 nandSize = 0;
u64 sdSize = 0;
u64 fatSize = 0;
u64 imgSize = 0;
static int getGbNumber(u64 bytes) {
int gbNumber = 0;
@ -87,28 +91,21 @@ const char* getDrivePath(void) {
return "ram2:/";
case 4:
return "nand:/";
case 5:
return "nitro:/";
case 6:
return "img:/";
}
return "";
}
void fixLabel(bool fat) {
if (fat) {
for (int i = 0; i < 12; i++) {
if (((fatLabel[i] == ' ') && (fatLabel[i+1] == ' ') && (fatLabel[i+2] == ' '))
|| ((fatLabel[i] == ' ') && (fatLabel[i+1] == ' '))
|| (fatLabel[i] == ' ')) {
fatLabel[i] = '\0';
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;
}
void fixLabel(char* label) {
for (int i = 0; i < 12; i++) {
if (((label[i] == ' ') && (label[i+1] == ' ') && (label[i+2] == ' '))
|| ((label[i] == ' ') && (label[i+1] == ' '))
|| (label[i] == ' ')) {
label[i] = '\0';
break;
}
}
}
@ -133,10 +130,13 @@ bool bothSDandFlashcard(void) {
}
}
bool imgFound(void) {
return (access("img:/", F_OK) == 0);
}
TWL_CODE bool nandMount(void) {
fatMountSimple("nand", &io_dsi_nand);
if (nandFound()) {
nandMountedDone = true;
struct statvfs st;
if (statvfs("nand:/", &st) == 0) {
nandSize = st.f_bsize * st.f_blocks;
@ -157,7 +157,7 @@ TWL_CODE bool sdMount(void) {
if (sdFound()) {
sdMountedDone = true;
fatGetVolumeLabel("sd", sdLabel);
fixLabel(false);
fixLabel(&sdLabel[0]);
struct statvfs st;
if (statvfs("sd:/", &st) == 0) {
sdSize = st.f_bsize * st.f_blocks;
@ -296,7 +296,7 @@ TWL_CODE bool twl_flashcardMount(void) {
if (flashcardFound()) {
fatGetVolumeLabel("fat", fatLabel);
fixLabel(true);
fixLabel(&fatLabel[0]);
struct statvfs st;
if (statvfs("fat:/", &st) == 0) {
fatSize = st.f_bsize * st.f_blocks;
@ -312,7 +312,7 @@ bool flashcardMount(void) {
fatInitDefault();
if (flashcardFound()) {
fatGetVolumeLabel("fat", fatLabel);
fixLabel(true);
fixLabel(&fatLabel[0]);
struct statvfs st;
if (statvfs("fat:/", &st) == 0) {
fatSize = st.f_bsize * st.f_blocks;
@ -343,3 +343,27 @@ TWL_CODE void ramdrive2Mount(void) {
fatMountSimple("ram2", &io_ram_drive2);
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 bool nandMounted;
extern bool nandMountedDone;
extern bool sdMounted;
extern bool sdMountedDone; // true if SD mount is successful once
extern bool flashcardMounted;
extern bool ramdrive1Mounted;
extern bool ramdrive2Mounted;
extern bool imgMounted;
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 imgCurrentDrive;
extern char sdLabel[12];
extern char fatLabel[12];
extern char imgLabel[12];
extern u32 nandSize;
extern u64 sdSize;
extern u64 fatSize;
extern u64 imgSize;
extern void printDriveBytes(u64 bytes);
extern const char* getDrivePath(void);
@ -29,6 +32,7 @@ extern bool nandFound(void);
extern bool sdFound(void);
extern bool flashcardFound(void);
extern bool bothSDandFlashcard(void);
extern bool imgFound(void);
extern bool nandMount(void);
extern void nandUnmount(void);
extern bool sdMount(void);
@ -37,5 +41,7 @@ extern bool flashcardMount(void);
extern void flashcardUnmount(void);
extern void ramdrive1Mount(void);
extern void ramdrive2Mount(void);
extern bool imgMount(const char* imgName);
extern void imgUnmount(void);
#endif //FLASHCARD_H

View File

@ -234,6 +234,16 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
assignedOp[maxCursors] = 3;
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++;
assignedOp[maxCursors] = 4;
@ -328,9 +338,17 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
if (nitroMounted) {
chdir("nitro:/");
nitroCurrentDrive = currentDrive;
currentDrive = 5;
}
} else if (assignedOp[optionOffset] == 4) {
changeFileAttribs(entry);
} else if (assignedOp[optionOffset] == 5) {
imgMounted = imgMount(entry->name.c_str());
if (imgMounted) {
chdir("img:/");
imgCurrentDrive = currentDrive;
currentDrive = 6;
}
}
return assignedOp[optionOffset];
}
@ -550,8 +568,7 @@ string browseForFile (void) {
if ((!(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))
|| ((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, "nitro:/") == 0)))
if ((strcmp (entry->name.c_str(), "..") == 0) && (strcmp (path, getDrivePath()) == 0))
{
screenMode = 0;
return "null";
@ -567,9 +584,9 @@ string browseForFile (void) {
if (getOp == 0) {
// Return the chosen file
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
if (getOp == 3 && nitroMounted) {
if ((getOp == 3 && nitroMounted) || (getOp == 5 && imgMounted)) {
screenOffset = 0;
fileOffset = 0;
}
@ -599,7 +616,7 @@ string browseForFile (void) {
}
if (pressed & KEY_B) {
if ((strcmp (path, getDrivePath()) == 0) || (strcmp (path, "nitro:/") == 0)) {
if (strcmp (path, getDrivePath()) == 0) {
screenMode = 0;
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;
sprintf(titleName, "GodMode9i v%i.%i.%i", 2, 2, 1);
sprintf(titleName, "GodMode9i v%i.%i.%i", 2, 3, 0);
// initialize video mode
videoSetMode(MODE_4_2D);