📄 fat.c
字号:
case FS_UNKNOWN:
return false;
case FS_FAT12:
sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
offset = ((cluster * 3) / 2) % BYTE_PER_READ;
// If FAT buffer contains wrong sector
if (sector != fatBufferCurSector)
{
// Load correct sector to buffer
fatBufferCurSector = sector;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
if (cluster & 0x01) {
((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0x0F) | ((value & 0x0F) << 4);
offset++;
if (offset >= BYTE_PER_READ) {
offset = 0;
// write the buffer back to disc
disc_WriteSector(fatBufferCurSector, fatBuffer);
// read the next sector
fatBufferCurSector++;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
((unsigned char*)fatBuffer)[offset] = (value & 0x0FF0) >> 4;
} else {
((unsigned char*)fatBuffer)[offset] = value & 0xFF;
offset++;
if (offset >= BYTE_PER_READ) {
offset = 0;
// write the buffer back to disc
disc_WriteSector(fatBufferCurSector, fatBuffer);
// read the next sector
fatBufferCurSector++;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0xF0) | ((value >> 8) & 0x0F);
}
break;
case FS_FAT16:
sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
offset = cluster % (BYTE_PER_READ >> 1);
// If FAT buffer contains wrong sector
if (sector != fatBufferCurSector)
{
// Load correct sector to buffer
fatBufferCurSector = sector;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
// write the value to the FAT buffer
((unsigned short*)fatBuffer)[offset] = (value & 0xFFFF);
break;
case FS_FAT32:
sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
offset = cluster % (BYTE_PER_READ >> 2);
// If FAT buffer contains wrong sector
if (sector != fatBufferCurSector)
{
// Load correct sector to buffer
fatBufferCurSector = sector;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
// write the value to the FAT buffer
(((unsigned int*)fatBuffer)[offset]) = value;
break;
default:
return false;
}
// write the buffer back to disc
disc_WriteSector(fatBufferCurSector, fatBuffer);
return true;
}
#endif
#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_ReadWriteFatEntryBuffered
Internal function - writes FAT information about a cluster to a
buffer that should then be flushed to disc using
FAT_WriteFatEntryFlushBuffer()
Call FAT_WriteFatEntry first so as not to ruin the disc.
Also returns the entry being replaced
-----------------------------------------------------------------*/
unsigned int FAT_ReadWriteFatEntryBuffered (unsigned int cluster, unsigned int value)
{
unsigned int sector;
int offset;
unsigned int oldValue;
if ((cluster < 0x0002) || (cluster > fatLastCluster))
return CLUSTER_FREE;
switch (filesysType)
{
case FS_UNKNOWN:
oldValue = CLUSTER_FREE;
break;
case FS_FAT12:
sector = filesysFAT + (((cluster * 3) / 2) / BYTE_PER_READ);
offset = ((cluster * 3) / 2) % BYTE_PER_READ;
// If FAT buffer contains wrong sector
if (sector != fatBufferCurSector)
{
// write the old buffer to disc
if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
disc_WriteSector(fatBufferCurSector, fatBuffer);
// Load correct sector to buffer
fatBufferCurSector = sector;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
if (cluster & 0x01) {
oldValue = (((unsigned char*)fatBuffer)[offset] & 0xF0) >> 4;
((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0x0F) | ((value & 0x0F) << 4);
offset++;
if (offset >= BYTE_PER_READ) {
offset = 0;
// write the buffer back to disc
disc_WriteSector(fatBufferCurSector, fatBuffer);
// read the next sector
fatBufferCurSector++;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
oldValue |= ((((unsigned char*)fatBuffer)[offset]) << 4) & 0x0FF0;
((unsigned char*)fatBuffer)[offset] = (value & 0x0FF0) >> 4;
} else {
oldValue = ((unsigned char*)fatBuffer)[offset] & 0xFF;
((unsigned char*)fatBuffer)[offset] = value & 0xFF;
offset++;
if (offset >= BYTE_PER_READ) {
offset = 0;
// write the buffer back to disc
disc_WriteSector(fatBufferCurSector, fatBuffer);
// read the next sector
fatBufferCurSector++;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
oldValue |= (((unsigned char*)fatBuffer)[offset] & 0x0F) << 8;
((unsigned char*)fatBuffer)[offset] = (((unsigned char*)fatBuffer)[offset] & 0xF0) | ((value >> 8) & 0x0F);
}
if (oldValue >= 0x0FF7)
{
oldValue = CLUSTER_EOF;
}
break;
case FS_FAT16:
sector = filesysFAT + ((cluster << 1) / BYTE_PER_READ);
offset = cluster % (BYTE_PER_READ >> 1);
// If FAT buffer contains wrong sector
if (sector != fatBufferCurSector)
{
// write the old buffer to disc
if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
disc_WriteSector(fatBufferCurSector, fatBuffer);
// Load correct sector to buffer
fatBufferCurSector = sector;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
// write the value to the FAT buffer
oldValue = ((unsigned short*)fatBuffer)[offset];
((unsigned short*)fatBuffer)[offset] = value;
if (oldValue >= 0xFFF7)
{
oldValue = CLUSTER_EOF;
}
break;
case FS_FAT32:
sector = filesysFAT + ((cluster << 2) / BYTE_PER_READ);
offset = cluster % (BYTE_PER_READ >> 2);
// If FAT buffer contains wrong sector
if (sector != fatBufferCurSector)
{
// write the old buffer to disc
if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
disc_WriteSector(fatBufferCurSector, fatBuffer);
// Load correct sector to buffer
fatBufferCurSector = sector;
disc_ReadSector(fatBufferCurSector, fatBuffer);
}
// write the value to the FAT buffer
oldValue = ((unsigned int*)fatBuffer)[offset];
((unsigned int*)fatBuffer)[offset] = value;
if (oldValue >= 0x0FFFFFF7)
{
oldValue = CLUSTER_EOF;
}
break;
default:
oldValue = CLUSTER_FREE;
break;
}
return oldValue;
}
#endif
#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_WriteFatEntryFlushBuffer
Flush the FAT buffer back to the disc
-----------------------------------------------------------------*/
char FAT_WriteFatEntryFlushBuffer (void)
{
// write the buffer disc
if ((fatBufferCurSector >= filesysFAT) && (fatBufferCurSector < (filesysFAT + filesysSecPerFAT)))
{
disc_WriteSector(fatBufferCurSector, fatBuffer);
return true;
} else {
return false;
}
}
#endif
#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_FirstFreeCluster
Internal function - gets the first available free cluster
-----------------------------------------------------------------*/
unsigned int FAT_FirstFreeCluster(void)
{
// Start at first valid cluster
if (fatFirstFree < CLUSTER_FIRST)
fatFirstFree = CLUSTER_FIRST;
while ((FAT_NextCluster(fatFirstFree) != CLUSTER_FREE) && (fatFirstFree <= fatLastCluster))
{
fatFirstFree++;
}
if (fatFirstFree > fatLastCluster)
{
return CLUSTER_EOF;
}
return fatFirstFree;
}
#endif
#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_LinkFreeCluster
Internal function - gets the first available free cluster, sets it
to end of file, links the input cluster to it then returns the
cluster number
-----------------------------------------------------------------*/
unsigned int FAT_LinkFreeCluster(unsigned int cluster)
{
unsigned int firstFree;
unsigned int curLink;
if (cluster > fatLastCluster)
{
return CLUSTER_FREE;
}
// Check if the cluster already has a link, and return it if so
curLink = FAT_NextCluster (cluster);
if ((curLink >= CLUSTER_FIRST) && (curLink < fatLastCluster))
{
return curLink; // Return the current link - don't allocate a new one
}
// Get a free cluster
firstFree = FAT_FirstFreeCluster();
// If couldn't get a free cluster then return
if (firstFree == CLUSTER_EOF)
{
return CLUSTER_FREE;
}
if ((cluster >= CLUSTER_FIRST) && (cluster < fatLastCluster))
{
// Update the linked from FAT entry
FAT_WriteFatEntry (cluster, firstFree);
}
// Create the linked to FAT entry
FAT_WriteFatEntry (firstFree, CLUSTER_EOF);
return firstFree;
}
#endif
#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_ClearLinks
Internal function - frees any cluster used by a file
-----------------------------------------------------------------*/
char FAT_ClearLinks (unsigned int cluster)
{
unsigned int nextCluster;
if ((cluster < 0x0002) || (cluster > fatLastCluster))
return false;
// Store next cluster before erasing the link
nextCluster = FAT_NextCluster (cluster);
// Erase the link
FAT_WriteFatEntry (cluster, CLUSTER_FREE);
// Move onto next cluster
cluster = nextCluster;
while ((cluster != CLUSTER_EOF) && (cluster != CLUSTER_FREE))
{
cluster = FAT_ReadWriteFatEntryBuffered (cluster, CLUSTER_FREE);
}
// Flush fat write buffer
FAT_WriteFatEntryFlushBuffer ();
return true;
}
#endif
/*-----------------------------------------------------------------
FAT_InitFiles
Reads the FAT information from the CF card.
You need to call this before reading any files.
char return OUT: true if successful.
-----------------------------------------------------------------*/
char FAT_InitFiles (void)
{
int i;
int bootSector;
BOOT_SEC* bootSec;
if (!disc_Init())
{ return (false);
}
// Read first sector of CF card
if( !disc_ReadSector(0, globalBuffer)) return false;
// Make sure it is a valid MBR or boot sector
if((globalBuffer[0x1FE] != 0x55) || (globalBuffer[0x1FF] != 0xAA))
{ return false;
}
// Check if there is a FAT string, which indicates this is a boot sector
if((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T'))
{ bootSector = 0;
}
// Check for FAT32
else if ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))
{ bootSector = 0;
}
else // This is an MBR
{
// Find first valid partition from MBR
// First check for an active partition
for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i] != 0x80); i+= 0x10) ;
// If it didn't find an active partition, search for any valid partition
if (i == 0x1FE)
{ for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i+0x04] == 0x00); i+= 0x10); }
// Go to first valid partition
if ( i != 0x1FE) // Make sure it found a partition
{ bootSector = globalBuffer[0x8 + i] + (globalBuffer[0x9 + i] << 8) + (globalBuffer[0xA + i] << 16) + ((globalBuffer[0xB + i] << 24) & 0x0F);
}
else
{ bootSector = 0; // No partition found, assume this is a MBR free disk
}
}
// Read in boot sector
bootSec = (BOOT_SEC*) globalBuffer;
if (!disc_ReadSector (bootSector, bootSec))
{ return false;
}
// Store required information about the file system
if (bootSec->sectorsPerFAT != 0)
{ filesysSecPerFAT = bootSec->sectorsPerFAT;
}
else
{ filesysSecPerFAT = bootSec->extBlock.fat32.sectorsPerFAT32;
}
if(bootSec->numSectorsSmall != 0)
{ filesysNumSec = bootSec->numSectorsSmall;
}
else
{ filesysNumSec = bootSec->numSectors;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -