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

📄 storage.c

📁 一种文件系统的结构
💻 C
字号:
#include "..\define.h"
#include "..\all.h"
//================================================================================================
data	U8	gc_ReadWriteTimeOut;
data	U8	gc_CurrentCard;
data	U8	gc_ReadWriteDataArea;

xdata	U8	gc_CurrentExistMedia;	
xdata	U8	gc_DOS_FileSystemType	_at_	0x68c0;
xdata	U16	gw_DOS_SectorSize		_at_	0x68c1;
xdata	U8	gc_DOS_SectorPerCluster	_at_	0x68c3;
xdata	U32	gdw_DOS_SectorPerFAT	_at_	0x68c4;
xdata	U32	gdw_DOS_RootDirAddr		_at_	0x68c8;
xdata	U32	gdw_DOS_Fat1Addr		_at_	0x6010;
xdata	U32	gdw_DOS_DataAddr		_at_	0x68D0;
xdata	U32	gdw_DOS_Fat1EndAddr;
xdata	U32	gdw_DOS_Fat2Addr;
xdata	U32	gdw_CARD_TotalSizeMB;
xdata	U32	gdw_DOS_RootDirClus;
xdata	U32	gdw_DOS_FatMaxCluster;
xdata	U32	gdw_DOS_SectorPerCard; 

void	FlashExchang(U8 ActFlash, U8 InactFlash,U8 PageSize);
bit		USR_Check_Character(U8 *SourceArray,U8 offset,U8 *CompareArray,U8 Numbyte);
U8		DOS_Initialize(void);
U8		SMC_STORAGE_Initialize(void);



U8 DOS_Initialize(void)
{
	U8  tc_IniCode;
	U8  tc_Status,tc_Count;
	U8 tc_FileSystem,tc_ActiveFlag;
	U16 tw_RootDirSize;
	U16 tw_DOS_ReserveSector;
	U32 tdw_PBRAddr;
	U32 tdw_PartitionSectorSize;
	U32 tdw_PBRAddr1,tdw_PBRAddr2;
	U16 tw_offset;
	U32 tdw_ParSize;

	gdw_TotalFreeClusCounter=0;
	gdw_TotalFreeClusNumber=0;
	tdw_PBRAddr=0;
	tc_IniCode=0;
	tdw_PBRAddr1 = 0;
	tdw_PBRAddr2 = 0;
	tc_Count = 0;
		
	gc_StartSearchFreeCluster=1;
	gc_ReadWriteDataArea = 0;
	tc_Status = DOS_Read_LogicSector(0, 1);

	if(!tc_Status)
	{
		if(((gc_PlayRecordDataBuf[0x1fe]==0x55)&&(gc_PlayRecordDataBuf[0x1ff]==0xaa))||((gc_PlayRecordDataBuf[0x3fe]==0x55)&&(gc_PlayRecordDataBuf[0x3ff]==0xaa)))	// maxliao 20070409
		{//mark ok
			if((USR_Check_Character(gc_PlayRecordDataBuf,0x36,FAT_String,3)!=0)&&(USR_Check_Character(gc_PlayRecordDataBuf,0x52,FAT_String,3)!=0))
			{
				for(tw_offset=0x1C2;tw_offset<0x1ff;)
				{					
					tc_ActiveFlag = gc_PlayRecordDataBuf[tw_offset-4];
					tc_FileSystem = gc_PlayRecordDataBuf[tw_offset];
					((U8 *)(&tdw_PBRAddr))[0] = gc_PlayRecordDataBuf[tw_offset+7];
					((U8 *)(&tdw_PBRAddr))[1] = gc_PlayRecordDataBuf[tw_offset+6];
					((U8 *)(&tdw_PBRAddr))[2] = gc_PlayRecordDataBuf[tw_offset+5];
					((U8 *)(&tdw_PBRAddr))[3] = gc_PlayRecordDataBuf[tw_offset+4];
	
					((U8 *)(&tdw_ParSize))[0] = gc_PlayRecordDataBuf[tw_offset+11];
					((U8 *)(&tdw_ParSize))[1] = gc_PlayRecordDataBuf[tw_offset+10];
					((U8 *)(&tdw_ParSize))[2] = gc_PlayRecordDataBuf[tw_offset+9];
					((U8 *)(&tdw_ParSize))[3] = gc_PlayRecordDataBuf[tw_offset+8];
					tc_Count ++;
	
					if((tc_ActiveFlag==0x80)||tc_ActiveFlag==0x00||tc_ActiveFlag==0x70)
					{
	//					if((tc_FileSystem == 0x01)||(tc_FileSystem == 0x04)||(tc_FileSystem == 0x06)||(tc_FileSystem == 0x0b)||(tc_FileSystem == 0x0c)||(tc_FileSystem == 0x0e))
						{
							if(tdw_PBRAddr&&tdw_ParSize)
							{
								if((tdw_PBRAddr<tdw_PBRAddr1)||(tdw_PBRAddr>tdw_PBRAddr2))
								{//tdw_PBRAddr1:the stat Addr of last par,tdw_PBRAddr2:the end Addr of last par						
									tc_Count--;	
									tdw_PBRAddr1 = tdw_PBRAddr;  //save the stat Addr of current partion 
									tdw_PBRAddr2 = tdw_PBRAddr+tdw_ParSize; //save the last Addr of current partion 
								}
							}
						}
					}
					tw_offset += 0x10;	
					if(tc_Count>=4)
					{
						tc_Status = 1;	
					}
				}
			}
			else
			{
				tc_Status = 1;	
			}

			if(tc_Status == 1)
			{//the disk has no MBS,
				tdw_PBRAddr = 0;	
			}
			else
			{
				tdw_PBRAddr = tdw_PBRAddr1;				
				if(DOS_Read_LogicSector(tdw_PBRAddr, 1)!=0)
				{//read PBR sector error.
					return DOS_READ_PBS_ERR;
				}
				if(((gc_PlayRecordDataBuf[0x1fe]!=0x55)||(gc_PlayRecordDataBuf[0x1ff]!=0xaa))&&((gc_PlayRecordDataBuf[0x3fe]!=0x55)&&(gc_PlayRecordDataBuf[0x3ff]!=0xaa)))	// maxliao 20070409
				{
					return DOS_PBS_MARK_ERR;
				}
			}			

			if(USR_Check_Character(gc_PlayRecordDataBuf, 0x36, FAT_String, 3) == 0)
			{
				//check PBR
				if( (gc_PlayRecordDataBuf[0x39] == '1') && (gc_PlayRecordDataBuf[0x3a] == '2') )
				{//FAT12
					gc_DOS_FileSystemType = 0x00;
				}else if( (gc_PlayRecordDataBuf[0x39] == '1') && (gc_PlayRecordDataBuf[0x3a] == '6') )
				{//FAT16
					gc_DOS_FileSystemType = 0x01;
				}
				else
				{
					return DOS_UNKNOW_FILESYSTEM_ERR;
				}
			}
			else
			{//check if FAT32
				if((USR_Check_Character(gc_PlayRecordDataBuf, 0x52, FAT_String, 3) == 0) &&
				 ((gc_PlayRecordDataBuf[0x55] == '3') && (gc_PlayRecordDataBuf[0x56] == '2')))
				{//FAT32						
					gc_DOS_FileSystemType = 0x02;
				}
				else
				{//not FAT12/16/32					
					return DOS_UNKNOW_FILESYSTEM_ERR;
				}
			}
		
			//initialize global varible according to the parameters in PBR.
			((U8 *)(&gw_DOS_SectorSize))[0] = gc_PlayRecordDataBuf[0x0c];
			((U8 *)(&gw_DOS_SectorSize))[1] = gc_PlayRecordDataBuf[0x0b];
			
			gc_DOS_SectorPerCluster = gc_PlayRecordDataBuf[0x0d];
			
			((U8 *)(&tw_DOS_ReserveSector))[0] = gc_PlayRecordDataBuf[0x0f];
			((U8 *)(&tw_DOS_ReserveSector))[1] = gc_PlayRecordDataBuf[0x0e];

			((U8 *)(&gdw_DOS_SectorPerFAT))[0] = 0;
			((U8 *)(&gdw_DOS_SectorPerFAT))[1] = 0;
			((U8 *)(&gdw_DOS_SectorPerFAT))[2] = gc_PlayRecordDataBuf[0x17];
			((U8 *)(&gdw_DOS_SectorPerFAT))[3] = gc_PlayRecordDataBuf[0x16];

			if (gdw_DOS_SectorPerFAT == 0)
			{//FAT32										
				((U8 *)(&gdw_DOS_SectorPerFAT))[0] = gc_PlayRecordDataBuf[0x27];
				((U8 *)(&gdw_DOS_SectorPerFAT))[1] = gc_PlayRecordDataBuf[0x26];
				((U8 *)(&gdw_DOS_SectorPerFAT))[2] = gc_PlayRecordDataBuf[0x25];
				((U8 *)(&gdw_DOS_SectorPerFAT))[3] = gc_PlayRecordDataBuf[0x24];
			}
			((U8 *)(&tw_RootDirSize))[0] = gc_PlayRecordDataBuf[0x12];
			((U8 *)(&tw_RootDirSize))[1] = gc_PlayRecordDataBuf[0x11];

			//tw_RootDirSize = (tw_RootDirSize/gw_DOS_SectorSize)*32;//for large root061222//Ching
			tw_RootDirSize = ((U32)tw_RootDirSize * 32) / (U32)gw_DOS_SectorSize;

			gdw_DOS_Fat1Addr = tdw_PBRAddr + tw_DOS_ReserveSector;
			if(gc_PlayRecordDataBuf[0x10] == 0x01)
			{
				gdw_DOS_Fat2Addr = gdw_DOS_Fat1Addr;
			}
			else
			{
				gdw_DOS_Fat2Addr = gdw_DOS_Fat1Addr + gdw_DOS_SectorPerFAT;
			}

			((U8 *)(&tdw_PartitionSectorSize))[0] = 0;
			((U8 *)(&tdw_PartitionSectorSize))[1] = 0;
			((U8 *)(&tdw_PartitionSectorSize))[2] = gc_PlayRecordDataBuf[0x014];
			((U8 *)(&tdw_PartitionSectorSize))[3] = gc_PlayRecordDataBuf[0x013];
				
			if (tdw_PartitionSectorSize == 0)
			{//partition larger than 32M.	
				((U8 *)(&tdw_PartitionSectorSize))[0] = gc_PlayRecordDataBuf[0x23];
				((U8 *)(&tdw_PartitionSectorSize))[1] = gc_PlayRecordDataBuf[0x22];
				((U8 *)(&tdw_PartitionSectorSize))[2] = gc_PlayRecordDataBuf[0x21];
				((U8 *)(&tdw_PartitionSectorSize))[3] = gc_PlayRecordDataBuf[0x20];
			}

			if (gc_DOS_FileSystemType != 0x02)                                     //lzp add
			{//FAT12/16	
				gdw_DOS_RootDirAddr = gdw_DOS_Fat2Addr + gdw_DOS_SectorPerFAT;//xyq040811
				gdw_DOS_DataAddr = gdw_DOS_RootDirAddr + tw_RootDirSize;//xyq040811
				//FAT12/16 have no root dir cluster. starting cluster '2' is in the beginning of data area
				gdw_DOS_RootDirClus = 0;  
			}
			else
			{//FAT32				 
				gdw_DOS_DataAddr = gdw_DOS_Fat2Addr + gdw_DOS_SectorPerFAT;				
				((U8 *)(&gdw_DOS_RootDirClus))[0] = gc_PlayRecordDataBuf[0x2f];
				((U8 *)(&gdw_DOS_RootDirClus))[1] = gc_PlayRecordDataBuf[0x2e];
				((U8 *)(&gdw_DOS_RootDirClus))[2] = gc_PlayRecordDataBuf[0x2d];
				((U8 *)(&gdw_DOS_RootDirClus))[3] = gc_PlayRecordDataBuf[0x2c];
				gdw_DOS_RootDirAddr = gdw_DOS_DataAddr + ((gdw_DOS_RootDirClus-2) * (U32)gc_DOS_SectorPerCluster);//start from cluster 2
			}	
			
			if (tdw_PartitionSectorSize != 0)
			{
				if(gc_PlayRecordDataBuf[0x10] == 0x01)
				{				
					gdw_DOS_FatMaxCluster = tdw_PartitionSectorSize - tw_DOS_ReserveSector - (tw_RootDirSize) - gdw_DOS_SectorPerFAT;
				}
				else
				{
					gdw_DOS_FatMaxCluster = tdw_PartitionSectorSize - tw_DOS_ReserveSector - (tw_RootDirSize) - ( gdw_DOS_SectorPerFAT << 1 );
				}
				gdw_DOS_FatMaxCluster = gdw_DOS_FatMaxCluster / gc_DOS_SectorPerCluster;					
				gdw_DOS_FatMaxCluster = gdw_DOS_FatMaxCluster + 2;
				if (gdw_DOS_FatMaxCluster == 0 || gdw_DOS_FatMaxCluster > 0x0fffffff)
				{//0x0fffffff means last cluster in chain in FAT32.
					gdw_DOS_FatMaxCluster = 0x0fffffff;
				}
			
				if (gc_DOS_FileSystemType == 0)
				{// FAT 12
					gdw_DOS_Fat1EndAddr = gdw_DOS_Fat1Addr + ((gdw_DOS_FatMaxCluster * 3L / 2) >> 9);
				}
				else if(gc_DOS_FileSystemType == 1)
				{// FAT 16
					gdw_DOS_Fat1EndAddr = gdw_DOS_Fat1Addr + (gdw_DOS_FatMaxCluster >> 8);
				}
				else if (gc_DOS_FileSystemType == 2)					
				{// FAT 32
					gdw_DOS_Fat1EndAddr = gdw_DOS_Fat1Addr + (gdw_DOS_FatMaxCluster >> 7);
				}
	
				if(gc_CurrentCard<2)
				{
					//FAT area check.
					if(DOS_Read_LogicSector(gdw_DOS_Fat1Addr,1) == 0)
					{//check FAT1				
						if (gc_PlayRecordDataBuf[0] != 0xf8 || gc_PlayRecordDataBuf[1] != 0xff)
						{
							if(DOS_Read_LogicSector(gdw_DOS_Fat2Addr,1) == 0)
							{
								if (gc_PlayRecordDataBuf[0] !=	0xf8 ||	gc_PlayRecordDataBuf[1] != 0xff)
								{//FAT1 and FAT2 error
									return DOS_FAT_ERR;
								}
								else
								{// copy fat2 to fat1
									DOS_Copy_FATtoFAT(0x02,0x0fffffff,0);
								}
							}
							else
							{
								return DOS_READ_FAT2_ERR;
								
							}
						}
						else
						{// check FAT2
							if(DOS_Read_LogicSector(gdw_DOS_Fat2Addr,1) == 0)
							{
								if (gc_PlayRecordDataBuf[0] !=	0xf8 ||	gc_PlayRecordDataBuf[1] != 0xff)
								{// copy fat1 to fat2
									DOS_Copy_FATtoFAT(0x02,0x0fffffff,1);
								}
							}
							else
							{
								return DOS_READ_FAT2_ERR;
							}
						}
					}
					else
					{
						return DOS_READ_FAT1_ERR;
					}
				}
			}
			else
			{
				//tdw_PartitionSectorSize == 0, not FAT12/16/32
				return DOS_PARTITIONSIZE_ERR;
			}
		}
		else
		{
			//marker "0x55aa" error.
			return DOS_MBS_MARK_ERR;
		}
	}
	else
	{
		//read MBR sector error.
		return DOS_READ_MBS_ERR;
	}
	
	return DOS_SUCCESS;
}


void FlashExchang(U8 ActFlash, U8 InactFlash,U8 PageSize)
{
	switch(InactFlash)
	{
		case 0: InactFlash = 0x01; break;
		case 1: InactFlash = 0x04; break;
		case 2: InactFlash = 0x0C; break;
		case 3: InactFlash = 0x0C; break;
		case 4: break;
		case 5: InactFlash = 0x0C; break;
		
	   	default : InactFlash = 0; break;
	}

	XBYTE[0xB401] |= InactFlash;
	XBYTE[0xB405] |= InactFlash;

	switch(ActFlash)
	{
		case 0: 
			XBYTE[0xB08B] |=0x08;
 			XBYTE[0xB400] = 0x01;
			XBYTE[0xB422] = 0x00; 
			break;
		case 1: 
			XBYTE[0xB08B] |=0x08; 		
			XBYTE[0xB400] = 0x01;
			XBYTE[0xB422] = 0x01; 
		
			break;
		case 2: 
			XBYTE[0xB08B] &=0xF7; 	
			XBYTE[0xB400] = 0x06; 	
			XBYTE[0xB450] = 0x03; 
			break;
		case 3: 
			XBYTE[0xB08B] &=0xF7; 	
			XBYTE[0xB400] = 0x06; 		 
			XBYTE[0xB450] = 0x03; 
			break; 	
	}
	switch(PageSize)
	{
		case 1: 
			XBYTE[0xB4A3] = 0x01; 
			XBYTE[0xB455] = 0x00; 
			XBYTE[0xB456] = 0x02; 
			break;
	}
	if(ActFlash < 2)
	{
		XBYTE[0xB4A3] = 0x01;//512byte/page ECC mode
		//3.set read/write pause width
		XBYTE[0xB421] = 0x33;
		//4.set cmd time
		XBYTE[0xB802] = 0x66; //cmd time
	}
}



⌨️ 快捷键说明

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