📄 fat.c
字号:
fat_get_dir_file_list(id); /* create list of entries */
if (fat_dir_list_last == 0)
return KO; /* no requested (id) entry */
fat_dir_list_index = 0; /* point on first root entry */
/* extract info from table */
if (fat_dseek(fat_dir_entry_list[0] * DIR_SIZE) == OK)
{
fat_get_dir_entry(&fat_cache.current); /* update current file info */
/* parent dir is also root */
fat_cache.parent.start_cluster = 0;
fat_cache.parent.attributes = ATTR_ROOT_DIR; /* mark as root dir */
return OK;
}
else
return KO; /* low level error */
}
/*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 (Byte init)
{
static Byte fat12_parity;
static Uint16 cluster;
INT8U a,b;
if (fat_is_fat16)
{
a = Hard_read_byte();
b = Hard_read_byte();
cluster = fat_caculate_offset(a,b,0,0);
// ((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)
{
a = Hard_read_byte();
b = Hard_read_byte();
cluster = fat_caculate_offset(a,b,0,0);
fat12_parity = 1;
return (cluster & 0x0FFF);
}
else
{
cluster = (cluster & 0xF000) >> 12;
cluster += (Hard_read_byte() << 4);
fat12_parity = 0;
return (cluster);
}
}
/*F**************************************************************************
* NAME: fat_get_clusters
*----------------------------------------------------------------------------
* PARAMS:
* chain: allocation list address
* nb_frag: maximum number of fragment
*
* return:
* - OK: allocation done
* - KO: allocation done but truncated: file too much fragmented
*----------------------------------------------------------------------------
* PURPOSE:
* Prepare a list of the file 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:
* File cluster list is limited by the nb_frag parameter.
* If memory is too much fragmented, file may not be fully played.
* Last list item always has single cluster
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_get_clusters (fat_st_clust_chain *chain, Byte nb_frag)
{
Byte index; // index in chain
Uint16 i;
Uint16 new_cluster;
Uint16 old_cluster;
Uint16 temp;
nb_frag = nb_frag - 1; // set limit (index start at 0)
// build the first entry of the allocation list
chain[0].number = 1;
chain[0].cluster = fat_cache.current.start_cluster - 2; // 2 = 1st cluster
old_cluster = fat_cache.current.start_cluster;
index = 0;
// calculate the first offset in fat and read the corresponding sector
if (fat_is_fat16)
{
Hard_read_open(fat_ptr_fats + (old_cluster / (SECTOR_SIZE / 2)));
// compute offset in sector
for (i = (old_cluster % (SECTOR_SIZE / 2)); i != 0; i--)
{
fat_read_cluster(0);
}
// read first entry
new_cluster = fat_read_cluster(0);
temp = LAST_CLUSTER16;
}
else
{
Hard_read_open(fat_ptr_fats);
new_cluster = fat_read_cluster(1);
for (i = old_cluster; i != 0; i--)
{
new_cluster = fat_read_cluster(0);
}
temp = LAST_CLUSTER12;
}
while (new_cluster != temp) // loop until last cluster found
{
if ((new_cluster == (old_cluster + 1)) && (chain[index].number != MAX_CL_PER_FRAG))
{ // contiguous cluster up to 255 or 65535
chain[index].number++;
}
else
{ // compute fragmentation
index++;
chain[index].number = 1;
chain[index].cluster = new_cluster - 2; // 2 = 1st cluster
for (i = new_cluster - old_cluster - 1; i != 0; i--)
{
fat_read_cluster(0);
}
}
old_cluster = new_cluster;
if (index == nb_frag)
{ // end of chain reached
// last fragment always contains a single cluster
chain[nb_frag].number = 1;
fat_last_clust_index = nb_frag;
Hard_read_close(); // close physical read
return KO; // file too much fragmented
}
else
{
// read new entry
new_cluster = fat_read_cluster(0);
}
}
// end of file: last fragment must always contain a single cluster
if (chain[index].number == 1)
{ // last cluster is the current one
fat_last_clust_index = index;
}
else
{
fat_last_clust_index = index + 1;
chain[index].number--;
chain[fat_last_clust_index].cluster = chain[index].cluster + chain[index].number;
chain[fat_last_clust_index].number = 1;
}
Hard_read_close(); // close physical read
return OK;
}
/*F**************************************************************************
* NAME: fat_fopen
*----------------------------------------------------------------------------
* PARAMS:
* mode: READ: open file for read
* WRITE: open file for write
*
* return:
* - OK: file opened
* - KO: file not opened: - file is empty
* - low level read error
*----------------------------------------------------------------------------
* PURPOSE:
* Open the file in read or write mode
*----------------------------------------------------------------------------
* EXAMPLE:
* if (fat_get_root_directory(FILE_WAV) == OK) // Select first WAV file in root
* {
* fat_fopen(WRITE); // Open this file in WRITE mode
* for (j = 0; j < 10; j++)
* fat_fputc(buff[j]);
* fat_fclose();
* }
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
* For write mode, there must be an entry in the root and entry data must be
* updated.
*****************************************************************************/
Byte fat_fopen (Byte mode)
{
if (mode == READ)
{
if (fat_cache.current.size.l == 0)
{
return KO; // file empty
}
else
{
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);
// seek to the beginning of the file
fat_open_mode = READ;
return Hard_read_open(fat_ptr_data + ((Uint32)(fclusters[0].cluster)*fat_cluster_size));
}
}
else
{
fat_fclust_byte_count = 0; // byte 0 of cluster
fat_file_size.l = 0;
flag_end_disk_file = FALSE;
// reset the allocation list variable
fat_fchain_index = 0;
fat_fchain_nb_clust = 0; // start on first contiguous cl
fat_root_entry = fat_dclust_byte_count / 32;
// get file allocation list
fat_get_clusters(fclusters, MAX_FILE_FRAGMENT_NUMBER);
fat_open_mode = WRITE;
return Hard_write_open(fat_ptr_data + ((Uint32)(fclusters[0].cluster)
* fat_cluster_size));
}
}
/*F**************************************************************************
* NAME: fat_fgetc
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* byte read
*----------------------------------------------------------------------------
* PURPOSE:
* Read one byte from file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* As this function is called very often it must be short and optimized
* in execution time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_fgetc (void)
{
if( ( (Byte)fat_fclust_byte_count == 0x00 ) &&
( (((Byte)(fat_fclust_byte_count >> 8)) & fat_cluster_mask) == 0x00 )
)
// if ((((Byte*)&fat_fclust_byte_count)[1] == 0x00) &&
// ((((Byte*)&fat_fclust_byte_count)[0] & fat_cluster_mask) == 0x00))
{
/* extract if necessary the next cluster from the allocation list */
if (fclusters[fat_fchain_index].number == fat_fchain_nb_clust)
{ /* new fragment */
fat_fchain_index++;
fat_fchain_nb_clust = 1;
Hard_read_close();
Hard_read_open(fat_ptr_data + ((Uint32)(fclusters[fat_fchain_index].cluster) * fat_cluster_size));
}
else
{ /* no new fragment */
fat_fchain_nb_clust++; /* one more cluster read */
}
}
fat_fclust_byte_count++; /* one more byte read */
return Hard_read_byte();
}
/*F**************************************************************************
* NAME: fat_feof
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the file end flag
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_feof (void)
{
if (fat_fchain_index >= fat_last_clust_index)
{
if (fat_open_mode == READ)
return (fat_fclust_byte_count >= (Uint16)fat_cache.current.size.l);
else
return flag_end_disk_file;
}
else
{
return FALSE;
}
}
/*F**************************************************************************
* NAME: fat_fclose
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Close opened file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
//void fat_fclose (void)
//{
// if (fat_open_mode == READ)
// {
// Hard_read_close(); /* close reading */
// }
// else
// {
// Hard_write_close(); /* close writing */
// fat_update_entry_fat(); /* Update entry and fat */
// }
//}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -