📄 fat.c
字号:
unsigned short fatLastReadEntryNumber(void)
{
return lastReadEntryNumber;
}
unsigned long fatLastReadSectorNumber(void)
{
return lastReadSectorNumber;
}
// return the size of the last directory entry
unsigned long fatGetFilesize(void)
{
return FileSize;
}
// return the long name of the last directory entry
char* fatGetFilename(void)
{
return LongNameBuffer;
}
// return the directory of the last directory entry
char* fatGetDirname(void)
{
return DirNameBuffer;
}
// load a clusterfull of data
void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
{
register unsigned char i;
// read cluster
//while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0);
for(i=0; i<SectorsPerCluster; i++) {
// ataReadSectors( DRIVE0, clust2sect(cluster)+i, 1, buffer+(i<<9) );
// temporary fix for wierd misaligned cluster problem
// (only when using FAT16?)
ataReadSectors( DRIVE0, fatClustToSect(cluster+8)+i, 1, buffer+(i<<9) );
}
}
// find next cluster in the FAT chain
unsigned long fatNextCluster(unsigned long cluster)
{
unsigned long nextCluster;
unsigned long fatMask;
unsigned long fatOffset;
unsigned long sector;
unsigned int offset;
// get fat offset in bytes
if(Fat32Enabled) {
// four FAT bytes (32 bits) for every cluster
fatOffset = cluster << 2;
// set the FAT bit mask
fatMask = FAT32_MASK;
}
else {
// two FAT bytes (16 bits) for every cluster
fatOffset = cluster << 1;
// set the FAT bit mask
fatMask = FAT16_MASK;
}
// calculate the FAT sector that we're interested in
sector = FirstFATSector + (fatOffset / BytesPerSector);
// calculate offset of the our entry within that FAT sector
offset = fatOffset % BytesPerSector;
//rprintfProgStrM("sec: ");
//rprintfu32(sector);
// if we don't already have this FAT chunk loaded, go get it
if (sector != FatInCache) {
// read sector of FAT table
while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
FatInCache = sector;
}
// read the nextCluster value
nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
// check to see if we're at the end of the chain
if (nextCluster == (CLUST_EOFE & fatMask))
nextCluster = 0;
#if EXTRA_DEBUG
#ifdef DEBUG_FAT
rprintfProgStrM(">");
rprintfu32(nextCluster);
rprintfCRLF();
#endif
#endif
return nextCluster;
}
unsigned long fatFirstFATSector( void )
{
return FirstFATSector;
}
unsigned long fatFirstFAT2Sector( void )
{
return FirstFAT2Sector;
}
unsigned short fatFATSectors( void )
{
return FATSectors;
}
int fatFindFirstDeletedEntry( unsigned long * sect, unsigned short * entryNr )
{
ulong startSect = FirstDataSector; // first sect with root dir
for(;;) {
ataReadSectors(DRIVE0, startSect, 1, SectorBuffer);
uchar entry;
for( entry = 0;entry < 16; entry++ ) {
}
}
}
/*
*
*/
//ulong tmp;
int fatFindFreeAllocUnit( unsigned long * clusterNo, ulong * sect )
{
#if 0
unsigned long fatSect;
unsigned long clust = 0;
bool isFreeUnit = false;
ushort i = 0;
ulong clst = (*clusterNo) + 1; // next
fatSect = FirstFATSector;
fatSect += clst / (512 / 2);
for( ; fatSect < FirstFATSector + FATSectors; ++fatSect ) {
if( fatSect != FatInCache ) {
ataReadSectors( DRIVE0, fatSect, 1, FatCacheBuffer /*SectorBuffer*/ );
FatInCache = fatSect;
}
for( i = clst % (512 / 2); i < (512/2); ++i ) {
if( *((unsigned short*) &FatCacheBuffer[i*2]) == 0x0000 ) {
isFreeUnit = true;
break;
}
}
if( isFreeUnit ) break;
clust += 512/2;
}
*clusterNo = clust + i;
if( sect ) *sect = fatSect;
#endif
return 0;
}
/*
*
*/
// call after GetDirEntry
void fatFileUpadate( void )
{
ulong fileSize;
ulong fatSect;
ulong dirSectNo = fatLastReadSectorNumber();
ushort entryNo = fatLastReadEntryNumber();
ataReadSectors( DRIVE0, dirSectNo, 1, SectorBuffer );
struct direntry * de = (struct direntry*) SectorBuffer;
unsigned long clusterNo = 0;
fileSize = de[ entryNo ].deFileSize;
{
#if EXTRA_DEBUG
char str[64];
snprintf_P( str, sizeof( str ) , PSTR("file size: %ld, dirSectNo: [%lx], entryNo: %d\r\n"),
(long) fileSize, (long) dirSectNo, (int) entryNo );
PutTextDBG( str );
#endif
}
fileSize = 0;
if( fileSize == 0 ) {
fileSize = 10000;
fatFindFreeAllocUnit( & clusterNo, & fatSect );
ataReadSectors( DRIVE0, dirSectNo, 1, SectorBuffer );
de[ entryNo ].deFileSize = fileSize;
de[ entryNo ].deHighClust = clusterNo >> 16;
de[ entryNo ].deStartCluster = clusterNo & 0xFFFF;
ataWriteSectors( DRIVE0, dirSectNo, 1, SectorBuffer );
#if EXTRA_DEBUG
PutTextDBG("Update dir entry\r\n");
#endif
}
else {
clusterNo = ((ulong) de[ entryNo ].deHighClust << 16) + de[ entryNo ].deStartCluster;
fatSect = FirstFATSector;
fatSect += clusterNo / (512 / 2);
fileSize = de[ entryNo ].deFileSize;
}
if( fileSize == 0 ) return;
// update FAT
unsigned short cl;
unsigned long prevFatSect;
#if EXTRA_DEBUG
char str[64];
snprintf_P( str, sizeof( str ) , PSTR("File Size: %ld\r\n"), (long) fileSize );
PutTextDBG( str );
#endif
for( cl = 0; cl <= ( fileSize / 512 ); ++cl ) {
unsigned long prevClust = clusterNo;
prevFatSect = fatSect;
fatFindFreeAllocUnit( & clusterNo, & fatSect );
#if EXTRA_DEBUG
char str[64];
snprintf_P( str, sizeof( str ) , PSTR("clusterNo: %ld, cl: %d, fatSect: %lx\r\n"),
(long) clusterNo, (int) cl, (long) fatSect );
PutTextDBG( str );
#endif
if( prevFatSect != fatSect ) {
ataReadSectors( DRIVE0, prevFatSect, 1, SectorBuffer );
#if EXTRA_DEBUG
PutTextDBG("read sect\r\n");
#endif
}
if( cl < ( fileSize / 512 ) ) {
#if EXTRA_DEBUG
snprintf_P( str, sizeof( str ) , PSTR("prevClust: %ld, clusterNo: %ld \r\n"),
(long) prevClust, (long) clusterNo );
PutTextDBG( str );
#endif
* ((ushort*) (&SectorBuffer[ prevClust * 2 ])) = 0x1234 ; //clusterNo & 0x0000FFFFL;
{
#if EXTRA_DEBUG
ushort idx = 0;
uchar i;
idx += sprintf( &str[ idx ], "%04x: ", (ushort) ((prevClust * 2) / 16) * 16 );
for( i=0; i<16; i++ ) {
idx += sprintf( &str[ idx ], "%02x ", (ushort) SectorBuffer[ ((prevClust * 2) / 16) * 16 + i ] );
}
PutTextDBG( str );
PutTextDBG( "\r\n" );
#endif
}
//snprintf_P( str, sizeof( str ) , PSTR("clusterNo: %ld, cl: %d\r\n"), (long) clusterNo, (int) cl );
//PutTextDBG( str );
}
else {
* (ushort*) &SectorBuffer[ prevClust * 2 ] = 0xFFFF;
ataWriteSectors( DRIVE0, prevFatSect, 1, SectorBuffer );
#if EXTRA_DEBUG
unsigned short idx, i, j;
for( j=0; j<512/16; j++ ) {
idx = 0;
for( i=0; i<16; i++ ) {
idx += sprintf( &str[ idx ], "%02x ", (ushort) SectorBuffer[ j*16 + i ] );
}
PutTextDBG( str );
PutTextDBG( "\r\n" );
}
#endif
#if EXTRA_DEBUG
snprintf_P( str, sizeof( str ) , PSTR("prevFatSect: %lx\r\n"), (long) prevFatSect );
PutTextDBG( str );
PutTextDBG("[WR last]");
#endif
}
if( prevFatSect != fatSect ) {
ataWriteSectors( DRIVE0, prevFatSect, 1, SectorBuffer );
#if EXTRA_DEBUG
PutTextDBG("[WR]");
#endif
}
}
#if EXTRA_DEBUG
PutTextDBG("Update FAT\r\n");
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -