From 8a8271351c06a446b800d8fd6e6d50ba88108abf Mon Sep 17 00:00:00 2001 From: d0k3 Date: Tue, 5 Apr 2016 20:34:50 +0200 Subject: [PATCH] Allow mounting FAT (12/16/32) images --- source/fatfs/diskio.c | 68 ++++++++++++++++++++++++++++--------------- source/fatfs/ffconf.h | 2 +- source/fs.c | 5 +++- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/source/fatfs/diskio.c b/source/fatfs/diskio.c index 3419ca6..1e8fa0d 100644 --- a/source/fatfs/diskio.c +++ b/source/fatfs/diskio.c @@ -12,11 +12,12 @@ #include "nand.h" #include "sdmmc.h" -#define TYPE_SDCARD 0x00 +#define TYPE_NONE 0 #define TYPE_SYSNAND NAND_SYSNAND #define TYPE_EMUNAND NAND_EMUNAND #define TYPE_IMGNAND NAND_IMGNAND -#define TYPE_IMAGE 0xFF +#define TYPE_SDCARD (1<<4) +#define TYPE_IMAGE (1<<5) #define SUBTYPE_CTRN 0 #define SUBTYPE_CTRN_N 1 @@ -65,16 +66,32 @@ static BYTE nand_type_img = 0; /*-----------------------------------------------------------------------*/ -/* Get Drive Subtype helper */ +/* Get actual FAT partition type helper */ /*-----------------------------------------------------------------------*/ -SubtypeDesc* get_subtype_desc( +static inline BYTE get_partition_type( __attribute__((unused)) BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - BYTE type = DriveInfo[pdrv].type; - BYTE subtype = DriveInfo[pdrv].subtype; + if ((pdrv >= 7) && !nand_type_img) // special handling for FAT images + return (pdrv == 7) ? TYPE_IMAGE : TYPE_NONE; + return DriveInfo[pdrv].type; +} + + + +/*-----------------------------------------------------------------------*/ +/* Get Drive Subtype helper */ +/*-----------------------------------------------------------------------*/ + +static inline SubtypeDesc* get_subtype_desc( + __attribute__((unused)) + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + BYTE type = get_partition_type(pdrv); + BYTE subtype = (type) ? DriveInfo[pdrv].subtype : SUBTYPE_NONE; if (subtype == SUBTYPE_NONE) { return NULL; @@ -139,14 +156,16 @@ DRESULT disk_read ( UINT count /* Number of sectors to read */ ) { - BYTE type = DriveInfo[pdrv].type; + BYTE type = get_partition_type(pdrv); - if (type == TYPE_SDCARD) { - if (sdmmc_sdcard_readsectors(sector, count, buff)) { - return RES_PARERR; - } - } else if (type == TYPE_IMAGE) { + if (type == TYPE_NONE) { return RES_PARERR; + } else if (type == TYPE_SDCARD) { + if (sdmmc_sdcard_readsectors(sector, count, buff)) + return RES_PARERR; + } else if (type == TYPE_IMAGE) { + if (ReadImageSectors(buff, sector, count)) + return RES_PARERR; } else { SubtypeDesc* subtype = get_subtype_desc(pdrv); BYTE keyslot = subtype->keyslot; @@ -174,14 +193,16 @@ DRESULT disk_write ( UINT count /* Number of sectors to write */ ) { - BYTE type = DriveInfo[pdrv].type; + BYTE type = get_partition_type(pdrv); - if (type == TYPE_SDCARD) { - if (sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) { - return RES_PARERR; - } - } else if (type == TYPE_IMAGE) { + if (type == TYPE_NONE) { return RES_PARERR; + } else if (type == TYPE_SDCARD) { + if (sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) + return RES_PARERR; + } else if (type == TYPE_IMAGE) { + if (WriteImageSectors(buff, sector, count)) + return RES_PARERR; } else { SubtypeDesc* subtype = get_subtype_desc(pdrv); BYTE keyslot = subtype->keyslot; @@ -211,18 +232,18 @@ DRESULT disk_ioctl ( void *buff /* Buffer to send/receive control data */ ) { - BYTE type = DriveInfo[pdrv].type; + BYTE type = get_partition_type(pdrv); switch (cmd) { case GET_SECTOR_SIZE: *((DWORD*) buff) = 0x200; return RES_OK; case GET_SECTOR_COUNT: - if (type == TYPE_SDCARD) { + if (type == TYPE_SDCARD) { // SD card *((DWORD*) buff) = getMMCDevice(1)->total_size; - } else if (type == TYPE_IMAGE) { + } else if (type == TYPE_IMAGE) { // FAT image *((DWORD*) buff) = GetMountSize(); - } else { + } else if (type != TYPE_NONE) { // NAND *((DWORD*) buff) = get_subtype_desc(pdrv)->size; } return RES_OK; @@ -232,9 +253,10 @@ DRESULT disk_ioctl ( case CTRL_SYNC: if ((type == TYPE_IMAGE) || (type == TYPE_IMGNAND)) SyncImage(); - // nothing else to do here - sdmmc.c handles that + // nothing else to do here - sdmmc.c handles the rest return RES_OK; } + return RES_PARERR; } #endif diff --git a/source/fatfs/ffconf.h b/source/fatfs/ffconf.h index c267ec3..7512187 100644 --- a/source/fatfs/ffconf.h +++ b/source/fatfs/ffconf.h @@ -146,7 +146,7 @@ #define _STR_VOLUME_ID 0 -#define _VOLUME_STRS "sdcard","sysnand","systwln","systwlp","emunand","emutwln","emutwlp" +#define _VOLUME_STRS "sdcard","sysnand","systwln","systwlp","emunand","emutwln","emutwlp","imgnand","imgtwln","imgtwlp" /* _STR_VOLUME_ID option switches string volume ID feature. / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive / number in the path name. _VOLUME_STRS defines the drive ID strings for each diff --git a/source/fs.c b/source/fs.c index 3f38509..fa16d94 100644 --- a/source/fs.c +++ b/source/fs.c @@ -1,7 +1,8 @@ #include "ui.h" #include "fs.h" #include "virtual.h" -#include "fatfs/ff.h" +#include "image.h" +#include "ff.h" #define MAIN_BUFFER ((u8*)0x21200000) #define MAIN_BUFFER_SIZE (0x100000) // must be multiple of 0x200 @@ -596,6 +597,8 @@ bool GetRootDirContentsWorker(DirStruct* contents) { memset(entry->path, 0x00, 64); snprintf(entry->path + 0, 4, drvnum[pdrv]); 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"); entry->name = entry->path + 4; entry->size = GetTotalSpace(entry->path); entry->type = T_ROOT;