📄 fat.c
字号:
{ /* 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: 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.attributes != ATTR_ROOT_DIR)
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);
/* 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:
*----------------------------------------------------------------------------
* PURPOSE:
* Go to the parent directory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_parentdir (Byte id)
{
Uint16 temp_cluster;
/* save cluster info */
temp_cluster = dclusters[0].cluster + 2; //fat_cache.parent.start_cluster;
/* goto the parent directory */
fat_cache.current = fat_cache.parent;
/* issue the equivalent to a cd .. DOS command */
if (fat_goto_subdir(id))
{
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();
}
}
/* Fat_load_fat_sector(sector_number) bufferize an entire fat sector */
#define Fat_load_fat_sector(sector_number) \
Hard_read_open(fat_ptr_fats + sector_number); \
for (i=0; i < SECTOR_SIZE; i++) \
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_fat_sector(sector_number); \
i = 0; \
}
/*F**************************************************************************
* NAME: fat_update_entry_fat
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Update entry and FAT after a writing file session
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* FAT16 update : random update (direct access)
* FAT12 update : sequential update
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_update_entry_fat (void)
{
Byte index;
Byte chain_index;
Byte sector_number;
Uint16 i;
Uint16 j;
Uint16 cluster;
xdata Uint16 temp;
bit fat12_parity;
xdata Uint16 nb_cluster;
xdata Uint32 root_sector;
/*********************/
/* Update root entry */
/*********************/
fat_file_size.l = fat_current_file_size;
root_sector = fat_ptr_rdir + (fat_root_entry / 16); /* root sector address */
Hard_read_open(root_sector);
for (i = 0; i < SECTOR_SIZE; i++)
fat_buf_sector[i] = Hard_read_byte(); /* read one page */
j = (fat_root_entry % 16) * 32 ; /* Position of entry in the sector */
Hard_read_close();
/* Update file size */
fat_buf_sector[j + 28] = fat_file_size.b[3];
fat_buf_sector[j + 29] = fat_file_size.b[2];
fat_buf_sector[j + 30] = fat_file_size.b[1];
fat_buf_sector[j + 31] = fat_file_size.b[0];
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_file_size.l / SECTOR_SIZE) / fat_cluster_size;
if ((fat_file_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_fat_sector(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_fat_sector(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);
}
/********************/
/* FAT12 management */
/********************/
else
{
j = 1;
cluster = fclusters[index].cluster + 2;
sector_number = cluster * 3 / 1024;
/* Bufferize fat sector */
Fat_load_fat_sector(sector_number);
temp = cluster;
fat12_parity = cluster & 0x01;
i = (cluster * 3 / 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;
if (fat12_parity == 0)
{
fat_buf_sector[i++] = cluster & 0x00FF;
Fat_check_update(sector_number);
fat_buf_sector[i] &= 0xF0;
fat_buf_sector[i] |= ((cluster & 0x0F00) >> 8);
fat12_parity = 1;
}
else
{
fat_buf_sector[i] &= 0x0F;
fat_buf_sector[i] |= ((cluster & 0x000F) << 4);
i++;
Fat_check_update(sector_number);
fat_buf_sector[i++] = (cluster & 0x0FF0) >> 4;
Fat_check_update(sector_number);
fat12_parity = 0;
}
chain_index = 1;
temp = cluster * 3 / 1024;
if ( temp != sector_number)
{ /* Fat change sector */
fat_update_fat_sector(sector_number);
sector_number = temp;;
Fat_load_fat_sector(sector_number);
}
i = (cluster * 3 / 2) & 0x1FF;
}
else
{
cluster++;
if (fat12_parity == 0)
{
fat_buf_sector[i++] = cluster & 0x00FF;
Fat_check_update(sector_number);
fat_buf_sector[i] &= 0xF0;
fat_buf_sector[i] |= ((cluster & 0x0F00) >> 8);
fat12_parity = 1;
}
else
{
fat_buf_sector[i] &= 0x0F;
fat_buf_sector[i] |= ((cluster & 0x000F) << 4);
i++;
Fat_check_update(sector_number);
fat_buf_sector[i++] = (cluster & 0x0FF0) >> 4;
Fat_check_update(sector_number);
fat12_parity = 0;
}
chain_index++;
}
j++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -