📄 fat.c
字号:
cluster = fclusters[0].cluster + 2;
/* Start at first chain cluster */
sector_number = (fat_is_fat16 == TRUE) ? cluster / 256 : cluster * 3 / 1024;
/* Bufferize fat sector */
fat_load_sector(fat_ptr_fats + sector_number);
end = FALSE;
do
{
temp = (fat_is_fat16 == TRUE) ? cluster / 256 : cluster * 3 / 1024;
if (temp != sector_number)
{
fat_update_fat_sector(sector_number);
sector_number = temp;
fat_load_sector(fat_ptr_fats + sector_number);
}
if (fat_is_fat16 == TRUE)
{
i = (cluster * 2) & 0x1FF;
((Byte *)&cluster)[1] = fat_buf_sector[i];
fat_buf_sector[i++] = 0;
((Byte *)&cluster)[0] = fat_buf_sector[i];
fat_buf_sector[i] = 0;
end = (cluster == 0xFFFF);
}
else
{
i = (cluster * 3 / 2) & 0x1FF;
if ((cluster & 0x01) == 0)
{
((Byte *)&cluster)[1] = fat_buf_sector[i];
fat_buf_sector[i] = 0x00;
i++;
if (i == 512)
{
fat_update_fat_sector(sector_number);
sector_number++;
fat_load_sector(fat_ptr_fats + sector_number);
i = 0;
}
((Byte *)&cluster)[0] = fat_buf_sector[i] & 0x0F;
fat_buf_sector[i] &= 0xF0;
}
else
{
cluster = (fat_buf_sector[i] & 0xF0) >> 4;
fat_buf_sector[i] &= 0x0F;
i++;
if (i == 512)
{
fat_update_fat_sector(sector_number);
sector_number++;
fat_load_sector(fat_ptr_fats + sector_number);
i = 0;
}
cluster += (fat_buf_sector[i] << 4);
fat_buf_sector[i] = 0x00;
}
end = (cluster == 0xFFF);
}
}
while (!end);
fat_update_fat_sector(sector_number);
}
/*F**************************************************************************
* NAME: fat_refresh_dir_file_info
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*
*----------------------------------------------------------------------------
* PURPOSE:
* Reconstruct the file directory list and seek to the file pointed by
* fat_dir_list_index
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*
*****************************************************************************/
void fat_refresh_dir_file_info (Byte id)
{
/* update fat_dir_current_sect with directory starting value */
if (dir_is_root)
{
fat_dir_current_sect = fat_ptr_rdir;
}
else
{
fat_dir_current_sect = (((Uint32)(dclusters[0].cluster)) * fat_cluster_size)
+ fat_ptr_data;
}
fat_get_dir_file_list(id); /* Refresh file list */
fat_seek_entry_record(); /* Re-fetch the entry <-> fat_dir_list_index */
fat_get_dir_entry(&fat_cache.current); /* update current file info */
}
/*F**************************************************************************
* NAME: fat_fdelete
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - DEL_RET_OK: delete done & dir is not empty
* - DEL_RET_NO_MORE_FILE: dir is empty after delete or not
* - DEL_RET_ERROR_DIR: dir can not be deleted
*----------------------------------------------------------------------------
* PURPOSE:
* Delete a selected file, in the root directory or in a sub-dir
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* fat_frefresh may be called after fdelete to rebuilt the dir content list
*----------------------------------------------------------------------------
* REQUIREMENTS:
* File variables must be updated (fat_dclust_byte_count, entry record, ...)
*****************************************************************************/
Byte fat_fdelete (void)
{
Uint16 i;
Uint32 dir_sector;
if (((dir_is_root == TRUE) && (fat_dir_list_last == 0)) ||
((dir_is_root == FALSE) && (fat_dir_list_last == 2))) /* . and .. directory */
return DEL_RET_NO_MORE_FILE; /* directory already empty */
if (fat_check_ext() != FILE_DIR)
{
fat_seek_entry_record(); /* Re-fetch the entry <-> fat_dir_list_index */
Hard_read_close();
dir_sector = fat_dir_current_sect;
fat_root_entry = fat_dir_current_offs / 32; /* fat_dir_current_offs give the offset in byte starting */
fat_file_size.l = fat_cache.current.size.l; /* at the beginning of directory */
fat_load_sector(dir_sector); /* Load directory sector */
i = (fat_root_entry % 16) * 32 ; /* position of entry in the sector */
while (fat_buf_sector[i + 11] == ATTR_LFN_ENTRY)
{
/* mark file as deleted */
fat_buf_sector[i] = FILE_DELETED;
i += 32;
if (!dir_is_root)
fat_dclust_byte_count += 32;
if (i == SECTOR_SIZE)
{
Hard_write_open(dir_sector);
for (i = 0; i < SECTOR_SIZE; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
if (!dir_is_root) /* sub-directory */
{
/* check if we are at the end of a cluster */
if ((((Byte*)&fat_dclust_byte_count)[1] == 0x00) &&
((((Byte*)&fat_dclust_byte_count)[0] & fat_cluster_mask) == 0x00))
{
/* extract if necessary the next cluster from the allocation list */
if (dclusters[fat_dchain_index].number == fat_dchain_nb_clust)
{ /* new fragment */
fat_dchain_index++;
fat_dchain_nb_clust = 1;
dir_sector = (fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster) * fat_cluster_size));
}
else
{
fat_dchain_nb_clust++; /* one more cluster read */
dir_sector++; /* Contiguous cluster */
}
}
else
{ /* Don't change the cluster */
dir_sector++;
}
}
else
{ /* Root directory is linear */
dir_sector++;
}
fat_load_sector(dir_sector);
i = 0;
}
}
fat_buf_sector[i] = FILE_DELETED;
Hard_write_open(dir_sector);
for (i = 0; i < SECTOR_SIZE; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
/* FAT update */
fat_fclust_byte_count = 0; /* byte 0 of cluster */
/* reset the allocation list variable */
fat_fchain_index = 0;
fat_fchain_nb_clust = 0; /* start on first contiguous cl */
/* get file allocation list */
fat_get_clusters(&fclusters, MAX_FILE_FRAGMENT_NUMBER);
/* Clear fat cluster */
fat_clear_fat();
/* NF correction */
for (i = 0; i < 256; i++)
gl_buffer[i] = 0x00;
fat_dir_list_last--; /* one file deleted */
if (((dir_is_root == TRUE) && (fat_dir_list_last == 0)) ||
((dir_is_root == FALSE) && (fat_dir_list_last == 2))) /* . and .. directory */
return DEL_RET_NO_MORE_FILE; /* directory now empty */
if (fat_dir_list_index == fat_dir_list_last)
{
fat_dir_list_index--; /* in case of last file delete */
}
return DEL_RET_OK;
}
else
{
return DEL_RET_ERROR_DIR;
}
}
/*F**************************************************************************
* NAME: fat_free_space
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* number of free cluster
*----------------------------------------------------------------------------
* PURPOSE:
* Get free space
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
fat_st_free_space fat_free_space(void)
{
Uint32 temp;
Uint32 i;
Uint16 cluster;
bdata bit fat12_parity;
xdata fat_st_free_space free_space;
Hard_read_open(fat_ptr_fats);
temp = 2;
if (fat_is_fat16) /* FAT16 management */
{
for (i = 0; i < fat_count_of_clusters; i++)
{
((Byte*)&cluster)[1] = Hard_read_byte();
((Byte*)&cluster)[0] = Hard_read_byte();
if (cluster == 0x0000)
temp++;
}
Hard_read_close();
free_space.free_cluster = temp;
free_space.cluster_size = fat_cluster_size;
return free_space;
}
else
{
fat12_parity = 0;
for (i = 0; i < fat_count_of_clusters; i++)
{
if (fat12_parity == 0)
{
((Byte*)&cluster)[1] = Hard_read_byte();
((Byte*)&cluster)[0] = Hard_read_byte();
fat12_parity = 1;
}
else
{
cluster = (cluster & 0xF000) >> 12;
cluster += (Hard_read_byte() << 4);
fat12_parity = 0;
}
if (!(cluster & 0x0FFF))
temp++;
}
Hard_read_close();
free_space.free_cluster = temp;
free_space.cluster_size = fat_cluster_size;
return free_space;
}
}
/*F**************************************************************************
* NAME: fat_read_cluster12
*----------------------------------------------------------------------------
* PARAMS:
* init : initialize the parity bit or not
* return:
* FAT12 cluster value
*----------------------------------------------------------------------------
* PURPOSE:
* Read in fat12 file system a cluster value
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint16 fat_read_cluster (bit init)
{
static bit fat12_parity;
static idata Uint16 cluster;
if (fat_is_fat16)
{
((Byte*)&cluster)[1] = Hard_read_byte();
((Byte*)&cluster)[0] = Hard_read_byte();
return cluster;
}
if (init)
{
fat12_parity = 0;
cluster = 0;
}
if (fat12_parity == 0)
{
((Byte*)&cluster)[1] = Hard_read_byte();
((Byte*)&cluster)[0] = Hard_read_byte();
fat12_parity = 1;
return (cluster & 0x0FFF);
}
else
{
cluster = (cluster & 0xF000) >> 12;
cluster += (Hard_read_byte() << 4);
fat12_parity = 0;
return (cluster);
}
}
/*F**************************************************************************
* NAME: fat_set_clusters
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - OK: allocation done
* - KO: allocation cannot be done : no free cluster
*----------------------------------------------------------------------------
* PURPOSE:
* Prepare a list of the free clusters:
* chain[n].cluster contains the starting cluster number of a fragment
* chain[n].number contains the number of contiguous clusters in fragment
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* Free cluster list is limited by the nb_frag parameter.
* If memory is too much fragmented, created file may be limited in size.
* Last list item always has single cluster
*----------------------------------------------------------------------------
* REQUIREMENTS:
************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -