📄 fat16.c
字号:
// find next cluster
//printf("getting next cluster..");
File_CurrCluster = FAT_GetNextCluster(File_CurrCluster);
File_CurrSectorNumInCluster = 0;
}
File_CurrSector = (FAT_ConvertClusterToSector(File_CurrCluster)) + File_CurrSectorNumInCluster;
//printf("cluster 0x%lx, #%d -> sector 0x%8lx", File_CurrCluster, File_CurrSectorNumInCluster, File_CurrSector);
CF_CurrSector = File_CurrSector;
CF_StartSectorRead();
}
return c;
}
// dumps the named file to stdout
void FAT_ReadFile(char *name) {
byte result;
int16 idx;
if (FAT_loadFileWithName(name) == false)
return;
File_CurrByte = 0;
idx = 0;
File_CurrSectorNumInCluster = 0;
File_CurrCluster = File_StartCluster;
File_CurrSector = (FAT_ConvertClusterToSector(File_CurrCluster)) + File_CurrSectorNumInCluster;
CF_CurrSector = File_CurrSector;
CF_StartSectorRead();
while (File_CurrByte < File_Size) {
putc(CF_ReadByte());
File_CurrByte++; idx++;
if (idx == BPB_BytesPerSector) {
idx = 0;
// get next sector in cluster!
File_CurrSectorNumInCluster++;
// check if we need next cluster;
if (File_CurrSectorNumInCluster == BPB_SectorsPerCluster) {
// find next cluster
File_CurrCluster = FAT_GetNextCluster(File_CurrCluster);
if (File_CurrCluster >= 0xfff7 || File_CurrCluster == 0)
return;
File_CurrSectorNumInCluster = 0;
}
File_CurrSector = (FAT_ConvertClusterToSector(File_CurrCluster)) + File_CurrSectorNumInCluster;
CF_CurrSector = File_CurrSector;
CF_StartSectorRead();
}
}
}
/*********************** writing files */
// creates a file by reading from stdin
// need to add timeout, also, proper file length in case the transfer doesn't complete
boolean FAT_CreateFile(char *name, int16 startcluster, int32 len) {
// first get a root dir entry
char c;
int16 i, idx;
int16 currcluster, oldcluster, bytestoread;
if (startcluster == 0) {
startcluster = 2;
//printf("no space?\n\r"); return false;
} else {
printf("startcluster = %lx\t", startcluster);
}
for (i=0; i< BPB_RootDirEntryCount; i++) {
CF_CurrSector = (int32)FAT_RootDirStartSector + i/16;
File_DirEntryNum = i % 16;
File_DirSectorNum = CF_CurrSector; // start reading the directory sector
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
//printf("checking file #%ld...\n\r", i);
idx = (File_DirEntryNum<<4)*2;
c = sectorbuff[idx];
if (c == 0x0 || c == FAT_FILE_DELETED) {
if (c == 0x0) {
//printf("appending to EOD\n\r");
if (File_DirEntryNum != 15) {
// make the next entry the EOD
sectorbuff[idx+32] = 0x0;
} else if (i+1 != BPB_RootDirEntryCount) {
CF_CurrSector++;
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
sectorbuff[0] = 0x0;
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
CF_CurrSector--;
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
} else {
// the very last entry? oh well...
printf("the last entry!\n\r");
return false;
}
} else {
//printf("reusing deleted entry\n\r");
}
//printf("writing to / sector %4lx\n\r", CF_CurrSector);
for (c = 0; c<11; c++) { sectorbuff[idx++] = name[c]; }
sectorbuff[idx++] = 0; //Attr
idx += 14;
// the start cluster
sectorbuff[idx++] = startcluster;
sectorbuff[idx++] = startcluster >> 8;
sectorbuff[idx++] = len;
sectorbuff[idx++] = len >> 8;
sectorbuff[idx++] = len >> 16;
sectorbuff[idx++] = len >> 24;
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
puts("read in file");
// start reading in the file
currcluster = startcluster;
File_Size = len;
File_CurrSectorNumInCluster = 0;
File_CurrByte = 0;
while (1) {
// for each cluster, first set it to be the EOF cluster (to be safe)
CF_CurrSector = FAT_StartSector + (currcluster/256); // find the FAT sector to look in! (clust * 2) /512)
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
sectorbuff[(currcluster&0xff) * 2] = 0xff;
sectorbuff[(currcluster&0xff) * 2 + 1] = 0xff;
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
//printf("EOF Cluster: %lx written to FAT %4lx\n\r", currcluster, CF_CurrSector);
for (File_CurrSectorNumInCluster = 0; File_CurrSectorNumInCluster < BPB_SectorsPerCluster; File_CurrSectorNumInCluster++) {
// then read data into the buffer
if ((File_Size - File_CurrByte) > 512) {
bytestoread = 512;
} else {
bytestoread = File_Size - File_CurrByte;
//printf("only %lx left", bytestoread);
}
//printf("reading in %ld bytes\n\r", bytestoread);
putc('-');
for (i = 0; i< bytestoread; i++) {
sectorbuff[i] = getc();
//if ((i % 128) == 0) { putc('.'); }
}
File_CurrByte += bytestoread;
File_CurrSector = FAT_ConvertClusterToSector(currcluster) + File_CurrSectorNumInCluster;
CF_CurrSector = File_CurrSector;
//printf("dumping to sector %4lx\n\r", CF_CurrSector);
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
if (File_Size <= File_CurrByte) {
return true;
}
}
//printf("%4ld bytes left\n\r", File_Size - File_CurrByte);
//printf("finding next cluster");
oldcluster = currcluster;
currcluster = FAT_findNextUnusedCluster(currcluster);
//printf("fetching next free cluster: %lx\n\r", currcluster);
if (currcluster == 0) {
printf("eek! ran out of room?\n\r");
return false;
}
CF_CurrSector = FAT_StartSector + (oldcluster/256); // find the FAT sector to look in! (clust * 2) /512)
//printf("writing to %4lx\t", CF_CurrSector);
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
sectorbuff[(oldcluster&0xff) * 2] = currcluster;
sectorbuff[((oldcluster&0xff)* 2) + 1] = currcluster >> 8;
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
//printf("next %lx\n\r" , FAT_GetNextCluster(oldcluster));
//printf("OK\n\r");
}
return true;
}
}
return false;
}
int16 FAT_findNextUnusedCluster(int16 oldcluster) {
uint16 i, j;
i = (oldcluster+1)/256;
for (; i<BPB_FATSize; i++) {
CF_CurrSector = FAT_StartSector+i;
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
j = ((oldcluster+1) % 256) *2;
for (; j<512; j+=2) {
if ((sectorbuff[j + 1] == 0) && (sectorbuff[j] == 0)) {
return (i*256 + j/2);
}
}
}
return 0;
}
/************************** FAT utils */
// this is so sketchy. dont use it unless its an emergency
void FAT_QuickFormat() {
int32 last;
int16 j;
last = FAT_RootDirStartSector + FAT_RootDirNumSectors;
for (j=0; j< 512; j++) {
sectorbuff[j]=0;
}
for (CF_CurrSector=FAT_StartSector; CF_CurrSector < last; CF_CurrSector++) {
printf("clearing %4lx...", CF_CurrSector);
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
}
}
void FAT_DeleteFile(char *name) {
uint16 cluster, newcluster;
byte lo, ret;
uint16 filenum;
int16 i;
if (FAT_loadFileWithName(name) == false)
return;
newcluster = File_StartCluster;
//printf("starting with cluster %lx\n", newcluster);
cluster = newcluster;
CF_CurrSector = FAT_StartSector + (cluster/256); // find the FAT sector to look in! (clust * 2) /512)
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
while ((newcluster <= 0xFFF8) && (newcluster != 0x0000)) {
cluster = newcluster;
newcluster = sectorbuff[(cluster&0xff) * 2 + 1];
newcluster <<= 8;
newcluster |= sectorbuff[(cluster&0xff)* 2];
//printf("new cluster: %lx\n\r", newcluster);// getch();
sectorbuff[(cluster&0xff) * 2] = 0x0;
sectorbuff[(cluster&0xff) * 2 + 1] = 0x0;
if ((newcluster >= 0xFFF8) || (newcluster == 0x0000)) {break; }
if ((cluster/256) != (newcluster/256)) {
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
CF_CurrSector = FAT_StartSector + (newcluster/256); // find the FAT sector to look in! (clust * 2) /512)
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
}
}
//printf("writing");
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
// now remove it from root dir
//printf("remove from rootdir %4lx\n\r", File_DirSectorNum);
CF_CurrSector = File_DirSectorNum;
CF_StartSectorRead();
CF_ReadSectorIntoBuff();
filenum = File_DirEntryNum & 0x000F;
filenum <<= 4;
//printf("sec: %4lx filenum %ld -> %ld\n\r", CF_CurrSector, File_DirEntryNum & 0x000F, filenum);
sectorbuff[filenum * 2] = FAT_FILE_DELETED;
CF_StartSectorWrite();
CF_WriteBuffIntoSector();
return;
}
uint32 FAT_ConvertClusterToSector(uint16 cluster) {
uint32 sector;
sector = cluster - 2; // first two FAT entries are not data!
sector *= (int32)BPB_SectorsPerCluster; // find the sector num realtive to data start
sector += (int32)FAT_FirstDataSector; // find absolute sector num
return sector;
}
uint16 FAT_GetNextCluster(uint16 cluster) {
CF_CurrSector = FAT_StartSector + (cluster/256); // find the FAT sector to look in! (clust * 2) /512)
CF_StartSectorRead();
CF_ReadSkipInt16(cluster & 0xff); // since this is FAT16 we just skip over that many entries (each entry 16bit)
return CF_ReadInt16();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -