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

📄 dos.c

📁 MMC interface and FAT File system
💻 C
字号:
//###########################################################
// File: dos.c
//
// Using fopen() and fread() is very slow because a lot
// of calculations have to be done.
// Using ReadFileRaw() is up to 7 times faster.
//
//
//#########################################################################
// Last change: 04.03.2004
//#########################################################################
// holger.klabunde@t-online.de
// http://home.t-online.de/home/holger.klabunde/homepage.htm
//#########################################################################
// Compiler: WIN-AVR 3.3
//#########################################################################
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "protos.h"
#include "dos.h"
#include "mydefs.h"
#include "serial.h"

/*
unsigned char DeleteFile(char *name)
{
 // Look if file exists
   // if not return success
 
 // free clusters in cluster chain (make zero)
 // remove dir entry (mark first character in direntry with 0xE5)
 // return success  
}
*/


//###########################################################
// reset DOS
void InitDOS(void)
//###########################################################
{
 CurrentDirCluster=0; //root directory 
 CurrentSector=0;
 CurrentCluster=2;    //first possible free cluster
 FileFirstCluster=0;
 FileSize=0;
 FileFlag=0;
 lo=0; // no long filenames
}

//###########################################################
// write count bytes from buffer to file
// returns number of bytes written
//
// fwrite() does not write to CF until a sector is completely
// filled. you can force writing with fflush() when file should
// keep open, or close the file with fclose().
//###########################################################
unsigned int fwrite(unsigned char *buf, unsigned int count)
//###########################################################
{
 unsigned char *p, secoffset;
 unsigned long tmp;
 unsigned int buffoffset, bytecount;
 
 if(FileFlag==0) return 0; //don't write if file is closed
                           //written bytes are zero
 
 p=buf;
 bytecount=0;

 do
  {
   tmp=FileSize;         //next write position
   tmp-= FileClusterCount; //calc byte position in cluster
   
   if(tmp >= FileBytePerCluster)//is position in new cluster ?
    {
     CFWriteSector(FileCurrentSector,iob); //write last sector
     FileCurrentCluster=AllocCluster(FileCurrentCluster); //alloc new cluster
     if(FileCurrentCluster==DISK_FULL)
      {
#ifdef F_DEBUG
       puts("Disk full !\n");
#endif
       return bytecount; //return number of bytes written before disk full
      } 

     File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster);//set new 1st sector of cluster
#ifdef F_DEBUG
     printf("Cluster %lu Sector %lu\n",FileCurrentCluster,File1stClusterSector);
#endif
     FileCurrentSector=File1stClusterSector; //set new current sector
//       FileClusterCount++;                   //update cluster count
     FileClusterCount+=FileBytePerCluster;   //update cluster count
     tmp-= FileBytePerCluster;               //calc new byte position in cluster
    }

   secoffset=(unsigned char)(tmp / BYTE_PER_SEC);  //calc offset from first sector in cluster

   if(File1stClusterSector+secoffset != FileCurrentSector)
    {
     CFWriteSector(FileCurrentSector,iob); //write last sector used
     FileCurrentSector=File1stClusterSector+secoffset;
#ifdef F_DEBUG
     printf("Sector %lu\n",FileCurrentSector);
#endif
    }
      
   buffoffset=(unsigned int)(tmp % BYTE_PER_SEC); //calc offset in sector

   iob[buffoffset]=*p++;  //put byte in write buffer
   FileSize++;            //update Filesize
   bytecount++;           //one byte written to buffer

  }while(bytecount<count);

 return bytecount;
}

//###########################################################
// read count bytes into buffer
// returns number of bytes read
unsigned int fread(unsigned char *buf, unsigned int count)
//###########################################################
{
 unsigned char *p, secoffset;
 unsigned long tmp;
 unsigned int buffoffset, bytecount;
 
 if(FileFlag==0) return 0; //don't read if file is closed
                           //read bytes are zero
 
 p=buf;
 bytecount=0;

 do
  {
   tmp=FilePosition;
   if(tmp<FileSize) //end of file reached ?
    {
//     tmp-= FileClusterCount * FileBytePerCluster; //calc byte position in cluster
     tmp-= FileClusterCount; //calc byte position in cluster
//maybe its faster to count cluster and sectorbytes

     if(tmp >= FileBytePerCluster)//is position in current cluster ?
      {
       FileCurrentCluster=GetNextClusterNumber(FileCurrentCluster); //if not get next cluster
       File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster);//set new 1st sector of cluster
       CFReadSector(File1stClusterSector,iob); //read new sector
#ifdef F_DEBUG
       printf("Cluster %lu Sector %lu\n",FileCurrentCluster,File1stClusterSector);
#endif
       FileCurrentSector=File1stClusterSector; //set new current sector
//       FileClusterCount++;                   //update cluster count
       FileClusterCount+=FileBytePerCluster;   //update cluster count
       tmp-= FileBytePerCluster;               //calc new byte position in cluster
      }

     secoffset=(unsigned char)(tmp / BYTE_PER_SEC);  //calc offset from first sector in cluster

     if(File1stClusterSector+secoffset != FileCurrentSector)
      {
       FileCurrentSector=File1stClusterSector+secoffset;
       CFReadSector(FileCurrentSector,iob); //read new sector
#ifdef F_DEBUG
       printf("Sector %lu\n",FileCurrentSector);
#endif
      }
      
     buffoffset=(unsigned int)(tmp % BYTE_PER_SEC); //calc offset in sector

     *p++=iob[buffoffset];
     FilePosition++;
     bytecount++; //one byte read into buffer

    } //if(tmp<FileSize)
   else return bytecount; //return bytes read til end of file

  } while(bytecount<count);
  
 return bytecount;
}

//###########################################################
//open a file for reading OR writing, NOT both !
unsigned char fopen(char *name, unsigned char flag)
//###########################################################
{
 unsigned long tmp;

 FileBytePerCluster=BYTE_PER_SEC * secPerCluster; //bytes per cluster
 FileClusterCount=0;
 
 if(flag==F_READ)
  {
   if(FindName(name)==FULL_MATCH) //file MUST exist for reading
    {
     FilePosition=0; //actual read position
     FileCurrentCluster=FileFirstCluster;
     FileFlag=flag; //needed for fclose

     File1stClusterSector=GetFirstSectorOfCluster(FileFirstCluster);
     FileCurrentSector=File1stClusterSector;
     CFReadSector(FileCurrentSector,iob); //read first sector of file

#ifdef F_DEBUG
     puts("File is open for reading\n");
#endif
     return F_OK;      //give back something above zero
    }
#ifdef F_DEBUG
   else puts("File not found\n");  
#endif
  }

 if(flag==F_WRITE)
  {
   //if file exists, open it and spool to end of file to append data
   if(FindName(name)==FULL_MATCH)
    {
     tmp=FileFirstCluster;
     
     while(tmp<endofclusterchain) //go to end of cluster chain
      {
       tmp=GetNextClusterNumber(tmp);
       if(tmp<endofclusterchain)
        {
         FileCurrentCluster=tmp;
         FileClusterCount+=FileBytePerCluster;
        } 
      }

     tmp=FileSize-FileClusterCount;
     File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster); 
     FileCurrentSector=File1stClusterSector;
     FileCurrentSector+= tmp / BYTE_PER_SEC;

     CFReadSector(FileCurrentSector,iob); //read first sector of file
    }
   else //make a new file
    { 
     MakeFileName(name,FileName,FileExt); //Split into name and extension
     if(MakeNewFileEntry()) //file does not exist, make new file in currentdir
      {
       FileCurrentCluster=FileFirstCluster;
       File1stClusterSector=GetFirstSectorOfCluster(FileFirstCluster); 
       FileCurrentSector=File1stClusterSector;

       CFReadSector(FileCurrentSector,iob); //read first sector of file
      }
     else
      {
#ifdef F_DEBUG
       puts("fopen() failed !\nNo free DIR entry\n");
#endif
       FileFlag=0; //needed for fclose
       return F_ERROR; //new file could not be made
      }
    }

   FileFlag=flag; //needed for fclose
   return F_OK; //file is open for writing
  }//if(flag==F_WRITE)
  
 return F_ERROR; //something went wrong  
}

//###########################################################
// close the file
// no error codes
void fclose(void)
//###########################################################
{
 if(FileFlag==F_READ)
  {
  }

 if(FileFlag==F_WRITE)
  {
   fflush();  //write last sector used to CF and update filesize, filetime
  }

 FileFlag=0; //a second fclose should do nothing
             //reading and writing disabled

#ifdef F_DEBUG
 puts("File is closed\n");  
#endif
}

//###########################################################
// force writing last data written into sectorbuffer to be
// stored into CF without fclose(). direntry will also be
// updated.
void fflush(void)
//###########################################################
{
 if(FileFlag==0) return; //don't write if file is closed
 CFWriteSector(FileCurrentSector,iob); //write last sector used
 //update file entry filesize and date/time
 UpdateFileEntry();
}

//############################################################
// search for a filename or directoryname in current directory
unsigned char FindName(char *name)
//############################################################
{
 unsigned char result;
 
 if(CurrentDirCluster<2)
  {
   result=ScanRootDir(name);
  }
 else
  {
   result=ScanSubDir(CurrentDirCluster,name);
  }

 return result;
}

//###########################################################
// reads all clusters/sectors of the file.
// you have to check filesize from direntry to see how
// many bytes of last cluster are valid for the file. 
// much faster than fread()
unsigned char ReadFileRaw(unsigned long startcluster)
//###########################################################
{
 unsigned long tmp,tmpsector;
 unsigned char i;

 tmp=startcluster;
  
 while(tmp < endofclusterchain)
  {
   tmpsector=GetFirstSectorOfCluster(tmp);
   for(i=0; i<secPerCluster; i++)
    {
     CFReadSector(tmpsector,iob);

 //Remove this if you like
     DumpSector(iob); //Show sector on serial port

//**************************
//load your MP3-Chip here ;)
//**************************

     tmpsector++;
    }

   tmp=GetNextClusterNumber(tmp);
  }

 return F_OK;
}

⌨️ 快捷键说明

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