Skip to content

Commit f448f48

Browse files
committed
Merge pull request #7 from d0k3/ramdrive
Enable RAM drive feature
2 parents 6bd1cac + 51e7361 commit f448f48

File tree

5 files changed

+64
-17
lines changed

5 files changed

+64
-17
lines changed

source/fatfs/ffconf.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
4848

4949

50-
#define _USE_MKFS 0
50+
#define _USE_MKFS 1
5151
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
5252

5353

source/fatfs/image.c

+40-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
#include "image.h"
2+
#include "platform.h"
23
#include "fatfs/ff.h"
34

4-
FIL mount_file;
5-
u32 mount_state = 0;
5+
#define RAMDRV_BUFFER_O3DS ((u8*)0x22200000) // in O3DS FCRAM
6+
#define RAMDRV_SIZE_O3DS (0x01C00000) // 28MB
7+
#define RAMDRV_BUFFER_N3DS ((u8*)0x28000000) // in N3DS FCRAM
8+
#define RAMDRV_SIZE_N3DS (0x08000000) // 128MB
9+
10+
static u8* ramdrv_buffer = NULL;
11+
static u32 ramdrv_size = 0;
12+
13+
static FIL mount_file;
14+
static u32 mount_state = 0;
615

716
int ReadImageSectors(u8* buffer, u32 sector, u32 count) {
817
UINT bytes_read;
918
UINT ret;
1019
if (!count) return -1;
20+
if (mount_state == IMG_RAMDRV) {
21+
if ((sector + count) * 0x200 > ramdrv_size) return -1;
22+
memcpy(buffer, ramdrv_buffer + (sector * 0x200), count * 0x200);
23+
return 0;
24+
}
1125
if (!mount_state) return FR_INVALID_OBJECT;
1226
if (f_tell(&mount_file) != sector * 0x200) {
1327
if (f_size(&mount_file) < sector * 0x200) return -1;
14-
f_lseek(&mount_file, sector * 0x200);
28+
f_lseek(&mount_file, sector * 0x200);
1529
}
1630
ret = f_read(&mount_file, buffer, count * 0x200, &bytes_read);
1731
return (ret != 0) ? (int) ret : (bytes_read != count * 0x200) ? -1 : 0;
@@ -21,6 +35,11 @@ int WriteImageSectors(const u8* buffer, u32 sector, u32 count) {
2135
UINT bytes_written;
2236
UINT ret;
2337
if (!count) return -1;
38+
if (mount_state == IMG_RAMDRV) {
39+
if ((sector + count) * 0x200 > ramdrv_size) return -1;
40+
memcpy(ramdrv_buffer + (sector * 0x200), buffer, count * 0x200);
41+
return 0;
42+
}
2443
if (!mount_state) return FR_INVALID_OBJECT;
2544
if (f_tell(&mount_file) != sector * 0x200)
2645
f_lseek(&mount_file, sector * 0x200);
@@ -29,11 +48,13 @@ int WriteImageSectors(const u8* buffer, u32 sector, u32 count) {
2948
}
3049

3150
int SyncImage(void) {
32-
return (mount_state) ? f_sync(&mount_file) : FR_INVALID_OBJECT;
51+
return (mount_state == IMG_RAMDRV) ? FR_OK :
52+
mount_state ? f_sync(&mount_file) : FR_INVALID_OBJECT;
3353
}
3454

3555
u64 GetMountSize(void) {
36-
return mount_state ? f_size(&mount_file) : 0;
56+
return (mount_state == IMG_RAMDRV) ? ramdrv_size :
57+
mount_state ? f_size(&mount_file) : 0;
3758
}
3859

3960
u32 GetMountState(void) {
@@ -71,9 +92,22 @@ u32 IdentifyImage(const char* path) {
7192
return 0;
7293
}
7394

95+
u32 MountRamDrive(void) {
96+
if (mount_state && (mount_state != IMG_RAMDRV))
97+
f_close(&mount_file);
98+
if (GetUnitPlatform() == PLATFORM_3DS) {
99+
ramdrv_buffer = RAMDRV_BUFFER_O3DS;
100+
ramdrv_size = RAMDRV_SIZE_O3DS;
101+
} else {
102+
ramdrv_buffer = RAMDRV_BUFFER_N3DS;
103+
ramdrv_size = RAMDRV_SIZE_N3DS;
104+
}
105+
return (mount_state = IMG_RAMDRV);
106+
}
107+
74108
u32 MountImage(const char* path) {
75109
if (mount_state) {
76-
f_close(&mount_file);
110+
if (mount_state != IMG_RAMDRV) f_close(&mount_file);
77111
mount_state = 0;
78112
}
79113
if (!path || !IdentifyImage(path)) return 0;

source/fatfs/image.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
#include "common.h"
44

5-
#define IMG_FAT 1
6-
#define IMG_NAND 2
5+
#define IMG_FAT 1
6+
#define IMG_NAND 2
7+
#define IMG_RAMDRV 3
78

89
int ReadImageSectors(u8* buffer, u32 sector, u32 count);
910
int WriteImageSectors(const u8* buffer, u32 sector, u32 count);
@@ -12,4 +13,5 @@ int SyncImage(void);
1213
u64 GetMountSize(void);
1314
u32 GetMountState(void);
1415
u32 IdentifyImage(const char* path);
16+
u32 MountRamDrive(void);
1517
u32 MountImage(const char* path);

source/fs.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ bool InitExtFS() {
3636
for (u32 i = 1; i < NORM_FS; i++) {
3737
char fsname[8];
3838
snprintf(fsname, 7, "%lu:", i);
39-
if (f_mount(fs + i, fsname, 1) == FR_OK)
40-
fs_mounted[i] = true;
39+
fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK);
40+
if ((i == 7) && !fs_mounted[7] && (GetMountState() == IMG_RAMDRV)) {
41+
f_mkfs("7:", 0, 0); // format ramdrive if required
42+
f_mount(NULL, fsname, 1);
43+
fs_mounted[7] = (f_mount(fs + 7, "7:", 1) == FR_OK);
44+
}
4145
}
4246
return true;
4347
}
@@ -82,6 +86,8 @@ bool CheckWritePermissions(const char* path) {
8286
(GetVirtualSource(path) == VRT_SYSNAND) ? 1 :
8387
(GetVirtualSource(path) == VRT_EMUNAND) ? 4 : 7;
8488
else return false;
89+
} else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) {
90+
pdrv = 0; // ...and another hack
8591
}
8692

8793
if ((pdrv >= 1) && (pdrv <= 3) && (write_permission_level < 3)) {
@@ -720,6 +726,8 @@ bool GetRootDirContentsWorker(DirStruct* contents) {
720726
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]);
721727
if ((GetMountState() == IMG_FAT) && (pdrv == 7)) // FAT image special handling
722728
snprintf(entry->path + 4, 32, "[7:] FAT IMAGE");
729+
else if ((GetMountState() == IMG_RAMDRV) && (pdrv == 7)) // RAM drive special handling
730+
snprintf(entry->path + 4, 32, "[7:] RAMDRIVE");
723731
entry->name = entry->path + 4;
724732
entry->size = GetTotalSpace(entry->path);
725733
entry->type = T_ROOT;

source/godmode.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "virtual.h"
88
#include "image.h"
99

10-
#define VERSION "0.3.9"
10+
#define VERSION "0.4.0"
1111

1212
#define N_PANES 2
1313
#define IMG_DRV "789I"
@@ -41,8 +41,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
4141
u32 state_curr =
4242
((*curr_path) ? (1<<0) : 0) |
4343
((clipboard->n_entries) ? (1<<1) : 0) |
44-
((GetMountState()) ? (1<<2) : 0) |
45-
(curr_pane<<3);
44+
(GetMountState()<<2) |
45+
(curr_pane<<4);
4646

4747
if (state_prev != state_curr) {
4848
ClearScreenF(true, false, COLOR_STD_BG);
@@ -108,7 +108,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
108108
((GetWritePermissions() <= 1) ? "X - Unlock EmuNAND / image writing\nY - Unlock SysNAND writing\nR+B - Unmount SD card\n" :
109109
(GetWritePermissions() == 2) ? "X - Relock EmuNAND / image writing\nY - Unlock SysNAND writing\nR+B - Unmount SD card\n" :
110110
"X - Relock EmuNAND writing\nY - Relock SysNAND writing\nR+B - Unmount SD card\n"),
111-
(GetMountState() && !*curr_path) ? "R+X - Unmount image\n" : "",
111+
(*curr_path) ? "" : ((GetMountState() == IMG_RAMDRV) ? "R+X - Unmount RAM drive\n" :
112+
(GetMountState()) ? "R+X - Unmount image\n" : "R+X - Mount RAM drive\n"),
112113
"R+L - Make a Screenshot\n",
113114
"R+\x1B\x1A - Switch to prev/next pane\n",
114115
(clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full
@@ -407,7 +408,8 @@ u32 GodMode() {
407408
}
408409
} else if (switched && (pad_state & BUTTON_B)) { // unmount SD card
409410
DeinitExtFS();
410-
MountImage(NULL);
411+
if (GetMountState() != IMG_RAMDRV)
412+
MountImage(NULL);
411413
DeinitSDCardFS();
412414
clipboard->n_entries = 0;
413415
memset(panedata, 0x00, N_PANES * sizeof(PaneData));
@@ -463,7 +465,8 @@ u32 GodMode() {
463465
if (!(*current_path)) { // in the root folder...
464466
if (switched && !*current_path && (pad_state & BUTTON_X)) { // unmount image
465467
DeinitExtFS();
466-
MountImage(NULL);
468+
if (!GetMountState()) MountRamDrive();
469+
else MountImage(NULL);
467470
InitExtFS();
468471
GetDirContents(current_dir, current_path);
469472
if (clipboard->n_entries && (strcspn(clipboard->entry[0].path, IMG_DRV) == 0))

0 commit comments

Comments
 (0)