Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
122 changes: 120 additions & 2 deletions fatfs/ff.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@

#include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of disk I/O functions */

#include <stddef.h>



Expand Down Expand Up @@ -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) */
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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*/

Expand Down Expand Up @@ -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? */
Expand All @@ -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 */
Expand Down Expand Up @@ -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 */
}


Expand Down
4 changes: 4 additions & 0 deletions fatfs/ff.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
10 changes: 6 additions & 4 deletions fatfs/ffconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#ifndef _FFCONF
#define _FFCONF 8051 /* Revision ID */

#define _USE_HUMAN68K 1


/*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations
Expand Down Expand Up @@ -37,15 +39,15 @@
/* 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 */


#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
/* 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 */


Expand Down Expand Up @@ -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.
/
Expand All @@ -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. */
Expand Down