📄 fat16.c
字号:
#include "fat16.h"
#include "string.h"
// After enabling the card, use this to extract the drive
// info and find the FAT and root dir
boolean FAT_Init() {
if (!CF_isValid)
return FALSE;
// Get the MBR
//printf("Fetching MBR.. ");
CF_CurrSector = (int32)0x0;
CF_StartSectorRead();
// go to the first MBR boot record
CF_ReadSkipInt16(0xE3);
// read the boot sector location from MBR
BPB_StartSector = CF_ReadInt16();
//printf("Getting BPB from sector 0x%lx.. ", BPB_StartSector);
CF_CurrSector = (int32)BPB_StartSector;
CF_StartSectorRead();
CF_ReadSkipBytes(11); // skip jmpboot and OEMName
BPB_BytesPerSector = CF_ReadInt16();
printf("# bytes/sectors: %ld\n\r", BPB_BytesPerSector);
BPB_SectorsPerCluster = CF_ReadByte();
printf("# sectors/cluster: %d\n\r", BPB_SectorsPerCluster);
BPB_ReservedSectorCount = CF_ReadInt16();
printf("# reserved sectors: %ld\n\r", BPB_ReservedSectorCount);
BPB_NumFATs = CF_ReadByte();
printf("# FATs: %d\n\r", BPB_NumFATs);
BPB_RootDirEntryCount = CF_ReadInt16();
printf("# / entries: %ld\n\r", BPB_RootDirEntryCount);
CF_ReadSkipBytes(3); // skip total # sectors and media
BPB_FATSize = CF_ReadInt16();
// calculate where the fat and root directory are
FAT_StartSector =
BPB_StartSector + BPB_ReservedSectorCount;
FAT_RootDirNumSectors =
((BPB_RootDirEntryCount * 32) + (BPB_BytesPerSector - 1)) / BPB_BytesPerSector;
FAT_RootDirStartSector =
FAT_StartSector + ((int16) BPB_NumFATs * (int16) BPB_FATSize);
FAT_FirstDataSector =
FAT_RootDirStartSector + FAT_RootDirNumSectors;
// set CWD to be root dir
CWD_NAME[0] = '/'; CWD_NAME[1] = 0;
CWD_StartSector = (int32)FAT_RootDirStartSector;
CWD_CurrSector = CWD_StartSector;
CWD_NumEntries = BPB_RootDirEntryCount;
printf("FAT starts at sector 0x%lx\n\r", FAT_StartSector);
printf("/ starts at sector 0x%8lx\n\r", CWD_StartSector);
return TRUE;
}
// returns # of free clusters (ie those with 0x0 as the value in FAT)
int16 FAT_findFreeClusters(void) {
int16 freeclusters = 0;
int16 i, j;
int16 fatentry;
for (i=0; i< BPB_FATSize; i++) {
CF_CurrSector = FAT_StartSector+i;
CF_StartSectorRead();
for (j=0; j<256; j++) {
fatentry = CF_ReadInt16();
if (fatentry == 0x0) {
freeclusters++;
}
}
}
return freeclusters;
}
/************************ directory stuff */
// prints out the files in the current directory
void FAT_ListDir(void) {
int16 filenum;
byte ret;
int32 totalspace, freespace;
freespace = ((int32)(FAT_findFreeClusters())) * 2;
printf("Free Space: %4ld\n\r", freespace); // in kB
filenum = 0;
while (1) {
ret = FAT_LoadFileInCWD(filenum);
if (ret == FAT_END_OF_DIR) {
puts("<EOD>");
return;
}
if ((ret != FAT_FILE_DELETED) && (ret != FAT_LONG_FILENAME)) {
FAT_PrintCurrFileInfo();
}
filenum++;
}
}
// used by ListDir
void FAT_PrintCurrFileInfo() {
printf("%s %8lx (cluster 0x%lx, sector 0x%lx)\n\r" , File_Name, File_Size,
File_StartCluster, FAT_ConvertClusterToSector(File_StartCluster));
if (File_Attr & FAT_IS_DIR)
puts(" <DIR>");
else
putc('\n');
}
// cd into a directory off the current working directory
// This works, but i dont use it in this version...
boolean FAT_ChangeDir(char *dir) {
byte result;
result = FAT_loadFileWithName(dir);
if (result == false)
return result;
if (! (File_Attr & FAT_IS_DIR))
return false;
// ok change to that dirs
strncpy(CWD_Name, File_Name, 12);
CWD_StartSector = FAT_ConvertClusterToSector(File_StartCluster);
CWD_CurrSector = CWD_StartSector;
}
/************************** Loading files */
//looks in CWD for file with given name
boolean FAT_loadFileWithName(char *filename) {
int16 filenum;
byte ret;
filenum = 0;
while (1) {
ret = FAT_LoadFileInCWD(filenum);
if (ret == FAT_END_OF_DIR) {
//puts("<EOD>");
break;
}
if ((ret != FAT_FILE_DELETED) && (ret != FAT_LONG_FILENAME)) {
if (stricmp(File_Name, filename) == 0) {
printf("Found %s!\n", filename);
return true;
} else {
// printf("%s and %s do not match\n\r", filename, File_Name);
}
}
filenum++;
}
return false;
}
// tries to load the number in directory slot #filenum
byte FAT_LoadFileInCWD(int16 filenumber) {
char c;
CWD_CurrSector = CWD_StartSector;
if (filenumber > 16) {
while (filenumber > 16) {
CWD_CurrSector++;
filenumber -= 16;
}
}
File_DirEntryNum = filenumber;
File_DirSectorNum = CWD_CurrSector;
// start reading the directory sector
CF_CurrSector = (int32)File_DirSectorNum;
CF_StartSectorRead();
filenumber &= 0x000F;
CF_ReadSkipInt16(filenumber<<4);
c = CF_ReadByte();
if (c == 0x0)
return FAT_END_OF_DIR;
if (c == FAT_FILE_DELETED)
return FAT_FILE_DELETED;
// Read file information from directory
File_Name[0] = c;
for (c=1; c<11; c++) {
File_Name[c] = CF_ReadByte();
}
File_Name[11] = 0;
File_Attr = CF_ReadByte();
if (File_Attr == 0xf) { // long filename
return FAT_LONG_FILENAME;
}
CF_ReadSkipBytes(14);
File_StartCluster = CF_ReadInt16();
File_CurrCluster = File_StartCluster;
File_Size = CF_ReadInt32();
File_CurrSectorNumInCluster = 0;
return true;
}
/**************************** Reading files */
boolean FAT_StartReadFileNum(int num) {
byte result;
if (FAT_loadFileInCWD(num) != true)
return 0;
File_CurrByte = 0;
File_CurrSectorNumInCluster = 0;
File_CurrCluster = File_StartCluster;
File_CurrSector = (FAT_ConvertClusterToSector(File_CurrCluster)) + File_CurrSectorNumInCluster;
CF_CurrSector = File_CurrSector;
CF_StartSectorRead();
return true;
}
boolean FAT_StartReadFile(char *name) {
byte result;
if (FAT_loadFileWithName(name) == false)
return 0;
File_CurrByte = 0;
File_CurrSectorNumInCluster = 0;
File_CurrCluster = File_StartCluster;
File_CurrSector = (FAT_ConvertClusterToSector(File_CurrCluster)) + File_CurrSectorNumInCluster;
CF_CurrSector = File_CurrSector;
CF_StartSectorRead();
return 1;
}
// finds the next sector of the current file thru the FAT and
// loads that into the buff, returns 0 if EOF
byte FAT_ReadNextSectorIntoBuff() {
int16 idx;
byte c;
if (File_CurrByte >= File_Size)
return 0;
// get the current sector indicated
if (File_CurrSectorNumInCluster == BPB_SectorsPerCluster) {
// find next cluster
//printf("getting next cluster..");
File_CurrCluster = FAT_GetNextCluster(File_CurrCluster);
if (File_CurrCluster ==0 || File_CurrCluster > 0xfff7) {
return 0;
}
File_CurrSectorNumInCluster = 0;
}
File_CurrSector = (int32)FAT_ConvertClusterToSector(File_CurrCluster);
//printf("%8lx ", File_CurrSector);
File_CurrSector += File_CurrSectorNumInCluster;
//printf("cluster 0x%lx, #%d -> sector 0x%8lx\n\r", File_CurrCluster, File_CurrSectorNumInCluster, File_CurrSector);
CF_CurrSector = File_CurrSector;
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
File_CurrByte += 512;
File_CurrSectorNumInCluster++;
return 1;
}
// returns the next byte in the current file
byte FAT_ReadNextFileByte() {
int16 idx;
byte c;
if (File_CurrByte >= File_Size)
return 0;
c = CF_ReadByte();
idx = File_CurrByte & 0x1ff;
File_CurrByte++;
idx++;
if (idx == BPB_BytesPerSector) {
idx = 0;
// get next sector in cluster!
File_CurrSectorNumInCluster++;
//printf("getting next sector..");
// check if we need next cluster;
if (File_CurrSectorNumInCluster == BPB_SectorsPerCluster) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -