⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 这是atmel公司的89C51SND1C的mp3源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* check if current file is a directory */
  if ((fat_cache.info.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
  {
    /* computes the sector address (RELATIVE)                               */
    /* check also if we go to the root dir or not                           */
    if (fat_cache.info.start_cluster != 0)
    { 
      dir_is_root = FALSE;                /* not the root dir               */
      fat_get_clusters(&dir_clusters);    /* get directory allocation table */

      /* initialize fat pointers */
      fat_current_dir_fragment = 1;
      fat_current_dir_cluster = 0;
      fat_current_sector_cluster = 0;
      fat_current_byte_counter = 0;
                          
      /* computes sector number from allocation table */
      fat_current_sector = (((Uint32)(dir_clusters.cluster[0])) *
      fat_cluster_size) + (fat_ptr_data - fat_ptr_rdir);
    }
    else
    {
      return fat_get_root_directory(id);  /* goto root directory            */
    }

    /* set the ABSOLUTE sector address */
    fat_current_sector += fat_ptr_rdir;

    fat_get_directory_chain(id);

    fat_file_ptr = 1;
    /* now we are at the beginning of directory */
    if (fat_dseek((Int16)(fat_directory_chain[fat_file_ptr] * 32)) == OK)
    {
      /* update parent info in ".." entry*/
      fat_fetch_directory_info(&fat_cache.parent);

      /* point next file */
      return fat_goto_next();
    }
    else
    {
      return KO;
    }
  }
}
  

/*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.info = fat_cache.parent;
  
  /* issue the equivalent to a cd .. DOS command */
  return (fat_goto_subdir(id));    
}
  

/*F**************************************************************************
* NAME: fat_fopen
*----------------------------------------------------------------------------
* PARAMS:
*   mode: READ:   open file for read
*         WRITE:  open file for write
*
* return:
*   - OK: file opened
*   - KO: file not opened: - file is empty
*                          - file is too much fragmented
*----------------------------------------------------------------------------
* PURPOSE:
*   Open the file in read or write mode
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_fopen (bit mode)
{
  if (fat_cache.info.size == 0)
  {
    return KO;                              /* file empty */
  }
  else
  {
    /* fat file byte counter */
    fat_file_byte_counter = 0;

    /* reset the allocation list variable */
    fat_chain_index = 0;
    fat_chain_cluster = 0;
    if (fat_get_clusters(&clusters) != OK)
    {
      return KO;                            /* file too much fragmented */
    }

    /* seek to the beginning of the file */
    if (mode == READ)
    {
      fat_open_mode = READ;
      return Hard_read_open(fat_ptr_data + ((Uint32)(clusters.cluster[0]) 
                                             * fat_cluster_size));
    }
    else
    {
      fat_open_mode = WRITE;
      return Hard_write_open(fat_ptr_data + ((Uint32)(clusters.cluster[0]) 
                                             * fat_cluster_size));
    }
  }
}


/*F**************************************************************************
* NAME: fat_fclose
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Close opened file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fclose (void)
{
  if (fat_open_mode == READ)
  {
    Hard_read_close();                       /* close reading */
  }
  else
  {
    Hard_write_close();                      /* close writing */
  }
}


/*F**************************************************************************
* NAME: fat_get_clusters
*----------------------------------------------------------------------------
* PARAMS:
*   chain: allocation list address
*
* return:
*   - OK: allocation done
*   - KO: allocation not done: file too much fragmented
*----------------------------------------------------------------------------
* PURPOSE:
*   Prepare a list of all the file clusters built as two tables:
*     cluster[n] contains the staring cluster number of a fragment
*     number[n] contains the number of contiguous clusters in fragment
*   This way implies that file is not be too much fragmented
*   The number of possible fragment is defined by the constant
*   MAX_FILE_FRAGMENT_NUMBER in fat.h header file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_get_clusters (fat_cluster_chain *chain)
{
idata  Uint16 new_cluster;
idata  Uint16 old_cluster;
idata  Byte   index;                        /* index in chain */
idata  Uint16 i; 
idata  Uint16 fat12_cluster;
bdata  bit    fat12_parity;

  /* build the first entry of the allocation list */
  chain->number[0] = 1;
  chain->cluster[0] = fat_cache.info.start_cluster - 2; /* 2 = 1st cluster */
  old_cluster = fat_cache.info.start_cluster;
  index = 0;

  
  /* calculate the first offset in fat and read the corresponding sector */  
  if (fat_is_fat16)
    Hard_read_open(fat_ptr_fats + (old_cluster / (SECTOR_SIZE / 2)));
  else
    Hard_read_open(fat_ptr_fats);

  if (fat_is_fat16)                         /* FAT16 management */
  {   /* compute offset in sector */
    for (i = (old_cluster % (SECTOR_SIZE / 2)); i != 0; i--)
    {
      Hard_read_byte();                     /* dummy FAT read */
      Hard_read_byte();
    }
    /* read first entry */
    ((Byte *)&new_cluster)[1]= Hard_read_byte();
    ((Byte *)&new_cluster)[0]= Hard_read_byte();
  
    while (new_cluster != LAST_CLUSTER)     /* loop until last cluster found */
    {
      if ((new_cluster == (old_cluster + 1)) && (chain->number[index] != 255))
      { /* contiguous cluster */
        chain->number[index]++;
      }
      else
      { /* compute fragmentation */
        index++;
        chain->number[index] = 1;
        chain->cluster[index] = new_cluster - 2;  /* 2 = 1st cluster */
        for (i = new_cluster - old_cluster - 1; i != 0; i--)
        {
          Hard_read_byte();                 /* dummy FAT read */
          Hard_read_byte();
        }
      }
      old_cluster = new_cluster;
      if (index == MAX_FILE_FRAGMENT_NUMBER - 2)
      {
        return  KO;                         /* file too much fragmented */
      }
      else
      {
        /* read new entry */
        ((Byte *)&new_cluster)[1]= Hard_read_byte();
        ((Byte *)&new_cluster)[0]= Hard_read_byte();
      }
    }
  }
  else                                      /* FAT12 management */
  {   /* compute offset in sector */
    fat12_parity = 0;
    i = (old_cluster + 1);
    do
    {
      if (fat12_parity == 0)
      {
        ((Byte *)&fat12_cluster)[1]= Hard_read_byte();
        ((Byte *)&fat12_cluster)[0]= Hard_read_byte();
        new_cluster = (fat12_cluster & 0x00FF);
        new_cluster += (fat12_cluster & 0x0F00);
        fat12_parity = 1;
      }
      else
      {
        ((Byte *)&fat12_cluster)[1]= Hard_read_byte();
        new_cluster = (fat12_cluster & 0xF000) >> 12;
        new_cluster += (fat12_cluster & 0x00FF) << 4;
        fat12_parity = 0;
      }
      i--;
    }
    while (i != 0);

    while ( (new_cluster != 0xFFF) && (new_cluster != 0xFF8))                  
    /* loop until last cluster found */
    {
      if ((new_cluster == (old_cluster + 1)) && (chain->number[index] != 255))
      { /* contiguous cluster */
        chain->number[index]++;
      }
      else
      { /* compute fragmentation */
        index++;
        chain->number[index] = 1;
        chain->cluster[index] = new_cluster - 2;  /* 2 = 1st cluster */
        for (i = new_cluster - old_cluster - 1; i != 0; i--)
        {  /* dummy FAT read */
          if (fat12_parity == 0)
          {
            ((Byte *)&fat12_cluster)[1]= Hard_read_byte();
            ((Byte *)&fat12_cluster)[0]= Hard_read_byte();
            fat12_parity = 1;
          }
          else
          {
            ((Byte *)&fat12_cluster)[1]= Hard_read_byte();
            fat12_parity = 0;
          }
        }
      }
      old_cluster = new_cluster;
      if (index == MAX_FILE_FRAGMENT_NUMBER - 2)
      {
        return KO;                          /* file too much fragmented */
      }
      else
      {
        /* read new entry */
        if (fat12_parity == 0)
        {
          ((Byte *)&fat12_cluster)[1]= Hard_read_byte();
          ((Byte *)&fat12_cluster)[0]= Hard_read_byte();
          new_cluster = (fat12_cluster & 0x00FF);
          new_cluster += (fat12_cluster & 0x0F00);
          fat12_parity = 1;
        }
        else
        {
          ((Byte *)&fat12_cluster)[1]= Hard_read_byte();
          new_cluster = (fat12_cluster & 0xF000) >> 12;
          new_cluster += (fat12_cluster & 0x00FF) << 4;
          fat12_parity = 0;
        }
      }
    }
  }
  /* mark the last chain element with number= 0 */
  chain->number[index + 1] = 0;             /* end of chain marker */
  Hard_read_close();                        /* close physical read */
  return OK;
}


/*F**************************************************************************
* NAME: fat_fgetc
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   byte read
*----------------------------------------------------------------------------
* PURPOSE:
*   Read one byte from file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   As this function is called very often it must be short and optimized
*   in execution time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_fgetc (void)
{
  /* check if we are at the end of a cluster */
  if ((((Byte*)&fat_file_byte_counter)[3] == 0x00) &&
      ((((Byte*)&fat_file_byte_counter)[2] & fat_cluster_mask) == 0x00))
  {
    /* extract if necessary the next cluster from the allocation list */
    if (clusters.number[fat_chain_index] == fat_chain_cluster)
    { /* new fragment */
      fat_chain_index++;
      fat_chain_cluster = 1;
      Hard_read_open(fat_ptr_data + ((Uint32)(clusters.cluster[fat_chain_index]) * fat_cluster_size));
    }
    else
    { /* no new fragment */
      fat_chain_cluster++;                /* one more cluster read */
    }
  }
  fat_file_byte_counter++;                /* one more byte read */
  return Hard_read_byte();
}


/*F**************************************************************************
* NAME: fat_fputc
*----------------------------------------------------------------------------
* PARAMS:
*   d: data byte to write
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Write one byte to file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -