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

📄 fat.c

📁 这是atmel公司的89C51SND1C的mp3源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*C**************************************************************************
* $RCSfile: fat.c,v $
*----------------------------------------------------------------------------
* Copyright (c) 2002 Atmel.
*----------------------------------------------------------------------------
* RELEASE:      $Name: DEMO_FAT_1_2_5 $      
* REVISION:     $Revision: 1.12 $     
* FILE_CVSID:   $Id: fat.c,v 1.12 2002/06/10 14:14:53 dturpin Exp $       
*----------------------------------------------------------------------------
* PURPOSE:
* FAT16/FAT12 file-system basics functions
* 
* NOTES:
* Supports only the first partition
* Supports only 512 bytes sector size
* Supports only file fragmentation < MAX_FILE_FRAGMENT_NUMBER
* Supports only one file openned at a time
*
* Global Variables:
*   - gl_buffer: array of bytes in pdata space
*   - gl_wav_header:  wave structure in code
*
* CHANGES:
* - TD 2002/02/28
*   Add new variables for mass storage purpose:
*     fat_nb_sector
*     fat_sector_per_track
*     fat_end_head
*     fat_end_cylinder
* - FF 2002/03/06
*   Add fat_format function
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/

#include "config.h"                         /* system configuration */
#include "..\mem\hard.h"                    /* low level function definition */
#include "file.h"                           /* file function definition */
#include "fat.h"                            /* fat file-system definition */
#include "wav.h"                            /* wav file definition */


/*_____ M A C R O S ________________________________________________________*/


/*_____ D E F I N I T I O N ________________________________________________*/

extern  pdata   Byte    gl_buffer[];
extern  code    wav_struct  gl_wav_header;


/* For exploration matters */
xdata Uint16  fat_directory_chain[MAX_DIRECTORY_FILE]; /* array of relative entries position */
xdata Uint16  fat_directory_pos;            /* global entries offset */
xdata Uint16  fat_last_file;                /* number of file stored (MP3, VOC, DIR) */
xdata Uint32  fat_directory_base;           /* starting sector for directory */
idata Uint16  fat_file_ptr;                 /* entry number pointer */
xdata Uint32  fat_current_sector;           /* current sector where the current */
                                            /* file/dir info (cache.info) is situated */
xdata Uint16  fat_current_byte_counter;     /* the byte counter offset in the current */
                                            /* sector where is the current file/dir entry */

/* For file management matters */              
/* the global byte counter, mainly use for the eof check */
static data   Uint32   fat_file_byte_counter;  

xdata fat_Cache   fat_cache;                /* The cache structure, see the .h for more info */
char  pdata   *lfn_name = &(gl_buffer[32]); /* long filename limited to MAX_FILENAME_LEN chars */
xdata char    ext[3];                       /* file extension (limited to 3 characters) */

/* file chain management */
static  data  Byte    fat_chain_index;      /* the number of the fragment of the file, in fact */
                                            /* the index of the table in the cluster chain */
              
static  data  Byte    fat_chain_cluster;    /* the offset of the cluster from the first cluster */ 
                                            /* of the fragment */

static  xdata fat_cluster_chain clusters;       /* cluster chain for the current file */
static  xdata fat_cluster_chain dir_clusters;   /* cluster chain for the current directory */

static  bdata bit     dir_is_root;          /* TRUE: point the root directory  */
static  data  Uint32  fat_ptr_fats;         /* address of the first byte of FAT */
static  data  Uint32  fat_ptr_rdir;         /* address of the first byte of root dir */
static  data  Uint32  fat_ptr_data;         /* address of the first byte of data */
static  data  Byte    fat_cluster_size;     /* cluster size (sector count) */
static  data  Byte    fat_cluster_mask;     /* mask for end of cluster test */

static  idata Byte    fat_current_dir_fragment;
static  idata Uint16  fat_current_dir_cluster;
static  idata Byte    fat_current_sector_cluster;

static  bdata bit     fat_is_fat16;         /* TRUE: FAT16 - FALSE: FAT12 */
static  bdata bit     fat_open_mode;        /* READ or WRITE */

/*_____ D E C L A R A T I O N ______________________________________________*/

static  bit     fat_get_clusters (fat_cluster_chain *);
static  bit     fat_dopen (void);
static  bit     fat_dseek (Int16);
static  Byte    fat_dgetc (void);


/*F**************************************************************************
* NAME: fat_install
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   - OK: intallation succeeded
*   - KO: - partition 1 not active
*         - FAT type is not FAT16
*         - sector size is not 512 bytes
*         - MBR or PBR signatures are not correct
*         - low level read open failure
*----------------------------------------------------------------------------
* PURPOSE:
*   Install the fat system, read mbr, bootrecords...
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   sector size is fixed to 512 bytes to simplify low level drivers
*   fat_ptr_fats = partition offset + nb_reserved_sector
*   fat_ptr_rdir = fat_ptr_fat + fat_size * nb_fat
*   fat_ptr_data = fat_ptr_rdir + nb_root_entries * 32 / 512
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_install (void)
{
Byte i;
Uint16 fat_fat_size;
Uint32 count_of_clusters;
Uint32 Tot_sect;
Uint32 fat_nb_sector;

  /* read and check usefull MBR info */
  /* go to the first partition field */
  if (Hard_read_open(MBR_ADDRESS) == OK) 
  {
    for (i= 446/2; i != 0; i--)
    {
      Hard_read_byte();                     /* go to first partition entry */
      Hard_read_byte();
    }
    /* check first partition state */
    if (Hard_read_byte() != PARTITION_ACTIVE)
    {
      Hard_read_close();                    /* close physical read */
      return KO;
    }
    Hard_read_byte();                       /* dummy reads */
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();                       /* dummy reads */
    Hard_read_byte();
    Hard_read_byte();
    

    /* read partition offset (in sectors) at offset 8 */
    ((Byte*)&fat_ptr_fats)[3] = Hard_read_byte();
    ((Byte*)&fat_ptr_fats)[2] = Hard_read_byte();
    ((Byte*)&fat_ptr_fats)[1] = Hard_read_byte();
    ((Byte*)&fat_ptr_fats)[0] = Hard_read_byte();
    /* go to the MBR signature field */
    for (i= 52; i != 0; i--)
    {
      Hard_read_byte();                     /* dummy reads */
    }
    /* check MBR signature */
    if ((Hard_read_byte() != LOW(BR_SIGNATURE)) &&
        (Hard_read_byte() != HIGH(BR_SIGNATURE)))
    {
      Hard_read_close();                    /* close physical read */
      return KO;
    }
    Hard_read_close();                      /* close physical read */
  }
  else
  { /* low level error */
    return KO;
  }

  /* read and check usefull PBR info */
  if (Hard_read_open(fat_ptr_fats) == OK) 
  {
    /* go to sector size field */
    for (i= 11; i != 0; i--)
    {
      Hard_read_byte();                     /* dummy reads */
    }
    /* read sector size (in bytes) */
    if (Hard_read_byte() != LOW(SECTOR_SIZE) ||
        Hard_read_byte() != HIGH(SECTOR_SIZE))
    {
      Hard_read_close();                    /* close physical read */
      return KO;
    }
    /* read cluster size (in sector) */
    fat_cluster_size = Hard_read_byte();
    fat_cluster_mask = HIGH((Uint16)fat_cluster_size * SECTOR_SIZE) - 1;
    /* compute FATs sector address: add reserved sector number */
    fat_ptr_fats += Hard_read_byte();
    fat_ptr_fats += (Uint16)Hard_read_byte() << 8;
    /* read number of FATs */
    i = Hard_read_byte();
    /* read number of dir entries  and compute rdir offset */
    ((Byte*)&fat_ptr_data)[3] = Hard_read_byte();
    ((Byte*)&fat_ptr_data)[2] = Hard_read_byte();
    ((Byte*)&fat_ptr_data)[1] = 0;
    ((Byte*)&fat_ptr_data)[0] = 0;
    fat_ptr_data = (fat_ptr_data * DIR_SIZE) / SECTOR_SIZE;
    /* read number of sector in partition (<32Mb) */
    ((Byte*)&fat_nb_sector)[3] = Hard_read_byte();
    ((Byte*)&fat_nb_sector)[2] = Hard_read_byte();
    ((Byte*)&fat_nb_sector)[1] = 0x00;
    ((Byte*)&fat_nb_sector)[0] = 0x00;
    Hard_read_byte();
    /* compute root directory sector address */
    ((Byte*)&fat_fat_size)[1] = Hard_read_byte();
    ((Byte*)&fat_fat_size)[0] = Hard_read_byte();
    
    fat_ptr_rdir = i * fat_fat_size;
    fat_ptr_rdir += fat_ptr_fats;

    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();
    Hard_read_byte();

    /* read number of sector in partition (>32Mb) */
    ((Byte*)&fat_nb_sector)[3] += Hard_read_byte();
    ((Byte*)&fat_nb_sector)[2] += Hard_read_byte();
    ((Byte*)&fat_nb_sector)[1] += Hard_read_byte();
    ((Byte*)&fat_nb_sector)[0] += Hard_read_byte();

    Tot_sect = fat_nb_sector - ( 1 + (i * fat_fat_size) + fat_ptr_data);
    count_of_clusters = Tot_sect / fat_cluster_size;
    if (count_of_clusters <= MAX_CLUSTERS12)
      fat_is_fat16 = FALSE;
    else
      if (count_of_clusters <= MAX_CLUSTERS16)
        fat_is_fat16 = TRUE;
      /* else is FAT32 not supported */

    /* compute data sector address */
    fat_ptr_data += fat_ptr_rdir;
    /* go to the signature field */
    for (i= 237; i != 0; i--)
    {
      Hard_read_byte();                     /* dummy reads */
      Hard_read_byte();
    }
    /* check partition signature */
    if ((Hard_read_byte() != LOW(BR_SIGNATURE)) &&
        (Hard_read_byte() != HIGH(BR_SIGNATURE)))
    {
      Hard_read_close();                    /* close physical read */
      return KO;
    }
    Hard_read_close();                      /* close physical read */
    return OK;
  }
  else
  { /* low level error */
    return KO;
  }
}


/*F**************************************************************************
* NAME: fat_fetch_directory_info
*----------------------------------------------------------------------------
* PARAMS:
*   entry: directory entry structure
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Fetch from disk all information about a directory/file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   This function reads directly datas from sectors
*   It automaticaly computes difference between LFN and normal entries
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void fat_fetch_directory_info (fat_dir_entry *entry)
{
bit     exit_flag = FALSE;
bit     lfn_entry_found = FALSE;
Byte    i;

  /* clear the name buffer */
  for (i = MAX_FILENAME_LEN; i != 0; lfn_name[--i] = '\0');

  while (!exit_flag)
  /* loop while the entry is not a normal one. */
  {
    /* read the directory entry */
    if (dir_is_root == TRUE)
    {
      for (i = 0; i < DIR_SIZE; i++)
      {
        gl_buffer[i] = Hard_read_byte();
      }
    }
    else
    {
      for (i = 0; i < DIR_SIZE; i++)
      {
        gl_buffer[i] = fat_dgetc();
      }
    }

    /*computes gathered data
    /* check if we have a LFN entry */
    if (gl_buffer[11] != ATTR_LFN_ENTRY)
    {
      if (!lfn_entry_found)
      {
        /* 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];
        }

⌨️ 快捷键说明

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