📄 fat.c
字号:
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* As this function is called very often it must be short and optimized
* in execution time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fputc (Byte d)
{
/* check if we are at the end of a cluster */
if ((((Byte*)&fat_file_byte_counter)[3] == 0x00) &&
((((Byte*)&fat_file_byte_counter)[2] & fat_cluster_mask) == 0x00))
{
/* extract if necessary the next cluster from the allocation list */
if (clusters.number[fat_chain_index] == fat_chain_cluster)
{ /* new fragment */
fat_chain_index++;
fat_chain_cluster = 1;
Hard_write_open(fat_ptr_data + ((Uint32)(clusters.cluster[fat_chain_index]) * fat_cluster_size));
}
else
{ /* no new fragment */
fat_chain_cluster++; /* one more cluster read */
}
}
fat_file_byte_counter++; /* one more byte read */
Hard_write_byte(d);
}
/*F**************************************************************************
* NAME: fat_feof
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the file end flag
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_feof (void)
{
return (fat_file_byte_counter >= fat_cache.info.size);
}
/*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)
{
idata Byte nb_sect; /* number of sectors to seek */
idata Uint16 nb_byte; /* number of bytes to seek */
idata Uint16 next_cluster; /* the possible next cluster to load */
idata Uint16 target_cluster; /* the cluster to reach */
Uint16 i;
fat_directory_pos += offset; /* Calculate the absolute byte pos */
nb_sect = (Byte)((fat_directory_pos) / SECTOR_SIZE);
nb_byte = (Uint16)((fat_directory_pos) % SECTOR_SIZE);
fat_current_sector = fat_directory_base + nb_sect;
fat_current_byte_counter = nb_byte;
if (dir_is_root == FALSE) /* Sub-directory ? */
{ /* Fin the # cluster */
target_cluster = (nb_sect / fat_cluster_size);
fat_current_dir_cluster = 0;
next_cluster = dir_clusters.cluster[fat_current_dir_cluster];
fat_current_dir_fragment = 1;
for (i = 0; i < target_cluster; i++)
{
if (dir_clusters.number[fat_current_dir_cluster] <= fat_current_dir_fragment)
{ /* new fragment */
fat_current_dir_cluster++;
fat_current_dir_fragment = 1;
next_cluster = dir_clusters.cluster[fat_current_dir_cluster];
}
else
{ /* no new fragment */
next_cluster = dir_clusters.cluster[fat_current_dir_cluster] + fat_current_dir_fragment;
fat_current_dir_fragment++;
}
}
fat_current_sector = (((Uint32)(next_cluster) * fat_cluster_size)
+ fat_ptr_data + (nb_sect % fat_cluster_size));
}
if (Hard_read_open(fat_current_sector) == OK)
{
for (i = 0; i < fat_current_byte_counter; i += 2)
{
/* dummy reads */
nb_sect = Hard_read_byte();
nb_sect = Hard_read_byte();
}
return OK;
}
else
{
return KO;
}
}
/*F**************************************************************************
* NAME: fat_dgetc
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the directory data byte at the current position
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_dgetc (void)
{
idata Uint16 next_cluster; /* new cluster in allocation list */
/* check if we are at the end of a cluster */
if (((((Byte*)&fat_current_byte_counter)[0] & fat_cluster_mask) == 0x00) &&
(((Byte*)&fat_current_byte_counter)[1] == 0x00) && (fat_current_byte_counter != 0x00))
{
/* extract the next cluster from the clusters allocation list */
if (dir_clusters.number[fat_current_dir_cluster] == fat_current_dir_fragment)
/* if there is a new fragment */
{
fat_current_dir_cluster++;
fat_current_dir_fragment = 1;
next_cluster = dir_clusters.cluster[fat_current_dir_cluster];
}
else
{
next_cluster = dir_clusters.cluster[fat_current_dir_cluster] + fat_current_dir_fragment;
fat_current_dir_fragment++;
}
/* read the next sectors... */
fat_current_sector = fat_ptr_data + ((Uint32)(next_cluster) * fat_cluster_size);
while(Hard_read_open(fat_current_sector) != OK);
fat_current_byte_counter = 0;
}
/* increment the global counters */
fat_current_byte_counter++;
return Hard_read_byte();
}
/*F**************************************************************************
* NAME: fat_fseek
*----------------------------------------------------------------------------
* PARAMS: offset: seek offset in file
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Change file read pointer of an openned file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fseek (Uint32 offset)
{
Int16 cluster_offset; /* offset size in clusters */
Byte index;
/* compute cluster number */
cluster_offset = (offset / (SECTOR_SIZE * fat_cluster_size));
index = 0;
while (cluster_offset > clusters.number[index])
{
cluster_offset -= clusters.number[index];
index++;
}
/* init file byte counter */
fat_file_byte_counter = offset;
/* set the allocation list variable */
fat_chain_cluster = cluster_offset;
fat_chain_index = index;
/* re-open file in read or write mode */
if (fat_open_mode == READ)
{
Hard_read_close(); /* close reading */
Hard_read_open(((Uint32)(clusters.cluster[index] + cluster_offset) * fat_cluster_size)
+ (offset / SECTOR_SIZE) % fat_cluster_size + fat_ptr_data);
}
else
{
Hard_write_close(); /* close writing */
Hard_write_open(((Uint32)(clusters.cluster[index] + cluster_offset) * fat_cluster_size)
+ (offset / SECTOR_SIZE) % fat_cluster_size + fat_ptr_data);
}
/* seek in sector */
offset = offset % SECTOR_SIZE;
if (((Uint16)offset) != 0)
{
fat_chain_cluster++;
do
{
Hard_read_byte(); /* dummy read */
offset--;
}
while (((Uint16)offset) != 0);
}
}
/*F**************************************************************************
* NAME: fat_check_ext
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the type of the file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_check_ext (void)
{
if ((fat_cache.info.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
{
return FILE_DIR;
}
else
{
if ((ext[0] == 'M') &&
(ext[1] == 'P') &&
(ext[2] == '3'))
{
return FILE_MP3;
}
else
{
if ((ext[0] == 'W') &&
(ext[1] == 'A') &&
(ext[2] == 'V'))
{
return FILE_WAV;
}
else
{
if ((ext[0] == 'S') &&
(ext[1] == 'Y') &&
(ext[2] == 'S'))
{
return FILE_SYS;
}
else
{
return FILE_XXX;
}
}
}
}
}
/*F**************************************************************************
* NAME: fat_get_name
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Return the address of the file name string
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
char pdata * fat_get_name (void)
{
return (lfn_name);
}
/*F**************************************************************************
* NAME: fat_format
*----------------------------------------------------------------------------
* PARAMS:
* voice: - TRUE: format with voice files
* - FALSE: format without voice files
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Create single FAT12 or FAT16 partition and format the selected memory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* - Single partition
* - Cluster size is 4 or 8 Kbytes
* - Sector size is 512 bytes
* - 2 fats management
* - 512 entries in the root directory
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_format (bit voice)
{
#define WAV_CLUST_SIZE (Uint16)((WAV_SECTOR_SIZE) / fat_cluster_size)
#define FORMAT_NB_CYLINDER (*tab).nb_cylinder
#define FORMAT_NB_HEAD (*tab).nb_head
#define FORMAT_NB_SECTOR (*tab).nb_sector
#define FORMAT_NB_HIDDEN_SECTOR (*tab).nb_hidden_sector
#define FORMAT_NB_SECTOR_PER_CLUSTER (*tab).nb_sector_per_cluster
Byte i, j;
Uint32 nb_total_sectors;
Uint16 nb_sector_fat;
Uint16 s, t;
s_format code *tab;
tab = Hard_format();
fat_cluster_size = FORMAT_NB_SECTOR_PER_CLUSTER;
nb_total_sectors = (Uint32)FORMAT_NB_CYLINDER * FORMAT_NB_HEAD * FORMAT_NB_SECTOR;
/* FAT type caculation */
fat_is_fat16 = ((nb_total_sectors / fat_cluster_size) > MAX_CLUSTERS12);
/* -- MASTER BOOT RECORD -- */
Hard_write_open(0x00);
for (i = 446/2; i != 0; i--) /* Boot Code */
{
Hard_write_byte(0x00);
Hard_write_byte(0x00);
}
/* First Partition entry */
Hard_write_byte(0x80); /* Default Boot Partition */
Hard_write_byte((Byte)(FORMAT_NB_HIDDEN_SECTOR / FORMAT_NB_SECTOR)); /* Start head */
Hard_write_byte((Byte)((FORMAT_NB_HIDDEN_SECTOR % FORMAT_NB_SECTOR) + 1)); /* Start Sector */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -