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

📄 zfat.c

📁 可以实现fat文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 	   
 	   //Following while loops are shortened with EEPROM table longNameOffset. This reduces code size.
           /*i=0;
  	   while ((start<40)&&(i<5)) { fileName[start++]=longFile->Part1[i++]; }
  	   i=0;                                                                 
       	   while ((start<40)&&(i<6)) { fileName[start++]=longFile->Part2[i++]; }
       	   i=0;
  	   while ((start<40)&&(i<2)) { fileName[start++]=longFile->Part3[i++]; }*/
  	   
  	   //We only store text in fileName array if total length of text is less than 40 bytes
  	   i=0;
  	   while ((start<40)&&(i<13)) { fileName[start++] = sectorBuffer.data[longNameOffset[i++]]; }
  	   longNameFound=1;
	 }                                                                        
	 
 	 else {
 	  //Found Short file entry, now determine its type
 	  //------------------------------------------------------------------------------
          for (i=0; i<8; i++) {                               
           //Check for file name validity. There can be garbage in dir entry, that will cause system failure
           //j<47 comes from # of eeprom invalidFileChars table
           for (j=0; j<47; j++) if (invalidFileChars[j]== file->name[i]) goto CLEAR;
           
           //This may look redundant but its done so that we don't have to write another loop to read fileName
	   if (longNameFound==0) fileName[i]=file->name[i]; // Reading file name if long name not found
	  } 
        
  	  /* Found a file. -----------------------------------*/
 	  if ((file->attributes & 0x18 /*(ATTR_DIRECTORY | ATTR_VOLUME_ID)*/ ) == 0x00) {
	
	   	  
           for(i=0;i<3; i++) { //Collect the file extension
            fileExtension[i]=file->extension[i];

           }      
           extension = (*(dword *)fileExtension) & 0x00FFFFFF;
	   // if we wanted MP3 but extesion wasn't MP3 then goto CLEAR
           if ((onlyMP3==1)&&(extension!=0x0033504D)) goto CLEAR; //extension = 03PM (little endian struct)

	   
           fileNum++;						// File found, so increment fileNum	  
	   if (fileNum>currentFileNum) {	             	// Making sure that this entry is not read before  
	     currentFileNum=fileNum;				// New entry, so increment current file number.             	   	  	    	   	     
	     FileSize = file->fileSize;
	     currentCluster = file->highClust;
	     currentCluster = (currentCluster<<16) + file->startCluster;		     
             dirReadOffset.cluster=cluster;
             dirReadOffset.sectorPos=sectorPos;
	     dirReadOffset.fileNum=fileNum;
	     dirReadOffset.offset=readPos; 
	     return 1;
	   }
	   goto CLEAR;	//This file has already been encountered so clear the info

	  }                                                                                       
	  
	  //-------------------------------------------------------------------------------	  	  
          //Directory block
	  if ((file->attributes & 0x18) == ATTR_DIRECTORY) {
  	  /* Found a directory. */ 
	   
  	   if ((onlyMP3==1) && (subDirLevel<8)) { //Enter sub dir only if looking for MP3
  	    currentCluster=cluster; //pushDir will use value of currentCluster to push onto stack
  	    cluster = file->highClust; //Get the sub-directory cluster address
  	    cluster = (cluster<<16) + file->startCluster;  	   
  	    pushDir(); //push return cluster address on stack (gets value from currentCluster)
     	    subDirLevel++;
  	    readPos=0;	//A new cluster has to be read, so set readPos=0
  	    sectorPos=0;

	    //Fix dirString for LCD path display  	    
  	    i=0;
  	    j=dirString[0];
  	    while ((j<20)&&(fileName[i]!=0)) dirString[j++]=fileName[i++];
  	    dirString[j++]='/';  	     
  	    dirString[0]=j;
  	   }
  	   goto CLEAR;		   
	  }	  
	 } 	  
       } 
       while (1); 	 
}


dword findNextCluster(){
 unsigned long FatOffset, sector;
 unsigned int offset;                  

   FatOffset = (currentCluster << 2); //Lshift by 2 will be 1 in FAT16, not supported here
   sector = FirstFATSector + (FatOffset / Bytes_Per_Sector);
   offset = FatOffset % Bytes_Per_Sector;
   readPos=0; sectorPos=0;
   while (readPos<offset) ATA_Read_Sectors_LBA(sector,1);
   ATA_Read_Sectors_LBA(sector+sectorPos,2);//Have to read 1 word in FAT16, not supported here
   return (*(unsigned long *) sectorBuffer.data) & 0x0FFFFFFF;   //FAT32 address return
  
}

void GoToSectorOffset(dword LBASector,word offset) {
  //Find the offset in the sector
   readPos=0;
   while (readPos<offset) ATA_Read_Sectors_LBA(LBASector,1); //go to offset
}

void pushDir() {
 //pushes the directory return address on stack.
 //Also stores global variables sectorPos and readPos
 //Each record is 14 byte long. 
 //Dir return cluster address = 4 bytes
 //                   ReadPos = 2 bytes
 //                 SectorPos = 1 byte
 //                     Total = 7 bytes
 //Due to ZipAmp hardware, we can only store even bytes
 //Thus, we rearrange the 7 byte data in 14 byte space, with every even byte having actual data.
 
 byte offset, i;
 
 
 offset = subDirLevel * 14; //this is storage byte offset, position to store this dir info
 for (i=0; i<4; i++) //Arrange the cluster address data on even byte postion
  sectorBuffer.data[offset + (i<<1)]=currentCluster>>(24-(i<<3)); //1 word
  

 sectorBuffer.data[offset+8]=readPos>>8; //arrange readPos on even byte
 sectorBuffer.data[offset+10]=readPos;
 
 sectorBuffer.data[offset+12]=sectorPos;

 offset=offset>>1; //divide by 2 to get word offset
 if (offset>0) { //Go to offset if its not 0th position in sector
  readPos=0;             
  ATA_Read_Sectors_LBA(dirStackLBA, offset ); //Load previous dir info in buffer
 }                                           
 
 ATA_WriteSector(dirStackLBA); //Now write the buffer into file ZIPAMP.SYS pointed by dirStackLBA.
}  

void popDir(){ //Pops directory info from stack, reverse process of pushDir.
 byte offset,i;
 offset=subDirLevel*14; //Offset we have to read now
 readPos=0;
 ATA_Read_Sectors_LBA(dirStackLBA, 128); //Load whole dir stack
 
 //Arrange the data
 for (i=0; i<7; i+=2) currentCluster=(currentCluster<<8) + sectorBuffer.data[offset+i];

 readPos=sectorBuffer.data[offset+8];
 readPos=(readPos<<8) + sectorBuffer.data[offset+10];
 
 sectorPos=sectorBuffer.data[offset+12];

}

void saveConfig() {
//Saves player status on ZIPAMP.CFG file.

 struct configuration *cfg;
 byte i;
 cfg = (struct configuration *) sectorBuffer.data;
 cfg->Sign1=0xA5;			//DataValid signature
 cfg->SoundMode=soundMode;		//PlayType
 cfg->PlayMode=playMode;		//Play mode
 cfg->DriveSize=DriveSize;		//Drive size
 cfg->TotalFiles=totalFiles;		//Total files
 cfg->LastFile=currentFileNum-1;        //Played file
 cfg->Sign2=0x5A;			//DataValid end sign
 
 //Hardware lets us save only even bytes. So fix the array. Position i = position i*2
 //13 comes from total size of struct configuration byte size+1 (12+1 bytes)
 //Position 0 doesn't need to be fixed, its already in correct position.
 for (i=13; i>0; i--) sectorBuffer.data[i*2]=sectorBuffer.data[i]; //Format data for saving, gap every odd byte
 ATA_WriteSector(cfgFileLBA);
}

byte loadConfig() {
//Load player status from ZIPAMP.CFG file.

 struct configuration *cfg;
 byte i;
  
 readPos=0;
 ATA_Read_Sectors_LBA(cfgFileLBA,128);
 for (i=1; i<=13; i++) sectorBuffer.data[i]=sectorBuffer.data[i*2]; //Format data for reading, ungap every odd byte
 cfg = (struct configuration *) sectorBuffer.data;
 if (cfg->DriveSize==DriveSize) { //If hard drive info matches
  totalFiles=cfg->TotalFiles;
  soundMode=cfg->SoundMode;
  playMode=cfg->PlayMode;     
  currentFileNum=cfg->LastFile;  
  return 1; //Load was successful.
 }

 return 0; //Load failed.
}

⌨️ 快捷键说明

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