Skip to content

Commit

Permalink
Merge pull request #7 from d0k3/ramdrive
Browse files Browse the repository at this point in the history
Enable RAM drive feature
  • Loading branch information
d0k3 committed May 2, 2016
2 parents 6bd1cac + 51e7361 commit f448f48
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 17 deletions.
2 changes: 1 addition & 1 deletion source/fatfs/ffconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) */


Expand Down
46 changes: 40 additions & 6 deletions source/fatfs/image.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
#include "image.h"
#include "platform.h"
#include "fatfs/ff.h"

FIL mount_file;
u32 mount_state = 0;
#define RAMDRV_BUFFER_O3DS ((u8*)0x22200000) // in O3DS FCRAM
#define RAMDRV_SIZE_O3DS (0x01C00000) // 28MB
#define RAMDRV_BUFFER_N3DS ((u8*)0x28000000) // in N3DS FCRAM
#define RAMDRV_SIZE_N3DS (0x08000000) // 128MB

static u8* ramdrv_buffer = NULL;
static u32 ramdrv_size = 0;

static FIL mount_file;
static u32 mount_state = 0;

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;
Expand All @@ -21,6 +35,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);
Expand All @@ -29,11 +48,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) {
Expand Down Expand Up @@ -71,9 +92,22 @@ u32 IdentifyImage(const char* path) {
return 0;
}

u32 MountRamDrive(void) {
if (mount_state && (mount_state != IMG_RAMDRV))
f_close(&mount_file);
if (GetUnitPlatform() == PLATFORM_3DS) {
ramdrv_buffer = RAMDRV_BUFFER_O3DS;
ramdrv_size = RAMDRV_SIZE_O3DS;
} else {
ramdrv_buffer = RAMDRV_BUFFER_N3DS;
ramdrv_size = RAMDRV_SIZE_N3DS;
}
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;
Expand Down
6 changes: 4 additions & 2 deletions source/fatfs/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
12 changes: 10 additions & 2 deletions source/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 if required
f_mount(NULL, fsname, 1);
fs_mounted[7] = (f_mount(fs + 7, "7:", 1) == FR_OK);
}
}
return true;
}
Expand Down Expand Up @@ -82,6 +86,8 @@ bool CheckWritePermissions(const char* path) {
(GetVirtualSource(path) == VRT_SYSNAND) ? 1 :
(GetVirtualSource(path) == VRT_EMUNAND) ? 4 : 7;
else return false;
} else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) {
pdrv = 0; // ...and another hack
}

if ((pdrv >= 1) && (pdrv <= 3) && (write_permission_level < 3)) {
Expand Down Expand Up @@ -720,6 +726,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;
Expand Down
15 changes: 9 additions & 6 deletions source/godmode.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "virtual.h"
#include "image.h"

#define VERSION "0.3.9"
#define VERSION "0.4.0"

#define N_PANES 2
#define IMG_DRV "789I"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -407,7 +408,8 @@ u32 GodMode() {
}
} else if (switched && (pad_state & BUTTON_B)) { // unmount SD card
DeinitExtFS();
MountImage(NULL);
if (GetMountState() != IMG_RAMDRV)
MountImage(NULL);
DeinitSDCardFS();
clipboard->n_entries = 0;
memset(panedata, 0x00, N_PANES * sizeof(PaneData));
Expand Down Expand Up @@ -463,7 +465,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))
Expand Down

0 comments on commit f448f48

Please sign in to comment.