diff --git a/Makefile b/Makefile index 2206d9e..b95c12c 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ endif all: fathuman -fathuman: main.o fatfs/ff.o fatfs/option/cc932.o +fathuman: main.o fatfs/ff.o gcc $^ -o $@ $(LDFLAGS) %.o: %.c diff --git a/fatfs/ff.c b/fatfs/ff.c index ccf7114..e2ec872 100644 --- a/fatfs/ff.c +++ b/fatfs/ff.c @@ -117,7 +117,7 @@ #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of disk I/O functions */ - +#include @@ -456,6 +456,7 @@ typedef struct { #define DIR_Name 0 /* Short file name (11) */ #define DIR_Attr 11 /* Attribute (1) */ +#define DIR_HU68K_EXNAME 12 /* Human68k extended filename part (10) */ #define DIR_NTres 12 /* NT flag (1) */ #define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */ #define DIR_CrtTime 14 /* Created time (2) */ @@ -507,8 +508,16 @@ static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ #endif +#if _USE_HUMAN68K && _USE_LFN != 0 +#error Cannot use LFN feature with HUMAN68K +#endif + #if _USE_LFN == 0 /* No LFN feature */ +#if _USE_HUMAN68K +#define DEF_NAMEBUF BYTE sfn[22] +#else #define DEF_NAMEBUF BYTE sfn[12] +#endif #define INIT_BUF(dobj) (dobj).fn = sfn #define FREE_BUF() @@ -1539,8 +1548,14 @@ FRESULT dir_find ( // printf("mem_cmp(%c%c%c%c%c%c%c%c.%c%c%c, %c%c%c%c%c%c%c%c.%c%c%c, 11);\n", // dir[0], dir[1], dir[2], dir[3], dir[4], dir[5], dir[6], dir[7], dir[8], dir[9], dir[10], // dp->fn[0], dp->fn[1], dp->fn[2], dp->fn[3], dp->fn[4], dp->fn[5], dp->fn[6], dp->fn[7], dp->fn[8], dp->fn[9], dp->fn[10]); +#if _USE_HUMAN68K + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dp->fn, 11) && + !mem_cmp(dir + DIR_HU68K_EXNAME, dp->fn + DIR_HU68K_EXNAME, 10)) /* Is it a valid entry? */ + break; +#else if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dp->fn, 11)) /* Is it a valid entry? */ break; +#endif /* #if _USE_HUMAN68K */ #endif res = dir_next(dp, 0); /* Next entry */ } while (res == FR_OK); @@ -1594,8 +1609,14 @@ FRESULT dir_read ( } } #else /* Non LFN configuration */ +#if _USE_HUMAN68K + // Allow filenames that start with a dot. + if (c != DDE && a != AM_LFN && (int)(a == AM_VOL) == vol) /* Is it a valid entry? */ + break; +#else if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)(a == AM_VOL) == vol) /* Is it a valid entry? */ break; +#endif #endif res = dir_next(dp, 0); /* Next entry */ if (res != FR_OK) break; @@ -1745,6 +1766,51 @@ void get_fileinfo ( /* No return code */ FILINFO* fno /* Pointer to the file information to be filled */ ) { +#if _USE_HUMAN68K +// ------------------------------------------------------------------------- +// Human68K can handle filenames of (18+3) characters, +// but it does not use the VFAT format. +// ------------------------------------------------------------------------- + /* Get SFN */ + TCHAR *p = fno->fname; + if (dp->sect == 0) { + *p = 0; /* Terminate SFN string by a \0 */ + return; + } + + const BYTE *const dir = dp->dir; + const BYTE *s = dir; + const BYTE *q = dir + 8; + + while (q > dir && q[-1] == ' ') + --q; + while (s < q) + *p++ = *s++; + + s = dir + DIR_HU68K_EXNAME; + q = s + 10; + while (s < q) { + if (*s == 0) + break; + *p++ = *s++; + } + + s = dir + 8; + if (*s != ' ') { + *p++ = '.'; + q = s + 3; + while (q > (dir + 8) && q[-1] == ' ') + --q; + while (s < q) + *p++ = *s++; + } + *p = 0; + + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ +#else UINT i; TCHAR *p, c; @@ -1799,6 +1865,7 @@ void get_fileinfo ( /* No return code */ p[i] = 0; /* Terminate LFN string by a \0 */ } #endif +#endif } #endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2*/ @@ -1945,6 +2012,7 @@ FRESULT create_name ( for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ sfn = dp->fn; mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; #if _FS_RPATH if (p[si] == '.') { /* Is this a dot entry? */ @@ -1959,6 +2027,55 @@ FRESULT create_name ( return FR_OK; } #endif +#if _USE_HUMAN68K + mem_set(sfn + DIR_HU68K_EXNAME, 0, 10); + const char *const start = p; + for (;; p++) { + c = *p; + if (c < ' ' || c == '/') + break; + } + sfn[NS] = (c < ' ') ? NS_LAST : 0; + + const char *end = p; + if (start == end) return FR_INVALID_NAME; + + // find last dot + const char *dot = NULL; + while (--p > start) { /* NOT include first dot */ + if (*p == '.') { + dot = p; + break; + } + } + + // store ext(3) + if (dot == p && (end - p) <= 4 /* && p != start*/) { + char *q = sfn + 8; + p += 1; // skip dot + while (p < end) + *q++ = *p++; + end = dot; + } + + // store name(8) + p = start; + if ((end - p) > 18) + return FR_INVALID_NAME; /* too long name*/ + const char *pend = p + 8; + if (pend > end) pend = end; + char *q = sfn; + while (p < pend) + *q++ = *p++; + + // store ex-name(10) + q = sfn + DIR_HU68K_EXNAME; + while (p < end) + *q++ = *p++; + + *path = p; /* Return pointer to the next segment */ + +#else /* #if _USE_HUMAN68K */ for (;;) { c = (BYTE)p[si++]; if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ @@ -2007,9 +2124,10 @@ FRESULT create_name ( if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ sfn[NS] = c; /* Store NT flag, File name is created */ +#endif /* #if _USE_HUMAN68K */ return FR_OK; -#endif +#endif /* #if _USE_LFN */ } diff --git a/fatfs/ff.h b/fatfs/ff.h index a93d9a2..1c0ded5 100644 --- a/fatfs/ff.h +++ b/fatfs/ff.h @@ -166,7 +166,11 @@ typedef struct { WORD fdate; /* Last modified date */ WORD ftime; /* Last modified time */ BYTE fattrib; /* Attribute */ +#if _USE_HUMAN68K + TCHAR fname[23]; /* Short file name (18.3 human68k format) */ +#else TCHAR fname[13]; /* Short file name (8.3 format) */ +#endif #if _USE_LFN TCHAR* lfname; /* Pointer to the LFN buffer */ UINT lfsize; /* Size of LFN buffer in TCHAR */ diff --git a/fatfs/ffconf.h b/fatfs/ffconf.h index 21d0bed..4ece666 100644 --- a/fatfs/ffconf.h +++ b/fatfs/ffconf.h @@ -5,6 +5,8 @@ #ifndef _FFCONF #define _FFCONF 8051 /* Revision ID */ +#define _USE_HUMAN68K 1 + /*---------------------------------------------------------------------------/ / Functions and Buffer Configurations @@ -37,7 +39,7 @@ /* To enable string functions, set _USE_STRFUNC to 1 or 2. */ -#define _USE_MKFS 1 /* 0:Disable or 1:Enable */ +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ /* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ @@ -45,7 +47,7 @@ /* To enable fast seek feature, set _USE_FASTSEEK to 1. */ -#define _USE_LABEL 1 /* 0:Disable or 1:Enable */ +#define _USE_LABEL 0 /* 0:Disable or 1:Enable */ /* To enable volume label functions, set _USE_LAVEL to 1 */ @@ -89,7 +91,7 @@ / 1 - ASCII (Valid for only non-LFN configuration) */ -#define _USE_LFN 2 /* 0 to 3 */ +#define _USE_LFN 0 /* 0 to 3 */ #define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ /* The _USE_LFN option switches the LFN feature. / @@ -114,7 +116,7 @@ / functions. This option must be 0 when LFN feature is not enabled. */ -#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ +#define _STRF_ENCODE 0 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ /* When Unicode API is enabled by _LFN_UNICODE option, this option selects the character / encoding on the file to be read/written via string I/O functions, f_gets(), f_putc(), / f_puts and f_printf(). This option has no effect when Unicode API is not enabled. */