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

📄 fat16.c

📁 杭州立宇泰ARMsys-P型ARM开发板BIOS代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		{
			SectorBuffer[j*2]=(FatCache[i*256+j])%256;
		    SectorBuffer[j*2+1]=(FatCache[i*256+j])>>8;
		}
		memcpy(ClusterBuffer[i+FirstFATSector+FATsectors],SectorBuffer,BytesPerSector);
	}
	NFEraseBlock(0);					//写入之前,擦除当前簇;
	for(i=0;i<SectorsPerCluster;i++)	//一扇区接一扇区写入
    {
    	for(j=0;j<255;j++);				//延时
    	WritePage(0,i,ClusterBuffer[i]);
	}
}


//The sector number of the first sector of that cluster.
//FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector;
//Because No MBR,so: clust-1!
unsigned long FirstSectorofCluster(unsigned long clust)		//数据存放的cluster转为sector
{
     return ((clust-1) * SectorsPerCluster + FirstDataSector);
}
 
// alloc a free cluster. policy is searching from prev cluster number, if no free cluster till end of fat, then search from head of fat.
// return a cluster number. 0xffff indicate NULLd, disk overflow.
// argument 0 : no prev cluster.
WORD AllocCluster(WORD PrevClusterNum)
{
	static WORD LastAllocClusterNum=0;
	WORD i;

	if(LastAllocClusterNum == 0)
		LastAllocClusterNum = PrevClusterNum;

	for(i = LastAllocClusterNum; i < BytesPerSector * FATsectors / sizeof(WORD); i++)
	{
		if(FatCache[i] == 0)		//此簇为空簇
		{
			FatCache[i] = 0xffff;	// flag with 0xffff, this is the last cluster.
			LastAllocClusterNum = i;
			//chain this cluster to prev one.
			if(PrevClusterNum != 0)
				FatCache[PrevClusterNum] = LastAllocClusterNum;
			
			return LastAllocClusterNum;//返回簇号
		}
	}

	// we have to search from head of fat
	for(i = 2; i < BytesPerSector * FATsectors / sizeof(WORD); i++)
	{
		if(FatCache[i] == 0)
		{
			FatCache[i] = 0xffff;	// flag with 0xffff, this is the last cluster.
			
			LastAllocClusterNum = i;
			
			//chain this cluster to prev one.	
			if(PrevClusterNum != 0)
				FatCache[PrevClusterNum] = LastAllocClusterNum;
			
			return LastAllocClusterNum;
		}
	}
	
	return 0xffff;
} 

//return next cluster num,
//0xffff indicate no next cluster.
//Note! : this function will dirty cache!
WORD GetNextClusterNum(WORD ClusterNum)
{
	return FatCache[ClusterNum];
}

// free cluster chain.此函数应当是用于依次释放fat链时
// argument 0 : no prev cluster.
void FreeCluster(WORD StartClusterNum)	//何时更新disk中的FAT表?
{
	WORD Cluster;
	WORD NextCluster;

	Cluster = StartClusterNum;

	while(Cluster != 0xffff)
	{
		NextCluster = FatCache[Cluster];
		FatCache[Cluster] = 0x0000;
		Cluster = NextCluster;
	}
}

DWORD CurrentCacheSector;
//Read a special sector into disk cache.
//NULL indicate NULLed.
BYTE* GetSectorData(DWORD StartSector)//LBA
{
	
	unsigned int block;
	unsigned int page;
	
	if((CurrentCacheSector == StartSector) && (StartSector != 0))
		return SectorBuffer;
	block=StartSector/0x20;
	page=StartSector%0x20;
	
	NFReadPage(block,page,SectorBuffer);
	CurrentCacheSector = StartSector;
	return SectorBuffer;
}

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
void Flush(void)
{
	
	int i,j;
	unsigned int block;
	unsigned int page;
	block=CurrentCacheSector/0x20;
	page =CurrentCacheSector%0x20;
	
	memcpy(ClusterBuffer[page],SectorBuffer, BytesPerSector);
	
    if(page==0)
	{
		for(i=1;i<SectorsPerCluster;i++)
		{
    		NFReadPage(block,i,SectorBuffer);
	    	memcpy(ClusterBuffer[i], SectorBuffer, BytesPerSector);
		}
    }
	else
	{
		for(i=0;i<page-1;i++)
    	{
        	NFReadPage(block,i,SectorBuffer);
	        memcpy(ClusterBuffer[i], SectorBuffer, BytesPerSector);
    	}
    	for(i=page+1;i< SectorsPerCluster;i++)
    	{
    		NFReadPage(block,i,SectorBuffer);
    	    memcpy(ClusterBuffer[i], SectorBuffer, BytesPerSector);
    	}   
	}

    memcpy(SectorBuffer,ClusterBuffer[page],BytesPerSector);	//保持Sectorbuffer作为cache内容保持不变!!
	
	NFEraseBlock(block);				//写入之前,擦除当前簇;
    for(i=0;i<SectorsPerCluster;i++)	//一扇区接一扇区写入
    {
    	for(j=0;j<255;j++);//延时
    	WritePage(block,i,ClusterBuffer[i]);
    } 
	//没有检验
}

WORD SectorNum2ClusterNum(DWORD SectorNum)
{
	return (WORD)((SectorNum - FirstDataSector) / SectorsPerCluster + 1);//NOTE:NO MBR!!!
}

DWORD ClusterNum2SectorNum(WORD ClusterNum)
{
	return FirstDataSector + (ClusterNum - 1) * SectorsPerCluster;//NOTE:NO MBR!!!
}

// return the first sector number of dir content .
// 0xffffffff indicate NULLed.//从目录区中取得一个目录项
int AllocDir(DWORD ParentDirSectorNum, DIRENTRY* new_dir, _FILE * fp)
{
	BYTE* Cache;
	DIRENTRY *dir;
	DWORD i;
	WORD PrevCluster;
	WORD Cluster;
	DWORD DirSectorNum = ParentDirSectorNum;
	
	if(ParentDirSectorNum == FirstDirSector)//在根目录区
	{
		for(i=0; i<RootDirCount * sizeof(DIRENTRY) / BytesPerSector; i++)
		{
			Cache = GetSectorData(DirSectorNum);
			if(Cache == NULL)
				return 2;
			
			for(dir = (DIRENTRY *)Cache; (BYTE*)dir < Cache + BytesPerSector; dir++)
			{
				if(dir->deName[0] == '\0' || dir->deName[0] == 0xe5)
				{
					memcpy((BYTE *)dir, (BYTE *)new_dir, sizeof(DIRENTRY));	//将新的目录信息写入				
					Flush();//更新disk中该扇区
					if(fp)//更新文件信息
					{
						fp->DirSectorNum = DirSectorNum;//当前目录项所在的扇区地址
						fp->DirIndex = ((BYTE*)dir - Cache) / sizeof(DIRENTRY);//目录索引,即该扇区中第x个目录项
						memcpy((BYTE *)(&fp->dir), (BYTE *)new_dir, sizeof(DIRENTRY));//新的目录信息写到文件结构中
					}
					return 0;//操作成功,退出
				}
			}
			DirSectorNum++;//下一个根目录扇区
		}
		// root dir have no room.
		return 3; 
	}
	
	else//不在根目录区
	{
		Cluster = SectorNum2ClusterNum(DirSectorNum);//
		
		while(Cluster != 0xffff)
		{
			for(i=0; i< SectorsPerCluster; i++)//在整个簇中搜索
			{
				Cache = GetSectorData(DirSectorNum);
				if(Cache == NULL)
					return 2;
				
				for(dir = (DIRENTRY *)Cache; (BYTE*)dir < Cache + BytesPerSector; dir++)
				{
					if(dir->deName[0] == '\0' || dir->deName[0] == 0xe5)
					{
						memcpy((BYTE *)dir, (BYTE *)new_dir, sizeof(DIRENTRY));
						Flush();
						
						if(fp)
						{
							fp->DirSectorNum = DirSectorNum;
							fp->DirIndex = ((BYTE*)dir - Cache) / sizeof(DIRENTRY);
							memcpy((BYTE *)(&fp->dir),(BYTE *)new_dir, sizeof(DIRENTRY));
						}
						return 0;
					}
				}
				DirSectorNum++;//下一个扇区
			}
			//搜索完当前簇,没有空的目录项
			PrevCluster = Cluster;//从FAT表中找出下一簇
			Cluster = GetNextClusterNum(Cluster);
			DirSectorNum = ClusterNum2SectorNum(Cluster);//刷新目录扇区
		}
		//且这已经是最后一个簇
		//
		// we have to extend this parent dir room.
		//
		Cluster = AllocCluster(PrevCluster);//利用FAT表获得一个空簇
		if(Cluster == 0xffff)//没有空簇
			return 4;
		
		DirSectorNum = ClusterNum2SectorNum(Cluster);//空簇做新的目录扇区地址
		
		Cache = GetSectorData(DirSectorNum);
		if(Cache == NULL)
			return 2;
		
		dir = (DIRENTRY *)Cache;
		
		memcpy((BYTE *)dir, (BYTE *)new_dir, sizeof(DIRENTRY));
		Flush();
		
		if(fp)
		{
			fp->DirSectorNum = DirSectorNum;
			fp->DirIndex = ((BYTE*)dir - Cache) / sizeof(DIRENTRY);
			memcpy((BYTE *)(&fp->dir), (BYTE *)new_dir, sizeof(DIRENTRY));
		}
		return 0;
	}
	return 5;
}

int DeleteDir(_FILE *file)
{
	BYTE* Cache;
	DIRENTRY *dir;

	Cache = GetSectorData(file->DirSectorNum);	//文件在目录区的扇区地址
	if(Cache == NULL)
		return 1;

	dir = (DIRENTRY *)Cache;
	dir += file->DirIndex;	//目录的索引号

	dir->deName[0] = 0xe5;	//做删除标记
	Flush();

	return 0;
}

// helper functions

// NULL indicate NULLed.
// Valid format is full path:	\[8.3\]*DIR_Name检验文件路径字符串是否合法
// limits:
// length < 80 && !(special char)
char* get_valid_format(const char *fullpath)
{
	static char static_path[512];
	char* p=static_path;
	char path[80];
	char* ppath = path;
	int dir_len_count; //count dir len.
	int i;

	if(fullpath == NULL || strlen(fullpath) >=80 || *fullpath != '\\') //第一个字符是‘\’
		return NULL;

	if(strlen(fullpath) > 1 && fullpath[strlen(fullpath)-1] =='\\')//最后一个字符是‘\’
		return NULL;

	strcpy(path, fullpath);
	//strupr(path);
	memset(p, 0, 512);

	for(;;)
	{
		switch(*ppath)
		{
		case 0x00:	//结束符
			{
				if(dir_len_count != 0) 		// prev is not '\\'
				{
					for(i=0; i<(11 - dir_len_count); i++)	//未满11字节,用blank填满
					{
						*p = 0x20;
						p++;
					}
				}
			}
			return static_path;	//返回整个字符串

		case '\\':
			{
				if(p != static_path) // this is not the first '\\'
				{
					if(dir_len_count == 0)// more than one '\\'
						return NULL;

					for(i=0; i<(11 - dir_len_count); i++)
					{
						*p = 0x20;
						p++;
					}
				}
				
				*p = '\\';
				p++;
				

⌨️ 快捷键说明

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