📄 mcc_fat32.c
字号:
}
char FindDirEntry (char *fname, char f)
{
DIR *pDir;
int16 i;
char filename[16];
int32 nextcluster;
int32 actsector;
if (f > (MAXFILES-1)) return FALSE;
gFAT32Vars.gFirstEmptyDirEntry = 0xFFFF;
gFAT32Vars.gFirstDirEntryCluster = 0x0FFFFFFF;
do
{
pDir = (DIR*)(gFiles[f].IOpuffer);
for (i = 0; i < 16; i++)
{
if (((pDir->sName[0] == 0xE5) || (pDir->sName[0] == 0)) && (gFAT32Vars.gFirstEmptyDirEntry == 0xFFFF))
{
// store first free
gFAT32Vars.gFirstEmptyDirEntry = i;
gFAT32Vars.gFirstDirEntryCluster = gFiles[f].CurrentCluster;
}
if (pDir->sName[0] == 0) return FALSE;
ConvertFilename (pDir,filename);
if (!strcmp (filename, fname))
{
memcpy(&(gFiles[f].DirEntry), pDir, 32);
gFiles[f].dirIdx = i;
gFAT32Vars.gDirEntryIdx = i;
return TRUE;
}
pDir++;
}
nextcluster = GetNextCluster (gFiles[f].CurrentCluster);
if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
{
actsector = nextcluster + gFAT32Vars.gFirstDataSector;
ReadSector (actsector, gFiles[f].IOpuffer);
gFAT32Vars.gDirEntrySector = actsector;
gFiles[f].dirSector = actsector;
gFiles[f].CurrentCluster = nextcluster;
}
} while ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0));
return FALSE;
}
// file I/O routines
char *TryFile(char *fname, char *f)
{
char i;
char leng;
char *filename;
(*f) = 0xFF;
for (i = 0; i < MAXFILES; i++)
{
if (gFiles[i].Free)
{
(*f) = i;
break;
}
}
if ((*f) == 0xFF) return 0;
ReadRootDirectory (*f);
filename = fname;
leng = strlen (fname);
for (i = 0; i < leng; i++)
{
if (fname[i] == '/')
{
fname[i] = 0;
if (! cwd (filename,(*f)))
{
gFiles[(*f)].Free = TRUE;
return 0;
}
filename = fname + i + 1;
}
}
return filename;
}
char fcreate (char f, char *fname)
{
DIR *pDir;
int32 actsector;
char actcl;
int16 i;
if (f > (MAXFILES-1)) return FALSE;
if (gFAT32Vars.gFirstDirEntryCluster == 0x0FFFFFFF)
{
// extend the directory file !!!
gFAT32Vars.gFirstDirEntryCluster = FindFirstFreeCluster ();
gFAT32Vars.gFirstEmptyDirEntry = 0;
SetClusterEntry(gFiles[f].CurrentCluster, gFAT32Vars.gFirstDirEntryCluster);
SetClusterEntry(gFAT32Vars.gFirstDirEntryCluster, 0x0FFFFFFF);
actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector;
for (i = 0; i < 512; i++)
{
gFiles[f].IOpuffer[i] = 0;
}
WriteSector(actsector, gFiles[f].IOpuffer);
}
actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector;
ReadSector (actsector, gFiles[f].IOpuffer);
pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gFirstEmptyDirEntry]));
gFiles[f].dirSector = actsector;
gFiles[f].dirIdx = gFAT32Vars.gFirstEmptyDirEntry;
GetDOSName (pDir, fname);
pDir->bAttr = 0;
actcl = FindFirstFreeCluster ();
pDir->hCluster = actcl & 0xFFFF;
pDir->hClusterH = actcl >> 16;
SetClusterEntry (actcl, 0x0FFFFFFF);
pDir->wSize = 0;
gFiles[f].position = 0;
pDir->hDate = GetCurrentDOSDate ();
pDir->hTime = GetCurrentDOSTime ();
WriteSector (actsector, gFiles[f].IOpuffer);
memcpy (&(gFiles[f].DirEntry), pDir,32);
return TRUE;
}
int32 ComposeCluster (char f)
{
int32 retval;
retval = gFiles[f].DirEntry.hClusterH;
retval <<= 16;
retval |= gFiles[f].DirEntry.hCluster;
return retval;
}
char fopen (char *fname, char mode)
{
char found;
char f;
int32 actsector;
int32 actcluster;
int32 nextcluster;
char *filename;
//if (input(CardInserted)) return 0xFF;
filename = TryFile (fname, &f);
if (filename == 0) return 0xFF;
found = FALSE;
found = FindDirEntry (filename,f);
if (!found)
{
if (mode == 'r')
{
gFiles[f].Free = TRUE;
return 0xFF;
}
else
{
if (! fcreate(f, filename)) return 0xFF;
found = TRUE;
}
}
if (found)
{
gFiles[f].Free = FALSE;
gFiles[f].mode = mode;
if (mode == 'a') // com problemas
{
gFiles[f].position = gFiles[f].DirEntry.wSize;
actcluster = ComposeCluster(f);
while ((actcluster != 0x0FFFFFFF) && (nextcluster != 0))
{
nextcluster = GetNextCluster(actcluster);
if ((nextcluster == 0x0FFFFFFF) || (nextcluster == 0)) break;
actcluster = nextcluster;
}
actsector = actcluster + gFAT32Vars.gFirstDataSector;
ReadSector (actsector, gFiles[f].IOpuffer);
gFiles[f].CurrentCluster = actcluster;
gFiles[f].posinsector = gFiles[f].position & 0x01FF;
if ((gFiles[f].posinsector == 0) && (gFiles[f].position != 0))
{
gFiles[f].posinsector = 512;
}
}
else
{
gFiles[f].position = 0;
actsector = ComposeCluster (f);
actsector += gFAT32Vars.gFirstDataSector;
ReadSector(actsector,gFiles[f].IOpuffer);
gFiles[f].CurrentCluster = ComposeCluster (f);
gFiles[f].posinsector = 0;
}
}
return f;
}
void fclose (char f)
{
if (f > (MAXFILES-1)) return;
if ((gFiles[f].mode == 'a') || (gFiles[f].mode == 'w')) fflush(f);
gFiles[f].Free = TRUE;
}
void fflush (char f)
{
int32 actsector;
DIR *pDir;
if (f > (MAXFILES-1)) return;
actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector;
WriteSector (actsector, gFiles[f].IOpuffer);
ReadSector(gFiles[f].dirSector, gFiles[f].IOpuffer);
pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFiles[f].dirIdx]));
if (gFiles[f].DirEntry.bAttr & 0x10) pDir->wSize = 0; // if it is a directory
else pDir->wSize = gFiles[f].position;
pDir->hDate = GetCurrentDOSDate ();
pDir->hTime = GetCurrentDOSTime ();
WriteSector(gFiles[f].dirSector,gFiles[f].IOpuffer);
ReadSector(actsector, gFiles[f].IOpuffer);
}
char cwd (char *fname, char f)
{
int32 actsector;
if (f > (MAXFILES-1))
{
return FALSE; // just in case of overaddressing
}
if (IsSelfDir(fname))
{
return TRUE; // already in Root dir
}
if (!FindDirEntry(fname,f))
{
return FALSE; // not found
}
actsector = ComposeCluster (f);
actsector += gFAT32Vars.gFirstDataSector; // read current dir
ReadSector (actsector, gFiles[f].IOpuffer);
gFAT32Vars.gDirEntrySector = actsector;
gFiles[f].dirSector = actsector;
gFiles[f].CurrentCluster = ComposeCluster (f);
return TRUE;
}
void fputch (char be, char f)
{
int32 nextcluster;
int32 actsector;
if (f > (MAXFILES-1)) return;
if (gFiles[f].posinsector == 512)
{
actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector;
WriteSector (actsector,gFiles[f].IOpuffer);
nextcluster = FindFirstFreeCluster ();
if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
{
SetClusterEntry (gFiles[f].CurrentCluster, nextcluster);
SetClusterEntry (nextcluster, 0x0FFFFFFF);
actsector = nextcluster + gFAT32Vars.gFirstDataSector;
//ReadSector (actsector,gFiles[f].IOpuffer); //-- nao tem a necessidade de ler o setor toda vez que for gravar um bloco
gFiles[f].CurrentCluster = nextcluster;
gFiles[f].posinsector = 0;
}
}
gFiles[f].IOpuffer[gFiles[f].posinsector] = be;
gFiles[f].posinsector++;
gFiles[f].position++;
return;
}
void fputstring (char *be, char f)
{
int16 leng;
int16 i;
if (f > (MAXFILES-1)) return;
leng = strlen (be);
for (i = 0; i < leng; i++)
fputch (be[i], f);
}
int16 fread (char *buffer, int16 leng, char f)
{
int16 i;
int16 retv;
char c;
char v;
if (f > (MAXFILES-1)) return 0;
retv = 0;
for (i = 0; i < leng; i++)
{
v = fgetch (&c, f);
if (v)
{
buffer[i] = c;
retv++;
}
else break;
}
return retv;
}
void fwrite (char *buffer, int16 leng, char f)
{
int16 i;
if (f > (MAXFILES-1)) return;
for (i = 0; i < leng; i++)
fputch (buffer[i],f);
}
char fgetch (char *ki, char f)
{
int32 nextcluster;
int32 actsector;
if (f > (MAXFILES-1)) return FALSE;
if (gFiles[f].position >= gFiles[f].DirEntry.wSize) return FALSE;
*ki = gFiles[f].IOpuffer[gFiles[f].posinsector];
gFiles[f].posinsector++;
gFiles[f].position++;
if (gFiles[f].posinsector == 512)
{
nextcluster = GetNextCluster (gFiles[f].CurrentCluster);
if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
{
actsector = nextcluster + gFAT32Vars.gFirstDataSector;
ReadSector (actsector,gFiles[f].IOpuffer);
gFiles[f].CurrentCluster = nextcluster;
gFiles[f].posinsector = 0;
}
}
return TRUE;
}
char remove (char *fname)
{
char i;
char found;
char f;
DIR *pDir;
int32 nextcluster;
int32 currentcluster;
char *filename;
filename = TryFile (fname, &f);
if (filename == 0) return FALSE;
found = FindDirEntry (filename,f);
if (!found)
{
gFiles[f].Free = TRUE;
printf ("Arquivo n?o encontrado...\r\n");
return FALSE;
}
pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gDirEntryIdx]));
pDir->sName[0] = 0xE5;
for (i = 1; i < 8; i++)
pDir->sName[i] = ' ';
for (i = 0; i < 3; i++)
pDir->spam[i] = ' ';
WriteSector (gFAT32Vars.gDirEntrySector, gFiles[f].IOpuffer);
currentcluster = ComposeCluster (f);
while ((currentcluster != 0x0FFFFFFF) && (nextcluster != 0))
{
nextcluster = GetNextCluster (currentcluster);
ClearClusterEntry (currentcluster);
currentcluster = nextcluster;
}
ClearClusterEntry (currentcluster);
SetClusterEntry (currentcluster, 0);
currentcluster = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + gFAT32Vars.FATstartidx;
WriteSector (currentcluster, FATTable);
currentcluster += DiskInfo.hSectorsPerFat;
WriteSector (currentcluster, FATTable);
gFiles[f].Free = TRUE;
return TRUE;
}
char getfsize (char *fname, int32 *fsiz)
{
char found;
char f;
DIR *pDir;
char *filename;
filename = TryFile (fname, &f);
if (filename == 0) return FALSE;
found = FindDirEntry (filename, f);
if (!found)
{
gFiles[f].Free = TRUE;
return FALSE;
}
pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gDirEntryIdx]));
gFiles[f].Free = TRUE;
*fsiz = pDir->wSize;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -