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

📄 fat.c

📁 atmel at89c51snd1c mp3芯片方案源码
💻 C
📖 第 1 页 / 共 5 页
字号:
static idata Uint16 cluster;

  if (fat_is_fat16)
  {
    ((Byte*)&cluster)[1] = Hard_read_byte();
    ((Byte*)&cluster)[0] = Hard_read_byte();
    return cluster;
  }

  if (init)
  {
    fat12_parity = 0;
    cluster = 0;
  }

  if (fat12_parity == 0)
  {
    ((Byte*)&cluster)[1] = Hard_read_byte();
    ((Byte*)&cluster)[0] = Hard_read_byte();
    fat12_parity = 1;
    return (cluster & 0x0FFF);
  }
  else
  {
    cluster = (cluster & 0xF000) >> 12;
    cluster += (Hard_read_byte() << 4);
    fat12_parity = 0;
    return (cluster);
  }
}



/*F**************************************************************************
* NAME: fat_set_clusters
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   - OK: allocation done
*   - KO: allocation cannot be done : no free cluster
*----------------------------------------------------------------------------
* PURPOSE:
*   Prepare a list of the free clusters:
*     chain[n].cluster contains the starting cluster number of a fragment
*     chain[n].number contains the number of contiguous clusters in fragment
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   Free cluster list is limited by the nb_frag parameter.
*   If memory is too much fragmented, created file may be limited in size.
*   Last list item always has single cluster
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_set_clusters (void)
{
bit     cluster_free;
Uint16  cluster;

  cluster = 0;
  cluster_free = FALSE;
  fat_last_clust_index = 0;
  Hard_read_open(fat_ptr_fats);

  /* search the first free cluster in fat */
  fat_read_cluster(1);
  fat_read_cluster(0);
  do                                      /* search for first free cluster */
  {
    if (fat_read_cluster(0) == 0x0000)
      cluster_free = TRUE;
    else 
      cluster++;
  }
  while ((cluster != fat_count_of_clusters) && (!cluster_free));
   
  if (!cluster_free)
  {
    Hard_read_close();
    return KO;                                        /* no free cluster found */
  }

  fclusters[fat_last_clust_index].number = 1;  
  fclusters[fat_last_clust_index].cluster = cluster;                     /* store first cluster */
  cluster++;

  if (cluster != fat_count_of_clusters)
  {
    do                                                      /* construct the list */
    {
      cluster_free = FALSE;
      if (fat_read_cluster(0) == 0x0000)
        cluster_free = TRUE;
      else
        cluster++;

      if (cluster_free)                                     /* It's a contiguous cluster      */
      {                                                     /* add it to the list             */
        if (fclusters[fat_last_clust_index].number == MAX_CL_PER_FRAG) 
        {
          fat_last_clust_index++;
          if (fat_last_clust_index == MAX_FILE_FRAGMENT_NUMBER)
          {
            Hard_read_close();
            fat_last_clust_index--;
            return OK;
          }
          fclusters[fat_last_clust_index].number = 1;
          fclusters[fat_last_clust_index].cluster = cluster;
        }
        else
        {
          fclusters[fat_last_clust_index].number++;
        }
        cluster++;                                          /* process next cluster           */
      }
      else if (cluster != fat_count_of_clusters)
      {                                                     /* cluster is already used        */
        do                                                  /* search for next free fragment  */
        {
          if (fat_read_cluster(0) == 0x0000)
            cluster_free = TRUE;
          else
            cluster++;
        }
        while ((cluster != fat_count_of_clusters) && (!cluster_free));
    
        if (!cluster_free)                                  /* no more free cluster           */
        {
          Hard_read_close();
          return OK;                        /* end of partition reached */
        }
        
        fat_last_clust_index++;                                            /* new free fragment cluster      */
        if (fat_last_clust_index == MAX_FILE_FRAGMENT_NUMBER)
        {
          Hard_read_close();
          fat_last_clust_index--;
          return OK;
        }
        fclusters[fat_last_clust_index].number = 1;
        fclusters[fat_last_clust_index].cluster = cluster;
        cluster++;                                          /* process next cluster           */
      }
    }
    while ((fat_last_clust_index < MAX_FILE_FRAGMENT_NUMBER) && (cluster < fat_count_of_clusters));
  }

  Hard_read_close();
  return OK;
}





/*F**************************************************************************
* NAME: fat_save_cluster_info
*----------------------------------------------------------------------------
* PARAMS:
*   
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Save in locale variables cluster information for the current opened file
*   - cluster index
*   - number of the cluster 
*   - number of bytes in the cluster
*
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_save_cluster_info (void)
{
  fat_fchain_index_save = fat_fchain_index;
  fat_fchain_nb_clust_save = fat_fchain_nb_clust;
  fat_fclust_byte_count_save = fat_fclust_byte_count % (fat_cluster_size * SECTOR_SIZE);
}


/*F**************************************************************************
* NAME: fat_file_get_pos
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   current file position in bytes
*----------------------------------------------------------------------------
* PURPOSE:
*   Calculate the current file position
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint32 fat_file_get_pos (void)
{
Byte i;
Uint32 temp;

  if (fat_fchain_nb_clust == 0)
  {
    return 0x00000000;
  }

  temp = 0;
  for (i=0; i < fat_fchain_index; i++)
    temp += fclusters[i].number;
  temp += (fat_fchain_nb_clust - 1);
  temp = temp * fat_cluster_size * SECTOR_SIZE;
  temp = temp + (fat_fclust_byte_count % (fat_cluster_size * SECTOR_SIZE));

  return temp;
}
/*F**************************************************************************
* NAME: fat_feob
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   - TRUE : B position have been reached
*   - FALSE : B position have not benn reached
*----------------------------------------------------------------------------
* PURPOSE:
*   Determine if B position have been reached in mode repeat A/B
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_feob (void)
{
  if (fat_fchain_index >= fat_fchain_index_save)
  {
    if (fat_fchain_nb_clust >= fat_fchain_nb_clust_save)
      return (fat_fclust_byte_count >= fat_fclust_byte_count_save);
    else
      return FALSE;
  }
  else
  {
    return FALSE;
  }
}

/*F**************************************************************************
* NAME: fat_get_clusters
*----------------------------------------------------------------------------
* PARAMS:
*   chain:   allocation list address
*   nb_frag: maximum number of fragment 
*
* return:
*   - OK: allocation done
*   - KO: allocation done but truncated: file too much fragmented
*----------------------------------------------------------------------------
* PURPOSE:
*   Prepare a list of the file clusters:
*     chain[n].cluster contains the starting cluster number of a fragment
*     chain[n].number contains the number of contiguous clusters in fragment
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   File cluster list is limited by the nb_frag parameter.
*   If memory is too much fragmented, file may not be fully played.
*   Last list item always has single cluster
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_get_clusters (fat_st_clust_chain xdata *chain, Byte nb_frag)
{
Byte   index;                               /* index in chain */
Uint16 i; 
Uint16 new_cluster;
Uint16 old_cluster;
Uint16 temp;
  nb_frag = nb_frag - 1;                    /* set limit (index start at 0) */

  /* build the first entry of the allocation list */
  chain[0].number = 1;
  chain[0].cluster = fat_cache.current.start_cluster - 2; /* 2 = 1st cluster */
  old_cluster = fat_cache.current.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)));
    /* compute offset in sector */
    for (i = (old_cluster % (SECTOR_SIZE / 2)); i != 0; i--)
    { 
      fat_read_cluster(0);
    }
    /* read first entry */
    new_cluster = fat_read_cluster(0);
    temp = LAST_CLUSTER16;
  }
  else
  {
    Hard_read_open(fat_ptr_fats);
    new_cluster = fat_read_cluster(1);
    for (i = old_cluster; i != 0; i--)
    {
      new_cluster = fat_read_cluster(0);
    }
    temp = LAST_CLUSTER12;
  }
    
  while (new_cluster != temp)   /* loop until last cluster found */
  {
    if ((new_cluster == (old_cluster + 1)) && (chain[index].number != MAX_CL_PER_FRAG))
    { /* contiguous cluster up to 255 or 65535 */
      chain[index].number++;
    }
    else
    { /* compute fragmentation */
      index++;
      chain[index].number = 1;
      chain[index].cluster = new_cluster - 2;  /* 2 = 1st cluster */
      for (i = new_cluster - old_cluster - 1; i != 0; i--)
      {
        fat_read_cluster(0);
      }
    }
    old_cluster = new_cluster;
    if (index == nb_frag)
    { /* end of chain reached */
      /* last fragment always contains a single cluster */
      chain[nb_frag].number = 1;          
      fat_last_clust_index = nb_frag;
      Hard_read_close();                  /* close physical read */
      return  KO;                         /* file too much fragmented */
    }
    else
    {
      /* read new entry */
      new_cluster = fat_read_cluster(0);
    }
  }

  /* end of file: last fragment must always contain a single cluster */
  if (chain[index].number == 1)
  { /* last cluster is the current one */
    fat_last_clust_index = index;
  }
  else
  {
    fat_last_clust_index = index + 1;
    chain[index].number--;
    chain[fat_last_clust_index].cluster = chain[index].cluster + chain[index].number;
    chain[fat_last_clust_index].number = 1; 
  }
  Hard_read_close();                        /* close physical read */
       

⌨️ 快捷键说明

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