📄 dosfat.c
字号:
#include "..\define.h"
#include "..\all.h"
data bit gbt_FindFlag;
xdata U8 gc_ClusBufValidSize;
xdata U8 gc_ClusBufValidPoint;
xdata U32 gdw_ClusterBuffer[8];
xdata U32 gdw_FreeClusterNum[2];
xdata U32 gdw_TotalFreeClusCounter;
xdata U32 gdw_TotalFreeClusNumber;
void MoveUSBtoUserDataBuf(U16 tw_StartAddr);
U8 DOS_ConnectFATChain(U32 tdw_HeadCluster, U32 tdw_TailCluster);
U8 DOS_Copy_FATtoFAT(U32 tdw_HeadCluster, U32 tdw_TailCluster, bit tbt_fat1tofat2);
U8 DOS_MarkFATUpdate(U32 tdw_MarkFATAddr,U8 tc_Value);
U8 DOS_SearchFreeCluster(U8 tc_SearchMode);
U32 DOS_ClusterLogicAddr(U32 tdw_Cluster);
U32 DOS_GetAFreeCluster(void);
U32 DOS_GetNextCluster(U32 tdw_CurrentCLuster, U32 tdw_ClusterNumber);
U32 DOS_ClusterLogicAddr(U32 tdw_Cluster)
{
U32 tdw_LogicAddr;
if (tdw_Cluster == 0)
{//maybe Root dir
if (gc_DOS_FileSystemType == 2)
{//FAT32 cluster can not be 0
tdw_LogicAddr = 0;//mark error
}
else
{//FAT12&FAT16 root dir
tdw_LogicAddr = gdw_DOS_RootDirAddr;
}
}
else if (tdw_Cluster == 1)
{//cluster is disable to be 1
//when cluster is 1,error is occur
tdw_LogicAddr = 0;
}
else
{//normal state
tdw_LogicAddr = (gdw_DOS_DataAddr) + ((tdw_Cluster - 2) * gc_DOS_SectorPerCluster);
}
return tdw_LogicAddr;
}
//-------------------------------------------------------------------------------
U8 DOS_ConnectFATChain(U32 tdw_HeadCluster, U32 tdw_TailCluster)
{
U8 tc_Status;
U8 tc_ValidPoint;
U8 tc_ValidSize;
U8 tc_ArrayNum;
U8 tc_ChainEndFlag = 0;
U8 tc_ConnectMode;
U8 tc_Dirty = 0;
U16 tw_Offset;
U32 tdw_CopyStartCluster;
U32 tdw_CopyEndCluster;
U32 tdw_CurrentCluster;
U32 tdw_NextCluster;
U32 tdw_CurrentSector;
U32 tdw_NextSector;
U32 tdw_TempBuffer[8];
U32 tdw_FreeClusterNum;
U32 uTemp;
//backup DOS_SearchFreeCluster's global variable to temp
memcpy(tdw_TempBuffer,gdw_ClusterBuffer,32); //U32 tdw_TempBuffer 8*4=32
tc_ValidPoint = gc_ClusBufValidPoint;
tc_ValidSize = gc_ClusBufValidSize;
tdw_FreeClusterNum=gdw_FreeClusterNum[0];
//confirm FAT copy end address
if (tdw_HeadCluster > tdw_TailCluster)
{
tdw_CopyEndCluster = tdw_HeadCluster;
}
else
{
tdw_CopyEndCluster = tdw_TailCluster;
}
if (tdw_HeadCluster == tdw_TailCluster)
{//only connect 0xffffffff to HeadCluster
tc_ConnectMode = 0;//3
tdw_CopyStartCluster = tdw_HeadCluster;//confirm start address of FAT Copy
}
else if (DOS_GetNextCluster(tdw_HeadCluster,1) == 0)
{//Create new file's FAT chain
tc_ConnectMode = 1;//0
tdw_CopyStartCluster = tdw_HeadCluster;//confirm start address of FAT Copy
}
else
{//Connect to exist file's FAT chain
tc_ConnectMode = 2;//2
tdw_CopyStartCluster = 2;//confirm start address of FAT Copy
}
tdw_CurrentCluster = tdw_HeadCluster;
DOS_MarkFATUpdate(gdw_DOS_Fat1Addr,0xaa);//mark FAT1 is updating now
if (gc_DOS_FileSystemType == 0x00)
{//FAT12
U8 tc_SectorNum;
U8 tc_OddCluster;
tc_Dirty = 0;
tdw_CurrentSector = ((tdw_CurrentCluster * 3) >> 1) >> 9;
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);//must read again
while(!tc_ChainEndFlag)
{
//search free cluster initialize
gc_ClusBufValidPoint = 0;
gc_ClusBufValidSize = 1;
if (tc_ConnectMode == 2)
{//search free cluster from start
/*gdw_FreeClusterNum[0]=0;
while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1)))
{
DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
}*/
gdw_ClusterBuffer[1] = tdw_TailCluster;
}
else if (tc_ConnectMode == 1)
{
//gdw_ClusterBuffer[0] = tdw_CurrentCluster;
gdw_FreeClusterNum[0]=tdw_CurrentCluster; //lizhn modify 040907
while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1)))
{
DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
}
}
for (tc_ArrayNum = 1; tc_ArrayNum < 8; tc_ArrayNum ++)
{
tw_Offset = ((tdw_CurrentCluster * 3) >> 1) % 512;
if (tdw_CurrentCluster == tdw_TailCluster)
{//final a cluster chain
tdw_NextCluster = 0xffffffff;
}
else
{//get next cluster chain value
tdw_NextCluster = gdw_ClusterBuffer[tc_ArrayNum];
}
tc_SectorNum = tdw_CurrentSector % 3;//confirm current sector's situation
tc_OddCluster = (U8)(tdw_CurrentCluster & 0x01);//odd or even
//write next cluster number into previous cluster entry
if (tw_Offset == 511)
{//over edge state
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
if ((tc_SectorNum == 0)||(tc_SectorNum == 1))
{
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
if(tc_SectorNum == 0)
{
gc_PlayRecordDataBuf[tw_Offset] &= 0x0f;
gc_PlayRecordDataBuf[tw_Offset] |= (U8)((tdw_NextCluster & 0x0f) << 4);
}
else
{
gc_PlayRecordDataBuf[tw_Offset] = (U8)tdw_NextCluster;
}
uTemp= gdw_DOS_Fat1Addr + tdw_CurrentSector;
tc_Status = DOS_AppendWrite_LogicSector(uTemp, 1);
tdw_CurrentSector++;
//read next sector
tc_Status = DOS_Read_LogicSector(uTemp+1, 1);
if(tc_SectorNum == 0)
{
gc_PlayRecordDataBuf[0] = (U8)(tdw_NextCluster >> 4);
}
else
{
gc_PlayRecordDataBuf[0] &= 0xf0;
gc_PlayRecordDataBuf[0] |= (U8)((tdw_NextCluster >> 8) & 0x0f);
}
}
}
else
{//normal state
if (tc_OddCluster)
{//odd cluster
gc_PlayRecordDataBuf[tw_Offset] &= 0x0f;
gc_PlayRecordDataBuf[tw_Offset] |= (U8)((tdw_NextCluster & 0x0f) << 4);
gc_PlayRecordDataBuf[tw_Offset+1] = (U8)(tdw_NextCluster >> 4);
}
else
{//even cluster
gc_PlayRecordDataBuf[tw_Offset] = (U8)tdw_NextCluster;
gc_PlayRecordDataBuf[tw_Offset+1] &= 0xf0;
gc_PlayRecordDataBuf[tw_Offset+1] |= (U8)(0x0f & (tdw_NextCluster >> 8));
}
}
tc_Dirty = 1;
if (tdw_NextCluster == 0xffffffff)
{
tc_ChainEndFlag = 1;
break;
}
tdw_NextSector = ((tdw_NextCluster * 3) >> 1) >> 9;//next sector
tdw_CurrentCluster = tdw_NextCluster;
if (tdw_NextSector != tdw_CurrentSector)
{
tc_Dirty = 0;
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);
tdw_CurrentSector = tdw_NextSector;
DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_NextSector,1);
}
}//end for
}//end while
if (tc_Dirty)
{
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector, 1);//write sector back
}
}//FAT12 end
else
{//FAT16&FAT32
tc_Dirty = 0;
tdw_CurrentSector = (tdw_CurrentCluster << gc_DOS_FileSystemType) >> 9;
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);//must read again
//do connect chain
while(!tc_ChainEndFlag)
{
//search free cluster initialize
gc_ClusBufValidPoint = 0;
gc_ClusBufValidSize = 1;
if (tc_ConnectMode == 2)
{//search free cluster from start
/*gdw_FreeClusterNum[0]=0;
while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1)))
{
DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
}*/
gdw_ClusterBuffer[1] = tdw_TailCluster;
}
else if (tc_ConnectMode == 1)
{
//gdw_ClusterBuffer[0] = tdw_CurrentCluster;
gdw_FreeClusterNum[0]=tdw_CurrentCluster;
while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1)))
{
DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
}
}
for (tc_ArrayNum = 1; tc_ArrayNum < 8; tc_ArrayNum ++)
{
tw_Offset = (tdw_CurrentCluster << gc_DOS_FileSystemType) % 512;
if (tdw_CurrentCluster == tdw_TailCluster)
{//final a cluster chain
tdw_NextCluster = 0xffffffff;
}
else
{//get next cluster chain value
tdw_NextCluster = gdw_ClusterBuffer[tc_ArrayNum];
}
//write next cluster number into previous cluster entry
gc_PlayRecordDataBuf[tw_Offset] = tdw_NextCluster;
gc_PlayRecordDataBuf[tw_Offset + 1] = tdw_NextCluster >> 8;
if (gc_DOS_FileSystemType == 0x02)
{//FAT32
gc_PlayRecordDataBuf[tw_Offset + 2] = tdw_NextCluster >> 16;
gc_PlayRecordDataBuf[tw_Offset + 3] = tdw_NextCluster >> 24;
}
tc_Dirty = 1;
if (tdw_NextCluster == 0xffffffff)
{
tc_ChainEndFlag = 1;
break;
}
tdw_NextSector = (tdw_NextCluster << gc_DOS_FileSystemType) >> 9;//next sector
tdw_CurrentCluster = tdw_NextCluster;
if (tdw_NextSector != tdw_CurrentSector)
{
tc_Dirty = 0;
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);
tdw_CurrentSector = tdw_NextSector;
DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_NextSector,1);
}
}//end for
}//end while
if (tc_Dirty)
{
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector, 1);//write sector back
}
}//FAT16&FAT32 end
#if ((K_CARD_TYPE &0x01)== 0x01)//if nand flash is support
if (gc_CurrentCard < 2)
{//close new block when FAT1 to FAT2 end
SMC_LogicWriteEnd(0xffff);
gc_NewBlockStatus = 0;
}
#endif
DOS_MarkFATUpdate(gdw_DOS_Fat1Addr,0xf8);//mark updating is complete
DOS_Copy_FATtoFAT(tdw_CopyStartCluster,tdw_CopyEndCluster, 1);//copy FAT1 to FAT2
//restore DOS_SearchFreeCluster's global variable from temp
memcpy(gdw_ClusterBuffer,tdw_TempBuffer,32);
gc_ClusBufValidPoint = tc_ValidPoint;
gc_ClusBufValidSize = tc_ValidSize;
gdw_FreeClusterNum[0]=tdw_FreeClusterNum;
return tc_Status;
}
//-------------------------------------------------------------------------------
U8 DOS_Copy_FATtoFAT(U32 tdw_HeadCluster, U32 tdw_TailCluster, bit tbt_fat1tofat2)
{
U8 tc_Status = DOS_SUCCESS;
U32 tdw_StartSector;
U32 tdw_EndSector;
U32 tdw_CopySize;
U32 tdw_CopySourcetAddr;
U32 tdw_CopyTargetAddr;
U32 tdw_LoopCount;
U32 tdw_MarkAddr;
if (tdw_TailCluster >= gdw_DOS_FatMaxCluster)//exceed max cluster
tdw_TailCluster = gdw_DOS_FatMaxCluster - 1;
//calculate start and end address of copying
if (gc_DOS_FileSystemType == 0)
{//FAT12
tdw_StartSector = (tdw_HeadCluster * 3 + 1) >> 1;
tdw_StartSector >>= 9;
tdw_EndSector = (tdw_TailCluster * 3 + 1) >> 1;
tdw_EndSector >>= 9;
}
else
{//FAT16&FAT32
tdw_StartSector = (tdw_HeadCluster << gc_DOS_FileSystemType);
tdw_StartSector >>= 9;
tdw_EndSector = tdw_TailCluster << gc_DOS_FileSystemType;
tdw_EndSector >>= 9;
}
tdw_CopySize = (tdw_EndSector - tdw_StartSector) + 1;
//confirm the direction of the Copy operation
if (tbt_fat1tofat2)
{//FAT1 to FAT2
tdw_CopySourcetAddr = gdw_DOS_Fat1Addr + tdw_StartSector;//copy source address
tdw_CopyTargetAddr = gdw_DOS_Fat2Addr + tdw_StartSector;//copy target address
tdw_MarkAddr = gdw_DOS_Fat2Addr;//mark updating address
}
else
{//FAT2 to FAT1
tdw_CopySourcetAddr = gdw_DOS_Fat2Addr + tdw_StartSector;
tdw_CopyTargetAddr = gdw_DOS_Fat1Addr + tdw_StartSector;
tdw_MarkAddr = gdw_DOS_Fat1Addr;
}
if (tdw_CopyTargetAddr != tdw_MarkAddr)
{
//mark updating flag 0xf8 ---> 0xaa
DOS_MarkFATUpdate(tdw_MarkAddr,0xaa);
}
for (tdw_LoopCount = 0; tdw_LoopCount < tdw_CopySize; tdw_LoopCount ++)
{
gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
tc_Status = DOS_Read_LogicSector(tdw_CopySourcetAddr, 1);
//not close new block
if (tdw_LoopCount == 0 && tdw_CopyTargetAddr == tdw_MarkAddr)
{//fisrt write sector is FAT1's start sector
gc_PlayRecordDataBuf[0] = 0xaa;
}
tc_Status = DOS_AppendWrite_LogicSector(tdw_CopyTargetAddr, 1);
tdw_CopySourcetAddr ++;//next sector
tdw_CopyTargetAddr ++;//next sector
}
#if ((K_CARD_TYPE &0x01)== 0x01)//if nand flash is support
if (gc_CurrentCard < 2)
{//close new block when FAT1 to FAT2 end
SMC_LogicWriteEnd(0xffff);
gc_NewBlockStatus = 0;
}
#endif
DOS_MarkFATUpdate(tdw_MarkAddr,0xf8);//mark updating is complete
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -