📄 fat.c
字号:
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:
*****************************************************************************/
bit fat_set_clusters (void)
{
bit cluster_free;
Uint16 cluster;
cluster = 0;
cluster_free = FALSE;
fat_last_clust_index = 0;
Hard_read_open(fat_ptr_fats);
/* search the first free cluster in fat */
fat_read_cluster(1);
fat_read_cluster(0);
do /* search for first free cluster */
{
if (fat_read_cluster(0) == 0x0000)
cluster_free = TRUE;
else
cluster++;
}
while ((cluster != fat_count_of_clusters) && (!cluster_free));
if (!cluster_free)
{
Hard_read_close();
return KO; /* no free cluster found */
}
fclusters[fat_last_clust_index].number = 1;
fclusters[fat_last_clust_index].cluster = cluster; /* store first cluster */
cluster++;
if (cluster != fat_count_of_clusters)
{
do /* construct the list */
{
cluster_free = FALSE;
if (fat_read_cluster(0) == 0x0000)
cluster_free = TRUE;
else
cluster++;
if (cluster_free) /* It's a contiguous cluster */
{ /* add it to the list */
if (fclusters[fat_last_clust_index].number == MAX_CL_PER_FRAG)
{
fat_last_clust_index++;
if (fat_last_clust_index == MAX_FILE_FRAGMENT_NUMBER)
{
Hard_read_close();
fat_last_clust_index--;
return OK;
}
fclusters[fat_last_clust_index].number = 1;
fclusters[fat_last_clust_index].cluster = cluster;
}
else
{
fclusters[fat_last_clust_index].number++;
}
cluster++; /* process next cluster */
}
else if (cluster != fat_count_of_clusters)
{ /* cluster is already used */
do /* search for next free fragment */
{
if (fat_read_cluster(0) == 0x0000)
cluster_free = TRUE;
else
cluster++;
}
while ((cluster != fat_count_of_clusters) && (!cluster_free));
if (!cluster_free) /* no more free cluster */
{
Hard_read_close();
return OK; /* end of partition reached */
}
fat_last_clust_index++; /* new free fragment cluster */
if (fat_last_clust_index == MAX_FILE_FRAGMENT_NUMBER)
{
Hard_read_close();
fat_last_clust_index--;
return OK;
}
fclusters[fat_last_clust_index].number = 1;
fclusters[fat_last_clust_index].cluster = cluster;
cluster++; /* process next cluster */
}
}
while ((fat_last_clust_index < MAX_FILE_FRAGMENT_NUMBER) && (cluster < fat_count_of_clusters));
}
Hard_read_close();
return OK;
}
/*F**************************************************************************
* NAME: fat_save_cluster_info
*----------------------------------------------------------------------------
* PARAMS:
*
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Save in locale variables cluster information for the current opened file
* - cluster index
* - number of the cluster
* - number of bytes in the cluster
*
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_save_cluster_info (void)
{
fat_fchain_index_save = fat_fchain_index;
fat_fchain_nb_clust_save = fat_fchain_nb_clust;
fat_fclust_byte_count_save = fat_fclust_byte_count % (fat_cluster_size * SECTOR_SIZE);
}
/*F**************************************************************************
* NAME: fat_file_get_pos
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* current file position in bytes
*----------------------------------------------------------------------------
* PURPOSE:
* Calculate the current file position
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint32 fat_file_get_pos (void)
{
Byte i;
Uint32 temp;
if (fat_fchain_nb_clust == 0)
{
return 0x00000000;
}
temp = 0;
for (i=0; i < fat_fchain_index; i++)
temp += fclusters[i].number;
temp += (fat_fchain_nb_clust - 1);
temp = temp * fat_cluster_size * SECTOR_SIZE;
temp = temp + (fat_fclust_byte_count % (fat_cluster_size * SECTOR_SIZE));
return temp;
}
/*F**************************************************************************
* NAME: fat_feob
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - TRUE : B position have been reached
* - FALSE : B position have not benn reached
*----------------------------------------------------------------------------
* PURPOSE:
* Determine if B position have been reached in mode repeat A/B
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_feob (void)
{
if (fat_fchain_index >= fat_fchain_index_save)
{
if (fat_fchain_nb_clust >= fat_fchain_nb_clust_save)
return (fat_fclust_byte_count >= fat_fclust_byte_count_save);
else
return FALSE;
}
else
{
return FALSE;
}
}
/*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:
*****************************************************************************/
bit fat_get_clusters (fat_st_clust_chain xdata *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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -