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

📄 zfat.c

📁 可以实现fat文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "zfat.h"

//Following includes aren't required if using CodeVision AVR C
//CodeVision will include automatically if .H files are in project list.
//#include "ztype.h"
//#inlcude "zata.h"
//#inlcude "zlcd.h"
//#include "zcontrol.h"


unsigned long clust2LBA(unsigned long clust) {
//Convert cluster address to LBA address, uses the formula    将簇地址转换为lba地址 使用下面的公式
	return ((clust-2) * Sectors_Per_Cluster) + FirstDataSector;
}

/*
unsigned long LBA2Cluster(unsigned long LBA) {
 return ((LBA-FirstDataSector)/Sectors_Per_Cluster)+2; 将lba地址转换为簇地址
}
*/

void InitFAT(){
 	struct partRec *pr; 指向分区表的指针
	struct bootSec710 *boot; 指向启动扇区  ????????
	struct driveID *driveInfo; 指向硬盘id结构
	word  rootDirSectors; 
	struct FAT32fsInfo *fsInfo; ??????????	
	dword tartSector;
	dword FATSz, dataSec, totalSector;
	byte	i;	
        RegWrite(DrvHeadReg,LBAMaster); 表示大硬盘模式
	RegWrite(CmdStsReg,0xEC); //ATA identify command. ata识别命令 也就是读出ata的信息	
	while ((RegRead(CmdStsReg) & SR_DRQ)!=SR_DRQ);  //no error handling 没有错误
	WriteAddr(IOReg); 
	ATA_Read(128);读出128*2个字节
	driveInfo = (struct driveID *) sectorBuffer.data; 得到硬盘信息

        LCDclrscr();

	for (i=0; i<20; i+=2)  将读出的数据进行解析
           {writechar(driveInfo->model[i+1]);//显示部分
            writechar(driveInfo->model[i]); }; //显示部分
	//Determine drive size. Multiplication and division is done by shifts
	startSector = driveInfo->totalSecHi;
	startSector = ((startSector<<16) + driveInfo->totalSecLo)>>11;	
	gotoxy(1,0);
	writeNumber(startSector); //Display drive size
	writestring("MB ");	
	
	
        //skipping boot code in first 445 bytes. So go to offset 446
        GoToSectorOffset(0,446);
	ATA_Read_Sectors_LBA(0, 32); 	  	//reading 64 byte partition records of 4 partition

  	readPos=0;				//New sector needs to be read	
  	sectorPos=0;
	pr = (struct partRec *) sectorBuffer.data;
	startSector = pr->startLBA;
	ATA_Read_Sectors_LBA(startSector, 64);  //Go to start sector of the partition

	boot = (struct bootSec710 *) sectorBuffer.data; //Load BPB struct pointer

	//All of the following calculations are from Microsoft FAT32 White Paper	
	Sectors_Per_Cluster = boot->BPB.secPerClust;
	Bytes_Per_Sector = boot->BPB.bytesPerSec;

	FirstFATSector = boot->BPB.resSectors + startSector;
	
	rootDirSectors=(((boot->BPB.rootDirEnts * 32)+ (Bytes_Per_Sector - 1)) / Bytes_Per_Sector);
	FATSz = boot->BPB.FATSz16;
	if (FATSz==0) FATSz = boot->BPB.FATSz32;
	if (boot->BPB.totSec16 != 0) totalSector=boot->BPB.totSec16;
	else totalSector=boot->BPB.totSec32;
	dataSec = totalSector - (boot->BPB.resSectors + (boot->BPB.FATs * FATSz) + rootDirSectors);

	FirstDataSector = boot->BPB.resSectors + (boot->BPB.FATs * FATSz) + rootDirSectors + startSector;

	if ((dataSec / Sectors_Per_Cluster) < 65525) {
	 Halt(3); //System is FAT16, not supported in this version.
	} 
	else {
	 FirstDirSector = boot->BPB.rootClust;
	 writestring("FAT32");//FATType=32;   
	} 
	
        GoToSectorOffset(startSector+1,484);	//Goto offset 484 of FSInfo sector (2nd sector)
 	ATA_Read(28);            
	fsInfo= (struct FAT32fsInfo *) sectorBuffer.data;
        DriveSize=fsInfo->freeCluster; //driveSize in # of cluster
					//Next freeCluster address changes everytime new file added or removed
	                                //Thus ZipAmp will see that user modified total files in drive, so
	                                //re-count of all files are needed.

 
	gotoxy(2,0);
	writeNumber((DriveSize*Sectors_Per_Cluster)>>11); //Display approx. free space in MB
	writestring("MB Free");		                  //Right shift of 11 is found from equation given below
							  //Display will give wrong value if free space > 65GB
							  //Because writeNumber function expects word value.
	
	//DriveSize is in # of cluster
	//size = (DriveSize * Sectors_Per_Cluster * Bytes_Per_Sector / (1024 * 1024)) MB
	//Assume Bytes_Per_Sector = 512,
	//Therefore, operation of ( 512 / ( 1024 * 1024) ) = Right shift of 11
 	
}

unsigned char getDirEntry(byte onlyMP3){
//gets a filename.ext, filesize, and start cluster of that file from the directory entry table.
//Returns 1 if file is found, returns 0 if no file found and reaches end of dir table.
//Finds only MP3 files and enters sub-directory if onlyMP3 is set, if its 0 then only reads root dir.
//Each file record in dir is 32 byte long.


	unsigned long cluster;
	word fileNum=0;
	dword extension;
	byte i,j,start,longNameFound;	
	struct direntry *file;	
	struct winentry *longFile;
	
	readPos=0; 

        if ((currentFileNum & dirReadOffset.fileNum) ==0) { //if reading from start of root dir
	  cluster=FirstDirSector;
	  sectorPos=0;
	  subDirLevel=0;   
	  
	  dirString[0]=2;
	  dirString[1]='/';
	  
	}
	else { 
       	 cluster=dirReadOffset.cluster;		//Start from last read cluster position.		
	 sectorPos=dirReadOffset.sectorPos;     //Last read sectorPos
	 fileNum=dirReadOffset.fileNum;		//Last read file number

	 //Find the previous file record read offset in the cluster
 	 GoToSectorOffset(clust2LBA(cluster)+sectorPos,dirReadOffset.offset);
	}               
	

	CLEAR:				//Jump position if an entry was invalid entry, clear fileName
	
	for (i=0; i<40; i++) fileName[i]=0; //Clear file name so all position is NULL.
	extension=0;
	longNameFound=0;

      do { //Directory read loop (infinite, unless a file found or reached end of directory)
      
 	  ATA_Read_Sectors_LBA(clust2LBA(cluster)+sectorPos, 16); //reading 32 byte in each iteration
          if (sectorPos==Sectors_Per_Cluster) {
           currentCluster=cluster;
           cluster=findNextCluster();           
           sectorPos=0; readPos=0;             
          } 	  

 	 
 	 
 	longFile=(struct winentry *) sectorBuffer.data; //Initialize pointer for long file name structure
 	file = (struct direntry *) sectorBuffer.data;   //Initialize pointer for short file name structure
 	
 	if (sectorBuffer.data[0] == 0xE5) {
	  //Deleted entry
 	 goto CLEAR;
 	}

 	 //------------------------------------------------------------------------------        	  
         /*End of a directory  block */ 
 	 if (sectorBuffer.data[0] == 0) {  //We reached end of a dir
 	  if (subDirLevel>0) { //Check if this end of a sub-dir, if true then go to one level up directory
  	    subDirLevel--;
  	    popDir(); //pop cluster address from stackfile to currentCluster
  	    cluster=currentCluster; //set dir cluster to popped cluster
  	    GoToSectorOffset(clust2LBA(cluster)+sectorPos,readPos); //go to dir file entry offset
  	    
  	    //Remove subdir text in dir string
  	    j=dirString[0]-2;
  	    while ((j>1)&&(dirString[j]!='/')) j--;
  	    dirString[0]=j+1;
  	    
  	    goto CLEAR; 	   
 	  }                             

 	  //If we are here then we reached end of root directory.
 	  currentFileNum=0;
 	  return 0; //Done. Finished reading all entries so return 0
 	 } 	 
 	
 	//-------------------------------------------------------------------------------              
	/* Active long name sub-component block. */ 	
 	 if ((longFile->Attr & ATTR_LONG_NAME_MASK) == ATTR_LONG_NAME) {
	   	
 	   start = 13 *( (longFile->Cnt-1) & 0x0F); //Fine offset of text in long file name

⌨️ 快捷键说明

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