📄 fato.c
字号:
#define IN_FAT
#include "User.h"
#include "UNICODE.H"
#define MAX_DIR_NU_List 20
#define MAX_CACHE_SIZE 580
DIR_LIST *pF;
DIR_LIST Superior_Dir,Current_Dir;
FDI Valid_FDI;
struct QueueDL
{
DIR_LIST Directory_List[MAX_DIR_NU_List];
INT8U front,rear,len;
}QU_DIR_List;
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)
{
Q->front = 0;
Q->rear = 0;
Q->len = 0;
}
void EnQueueDL(struct QueueDL *Q, DIR_LIST *x)
{//向队列插入元素
if((Q->rear == Q->front) && Q->len != 0)
{//队列满时将产生覆盖
Q->front = (Q->front + 1) % MAX_DIR_NU_List; //使队首元素指向下一个位置
}
Q->Directory_List[Q->rear].FstClu = x->FstClu;
Q->Directory_List[Q->rear].FileSize = x->FileSize;
Q->Directory_List[Q->rear].Attr = x->Attr;
Q->rear = (Q->rear + 1) % MAX_DIR_NU_List;//求出新队尾
if(Q->len < MAX_DIR_NU_List)
Q->len += 1;//队列长度加1
}
DIR_LIST *GetElemQDL(struct QueueDL *Q,INT8U pos)
{//读取POS位置的元素
if(pos < 1 || pos > MAX_DIR_NU_List)
return((void *)0);
return(&Q->Directory_List[(Q->front + pos - 1) % MAX_DIR_NU_List]);
}
void InitQueueDC(struct QueueDC *Q)
{
Q->front = 0;
Q->rear = 0;
Q->len = 0;
Q->MaxSize = 576;
}
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;
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; //如果找不到,则显示??
}
void Print_DIR_List(INT16U SecOfDir,INT32U FistDirSecNum)
{//显示目录项
INT16U i,j,k;
INT8U Sname[18];
INT8U temp8u,List_NU=0;
SDIR sSDIR;
DIR_LIST DIR_LISTx;
SDIR *pSD;
INT8U Data_Buf[512];
Disk_Info *pDI;
Disk_RW_Parameter DP;
pSD = &sSDIR;
pDI = GetDiskInfo('A');
for(i = 0;i < SecOfDir;i++)
{
DP.SectorIndex = FistDirSecNum + i;
DP.Buf = Data_Buf;
(* pDI->DiskDrive)(ReadSec, &DP);
for(j=0;j<512;(j+=32))
{
pSD->SName[0] = Data_Buf[j + OFSDIR_SName];
pSD->SName[1] = Data_Buf[j + OFSDIR_SName + 1];
pSD->Attr = Data_Buf[j + OFSDIR_Attr];
if(((pSD->Attr & ATTR_LONG_NAME_MASK) != ATTR_LONG_NAME) && (pSD->SName[0] != 0xE5) && (pSD->SName[0] != 0))
{//找到一个活动的短目录项
if((pSD->Attr & ATTR_VOLUME) == 0)
{//找到一个文件或子目录
if((pSD->SName[0] != '.') && (pSD->SName[1] != '.'))
{
List_NU++;
for(k=2;k<=10;k++)
{
pSD -> SName[k] = Data_Buf[j + OFSDIR_SName + k];
}
if(List_NU/100 != 0)
Sname[0] = List_NU/100 + 48;
else
Sname[0] = ' ';
temp8u = List_NU%100;
if(List_NU/10 != 0)
Sname[1] = temp8u/10 + 48;
else
Sname[1] = ' ';
Sname[2] = temp8u % 10 + 48;
Sname[3] = '-';
temp8u=4;
for(k=0;k<=10;k++)
{
if(pSD -> SName[k] != 0x20)
{
if(k == 8)
{
Sname[temp8u] = '.';
temp8u++;
}
Sname[temp8u] = pSD->SName[k];
temp8u++;
}
}
Sname[temp8u] = '\n';
Sname[temp8u+1] = '\0';
Sname[16] = '\n';
Sname[17] = '\0';
pSD->FstCluH = Data_Buf[j + OFSDIR_FstCluH + 1]*256 +
Data_Buf[j + OFSDIR_FstCluH];
pSD->FstCluL = Data_Buf[j + OFSDIR_FstCluL +1 ]*256 +
Data_Buf[j + OFSDIR_FstCluL];
pSD->FileSize = ((INT32U)Data_Buf[j + OFSDIR_FileSize + 3] << 24) |
((INT32U)Data_Buf[j + OFSDIR_FileSize + 2] << 16) |
((INT32U)Data_Buf[j + OFSDIR_FileSize + 1] << 8) |
((INT32U)Data_Buf[j + OFSDIR_FileSize]);
DIR_LISTx.FstClu = ((INT32U)pSD->FstCluH << 16) | pSD->FstCluL;
DIR_LISTx.FileSize = pSD->FileSize;
DIR_LISTx.Attr = pSD->Attr;
EnQueueDL(&QU_DIR_List,&DIR_LISTx);
uar_putchar(Sname);
}
else if(pSD->SName[1] == '.')
{//指向上层目录
pSD->FstCluH = Data_Buf[j + OFSDIR_FstCluH + 1]*256 +
Data_Buf[j + OFSDIR_FstCluH];
pSD->FstCluL = Data_Buf[j + OFSDIR_FstCluL +1 ]*256 +
Data_Buf[j + OFSDIR_FstCluL];
pSD->FileSize = ((INT32U)Data_Buf[j + OFSDIR_FileSize + 3] << 24) |
((INT32U)Data_Buf[j + OFSDIR_FileSize + 2] << 16) |
((INT32U)Data_Buf[j + OFSDIR_FileSize + 1] << 8) |
((INT32U)Data_Buf[j + OFSDIR_FileSize]);
Superior_Dir.FstClu = ((INT32U)pSD->FstCluH << 16) | pSD->FstCluL;
Superior_Dir.FileSize = pSD->FileSize;
Superior_Dir.Attr = pSD->Attr;
}
}
}
else if(pSD->SName[0] == 0x00)
{//此目录为空,并且后续的磁盘空间都为空
i = 0xFFF0;
break;
}
}
}
}
INT32U GetNextClu(INT32U Index)
{
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('A');
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 = Data_Buf[ThisFATEntOffset] | (Data_Buf[ThisFATEntOffset + 1] << 8);
break;
}
return(NextClu);
}
void DIR(DIR_LIST *Directory_List)
{
INT32U FirstSectorOfCluster; //给定一个簇号N,该簇的第一个扇区
INT16U NextCluOfFAT16,temp;
Disk_Info *pDI;
pDI = GetDiskInfo('A');
if((Directory_List == NULL) || (Directory_List->FstClu == 0))
{//进入根目录
if(pDI->FilSysType == FAT16)
{
pDI->FistRootDirSecNum = pDI->RsvdSecCnt + (pDI->NumFATs * pDI->FATSz16) + pDI->RelaStaSect;
Print_DIR_List(pDI->RootDirSectors,pDI->FistRootDirSecNum);
}
}
else if(Directory_List != NULL)
{//进入子目录
if(pDI->FilSysType == FAT16)
{
FirstSectorOfCluster = ((Directory_List->FstClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
NextCluOfFAT16 = (INT16U)GetNextClu(Directory_List->FstClu);
do
{
Print_DIR_List(pDI->SecPerClus,FirstSectorOfCluster);
FirstSectorOfCluster = ((NextCluOfFAT16 - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
temp = NextCluOfFAT16;
NextCluOfFAT16 = (INT16U)GetNextClu(temp);
} while((NextCluOfFAT16 >= 0x0002) && (NextCluOfFAT16 <= 0xFFEF));
}
}
}
void ChDir(DIR_LIST *pList)
{//改变当前目录
IintQueueDL(&QU_DIR_List);
DIR(pList);
}
void ReadFile(DIR_LIST *pList)
{//读取文件,一次读取512个数据
INT32U SurplusLen,temp;
INT8U Data_Buf[512];
Disk_Info *pDI;
Disk_RW_Parameter DP;
pDI = GetDiskInfo('A');
if(pDI->FilSysType == FAT16)
{
if(Valid_FDI.Read_Flag == 0)
{
Valid_FDI.FirstSectorOfCluster = ((pList->FstClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
Valid_FDI.NextCluOfFAT16 = (INT16U)GetNextClu(pList->FstClu);
Valid_FDI.FileLen = 0;
Valid_FDI.OffsetCluSce = 0;
Valid_FDI.Read_Flag = 1;
}
if(Valid_FDI.FileLen < pList->FileSize)
{
if(Valid_FDI.OffsetCluSce < pDI->SecPerClus)
{
DP.SectorIndex = Valid_FDI.FirstSectorOfCluster + Valid_FDI.OffsetCluSce;
DP.Buf = Data_Buf;
(* pDI->DiskDrive)(ReadSec, &DP);
Valid_FDI.OffsetCluSce += 1;
SurplusLen = pList->FileSize - Valid_FDI.FileLen;
if(SurplusLen >= 512)
{
UART_print(Data_Buf,512);
Valid_FDI.FileLen += 512;
}
else
{
UART_print(Data_Buf,SurplusLen);
Valid_FDI.FileLen += SurplusLen;
Valid_FDI.Read_Flag = 0;
return;
}
}
else if((Valid_FDI.NextCluOfFAT16 >= 0x0002) && (Valid_FDI.NextCluOfFAT16 <= 0xFFEF))
{
Valid_FDI.OffsetCluSce = 0;
temp = Valid_FDI.NextCluOfFAT16;
Valid_FDI.FirstSectorOfCluster = (temp - 2) * pDI->SecPerClus + pDI->FirstDataSector;
Valid_FDI.NextCluOfFAT16 = (INT16U)GetNextClu(temp);
}
else uar_putchar((void *)("file end "));
}
}
}
DIR_LIST *OpenFile(INT8U File_ID)
{//打开文件
return(GetElemQDL(&QU_DIR_List,File_ID));
}
void FileOperation(INT8U List_NU)
{
if(List_NU == '/')
{//显示根目录
ChDir(NULL);
return;
}
else if(List_NU == '*')
{//返回上层目录
ChDir(&Superior_Dir);
return;
}
else if(List_NU == '.')
{//显示当前目录
ChDir(&Current_Dir);
return;
}
else if(List_NU == 'c')
{//继续读取文件中数据
if(pF != NULL)
ReadFile(pF);
}
else
{
pF = OpenFile(List_NU);
if((pF->Attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == 0x00)
{//读收文件中数据
Valid_FDI.Read_Flag = 0;
InitQueueDC(&Disk_Cache);
if(pF != NULL)
ReadFile(pF);
}
else if((pF->Attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == ATTR_DIRECTORY)
{//改变当前目录
Current_Dir.Attr = pF->Attr;
Current_Dir.FstClu = pF->FstClu;
Current_Dir.FileSize = pF->FileSize;
ChDir(pF);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -