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

📄 dos.c

📁 使用IAR430编译源文件
💻 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.

//#########################################################################
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "dos.h"
//#include "lcd.h"

#ifdef DOS_WRITE
#ifdef DOS_DELETE
//###########################################################
// delete a file
unsigned char remove(char *name)
//###########################################################
{
#ifdef USE_FAT32
 unsigned long tmp,tmp1;
#else
 unsigned int tmp,tmp1;
#endif

 if(FileFlag!=0) return F_ERROR; // don't delete if a file is open

 FileAttr=0xFF; // test if we really find a file and not a directory
                // FileAttr then must be ATTR_FILE
                
 if(FindName(name)==FULL_MATCH) // Look if file exists
  {
   if(FileAttr!=ATTR_FILE) return F_ERROR; // this was not a file !

   tmp=FileFirstCluster;

   // free clusters in FAT cluster chain (make zero)
   do
    {
     tmp1=GetNextClusterNumber(tmp); // save next cluster number
     WriteClusterNumber(tmp,0);      // free cluster
     tmp=tmp1;                       // restore next cluster number
    }while(tmp<endofclusterchain);

#ifdef USE_FATBUFFER
   if(FATStatus>0)
    {
     WriteSector(FATCurrentSector,fatbuf); // write the FAT buffer
     FATStatus=0;
    } 
#endif

   FileName[0]=0xE5;   //mark file as deleted. does not affect long filename entrys !
   FileSize=0;         //make filesize 0
   FileFirstCluster=0; //delete first cluster
   FileAttr=0;         //is this necessary ? 
   UpdateFileEntry();
  }
  
 return F_OK;  
}
#endif //DOS_DELETE
#endif //DOS_WRITE

#ifdef DOS_WRITE
//###########################################################
// 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;  //pointer to write buffer
 bytecount=0;

 do
  {
   tmp=FileSize;         //next write position
   tmp-= FileClusterCount; //calc byte position in cluster
   
   if(tmp >= FileBytePerCluster)//is position in new cluster ?
    {
     WriteSector(FileCurrentSector,iob); //write last sector
     FileCurrentCluster=AllocCluster(FileCurrentCluster); //alloc new cluster
     if(FileCurrentCluster==DISK_FULL)
      {
       return bytecount; //return number of bytes written before disk full
      } 

     File1stClusterSector=GetFirstSectorOfCluster(FileCurrentCluster);//set new 1st sector of cluster
     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)
    {
     WriteSector(FileCurrentSector,iob); //write last sector used
     FileCurrentSector=File1stClusterSector+secoffset;
    }
      
   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;
}
#endif //DOS_WRITE

#ifdef DOS_READ
//###########################################################
// 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;  //pointer to read buffer
 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
       ReadSector(File1stClusterSector,iob); //read new sector
       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 sector offset from first sector in cluster

     if(File1stClusterSector+secoffset != FileCurrentSector) //new sector ?
      {
       FileCurrentSector=File1stClusterSector+secoffset;
       ReadSector(FileCurrentSector,iob); //read new sector
      }
      
     buffoffset=(unsigned int)(tmp % BYTE_PER_SEC); //calc offset in sector

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

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

  } while(bytecount<count);
  
 return bytecount;
}
#endif //DOS_READ





#ifdef DOS_READ
//------------------------------------------------------------//
// read count bytes into buffer in Position
// returns number of bytes read
#ifdef USE_FAT32
unsigned int fread_InPosition(unsigned char *buf, unsigned int count,unsigned long Position)
#else
unsigned int fread_InPosition(unsigned char *buf, unsigned int count,unsigned int Position)
#endif
//----------------zhangbao 06.05.24 创建---------------------//
{
 unsigned char *p, secoffset;
 unsigned long tmp;
 unsigned int buffoffset, bytecount;
 unsigned long cluster_No;
 if(FileFlag==0) return 0; //don't read if file is closed
                           //read bytes are zero
 
 p=buf;  //pointer to read buffer
 bytecount=0;
 
 FilePosition = Position;
 

   if(Position < FileSize) //end of file reached ? 
      {  
      cluster_No = Position / FileBytePerCluster;
      tmp = Position % FileBytePerCluster;
      GoToNoCluster(cluster_No);
  
      secoffset = (unsigned char)(tmp / BYTE_PER_SEC);  //calc sector offset from first sector in cluster

       FileCurrentSector = File1stClusterSector + secoffset;
       ReadSector(FileCurrentSector,iob); //read new sector
      
      buffoffset = (unsigned int)(tmp % BYTE_PER_SEC); //calc offset in sector
      
        
       //bytecount = 0;
      do
      {
        
      for(; buffoffset<BYTE_PER_SEC; buffoffset++)
      {
        *p++ = iob[buffoffset];
        bytecount++;
        FilePosition++;
        if(FilePosition >= FileSize)
        {
          return(bytecount);
        }
        if(bytecount >= count)
        {
          return(bytecount);
        } 
      }
      
      FileCurrentSector++;
      if(FileCurrentSector > secPerCluster)
      {
       GoToNoCluster(++cluster_No);
      }
      ReadSector(FileCurrentSector,iob); //read new sector  
      buffoffset = 0;
      
      }while(bytecount < count);
      return(count);
     }
     else return(0);
      
}
#endif //DOS_READ

















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

 FileBytePerCluster = BYTE_PER_SEC * secPerCluster; //bytes per cluster
 FileClusterCount = 0;
 
#ifdef DOS_READ
 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;
     ReadSector(FileCurrentSector,iob); //read first sector of file

     return F_OK;      //give back something above zero
    }
  }
#endif //DOS_READ

#ifdef DOS_WRITE
 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;

     ReadSector(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, try to make new file in currentdir
      {
       FileCurrentCluster=FileFirstCluster;
       File1stClusterSector=GetFirstSectorOfCluster(FileFirstCluster); 
       FileCurrentSector=File1stClusterSector;

       ReadSector(FileCurrentSector,iob); //read first sector of file
      }
     else
      {
       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)
#endif //DOS_WRITE
  
 return F_ERROR; //something went wrong  
}

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

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

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

#ifdef DOS_WRITE
//###########################################################
// 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

#ifdef USE_FATBUFFER
 if(FATStatus>0)
  {
   WriteSector(FATCurrentSector,fatbuf); // write the FAT buffer
   FATStatus=0;
  } 
#endif

 WriteSector(FileCurrentSector,iob); //write last sector used
 //update file entry filesize and date/time
 UpdateFileEntry();
}
#endif //DOS_WRITE

//############################################################
// search for a filename or directoryname in current directory
unsigned char FindName(char *name)
//############################################################
{
 unsigned char result;

 if(FileFlag>0) return NO_MATCH; //don't search if a file is open
 
 if(FirstDirCluster<2)
  {
   result=ScanRootDir(name);
  }
 else
  {
   result=ScanSubDir(FirstDirCluster,name);
  }

 return result;
}





⌨️ 快捷键说明

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