📄 fat.c
字号:
{
/* true DOS 8.3 entry format */
for (i = 0; i < 8; i++)
{
lfn_name[i] = gl_buffer[i];
if (lfn_name[i] == ' ')
{ /* space is end of name */
break;
}
}
/* append extension */
lfn_name[i++] = '.';
lfn_name[i++] = gl_buffer[8];
lfn_name[i++] = gl_buffer[9];
lfn_name[i++] = gl_buffer[10];
for (; i != 14; i++)
{
lfn_name[i] = ' '; /* append spaces for display reason */
}
lfn_name[i] = '\0'; /* end of string */
}
else
{ /* LFN name treatment */
i = 0;
/* search for the end of the string */
while (lfn_name[i] != '\0')
{
i++;
}
if (i <= 14)
{ /* append spaces for display reason (no scrolling) */
while (i != 14)
{
lfn_name[i++] = ' ';
}
}
else
{ /* append beginning of name to ease scrolling display */
lfn_name[i++] = ' ';
lfn_name[i++] = ' ';
lfn_name[i++] = lfn_name[0];
lfn_name[i++] = lfn_name[1];
lfn_name[i++] = lfn_name[2];
lfn_name[i++] = lfn_name[3];
lfn_name[i++] = lfn_name[4];
lfn_name[i++] = lfn_name[5];
lfn_name[i++] = lfn_name[6];
lfn_name[i++] = lfn_name[7];
lfn_name[i++] = lfn_name[8];
lfn_name[i++] = lfn_name[9];
lfn_name[i++] = lfn_name[10];
lfn_name[i++] = lfn_name[11];
lfn_name[i++] = lfn_name[12];
}
lfn_name[i] = '\0'; /* end of name */
}
/* store extension */
ext[0]= gl_buffer[8];
ext[1]= gl_buffer[9];
ext[2]= gl_buffer[10];
/* standard computing for normal entry */
entry->attributes = gl_buffer[11];
entry->start_cluster = gl_buffer[26];
entry->start_cluster += ((Uint16) gl_buffer[27]) << 8;
entry->size.b[3] = gl_buffer[28];
entry->size.b[2] = gl_buffer[29];
entry->size.b[1] = gl_buffer[30];
entry->size.b[0] = gl_buffer[31];
/* now it's time to stop */
exit_flag = TRUE;
}
else
{ /* LFN entry format */
lfn_entry_found = TRUE; /* a 8.3 name will follow */
if ((gl_buffer[0] & LFN_SEQ_MASK) <= MAX_LFN_ENTRIES)
{ /* Maximum number of entries for LFN? */
for (i = 0; i < 5; i++)
{
song_name[i] = gl_buffer[2*i + 1]+gl_buffer[2*i + 1 + 1]*256;
lfn_name[i + 13*((gl_buffer[0] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 1];
}
for (i = 0; i < 6; i++)
{
song_name[i + 5] = gl_buffer[2*i + 14]+gl_buffer[2*i + 14 + 1]*256;
lfn_name[i + 5 + 13*((gl_buffer[0] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 14];
}
for (i = 0; i < 2; i++)
{
lfn_name[i + 11 + 13*((gl_buffer[0] & LFN_SEQ_MASK) - 1)] = gl_buffer[2*i + 28];
}
}
}
}
Hard_read_close(); /* close physical read */
}
/*F**************************************************************************
* NAME: fat_get_dir_file_list
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Construct the file directory list
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* The value are relative position with the previous file.
* Call to this function assume that the dir fragment chain has been created
*----------------------------------------------------------------------------
* REQUIREMENTS:
* Maximum of 256 entries between 2 authorized file (id extension)
* because the relative position is stored on one byte.
* To allow more than 256 entries (-> 32768), change type of
* fat_dir_entry_list[] from Byte to Uint16 (no overflow management)
* and change MAX_DIRECTORY_GAP_FILE from 255 to 32767
*****************************************************************************/
void fat_get_dir_file_list (Byte id)
{
Uint16 index; /* chain index */
Uint16 counter_entry; /* entry counter: 0..MAX_DIRECTORY_FILE */
Uint16 entry_pos; /* relative entry position */
Uint16 entry_pos_saved; /* used when the file is not the id etension */
Byte i;
index = 0;
fat_dir_list_last = 0;
counter_entry = 0;
entry_pos = 0;
fat_dir_start_sect = fat_dir_current_sect;
fat_dir_current_offs = 0;
Hard_read_open(fat_dir_start_sect);
do /* scan all entries */
{
if (dir_is_root == TRUE)
{ /* root dir is linear -> Hard_read_byte() */
for (i = 0; i < DIR_SIZE; i++)
gl_buffer[i] = Hard_read_byte();
}
else
{ /* subdir can be fragmented -> dgetc() */
for (i = 0; i < DIR_SIZE; i++)
gl_buffer[i] = fat_dgetc();
}
counter_entry++; /* increase the # entry */
if ((gl_buffer[0] != FILE_DELETED) && (gl_buffer[0] != FILE_NOT_EXIST))
{ /* Existing file ? */
fat_dir_entry_list[index] = entry_pos; /* save the relative position */
entry_pos_saved = entry_pos;
entry_pos = 1; /* reset the relative position */
index++; /* increase the index */
while (gl_buffer[11] == ATTR_LFN_ENTRY) /* LFN entry ? */
{ /* then read all the LFN entry */
if (dir_is_root == TRUE)
{ /* root dir is linear -> Hard_read_byte() */
for (i = 0; i < DIR_SIZE; i++)
gl_buffer[i] = Hard_read_byte();
}
else
{ /* subdir can be fragmented -> dgetc() */
for (i = 0; i < DIR_SIZE; i++)
gl_buffer[i] = fat_dgetc();
}
counter_entry++; /* increase the # entry */
entry_pos++; /* increase the relative position */
/* for the next file */
}
/* filter on the file type */
fat_cache.current.attributes = gl_buffer[11];
ext[0] = gl_buffer[8];
ext[1] = gl_buffer[9];
ext[2] = gl_buffer[10];
if ((fat_check_ext() & id) == FILE_XXX)
{ /* Don't valid the entry */
index--;
entry_pos += entry_pos_saved;
}
}
else /* Not an existing file */
entry_pos++;
fat_dir_list_last = index; /* update last file index */
/* For sub-directory, there is no logical limit for the number of entries */
/* In order to detect the last file, we check gl_buffer[0] */
/* We can put in the chain directory MAX_DIRECTORY_FILE selected file */
if (gl_buffer[0] == FILE_NOT_EXIST)
index = MAX_DIRECTORY_FILE;
/* Overflow of entry_pos */
if (entry_pos > MAX_DIRECTORY_GAP_FILE)
index = MAX_DIRECTORY_FILE;
/* For Root directory, the maximum entries is 512! */
if ((dir_is_root == TRUE) && (counter_entry == MAX_DIRECTORY_FILE))
index = MAX_DIRECTORY_FILE;
if (dir_is_root == FALSE)
{
/* check if we are at the end of the directory */
if ((((Byte*)&fat_dclust_byte_count)[1] == 0x00) &&
((((Byte*)&fat_dclust_byte_count)[0] & fat_cluster_mask) == 0x00) &&
(fat_last_dclust_index == fat_dchain_index))
index = MAX_DIRECTORY_FILE;
}
}
while (index < MAX_DIRECTORY_FILE);
fat_dir_current_sect = fat_dir_start_sect;
Hard_read_close();
}
/*F**************************************************************************
* NAME: fat_get_root_directory
*----------------------------------------------------------------------------
* PARAMS:
* id: file extension to select
*
* return:
* - OK: file available
* - KO: no requested file found
* - KO: low_level memory error
*----------------------------------------------------------------------------
* PURPOSE:
* Select first available file/dir in root diretory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* Fill all the cache information for the first time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_get_root_directory (Byte id)
{
/* select first root dir entry */
fat_dir_current_sect = fat_ptr_rdir;
fat_dclust_byte_count = 0;
dir_is_root = TRUE;
fat_get_dir_file_list(id); /* create list of entries */
if (fat_dir_list_last == 0)
return KO; /* no requested (id) entry */
fat_dir_list_index = 0; /* point on first root entry */
/* extract info from table */
if (fat_dseek(fat_dir_entry_list[0] * DIR_SIZE) == OK)
{
fat_get_dir_entry(&fat_cache.current); /* update current file info */
/* parent dir is also root */
fat_cache.parent.start_cluster = 0;
fat_cache.parent.attributes = ATTR_ROOT_DIR; /* mark as root dir */
return OK;
}
else
return KO; /* low level error */
}
/*F**************************************************************************
* NAME: fat_goto_next
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - OK: next file available
* - KO: last file reached
* - KO: low_level memory error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the next dir/file info in cache
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_next (void)
{
if (fat_dir_list_index < (fat_dir_list_last - 1))
{
fat_dir_list_index++;
if (fat_dseek((Int16)(fat_dir_entry_list[fat_dir_list_index ] * DIR_SIZE))== OK)
{
fat_get_dir_entry(&fat_cache.current);/* update current file info */
return OK;
}
else
return KO; /* low level error */
}
else
return KO; /* already on last file */
}
/*F**************************************************************************
* NAME: fat_goto_prev
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - OK: previous file available
* - KO: first file reached
* - KO: low_level memory error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the previous directory info in cache
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_goto_prev (void)
{
Byte min;
if (dir_is_root)
min = 0;
else
min = 2;
if (fat_dir_list_index != min) /* first file of the directory? */
{
if (fat_dseek((Int16)(fat_dir_entry_list[fat_dir_list_index] * (-DIR_SIZE))) == OK)
{ /* go to previous file */
fat_dir_list_index--;
fat_get_dir_entry(&fat_cache.current);/* update current file info */
return OK;
}
else
return KO; /* low level error */
}
else
return KO; /* already on first file */
}
/*F**************************************************************************
* NAME: fat_seek_last
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* OK: last file available
* KO: low level error
*----------------------------------------------------------------------------
* PURPOSE:
* Fetch the last directory info in cache
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_seek_last (void)
{
Uint16 gl_offset;
Uint16 i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -