📄 fat.c
字号:
#ifndef __FAT_C__
#define __FAT_C__
//***********************************************
#include "dp8051.h"
#include "config.h"
#include "absacc.h"
#include "constant.h"
#include "variable.h"
#include "function.h"
#include "sdhost.h"
#include "sssmp3_regs.h"
#include "fat.h"
#include "mp3_appl.h"
//***********************************************
//***********************************************
xdata U8 sbuf1[512] _at_(0xE000);
xdata U8 sbuf2[512] _at_(0xF000);
//***********************************************
/************************************************
函 数 名: InitFat()
功 能:初始化Fat
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
U8 InitFat(void)
{
//setting LBA = 0 to read MBR info. or BPB
DMA_load_sector(0, 0x05);
//Assume it is MBR, now load Boot Sector
if((((((MBR *)sbuf1)->P1).x86Boot == 0x00)
||((((MBR *)sbuf1)->P1).x86Boot == 0x80))
&&((((((MBR *)sbuf1)->P1).PartitionType)& 0xF0)== 0x00))
{
if(((MBR *)sbuf1)->Signature != 0x55AA )
{ //NOTE: must be 0x55AA in MBR
return FATERR_NO_DOSFORMAT;
}
ENDIAN_ASSIGN_4( &CFatData.dwFatTabStartlba, &((MBR *)sbuf1)->P1.LogStartSector ); //not done yet! See below.
//CFatData.dwFatTabStartlba = LE32(((MBR *)sbuf1)->P1.LogStartSector);
//setting BPB LBA, load Boot Sector
DMA_load_sector(CFatData.dwFatTabStartlba, 0x05);
//*********************************************
#if TX_DEBUG
//TXSend((Uint8 xdata *)0xE000);
#endif
//*********************************************
}
else if((((BS16 *)sbuf1)->JmpCode[0] == 0xEB)
&&(((BS16 *)sbuf1)->JmpCode[2] == 0x90)
&&(((BS16 *)sbuf1)->Signature == 0x55AA))
{
CFatData.dwFatTabStartlba = 0; //not done yet! See below.
}
else
{
return FATERR_NO_DOSFORMAT;
}
if(((BS16 *)sbuf1)->FATSz16)
CFatData.fFAT32 = 0;//FAT16 mode
else
CFatData.fFAT32 = 1; // FAT32 mode
// HERE: sbuf should be containing Boot sector ////
if(CFatData.fFAT32)
{//FAT32
ENDIAN_ASSIGN_2(&CFatData.wBytesPerSec, &((BS32 *)sbuf1)->BytesPerSector);
//CFatData.wBytesPerSec = LE16(((BS32 *)sbuf1)->BytesPerSector);
CFatData.bSectorsPerClu = ((BS32 *)sbuf1)->SectorsPerCluster;
CFatData.dwFatTabStartlba += ((U8 *)&((BS32 *)sbuf1)->ReservedSectors)[0];
ENDIAN_ASSIGN_4( &CFatData.dwSecNumInFat, &((BS32 *)sbuf1)->FATSz32);
//CFatData.dwSecNumInFat = LE32(((BS32 *)sbuf1)->FATSz32);
CFatData.dwClu2Startlba = CFatData.dwFatTabStartlba + CFatData.dwSecNumInFat *((U32)(((BS32 *)sbuf1)->NumFATs));
ENDIAN_ASSIGN_4( &CFatData.dwRootStartCluNo, &((BS32 *)sbuf1)->RootClus);
//CFatData.dwRootStartCluNo = LE32(((BS32 *)sbuf1)->RootClus);
CFatData.dwRootStartlba = (CFatData.dwRootStartCluNo - 2)* CFatData.bSectorsPerClu + CFatData.dwClu2Startlba;
CFatData.wSecNumInRoot = CFatData.bSectorsPerClu;
FATTab.bShiftBits = 2;//Fat32 records each cluster by four bytes
CFatData.dwMask = 0x0FFFFFFF;//fat32 using bit28~bit0
//FAT32根目录簇链
ReadRootCluster();
}
else
{//FAT16
ENDIAN_ASSIGN_2( &CFatData.wBytesPerSec, &((BS16 *)sbuf1)->BytesPerSector);
//CFatData.wBytesPerSec = LE16(((BS16 *)sbuf1)->BytesPerSector);
CFatData.bSectorsPerClu = ((BS16 *)sbuf1)->SectorsPerCluster;
CFatData.dwFatTabStartlba += ((U8 *)&((BS16 *)sbuf1)->ReservedSectors)[0];
//ENDIAN_ASSIGN_2( &varAl.TmpShort, &((BS16 *)sbuf1)->FATSz16);
//CFatData.dwSecNumInFat = (0x0000FFFF)&((ULONG)varAl.TmpShort);
CFatData.dwSecNumInFat = ((U32)LE16(((BS16 *)sbuf1)->FATSz16))& 0x0000FFFF;
ENDIAN_ASSIGN_2(&CFatData.wSecNumInRoot, &((BS16 *)sbuf1)->RootDirEntries);
//CFatData.wSecNumInRoot = LE16(((BS16 *)sbuf1)->RootDirEntries);
FileData.RootDirNum = (U32)CFatData.wSecNumInRoot;
CFatData.wSecNumInRoot <<= 5;//Each FDB = 32bytes
CFatData.wSecNumInRoot /= CFatData.wBytesPerSec;
CFatData.dwRootStartlba = CFatData.dwFatTabStartlba + CFatData.dwSecNumInFat *((U32)(((BS16 *)sbuf1)->NumFATs));
CFatData.dwRootStartCluNo = 0;//Assigning "0" to the start cluster# of root for fat16 mode.
CFatData.dwClu2Startlba = CFatData.dwRootStartlba +(U32)CFatData.wSecNumInRoot;
FATTab.bShiftBits = 1;//Fat16 records each cluster by two bytes.
CFatData.dwMask = 0x0000FFFF;
}
CFatData.bFDBNumInSec = (U8)(CFatData.wBytesPerSec / DIREntrySize);//Coutning the number of FDB in one sector.
return FATERR_NO_ERROR;
}
/************************************************
函 数 名: Forward()
功 能:
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:
************************************************/
bit Forward(void)
{
bit flag = 0;
U8 index;
U32 position;
if(CFatData.fFAT32)
{
//FAT32
for(;FileData.dwCurCluNo < FileData.RootDirNum;)
{
position = FileData.dwCurCluNo;
for(index = 0; index < MAX_FILE_FRAGMENT_NUMBER; index++)
{
if(position < rootclusters[index].number)
{
position = rootclusters[index].cluster + position;
break;
}
else
{
position -= rootclusters[index].number;
}
}
position = CFatData.dwClu2Startlba + (position - 2)* (U32)CFatData.bSectorsPerClu;
for(;FileData.wCurFDBNo < (U16)CFatData.bSectorsPerClu * CFatData.wBytesPerSec / DIREntrySize;)
{
//position += FileData.wCurFDBNo / DIREntrySize / CFatData.wBytesPerSec;
if(!flag)
{
DMA_load_sector(position + FileData.wCurFDBNo * DIREntrySize / CFatData.wBytesPerSec, 0x05);
flag = 1;
}
if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute != 0x0F)
&&((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute & ARCHIVE_DIR) != ARCHIVE_DIR))
{
if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[0] == (S8)'M')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[1] == (S8)'P')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[2] == (S8)'3')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Unused)
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Deleted))
{
ENDIAN_ASSIGN_4(&FileData.dwFileDataSize,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
FileData.dwFileStartCluNo = CFatData.dwMask &((U32)LE16(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO));
FileData.dwFileStartCluNo += CFatData.dwMask &(((U32)LE16(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusHI)) << 16);
ReadFileFAT();
return OK;
}
else
{
FileData.wCurFDBNo++;
if(!(FileData.wCurFDBNo & 0x0F))
flag = 0;
}
}
else
{
FileData.wCurFDBNo++;
if(!(FileData.wCurFDBNo & 0x0F))
flag = 0;
}
}
FileData.wCurFDBNo = 0;
FileData.dwCurCluNo++;
}
return KO;
}
else
{
//FAT16
for(;FileData.wCurFDBNo < (U16)FileData.RootDirNum;)
{
if(!flag)
{
DMA_load_sector(CFatData.dwRootStartlba + (FileData.wCurFDBNo / CFatData.bFDBNumInSec),0x05);
flag = 1;
}
if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute != 0x0F)
&&((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Attribute & ARCHIVE_DIR) != ARCHIVE_DIR))
{
if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[0] == (S8)'M')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[1] == (S8)'P')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[2] == (S8)'3')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Unused)
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileName[0] != (S8)DIR_Deleted))
{
ENDIAN_ASSIGN_4(&FileData.dwFileDataSize,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
//FileData.dwFileDataSize = LE32(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
//ENDIAN_ASSIGN_2(&varAl.TmpShort,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO);
//FileData.dwFileStartCluNo = (0x0000FFFF)&((Uint32)varAl.TmpShort);
FileData.dwFileStartCluNo = CFatData.dwMask &((U32)LE16(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO));
//CFatData.fRet = FATERR_NO_ERROR;
//将该文件FAT表读出并放到SRAM中
ReadFileFAT();
//varAl.WAVE_Flg = 0;
return OK;
}
/*else if((((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[0] == 'W')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[1] == 'A')
&&(((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->Extension[2] == 'V'))
{
ENDIAN_ASSIGN_4(&FileData.dwFileDataSize,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FileSize);
ENDIAN_ASSIGN_2(&varAl.TmpShort,&((_DIR *)(sbuf1 + (FileData.wCurFDBNo & 0x0F)* DIREntrySize))->FSClusLO);
FileData.dwFileStartCluNo = (0x0000FFFF)&((Uint32)varAl.TmpShort);
//CFatData.fRet = FATERR_NO_ERROR;
FileData.wCurFDBNo++;
//将该文件FAT表读出并放到SRAM中,起始地址为0xD000
ReadFileFAT();
varAl.WAVE_Flg = 1;
return(1);
}*/
else
{
FileData.wCurFDBNo++;
if(!(FileData.wCurFDBNo & 0x0F))
flag = 0;
}
}
else
{
FileData.wCurFDBNo++;
if(!(FileData.wCurFDBNo & 0x0F))
flag = 0;
}
}
//CFatData.fRet = FATERR_NO_FILE;
#if TX_DEBUG
//SendChar(0xC1);
#endif
return KO;
}
}
/************************************************
函 数 名: Backward()
功 能:
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:
************************************************/
bit Backward(void)
{
bit flag = 0;
U8 index;
U32 position;
if(CFatData.fFAT32)
{
//FAT32
varAl.TmpShort = FileData.wCurFDBNo;
varAl.TmpLong = FileData.dwCurCluNo;
if(FileData.wCurFDBNo)
FileData.wCurFDBNo--;
else
{
FileData.wCurFDBNo = (U16)CFatData.bSectorsPerClu * CFatData.wBytesPerSec / DIREntrySize - 1;
if(FileData.dwCurCluNo)
FileData.dwCurCluNo--;
else
FileData.dwCurCluNo = FileData.RootDirNum - 1;
}
for(;;)
{
position = FileData.dwCurCluNo;
for(index = 0; index < MAX_FILE_FRAGMENT_NUMBER; index++)
{
if(position < rootclusters[index].number)
{
position = rootclusters[index].cluster + position;
break;
}
else
{
position -= rootclusters[index].number;
}
}
position = CFatData.dwClu2Startlba + (position - 2)* (U32)CFatData.bSectorsPerClu;
for(;FileData.wCurFDBNo < (U16)CFatData.bSectorsPerClu * CFatData.wBytesPerSec / DIREntrySize;)
{
if(!flag)
{
DMA_load_sector(position + FileData.wCurFDBNo * DIREntrySize / CFatData.wBytesPerSec, 0x05);
flag = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -