📄 fat.c
字号:
#define IN_FAT
#include "User.h"
#include "UNICODE.H"
#define MAX_DIR_NU_List 32
#define MAX_CACHE_SIZE 544
ShortFileDirTab *pF;
extern INT8U MP3Handle;
struct QueueDL
{
ShortFileDirTab SFDT[MAX_DIR_NU_List];
INT8U front,frontE,rear,len,lenE,MaxSize;
INT8U ListNu;
}QuDirList;
struct QueueDC
{
INT8U Buf[MAX_CACHE_SIZE];
INT16U front,rear,len;
INT16U MaxSize;
}Disk_Cache;
extern Disk_Info * GetDiskInfo(INT8U DriveID);
void IintQueueDL(struct QueueDL *Q)
{
INT8U i;
Q->front = 0;
Q->frontE = 0;
Q->rear = 0;
Q->len = 0;
Q->lenE = 0;
Q->ListNu = 0;
Q->MaxSize = MAX_DIR_NU_List - 2;
for(i=0; i<MAX_DIR_NU_List; i++)
{
Q->SFDT[i].FDP.Len = 0;
Q->SFDT[i].FDP.OfClu = 0;
Q->SFDT[i].FDP.OfSec = 0;
Q->SFDT[i].FDP.OfByte = 0;
}
}
void EnQueueDL(struct QueueDL *Q, ShortFileDirTab *x)
{//向队列插入元素
INT8U i;
if((Q->rear == Q->frontE) && Q->lenE != 0)
{//队列满时将产生覆盖
Q->frontE = (Q->frontE + 1) % Q->MaxSize; //使队首元素指向下一个位置
}
for(i=0; i<11; i++)
{
Q->SFDT[Q->rear].SName[i] = x->SName[i];
}
Q->SFDT[Q->rear].Attr = x->Attr;
Q->SFDT[Q->rear].FstClu = x->FstClu;
Q->SFDT[Q->rear].FileSize = x->FileSize;
Q->SFDT[Q->rear].FDP.OfClu = x->FstClu;
Q->rear = (Q->rear + 1) % Q->MaxSize;//求出新队尾
if(Q->len < Q->MaxSize)
Q->len += 1;//队列长度加1
if(Q->lenE < Q->MaxSize)
Q->lenE += 1;
}
ShortFileDirTab * PeekQueueDL(struct QueueDL *Q)
{//取出队首元素
ShortFileDirTab *pSFDT;
pSFDT = &Q->SFDT[Q->front];
Q->front = (Q->front + 1) % Q->MaxSize;//求出新队首位置
if(Q->len >0)
Q->len -= 1;//队列长度-1
return(pSFDT);
}
ShortFileDirTab * GetElemQDL(struct QueueDL *Q,INT8U pos)
{//读取POS位置的元素
if((pos < 1) || (pos > Q->lenE))
{
return(NULL);
}
return(&Q->SFDT[(Q->frontE + pos - 1) % Q->MaxSize]);
}
INT8U GetSizeQDL(struct QueueDL *Q)
{
if(Q != NULL)
return(Q->len);
else
return 0;
}
void InitQueueDC(struct QueueDC *Q)
{
Q->front = 0;
Q->rear = 0;
Q->len = 0;
Q->MaxSize = 544;
}
INT16U GetSizeDC(struct QueueDC *Q)
{
if(Q != NULL)
return(Q->len);
else
return 0;
}
void EnQueueDC(struct QueueDC *Q,INT8U x)
{//不考虑队列满的情况,实际使用中不出现这种情况
Q->Buf[Q->rear] = x;//新值赋给队尾
Q->rear = (Q->rear + 1) % Q->MaxSize;//求出队尾的下一个位置
if(Q->len < Q->MaxSize)
Q->len += 1;//队列长度+1
}
INT8U PeekQueueDC(struct QueueDC *Q)
{//取出队首元素
INT8U temp;
if(Q->len == 0)
{
return 0;
}
temp = Q->Buf[Q->front];
Q->front = (Q->front + 1) % Q->MaxSize;//求出新队首位置
if(Q->len >0)
Q->len -= 1;//队列长度-1
return(temp);
}
void Uincode_to_GB(INT16U * x)
{//UNICODE码转换为GB2313汉字编码
INT16U a,b,c;
if(((*x) >= 0x0020) && ((*x) <= 0x007E))
{
if((*x) >= 'a' && (*x) <= 'z')
(*x)-='a'-'A';
*x+=0xA380;
return;
}
if((*x)<Unicode[0][0])
{
*x=0x3F3F;
return;
}
if((*x)>Unicode[UNICODE_MAX-1][0])
{
*x=0x3F3F;
return;
}
a=0;
b=UNICODE_MAX-1;
do //采用二分查表法,因为该表为顺序表
{
c=(a+b)/2;
if((*x)==Unicode[c][0])
{
*x=Unicode[c][1];
return;
}
if((*x)<Unicode[c][0])
{
b=(a+b)/2;
}
else
{
a=(a+b+1)/2;
}
} while(a!=b);
if((*x)==Unicode[a][0])
{
*x=Unicode[a][1];
return;
}
*x=0x3F3F; //如果找不到,则显示??
}
ShortFileDirTab * OpenFile(INT8U DirListIndex)
{
ShortFileDirTab *pSFDT;
pSFDT = GetElemQDL(&QuDirList, DirListIndex);
return pSFDT;
}
INT8U CloseFile(ShortFileDirTab **ppSFDT)
{
if(*ppSFDT == NULL)
return 1;
(*ppSFDT)->FDP.Len = 0;
(*ppSFDT)->FDP.OfClu = (*ppSFDT)->FstClu;
(*ppSFDT)->FDP.OfSec = 0;
(*ppSFDT)->FDP.OfByte = 0;
*ppSFDT = NULL;
return 0;
}
void PrintDir(void)
{
INT8U i,j,tempa,tempb,tempc,len;
ShortFileDirTab *pSFDT;
len = GetSizeQDL(& QuDirList);
for(i=0; i<len; i++)
{
QuDirList.ListNu += 1;
tempa = QuDirList.ListNu / 100 + 48;
if(tempa > 48)
UartPutchar(tempa);
else
UartPutchar(' ');
tempb = QuDirList.ListNu % 100;
tempc = tempb % 10 + 48;
tempb = tempb / 10 + 48;
if(tempa > 48 || tempb > 48)
UartPutchar(tempb);
else
UartPutchar(' ');
UartPutchar(tempc);
UartPutchar('-');
pSFDT = PeekQueueDL(&QuDirList);
for(j=0; j<11; j++)
{
if(j == 8)
{
if(pSFDT->SName[j] != ' ')
UartPutchar('.');
}
if(pSFDT->SName[j] != ' ')
UartPutchar(pSFDT->SName[j]);
}
UartPutchar('\n');
}
}
INT32U GetNextClu(INT32U Index, INT8U DiskID)
{
INT32U FATOffset;
INT32U NextClu; //下一个簇号
INT32U ThisFATSceNum; //FAT表中包含该簇号N的扇区号
INT16U ThisFATEntOffset; //该簇号N位于FAT表中FAT项的偏移量
INT8U Data_Buf[512];
Disk_Info *pDI;
Disk_RW_Parameter DP;
pDI = GetDiskInfo(DiskID);
switch(pDI->FilSysType)
{
case FAT16:
FATOffset = Index * 2;
ThisFATSceNum = FATOffset / pDI->BytsPerSec + pDI->RsvdSecCnt + pDI->RelaStaSect;
DP.SectorIndex = ThisFATSceNum;
DP.Buf = Data_Buf;
(* pDI->DiskDrive)(ReadSec, &DP);
ThisFATEntOffset = FATOffset % pDI->BytsPerSec;
NextClu = (INT32U)Data_Buf[ThisFATEntOffset] | (INT32U)(Data_Buf[ThisFATEntOffset + 1] << 8);
break;
case FAT32:
FATOffset = Index * 4;
ThisFATSceNum = FATOffset / pDI->BytsPerSec + pDI->RsvdSecCnt + pDI->RelaStaSect;
DP.SectorIndex = ThisFATSceNum;
DP.Buf = Data_Buf;
(* pDI->DiskDrive)(ReadSec, &DP);
ThisFATEntOffset = FATOffset % pDI->BytsPerSec;
NextClu = (INT32U)Data_Buf[ThisFATEntOffset] |
(INT32U)(Data_Buf[ThisFATEntOffset + 1] << 8) |
(INT32U)(Data_Buf[ThisFATEntOffset + 2] << 16) |
(INT32U)(Data_Buf[ThisFATEntOffset + 3] << 24);
break;
}
return(NextClu);
}
INT8U GetFDI(ShortFileDirTab *pSFDT, INT8U DiskID)
{
INT8U i,k,temp,flag;
INT8U Data_Buf[512];
INT16U j;
INT32U NextCluOfFAT; //文件簇链中下一个簇号
INT32U FirstSectorOfCluster; //该簇号第一个扇区号
INT32U FistRootDirSecNum; //根目录第一个扇区号
Disk_Info *pDI;
Disk_RW_Parameter DP;
ShortFileDirTab SFDT;
pDI = GetDiskInfo(DiskID);
IintQueueDL(&QuDirList);
if((pSFDT->Attr == 0xF0) && (pSFDT->FstClu == 0))
{//该卷为FAT16且读的是根目录
FistRootDirSecNum = pDI->RsvdSecCnt + (pDI->NumFATs * pDI->FATSz16) + pDI->RelaStaSect;
FirstSectorOfCluster = FistRootDirSecNum;
flag = 1;
}
else
{
FirstSectorOfCluster = ((pSFDT->FstClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
flag = 0;
}
DP.Buf = Data_Buf;
DP.SectorIndex = FirstSectorOfCluster + pSFDT->FDP.OfSec;
(* pDI->DiskDrive)(ReadSec, &DP);
for(i=0; ; )
{
j = pSFDT->FDP.OfByte;
SFDT.SName[0] = Data_Buf[j + OFSDIR_SName];
SFDT.SName[1] = Data_Buf[j + OFSDIR_SName + 1];
SFDT.Attr = Data_Buf[j + OFSDIR_Attr];
if(((SFDT.Attr & ATTR_LONG_NAME_MASK) != ATTR_LONG_NAME) && (SFDT.SName[0] != 0xE5) && (SFDT.SName[0] != 0))
{//找到一个活动的短目录项
if((SFDT.Attr & ATTR_VOLUME) == 0)
{//找到一个文件或子目录
for(k=2; k<11; k++)
{
SFDT.SName[k] = Data_Buf[j + OFSDIR_SName + k];
}
SFDT.FstClu = ((INT32U)Data_Buf[j + OFSDIR_FstCluH + 1] << 24) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -