📄 fat.c
字号:
return OK;
}
/*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)[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:
*****************************************************************************/
bit 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_dseek
*----------------------------------------------------------------------------
* PARAMS:
* offset: offset to current position in signed word value
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Seek from the current position to a new offset computing relative
* poisition +/- scan size limited to a 16 bit offset
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* We consider here that the seek size is minor to the cluster size !!!
* if you want to do a more than a cluster seek, issue two successive
* dseek commands
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_dseek (Int16 offset)
{
Byte nb_sect; /* number of sectors to seek */
Uint16 nb_byte; /* number of bytes to seek */
Uint16 target_cluster; /* the cluster to reach */
Uint16 i;
fat_dir_current_offs += offset; /* Calculate the absolute byte pos */
nb_sect = (Byte)((fat_dir_current_offs) / SECTOR_SIZE);
fat_dir_current_sect = fat_dir_start_sect + nb_sect;
nb_byte = (Uint16)((fat_dir_current_offs) % (SECTOR_SIZE * fat_cluster_size));
fat_dclust_byte_count = nb_byte;
nb_byte %= SECTOR_SIZE;
if (dir_is_root == FALSE) /* Sub-directory ? */
{ /* Find the # cluster */
target_cluster = (nb_sect / fat_cluster_size);
fat_dchain_index = 0;
fat_dchain_nb_clust = 0;
for (i = 0; i <= target_cluster; i++)
{
if (dclusters[fat_dchain_index].number == fat_dchain_nb_clust)
{
fat_dchain_index++; /* next fragment */
fat_dchain_nb_clust = 1; /* reset the nb cluster in this new fragment */
}
else
{
fat_dchain_nb_clust++; /* next contiguous cluster */
}
}
/* update fat_dir_current_sect value */
fat_dir_current_sect = (((Uint32)(dclusters[fat_dchain_index].cluster + fat_dchain_nb_clust - 1) * fat_cluster_size)
+ fat_ptr_data + (nb_sect % fat_cluster_size));
if (!fat_dclust_byte_count)
{
if ((target_cluster == 0) || (dclusters[fat_dchain_index].number == 1)) /* If seek is first directory byte, reset */
{ /* fat_dchain_nb_clust (see fat_dgetc()) */
fat_dchain_nb_clust = 0;
}
}
}
Hard_read_close();
if (Hard_read_open(fat_dir_current_sect) == OK)
{ /* seek in current sector */
for (i = 0; i < nb_byte; i += 2)
{
Hard_read_byte(); /* dummy reads */
Hard_read_byte();
}
return OK;
}
else
{
return KO; /* low level error */
}
}
/*F**************************************************************************
* NAME: fat_dgetc
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the directory data byte at the current position
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_dgetc (void)
{
/* 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;
Hard_read_close();
Hard_read_open(fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster) * fat_cluster_size));
fat_dir_current_sect = fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster) * fat_cluster_size);
}
else
{ /* no new fragment */
fat_dir_current_sect = fat_ptr_data + ((Uint32)(dclusters[fat_dchain_index].cluster + fat_dchain_nb_clust) * fat_cluster_size);
fat_dchain_nb_clust++; /* one more cluster read */
}
}
fat_dclust_byte_count++; /* one more byte read */
return Hard_read_byte();
}
/*F**************************************************************************
* NAME: fat_fseek
*----------------------------------------------------------------------------
* PARAMS:
* offset: relative signed seek offset in file
*
* return:
* seek status: - OK: seek done
* - KO: out of file seek
*----------------------------------------------------------------------------
* PURPOSE:
* Change file pointer of an openned file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* In read mode, seek is done with byte boundary
* In write mode, seek is done with sector boundary
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_fseek (Int32 offset)
{
Uint32 file_pos; /* current position in file */
Uint16 cluster_offset; /* cluster offset in file */
Byte sector_offset; /* sector offset in cluster */
#define i sector_offset /* local variable overlay */
#define byte_offset cluster_offset /* local variable overlay */
/* init file pos with the current cluster in the index */
if (fat_fchain_nb_clust != 0)
file_pos = fat_fchain_nb_clust - 1;
else
file_pos = 0;
/* Add the previous cluster number */
for (i = 0; i != fat_fchain_index; i++)
{
file_pos += fclusters[i].number;
}
/* convert absolute cluster value in byte position */
file_pos *= SECTOR_SIZE * fat_cluster_size;
if ((fat_fchain_nb_clust != 0) && ( fat_fclust_byte_count % (fat_cluster_size * SECTOR_SIZE) == 0))
{
file_pos += (fat_cluster_size * SECTOR_SIZE);
}
else
{
((Byte*)&fat_fclust_byte_count)[0] &= fat_cluster_mask;
file_pos += fat_fclust_byte_count; /* offset in cluster */
}
/* Check range value */
if (((file_pos + offset) < 0) ||
((file_pos + offset) > fat_cache.current.size.l))
{
return KO; /* out of file limits */
}
file_pos += offset; /* new position */
/* Calculate byte position in cluster */
((Byte*)&fat_fclust_byte_count)[1] = ((Byte*)&file_pos)[3];
((Byte*)&fat_fclust_byte_count)[0] = ((Byte*)&file_pos)[2];
/* Calculate the absolute cluster position */
cluster_offset = file_pos / (SECTOR_SIZE * fat_cluster_size);
fat_fchain_index = 0; /* reset fragment number */
/* Determinate the index for the chain cluster */
while (cluster_offset >= fclusters[fat_fchain_index].number)
{
cluster_offset -= fclusters[fat_fchain_index].number;
fat_fchain_index++; /* ome more fragment */
}
/* Determinate the cluster offset value for the selected index */
fat_fchain_nb_clust = cluster_offset;
/* Determinate the sector offset value in the selected cluster */
sector_offset = (fat_fclust_byte_count & ((fat_cluster_size * SECTOR_SIZE) - 1)) / SECTOR_SIZE;
/* seek into sector */
byte_offset = file_pos % SECTOR_SIZE;
/* re-open file in read or write mode */
if (fat_open_mode == READ)
{
Hard_read_close(); /* close reading */
Hard_read_open(((Uint32)(fclusters[fat_fchain_index].cluster + fat_fchain_nb_clust) * fat_cluster_size)
+ sector_offset + fat_ptr_data);
if ((fat_fchain_nb_clust != 0) || (sector_offset != 0) || (byte_offset != 0))
{ /* if no offset, nb_clust incremented in fgetc() function */
fat_fchain_nb_clust++; /* one-based variable */
}
while (byte_offset != 0)
{
Hard_read_byte(); /* dummy read */
byte_offset--;
}
}
return OK;
}
/*F**************************************************************************
* NAME: fat_fseek_abs
*----------------------------------------------------------------------------
* PARAMS:
* offset: absolute seek offset in file
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Move ahead file read pointer of an openned file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fseek_abs (Uint32 offset)
{
Byte sector_offset; /* sector offset in cluster */
Uint16 cluster_offset; /* cluster offset in file */
#define i sector_offset /* local variable overlay */
#define byte_offset cluster_offset /* local variable overlay */
/* Calculate byte position in cluster */
((Byte*)&fat_fclust_byte_count)[1] = ((Byte*)&offset)[3];
((Byte*)&fat_fclust_byte_count)[0] = (((Byte*)&offset)[2] & fat_cluster_mask);
/* Calculate the absolute cluster position */
cluster_offset = offset / (SECTOR_SIZE * fat_cluster_size);
fat_fchain_index = 0; /* reset fragment number */
/* Determinate the index for the chain cluster */
while (cluster_offset > fclusters[fat_fchain_index].number)
{
cluster_offset -= fclusters[fat_fchain_index].number;
fat_fchain_index++; /* ome more fragment */
}
/* Determinate the cluster offset value for the selected index */
fat_fchain_nb_clust = cluster_offset;
/* Determinate the sector offset value in the selected cluster */
sector_offset = fat_fclust_byte_count / (SECTOR_SIZE);
/* re-open file in read or write mode */
if (fat_open_mode == READ)
{
Hard_read_close(); /* close reading */
Hard_read_open(((Uint32)(fclusters[fat_fchain_index].clu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -