diff --git a/source/fatfs/ffconf.h b/source/fatfs/ffconf.h index 7512187..d4c0ea6 100644 --- a/source/fatfs/ffconf.h +++ b/source/fatfs/ffconf.h @@ -47,7 +47,7 @@ / f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */ -#define _USE_MKFS 0 +#define _USE_MKFS 1 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ diff --git a/source/fatfs/image.c b/source/fatfs/image.c index 4584823..20d1426 100644 --- a/source/fatfs/image.c +++ b/source/fatfs/image.c @@ -1,6 +1,9 @@ #include "image.h" #include "fatfs/ff.h" +#define RAMDRV_BUFFER ((u8*)0x22200000) +#define RAMDRV_SIZE (0x01C00000) // 28MB + FIL mount_file; u32 mount_state = 0; @@ -8,10 +11,15 @@ int ReadImageSectors(u8* buffer, u32 sector, u32 count) { UINT bytes_read; UINT ret; if (!count) return -1; + if (mount_state == IMG_RAMDRV) { + if ((sector + count) * 0x200 > RAMDRV_SIZE) return -1; + memcpy(buffer, RAMDRV_BUFFER + (sector * 0x200), count * 0x200); + return 0; + } if (!mount_state) return FR_INVALID_OBJECT; if (f_tell(&mount_file) != sector * 0x200) { if (f_size(&mount_file) < sector * 0x200) return -1; - f_lseek(&mount_file, sector * 0x200); + f_lseek(&mount_file, sector * 0x200); } ret = f_read(&mount_file, buffer, count * 0x200, &bytes_read); return (ret != 0) ? (int) ret : (bytes_read != count * 0x200) ? -1 : 0; @@ -21,6 +29,11 @@ int WriteImageSectors(const u8* buffer, u32 sector, u32 count) { UINT bytes_written; UINT ret; if (!count) return -1; + if (mount_state == IMG_RAMDRV) { + if ((sector + count) * 0x200 > RAMDRV_SIZE) return -1; + memcpy(RAMDRV_BUFFER + (sector * 0x200), buffer, count * 0x200); + return 0; + } if (!mount_state) return FR_INVALID_OBJECT; if (f_tell(&mount_file) != sector * 0x200) f_lseek(&mount_file, sector * 0x200); @@ -29,11 +42,13 @@ int WriteImageSectors(const u8* buffer, u32 sector, u32 count) { } int SyncImage(void) { - return (mount_state) ? f_sync(&mount_file) : FR_INVALID_OBJECT; + return (mount_state == IMG_RAMDRV) ? FR_OK : + mount_state ? f_sync(&mount_file) : FR_INVALID_OBJECT; } u64 GetMountSize(void) { - return mount_state ? f_size(&mount_file) : 0; + return (mount_state == IMG_RAMDRV) ? RAMDRV_SIZE : + mount_state ? f_size(&mount_file) : 0; } u32 GetMountState(void) { @@ -71,9 +86,15 @@ u32 IdentifyImage(const char* path) { return 0; } +u32 MountRamDrive(void) { + if (mount_state && (mount_state != IMG_RAMDRV)) + f_close(&mount_file); + return (mount_state = IMG_RAMDRV); +} + u32 MountImage(const char* path) { if (mount_state) { - f_close(&mount_file); + if (mount_state != IMG_RAMDRV) f_close(&mount_file); mount_state = 0; } if (!path || !IdentifyImage(path)) return 0; diff --git a/source/fatfs/image.h b/source/fatfs/image.h index 18dc5cd..98fd196 100644 --- a/source/fatfs/image.h +++ b/source/fatfs/image.h @@ -2,8 +2,9 @@ #include "common.h" -#define IMG_FAT 1 -#define IMG_NAND 2 +#define IMG_FAT 1 +#define IMG_NAND 2 +#define IMG_RAMDRV 3 int ReadImageSectors(u8* buffer, u32 sector, u32 count); int WriteImageSectors(const u8* buffer, u32 sector, u32 count); @@ -12,4 +13,5 @@ int SyncImage(void); u64 GetMountSize(void); u32 GetMountState(void); u32 IdentifyImage(const char* path); +u32 MountRamDrive(void); u32 MountImage(const char* path); diff --git a/source/fs.c b/source/fs.c index d3ff698..fa72956 100644 --- a/source/fs.c +++ b/source/fs.c @@ -36,8 +36,12 @@ bool InitExtFS() { for (u32 i = 1; i < NORM_FS; i++) { char fsname[8]; snprintf(fsname, 7, "%lu:", i); - if (f_mount(fs + i, fsname, 1) == FR_OK) - fs_mounted[i] = true; + fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); + if ((i == 7) && !fs_mounted[7] && (GetMountState() == IMG_RAMDRV)) { + f_mkfs("7:", 0, 0); // format ramdrive + f_mount(NULL, fsname, 1); + fs_mounted[7] = (f_mount(fs + 7, "7:", 1) == FR_OK); + } } return true; } @@ -720,6 +724,8 @@ bool GetRootDirContentsWorker(DirStruct* contents) { snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]); if ((GetMountState() == IMG_FAT) && (pdrv == 7)) // FAT image special handling snprintf(entry->path + 4, 32, "[7:] FAT IMAGE"); + else if ((GetMountState() == IMG_RAMDRV) && (pdrv == 7)) // RAM drive special handling + snprintf(entry->path + 4, 32, "[7:] RAMDRIVE"); entry->name = entry->path + 4; entry->size = GetTotalSpace(entry->path); entry->type = T_ROOT; diff --git a/source/godmode.c b/source/godmode.c index 3c0d936..dc7bbd6 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -41,8 +41,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c u32 state_curr = ((*curr_path) ? (1<<0) : 0) | ((clipboard->n_entries) ? (1<<1) : 0) | - ((GetMountState()) ? (1<<2) : 0) | - (curr_pane<<3); + (GetMountState()<<2) | + (curr_pane<<4); if (state_prev != state_curr) { ClearScreenF(true, false, COLOR_STD_BG); @@ -108,7 +108,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c ((GetWritePermissions() <= 1) ? "X - Unlock EmuNAND / image writing\nY - Unlock SysNAND writing\nR+B - Unmount SD card\n" : (GetWritePermissions() == 2) ? "X - Relock EmuNAND / image writing\nY - Unlock SysNAND writing\nR+B - Unmount SD card\n" : "X - Relock EmuNAND writing\nY - Relock SysNAND writing\nR+B - Unmount SD card\n"), - (GetMountState() && !*curr_path) ? "R+X - Unmount image\n" : "", + (*curr_path) ? "" : ((GetMountState() == IMG_RAMDRV) ? "R+X - Unmount RAM drive\n" : + (GetMountState()) ? "R+X - Unmount image\n" : "R+X - Mount RAM drive\n"), "R+L - Make a Screenshot\n", "R+\x1B\x1A - Switch to prev/next pane\n", (clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full @@ -463,7 +464,8 @@ u32 GodMode() { if (!(*current_path)) { // in the root folder... if (switched && !*current_path && (pad_state & BUTTON_X)) { // unmount image DeinitExtFS(); - MountImage(NULL); + if (!GetMountState()) MountRamDrive(); + else MountImage(NULL); InitExtFS(); GetDirContents(current_dir, current_path); if (clipboard->n_entries && (strcspn(clipboard->entry[0].path, IMG_DRV) == 0))