⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat16.c

📁 Build ourself a MP3 Player
💻 C
📖 第 1 页 / 共 2 页
字号:
			// 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 + -