📄 fat.c
字号:
*----------------------------------------------------------------------------
* 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)
{ /* 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 = 1;
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)
{
/* goto the parent directory */
fat_cache.current = fat_cache.parent;
/* issue the equivalent to a cd .. DOS command */
return (fat_goto_subdir(id));
}
/*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(bit f_delete)
{
Byte index;
Byte chain_index;
Byte sector_number;
Uint16 k;
Uint16 i;
Uint16 j;
Uint16 cluster;
xdata Uint16 temp;
bit fat12_parity;
xdata Uint16 nb_cluster;
xdata Uint32 root_sector;
/*********************/
/* Update root entry */
/*********************/
if (f_delete == FALSE)
{
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 < 512; 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 < 512; 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 + 1;
j = 0;
index = 0;
/********************/
/* FAT16 management */
/********************/
if (fat_is_fat16)
{
/* Start at first chain cluster */
sector_number = (fclusters[0].cluster + 2) / 256;
/* Bufferize fat sector */
Hard_read_open(fat_ptr_fats + sector_number);
for (i=0; i < 512; i++)
fat_buf_sector[i] = Hard_read_byte();
Hard_read_close();
/* i -> word fat sector position */
i = ((fclusters[index].cluster + 2) * 2) & 0x1FF;
/* init the starting cluster value */
cluster = fclusters[index].cluster;
chain_index = 1;
do
{
/* Determinate the value of the next cluster */
if (fclusters[index].number == (chain_index))
{
/* increase index */
index++;
if (f_delete == TRUE)
{
fat_buf_sector[i++] = 0x00;
fat_buf_sector[i++] = 0x00;
}
else
{
fat_buf_sector[i++] = fclusters[index].cluster + 2;
fat_buf_sector[i++] = (fclusters[index].cluster + 2) >> 8;
}
chain_index = 1;
if (((fclusters[index].cluster + 2) / 256) != sector_number)
{ /* Fat change sector */
/* FAT 1 update */
Hard_write_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; 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 < 512; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
}
sector_number = (fclusters[index].cluster + 2) / 256;
Hard_read_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; i++)
fat_buf_sector[i] = Hard_read_byte();
Hard_read_close();
}
i = ((fclusters[index].cluster + 2) * 2) & 0x1FF;
cluster = fclusters[index].cluster;
}
else
{
cluster++;
if (f_delete == TRUE)
{
fat_buf_sector[i++] = 0x00;
fat_buf_sector[i++] = 0x00;
}
else
{
fat_buf_sector[i++] = cluster + 2 ;
fat_buf_sector[i++] = (cluster + 2) >> 8;
}
chain_index++;
if (i == 512) /* Sector is full ? */
{
/* FAT 1 update */
Hard_write_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; 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 < 512; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
}
sector_number++;
Hard_read_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; i++)
fat_buf_sector[i] = Hard_read_byte();
Hard_read_close();
i = 0;
}
}
j++;
}
while (j < nb_cluster);
/* End of file indicate by 0xFFFF */
if (i == 0)
{
sector_number--;
Hard_read_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; i++)
fat_buf_sector[i] = Hard_read_byte();
Hard_read_close();
i = 510;
}
else
{
i = i - 2;
}
if (f_delete == TRUE)
{
fat_buf_sector[i++] = 0x00;
fat_buf_sector[i++] = 0x00;
}
else
{
fat_buf_sector[i++] = 0xFF;
fat_buf_sector[i++] = 0xFF;
}
Hard_write_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; 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 < 512; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
}
}
/********************/
/* FAT12 management */
/********************/
else
{
/* Start at first fat sector */
sector_number = 0;
Hard_read_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; i++)
fat_buf_sector[i] = Hard_read_byte();
Hard_read_close();
cluster = 0; /* scanning cluster value */
fat12_parity = 0; /* flag for 2 r/w or 1 r/w byte */
index = 0; /* cluster chain index : 0 -> nb_frag */
k = 0; /* cluster index : 0 -> nb_cluster-1 */
i = 0; /* sector index : 0 -> 511 */
do /* do while (k < nb_cluster) */
{
if (cluster == (fclusters[index].cluster + 2)) /* start of a fragment */
{
if (fat12_parity == 1)
{
if (i == 0)
{
/* go back to previous fat sector */
sector_number--;
Hard_read_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; i++)
{
fat_buf_sector[i] = Hard_read_byte();
}
Hard_read_close();
/* Last sector byte */
i = 511;
}
else
{
i--;
}
}
if (fclusters[index].number != 0) /* end of chain marker */
{
for (j = 0; (j < fclusters[index].number - 1) && (k < nb_cluster - 1); j++)
{ /* Compute chain cluster */
cluster++;
if (fat12_parity == 0)
{
if (f_delete == TRUE)
{
fat_buf_sector[i++] = 0x00;
}
else
{
fat_buf_sector[i++] = cluster & 0x00FF;
}
if (i == 512)
{
/* FAT 1 update */
Hard_write_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; 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 < 512; i++)
Hard_write_byte(fat_buf_sector[i]);
Hard_write_close();
}
sector_number++;
Hard_read_open(fat_ptr_fats + sector_number);
for (i = 0; i < 512; i++)
fat_buf_sector[i] = Hard_read_byte();
Hard_read_close();
i = 0;
}
if (f_delete == TRUE)
{
fat_buf_sector[i] &= 0xF0;
}
else
{
fat_buf_sector[i] &= 0xF0;
fat_buf_sector[i] += ((cluster & 0x0F00) >> 8);
}
fat12_parity = 1;
k++;
}
else
{
if (f_delete == TRUE)
{
fat_buf_sector[i] &= 0x0F;
}
else
{
fat_buf_sector[i] &= 0x0F;
fat_buf_sector[i] += ((cluster & 0x000F) << 4);
}
i++;
if (i == 512)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -