📄 fat.c
字号:
for (i = fat_dir_list_index + 1, gl_offset = 0; i < fat_dir_list_last; fat_dir_list_index++, i++)
gl_offset += fat_dir_entry_list[i];
if (fat_dseek(gl_offset * DIR_SIZE) == OK)
{
fat_get_dir_entry(&fat_cache.current);
return OK;
}
else
return KO; /* low level error */
}
/*F**************************************************************************
* NAME: fat_seek_entry_record
*----------------------------------------------------------------------------
* PARAMS:
* fat_dir_list_index : # of the fetched entry
*
* return:
* OK: file available
* KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the selected entry
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_seek_entry_record (void)
{
Uint16 gl_offset = 0;
Uint16 i;
if (dir_is_root)
{
fat_dir_current_sect = fat_ptr_rdir;
}
else
{
fat_dir_current_sect = (((Uint32)(dclusters[0].cluster)) * fat_cluster_size)
+ fat_ptr_data;
}
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_update_buf_fat
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function check if a fat sector have to be writen.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
* fat_root_entry must be updated.
*****************************************************************************/
void fat_update_buf_fat(Uint16 cluster_old, Uint16 cluster, bit end)
{
bit fat_12_parity;
Byte sector_number;
#define i cluster_old
fat_12_parity = ((Byte*)&cluster_old)[1] & 0x01;
sector_number = cluster_old * 3 / 1024;
i = (cluster_old * 3 / 2) & 0x1FF;
if (end == TRUE)
cluster = 0xFFF;
if (fat_12_parity == 0)
{
fat_buf_sector[i++] = ((Byte*)&cluster)[1];
if (((Byte*)&i)[0] == 0x02)
{
fat_update_fat_sector(sector_number);
sector_number++;
fat_load_sector(fat_ptr_fats + sector_number);
((Byte*)&i)[0] = 0x00;
}
fat_buf_sector[i] &= 0xF0;
fat_buf_sector[i] |= ((Byte*)&cluster)[0] & 0x0F;
}
else
{
fat_buf_sector[i] &= 0x0F;
fat_buf_sector[i] |= (((Byte*)&cluster)[1] & 0x0F) << 4;
i++;
if (((Byte*)&i)[0] == 0x02)
{
fat_update_fat_sector(sector_number);
sector_number++;
fat_load_sector(fat_ptr_fats + sector_number);
((Byte*)&i)[0] = 0x00;
}
fat_buf_sector[i++] = (cluster & 0x0FF0) >> 4;
if (((Byte*)&i)[0] == 0x02)
{
fat_update_fat_sector(sector_number);
sector_number++;
fat_load_sector(fat_ptr_fats + sector_number);
((Byte*)&i)[0] = 0x00;
}
}
if (end == TRUE)
fat_update_fat_sector(sector_number);
#undef i
}
/*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;
Uint16 i;
Uint16 cluster;
Uint16 nb_cluster;
/*********************/
/* Update root entry */
/*********************/
fat_load_sector(fat_ptr_rdir + (fat_root_entry >> 4));
i = (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[i + 28] = fat_cache.current.size.b[3];
fat_buf_sector[i + 29] = fat_cache.current.size.b[2];
fat_buf_sector[i + 30] = fat_cache.current.size.b[1];
fat_buf_sector[i + 31] = fat_cache.current.size.b[0];
ext[0] = fat_buf_sector[i + 8];
ext[1] = fat_buf_sector[i + 9];
ext[2] = fat_buf_sector[i + 10];
Hard_write_open(fat_ptr_rdir + (fat_root_entry >> 4));
for (i= 0; i< SECTOR_SIZE; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -