📄 fat.c
字号:
fat_dir_current_offs = 0; /* reset the global offset */
for (i = 0; i <= fat_dir_list_index; i++)
gl_offset += fat_dir_entry_list[i];
return fat_dseek(gl_offset * DIR_SIZE);
}
/*F**************************************************************************
* NAME: fat_seek_first
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - OK: first file found
* - KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the first directory info in cache
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_seek_first (void)
{
fat_dir_current_offs = 0; /* reset the global offset */
if (dir_is_root)
{ /* root diretory */
fat_dir_list_index = 0; /* point first root entry */
if (fat_dseek((Int16)(fat_dir_entry_list[0] * DIR_SIZE)) == OK)
{
fat_get_dir_entry(&fat_cache.current);/* update first file info */
return OK;
}
else
{
return KO; /* low level error */
}
}
else
{ /* not root dir */
fat_dir_list_index = 1; /* point ".." entry */
if (fat_dseek((Int16)(fat_dir_entry_list[1] * DIR_SIZE)) == OK)
{
fat_get_dir_entry(&fat_cache.parent); /* update parent dir info */
return fat_goto_next(); /* update first file info */
}
else
return KO; /* low level error */
}
}
/*F**************************************************************************
* NAME: fat_goto_subdir
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
*
* return:
* - OK: subdir selected
* - KO: current entry not a directory
* - KO: no file in subdir
* - KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Go to the subdir if current is a directory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* Also called by goto_parentdir() with current info from parent info
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_subdir (Byte id)
{
/* check if current file is a directory */
if ((fat_cache.current.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
{
/* computes the sector address (RELATIVE) */
if (fat_cache.current.start_cluster != 0)
{ /* go to not root dir */
dir_is_root = FALSE; /* not the root dir */
/* get directory allocation table */
fat_get_clusters(&dclusters, MAX_DIR_FRAGMENT_NUMBER);
/* Save last index position for chain cluster */
fat_last_dclust_index = fat_last_clust_index;
/* initialize fat pointers */
fat_dchain_nb_clust = 0;
fat_dchain_index = 0;
fat_dclust_byte_count = 0;
/* computes sector address from allocation table */
fat_dir_current_sect = (((Uint32)(dclusters[0].cluster)) * fat_cluster_size)
+ fat_ptr_data;
}
else
{ /* go to root dir */
return fat_get_root_directory(id);
}
fat_get_dir_file_list(id); /* create list of entries */
fat_dir_list_index = 1; /* point ".." entry */
if (fat_dseek((Int16)(fat_dir_entry_list[1] * DIR_SIZE)) == OK)
{
fat_get_dir_entry(&fat_cache.parent); /* update parent dir info */
return fat_goto_next(); /* update first file info */
}
else
return KO; /* low level error */
}
else
return KO; /* current entry is not a dir */
}
/*F**************************************************************************
* NAME: fat_goto_parentdir
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
*
* return:
* status: OK: parent_dir selected
* KO: no parent dir (root)
*----------------------------------------------------------------------------
* PURPOSE:
* Go to the parent directory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* File pointed is sub-dir if parent dir is not root or first file if root
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_parentdir (Byte id)
{
Uint16 temp_cluster;
if (dir_is_root)
{ /* already in root dir */
fat_seek_first(); /* point on first file */
return KO;
}
else
{ /* not in root dir */
temp_cluster = dclusters[0].cluster + 2;/* save cluster info */
fat_cache.current = fat_cache.parent; /* goto the parent directory */
/* issue the equivalent to a cd .. DOS command */
if (fat_goto_subdir(id))
{ /* reselect the dir entry in list */
while (temp_cluster != fat_cache.current.start_cluster)
{
if (fat_goto_next() == KO)
break;
}
if (temp_cluster == fat_cache.current.start_cluster)
return OK;
else
return KO;
}
else
{
return KO;
}
}
}
/*F**************************************************************************
* NAME: fat_update_fat_sector
*----------------------------------------------------------------------------
* PARAMS:
* sector_number : fat sector position
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* update a sector of fat
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* This function check if there is 2 fats to be updated
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_update_fat_sector (Uint16 sector_number)
{
Uint16 i;
/* FAT 1 update */
Hard_write_open(fat_ptr_fats + sector_number);
for (i = 0; i < SECTOR_SIZE; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
if (fat_2_is_present == TRUE)
{
/* FAT 2 update */
Hard_write_open(fat_ptr_fats + sector_number + fat_fat_size);
for (i = 0; i < SECTOR_SIZE; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
}
}
/*F**************************************************************************
* NAME: fat_load_sector
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function load a sector in fat_buf_sector
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
* fat_root_entry must be updated.
*****************************************************************************/
void fat_load_sector(Uint32 sector)
{
Uint16 i;
Hard_read_open(sector);
for (i = 0; i < (SECTOR_SIZE); i++)
{
fat_buf_sector[i++] = Hard_read_byte();
fat_buf_sector[i++] = Hard_read_byte();
fat_buf_sector[i++] = Hard_read_byte();
fat_buf_sector[i] = Hard_read_byte();
}
Hard_read_close();
}
/* Fat_check_update(sector_number) check if the fat sector is complete and save it */
#define Fat_check_update(sector_number) \
if (i == SECTOR_SIZE) /* Sector is full ? */ \
{ \
fat_update_fat_sector(sector_number); \
sector_number++; \
fat_load_sector(fat_ptr_fats + sector_number); \
i = 0; \
}
/*F**************************************************************************
* NAME: fat_update_entry_fat
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Update root entry and FAT after a writing file session (create or re-write)
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
* fat_root_entry must be updated.
*****************************************************************************/
void fat_update_entry_fat (void)
{
Byte index;
Byte chain_index;
Byte sector_number;
Byte id;
Uint16 i;
Uint16 j;
Uint16 cluster;
xdata Uint16 temp;
bit fat12_parity;
xdata Uint16 nb_cluster;
xdata Uint32 root_sector;
/*********************/
/* Update root entry */
/*********************/
root_sector = fat_ptr_rdir + (fat_root_entry / 16); /* root sector address */
fat_load_sector(root_sector);
j = (fat_root_entry % 16) * 32 ; /* Position of entry in the sector */
/* Update file size */
if (fat_cache.current.size.l <= fat_file_size.l)
fat_cache.current.size.l = fat_file_size.l;
fat_buf_sector[j + 28] = fat_cache.current.size.b[3];
fat_buf_sector[j + 29] = fat_cache.current.size.b[2];
fat_buf_sector[j + 30] = fat_cache.current.size.b[1];
fat_buf_sector[j + 31] = fat_cache.current.size.b[0];
ext[0] = fat_buf_sector[j + 8];
ext[1] = fat_buf_sector[j + 9];
ext[2] = fat_buf_sector[j + 10];
id = fat_check_ext();
Hard_write_open(root_sector);
for (i=0; i < SECTOR_SIZE; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
/********************/
/* Update fat 1 & 2 */
/********************/
/* Calculate file size cluster */
nb_cluster = (fat_cache.current.size.l / SECTOR_SIZE) / fat_cluster_size;
if ((fat_cache.current.size.l % (fat_cluster_size * SECTOR_SIZE)))
{
nb_cluster++;
}
j = 1;
index = 0;
/********************/
/* FAT16 management */
/********************/
if (fat_is_fat16)
{
/* init the starting cluster value */
cluster = fclusters[0].cluster + 2;
/* Start at first chain cluster */
sector_number = cluster / 256;
/* Bufferize fat sector */
fat_load_sector(fat_ptr_fats + sector_number);
/* i -> word fat sector position */
i = (cluster * 2) & 0x1FF;
chain_index = 1;
while (j < nb_cluster)
{
/* Determinate the value of the next cluster */
if (fclusters[index].number == (chain_index))
{
/* increase index */
index++;
cluster = fclusters[index].cluster + 2;
fat_buf_sector[i++] = cluster;
fat_buf_sector[i] = cluster >> 8;
chain_index = 1;
if ( (cluster / 256) != sector_number)
{ /* Fat change sector */
fat_update_fat_sector(sector_number);
sector_number = (Uint16)(cluster / 256);
fat_load_sector(fat_ptr_fats + sector_number);
}
i = (cluster * 2) & 0x1FF;
}
else
{
cluster++;
fat_buf_sector[i++] = cluster;
fat_buf_sector[i++] = cluster >> 8;
chain_index++;
Fat_check_update(sector_number);
}
j++;
}
/* End of file indicate by 0xFFFF */
fat_buf_sector[i++] = 0xFF;
fat_buf_sector[i] = 0xFF;
fat_update_fat_sector(sector_number);
}
/********************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -