📄 fs_fat.c
字号:
if (mmc.DskSize < 0x10000) {
set_u16 (&ca.buf[19], mmc.DskSize);
}
else {
set_u32 (&ca.buf[32], mmc.DskSize);
}
/* Media Type, must be the same as FAT byte 0 */
ca.buf[21] = 0xF8;
/* Number of Hidden Sectors */
set_u32 (&ca.buf[28], mmc.BootRecSec);
if (mmc.FatType != FS_FAT32) {
/* FAT Size */
set_u16 (&ca.buf[22], mmc.FatSize);
/* Physical Disk Number */
ca.buf[36] = 0x80;
/* Boot Sig */
ca.buf[38] = 0x29;
/* Volume ID */
set_u32 (&ca.buf[39], sernum);
/* Volume Label */
memcpy (&ca.buf[43], "NO NAME ", 11);
/* File System Type. */
if (mmc.FatType == FS_FAT12) {
memcpy (&ca.buf[54], "FAT12 ", 8);
}
else {
memcpy (&ca.buf[54], "FAT16 ", 8);
}
}
else {
/* FAT32 Structure different from offset 36. */
/* FAT Size */
set_u32 (&ca.buf[36], mmc.FatSize);
/* Root Cluster Number. */
set_u32 (&ca.buf[44], 2);
/* FSInfo */
set_u16 (&ca.buf[48], 1);
/* Backup Boot Sector */
set_u16 (&ca.buf[50], 6);
/* Physical Disk Number */
ca.buf[64] = 0x80;
/* Boot Sig */
ca.buf[66] = 0x29;
/* Volume ID */
set_u32 (&ca.buf[67], sernum);
/* Volume Label */
memcpy (&ca.buf[71], "NO NAME ", 11);
/* File System Type. */
memcpy (&ca.buf[82], "FAT32 ", 8);
}
/* Executable Marker */
set_u16 (&ca.buf[510], 0xAA55);
return (write_sector (mmc.BootRecSec));
}
/*--------------------------- wipe_disk -------------------------------------*/
static void wipe_disk (U32 dsize) {
/* Clear the whole disk, write FF to all sectors. */
U32 i,csize;
/* Invalidate the cache. */
ca.nwr = 0;
ca.nrd = 0;
/* Use the cache buffer. */
csize = _MC_CSIZE;
if (csize == 0) {
csize = 1;
}
memset (ca.buf, 0xFF, csize * 512);
for (i = 0; i < dsize; i += csize) {
mmc_write_sect (i, ca.buf, csize);
}
}
/*--------------------------- fat_free --------------------------------------*/
U32 fat_free (void) {
/* Calculate a free space for Flash Card. */
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (0);
}
/* For FAT32 count only once. */
if (mmc.FatType != FS_FAT32) {
free_clus = count_free_clus ();
}
if (free_clus > mmc.DataClusCnt) {
/* Error, something wrong. */
return (0);
}
/* Return free data space in bytes. */
return (free_clus * mmc.ClusSize);
}
/*--------------------------- fat_find_dir ----------------------------------*/
static BOOL fat_find_dir (const char *fn, IOB *fcb, U8 create) {
/* Look for directory if it exists and leave fcb to point to directory,
if it does not exist and create == 1, create it. */
U8 creating_f;
U32 sz;
creating_f = 0;
while (get_dir_name (fn, name_buf, &sz) == __TRUE) {
if (!creating_f) {
if (find_name (name_buf, fcb, ENT_DIR) == __FALSE) {
/* Directory does not exist. */
if (!create) {
/* Directory not found. */
return (__FALSE);
}
/* Create requested, set creating_f flag to 1. */
creating_f = 1;
}
}
if (creating_f) {
/* If creation of unexisting directory requested. */
if (alloc_name (name_buf, fcb) == __FALSE) {
/* If unable to find place to create directory. */
return (__FALSE);
}
/* fcb points to unallocated entry. */
if (write_entries (name_buf, fcb, ENT_DIR, ACT_NONE) == __FALSE) {
/* If unable to write entries for new directory. */
return (__FALSE);
}
/* Create '.' and '..' entries in created folder. */
write_dot_entries (fcb);
}
fn += sz;
}
/* Searched directory was found or created and fcb points to it, in
case of creating directory fcb points to entry after ".." entry. */
return (__TRUE);
}
/*--------------------------- fat_find_file ---------------------------------*/
BOOL fat_find_file (const char *fn, IOB *fcb) {
/* Look for file if it exists in requested directory, the fcb is left
pointing to requested file entries. */
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (__FALSE);
}
/* Remove starting '\' if it exists. */
if (*fn == '\\') fn++;
/* Exit function if "fn" is not given. */
if (*fn == 0) return(__FALSE);
/* To force search of path from root. */
fcb->_firstClus = 0;
/* Search for directory. */
if (fat_find_dir (fn, fcb, ACT_NONE) == __FALSE) {
/* Directory does not exist. */
return (__FALSE);
}
/* Search for file. */
if (find_name (name_buf, fcb, ENT_FILE) == __FALSE) {
/* File does not exist. */
return (__FALSE);
}
/* Set _currDatSect and _currDat Clus to show to data of found file. */
fcb->_currDatSect = 0;
fcb->_currDatClus = fcb->_firstClus;
/* If file exists. */
return (__TRUE);
}
/*--------------------------- fat_ffind -------------------------------------*/
BOOL fat_ffind (const char *fn, FINFO *info, IOB *fcb) {
/* Find a file or directory in requested directory. */
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (__FALSE);
}
/* Remove starting '\' if it exists. */
if (*fn == '\\') fn++;
/* Exit function if "fn" is not given. */
if (*fn == 0) return(__FALSE);
/* To force search of path from root. */
fcb->_firstClus = 0;
/* Search for directory. */
if (fat_find_dir (fn, fcb, 0) == __FALSE) {
/* Directory does not exist. */
return (__FALSE);
}
/* Get next valid info. */
if (get_next_info (info, fcb) == __FALSE) {
/* No more valid infos in current directory. */
return (__FALSE);
}
/* Info found. */
return (__TRUE);
}
/*--------------------------- fat_create ------------------------------------*/
BOOL fat_create (const char *fn, IOB *fcb) {
/* Create a file or directory in requested directory. */
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (__FALSE);
}
/* Remove starting '\' if it exists. */
if (*fn == '\\') fn++;
/* Exit function if "fn" is not given. */
if (*fn == 0) return(__FALSE);
/* To force search of path from root. */
fcb->_firstClus = 0;
/* Search for directory. */
if (fat_find_dir (fn, fcb, 1) == __FALSE) {
/* Directory does not exist and could not be created. */
return (__FALSE);
}
/* File does not exist, create one. */
if (alloc_name (name_buf, fcb) == __FALSE) {
/* If unable to find unallocated entry to create file. */
return (__FALSE);
}
/* fcb points to unallocated entry. */
if (write_entries (name_buf, fcb, ENT_FILE, ACT_NONE) == __FALSE) {
/* If unable to write entries for new file. */
return (__FALSE);
}
/* File created. */
return (__TRUE);
}
/*--------------------------- fat_delete ------------------------------------*/
BOOL fat_delete (const char *fn, IOB *fcb) {
/* Delete a file or directory from requested directory. */
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (__FALSE);
}
/* Remove starting '\' if it exists. */
if (*fn == '\\') fn++;
/* Exit function if "fn" is not given. */
if (*fn == 0) return(__FALSE);
/* To force search of path from root. */
fcb->_firstClus = 0;
/* Search for directory. */
if (fat_find_dir (fn, fcb, 0) == __FALSE) {
/* Directory does not exist. */
return (__FALSE);
}
if (name_buf[0]) {
/* Search for file. */
if (find_name (name_buf, fcb, ENT_FILE) == __FALSE) {
/* File does not exist. */
return (__FALSE);
}
}
else {
/* We want to delete a directory, see if it is empty. */
if (chk_dir_empty (fcb) == __FALSE) {
/* Directory is not empty, do not delete it. */
return (__FALSE);
}
}
/* File or directory entries found and fcb points to first entry. */
if (delete_entries (fcb, 0) == __FALSE) {
/* If file or directory was not deleted successfully. */
return (__FALSE);
}
/* File was deleted. */
return (__TRUE);
}
/*--------------------------- fat_read --------------------------------------*/
U32 fat_read (IOB *fcb, U8 *buf, U32 len) {
/* Read data from file at current file position. */
U32 sect,pos,nr,rlen;
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (0);
}
if (fcb->fpos + len > fcb->fsize) {
/* Check for End Of File. */
len = fcb->fsize - fcb->fpos;
if (len == 0) {
/* End of File. */
return (0);
}
}
pos = fcb->fpos & 0x1FF;
for (nr = 0; nr < len; nr += rlen) {
sect = clus_to_sect (fcb->_currDatClus) + fcb->_currDatSect;
/* Try to cache current cluster. */
read_cache (sect, mmc.SecPerClus - fcb->_currDatSect);
rlen = len - nr;
if ((rlen + pos) > 512) {
rlen = 512 - pos;
}
memcpy (&buf[nr], &ca.buf[pos], rlen);
pos = (pos + rlen) & 0x1FF;
if (pos == 0) {
/* Current sector complete, get next one. */
if (++fcb->_currDatSect == mmc.SecPerClus) {
/* This cluster is processed, get next one. */
fcb->_currDatSect = 0;
set_next_clus (&fcb->_currDatClus);
}
}
}
fcb->fpos += nr;
/* Number of characters read. */
return (len);
}
/*--------------------------- fat_write -------------------------------------*/
BOOL fat_write (IOB *fcb, const U8 *buf, U32 len) {
/* Write data to file at current file position. */
U32 sect,pos,nw,wlen,clus;
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (__FALSE);
}
if (fcb->_firstClus == 0) {
/* Data cluster not allocated yet. */
if (get_free_clus (&fcb->_currDatClus) == __FALSE) {
/* Disk Full, no free clusters found. */
return (__FALSE);
}
fcb->_firstClus = fcb->_currDatClus;
fcb->_currDatSect = 0;
}
pos = fcb->fpos & 0x1FF;
for (nw = 0; nw < len; nw += wlen) {
wlen = len - nw;
if ((wlen + pos) > 512) {
wlen = 512 - pos;
}
sect = clus_to_sect (fcb->_currDatClus) + fcb->_currDatSect;
if (pos != 0) {
/* File position not 512-byte aligned. */
read_sector (sect);
}
memcpy (&ca.buf[pos], &buf[nw], wlen);
write_cache (sect);
pos = (pos + wlen) & 0x1FF;
if (pos == 0) {
/* Current sector is full, get next one. */
if (++fcb->_currDatSect == mmc.SecPerClus) {
/* This cluster is processed, get next one. */
fcb->_currDatSect = 0;
clus = fcb->_currDatClus;
if (get_free_clus (&fcb->_currDatClus) == __FALSE) {
/* Failed to allocate a free cluster. */
return (__FALSE);
}
/* Update also a FAT cluster chain. */
write_fat_link (clus, fcb->_currDatClus);
}
}
}
fcb->fpos += nw;
return (__TRUE);
}
/*--------------------------- fat_close_write -------------------------------*/
BOOL fat_close_write (IOB *fcb) {
/* Close an opened file, update FAT and Directory record. */
FILEREC last_frec;
if (mmc.FatType == FS_RAW) {
/* RAW File System or FAT not initialized. */
return (__FALSE);
}
if (fcb->fpos > fcb->fsize) {
/* Write an EOC marker to FAT table Cluster chain. */
write_fat_link (fcb->_currDatClus, get_EOC());
/* Update File Length info from Directory Entry record. */
/* Read last entry to keep some informations from it. */
read_last_entry (fcb, &last_frec);
last_frec.FirstClusHI = (U16)(fcb->_firstClus >> 16);
last_frec.FirstClusLO = (U16)(fcb->_firstClus );
last_frec.FileSize = fcb->fpos;
/* Write updated last entry. */
write_last_entry (fcb, &last_frec);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -