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

📄 zfat.c

📁 &#8226 控制器(CPU): Atmel AT90S8515 AVR &#8226 MP3解码器: STA013 &#8226 音频 DAC: CS4334 &#8226 IDE 接口
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    Copyright 2003 Nasif Akand (nasif@yifan.net)
    http://go.to/zipamp
    http://zipamp.virtualave.net

    This file is part of ZipAmp MP3 software.

    ZipAmp is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    ZipAmp is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this code; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/

//This module is the implementation of FAT
//Nasif Akand

#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
	return ((clust-2) * Sectors_Per_Cluster) + FirstDataSector;
}

/*
unsigned long LBA2Cluster(unsigned long LBA) {
 return ((LBA-FirstDataSector)/Sectors_Per_Cluster)+2;
}
*/

void InitFAT(){
 	struct partRec *pr;
	struct bootSec710 *boot;
	struct driveID *driveInfo;
	word  rootDirSectors;
	struct FAT32fsInfo *fsInfo; 	
	dword startSector;
	dword FATSz, dataSec, totalSector;
	byte	i;	
        RegWrite(DrvHeadReg,LBAMaster);
	RegWrite(CmdStsReg,0xEC); //ATA identify command.	
	while ((RegRead(CmdStsReg) & SR_DRQ)!=SR_DRQ);  //no error handling
	WriteAddr(IOReg);
	ATA_Read(128);
	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; 	   
 	  }                             

⌨️ 快捷键说明

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