* fatio.c
* - FAT Manipulation and Cluster IO
*/
-#define DEBUG 1
+#define DEBUG 0
#include <acess.h>
#include <vfs.h>
#include "common.h"
Uint32 val = 0;
Uint32 ofs;
ENTER("pDisk xCluster", Disk, cluster);
+
Mutex_Acquire( &Disk->lFAT );
#if CACHE_FAT
if( Disk->ClusterCount <= giFAT_MaxCachedClusters )
{
val = Disk->FATCache[cluster];
- if(Disk->type == FAT12 && val == EOC_FAT12) val = -1;
- if(Disk->type == FAT16 && val == EOC_FAT16) val = -1;
- if(Disk->type == FAT32 && val == EOC_FAT32) val = -1;
+ if(Disk->type == FAT12 && val == EOC_FAT12) val = GETFATVALUE_EOC;
+ if(Disk->type == FAT16 && val == EOC_FAT16) val = GETFATVALUE_EOC;
+ if(Disk->type == FAT32 && val == EOC_FAT32) val = GETFATVALUE_EOC;
}
else
{
ofs = Disk->bootsect.resvSectCount*512;
if(Disk->type == FAT12) {
VFS_ReadAt(Disk->fileHandle, ofs+(cluster/2)*3, 3, &val);
- val = (cluster & 1 ? val>>12 : val & 0xFFF);
- if(val == EOC_FAT12) val = -1;
+ LOG("3 bytes at 0x%x are (Uint32)0x%x", ofs+(cluster/2)*3, val);
+ val = (cluster & 1) ? (val>>12) : (val & 0xFFF);
+ if(val == EOC_FAT12) val = GETFATVALUE_EOC;
} else if(Disk->type == FAT16) {
VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val);
- if(val == EOC_FAT16) val = -1;
+ if(val == EOC_FAT16) val = GETFATVALUE_EOC;
} else {
VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val);
- if(val == EOC_FAT32) val = -1;
+ if(val == EOC_FAT32) val = GETFATVALUE_EOC;
}
#if CACHE_FAT
}
*/
Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous)
{
- Uint32 ret = -1, eoc;
-
- switch(Disk->type)
- {
- case FAT12: eoc = EOC_FAT12; break;
- case FAT16: eoc = EOC_FAT16; break;
- case FAT32: eoc = EOC_FAT32; break;
- default: return 0;
- }
+ Uint32 ret = -1;
#if CACHE_FAT
if( Disk->ClusterCount <= giFAT_MaxCachedClusters )
{
int bFoundCluster = 0;
+ Uint32 eoc;
+
+ switch(Disk->type)
+ {
+ case FAT12: eoc = EOC_FAT12; break;
+ case FAT16: eoc = EOC_FAT16; break;
+ case FAT32: eoc = EOC_FAT32; break;
+ default: return 0;
+ }
+
Mutex_Acquire(&Disk->lFAT);
if( Previous != -1 )
{
}
Mutex_Release(&Disk->lFAT);
+ LOG("Allocated cluster %x", ret);
return ret;
}
else
// Search within the same block as the previous cluster first
do {
- VFS_ReadAt(Disk->fileHandle, base + block, block_size, sector_data);
+ VFS_ReadAt(Disk->fileHandle, base + block*block_size, block_size, sector_data);
for( block_ofs = 0; block_ofs < ents_per_block_12; block_ofs ++ )
{
Uint32 *valptr = (void*)( sector_data + block_ofs / 2 * 3 );
VFS_WriteAt(Disk->fileHandle, base + block, block_size, sector_data);
// Note the new cluster in the chain
- VFS_ReadAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val);
- if( ret & 1 ) {
- val &= 0x000FFF;
- val |= ret << 12;
- }
- else {
- val &= 0xFFF000;
- val |= ret << 0;
+ if( Previous != -1 )
+ {
+ LOG("Updating cluster %x to point to %x (offset %x)", Previous, ret,
+ base + (Previous>>1)*3);
+ VFS_ReadAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val);
+ if( Previous & 1 ) {
+ val &= 0x000FFF;
+ val |= ret << 12;
+ }
+ else {
+ val &= 0xFFF000;
+ val |= ret << 0;
+ }
+ VFS_WriteAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val);
}
- VFS_WriteAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val);
}
break;
case FAT16:
break;
}
Mutex_Release(&Disk->lFAT);
+ LOG("Allocated cluster %x", ret);
return ret;
#if CACHE_FAT
}
Uint32 FAT_int_FreeCluster(tFAT_VolInfo *Disk, Uint32 Cluster)
{
Uint32 ret;
+
+ if( Cluster < 2 || Cluster > Disk->ClusterCount ) // oops?
+ {
+ Log_Notice("FAT", "Cluster 0x%x is out of range (2 ... 0x%x)",
+ Cluster, Disk->ClusterCount-1);
+ return -1;
+ }
Mutex_Acquire(&Disk->lFAT);
#if CACHE_FAT
else
{
#endif
- Uint32 val;
+ Uint32 val = 0;
Uint32 ofs = Disk->bootsect.resvSectCount*512;
switch(Disk->type)
{
case FAT12:
VFS_ReadAt(Disk->fileHandle, ofs+(Cluster>>1)*3, 3, &val);
+ val = LittleEndian32(val);
if( Cluster & 1 ) {
- ret = val & 0xFFF0000;
+ ret = (val >> 12) & 0xFFF;
val &= 0xFFF;
}
else {
ret = val & 0xFFF;
val &= 0xFFF000;
}
+ val = LittleEndian32(val);
VFS_WriteAt(Disk->fileHandle, ofs+(Cluster>>1)*3, 3, &val);
break;
case FAT16:
VFS_ReadAt(Disk->fileHandle, ofs+Cluster*2, 2, &ret);
+ ret = LittleEndian16(ret);
val = 0;
VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val);
break;
case FAT32:
VFS_ReadAt(Disk->fileHandle, ofs+Cluster*4, 4, &ret);
+ ret = LittleEndian32(ret);
val = 0;
- VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val);
+ VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 4, &val);
break;
}
#if CACHE_FAT
}
#endif
Mutex_Release(&Disk->lFAT);
+ LOG("ret = %07x, eoc = %07x", ret, EOC_FAT12);
+ if(ret == 0) {
+ Log_Notice("FAT", "Cluster 0x%x was already free", Cluster);
+ return -1;
+ }
if(Disk->type == FAT12 && ret == EOC_FAT12) ret = -1;
if(Disk->type == FAT16 && ret == EOC_FAT16) ret = -1;
if(Disk->type == FAT32 && ret == EOC_FAT32) ret = -1;
+ LOG("ret = %07x", ret);
return ret;
}
#endif