FAT16 implementation - based on 8 bit RISC AVR processors



Hi! My name is Pawel Dienwebel (PELOS)
You can contact me at pelos@pelos.pl

Here is my yampp source code (oryginal ver. 011122) modyfication for FAT16. I was using a small electronic HDD from Advantech - capacity 32MB. One important thing - harddrive have to be formated like this "format d: /z:8" - 4096 B cluster.

Here is modification in fat.c
u08 init_fat( u08 device)
{
    struct partrecord *pr;

     #ifdef FAT16
	//structure for FAT16 see fat.h
	struct bpb50 *bpb;
     #else
	//structure for FAT32
	struct bpb710 *bpb;
     #endif
	
    u32 first_sec;

	// setup pointers
	long_name_buffer = (u08 *) LONGNAME_BUF;
	dir_name_buffer  = (u08 *) DIRNAME_BUF;

	// clear cache 
	FatInCache = 0;


//+++++++++++++++++++++++++++++++++++++++
//
     	//fix from Uli (Ulrich.Behrenbeck@Informatik-Werkstatt.de)
 	ATA_SW_Reset();
    	ATA_Read_Sectors(DRIVE0, 1, 1, 1, 1, SectorBuffer);  // LBA bit NOT set !!!,a raw erroneous CHS access
//
//++++++++++++++++++++++++++++++++++++++++

	// read partition table
    ATA_Read_Sectors_LBA(DRIVE0, 0, 1, SectorBuffer);
	
	// get the partition record
	pr = (struct partrecord *) ((struct partsector *) SectorBuffer)->psPart;

	// and find the first valid sector
	first_sec = pr->prStartLBA;

	// Read the Partition BootSector
    ATA_Read_Sectors_LBA(DRIVE0, first_sec, 1, SectorBuffer);

	#ifdef FAT16
	 // get BIOS parameter block for FAT16
	 bpb = (struct bpb50 *)  ((struct bootsector50 *) SectorBuffer)->bsBPB;
	#else
	 //// get BIOS parameter block for FAT32
	 bpb = (struct bpb710 *)  ((struct bootsector710 *) SectorBuffer)->bsBPB;
	#endif
	

	// and setup some constants
	#ifdef FAT16
	  //getting first Dir SECTOR
	  FirstDirSector	= bpb->bpbResSectors + (bpb->bpbFATs * bpb->bpbFATsecs) + first_sec;
	  FirstDataSector	= bpb->bpbResSectors + (bpb->bpbFATs*bpb->bpbFATsecs) + ((bpb->bpbRootDirEnts*32)/bpb->bpbBytesPerSec) + first_sec;
	  //recount from sectors to clusters - based on reverse function u32 clust2sect(u32 clust)
	  FirstDirSector	= ((FirstDirSector - FirstDataSector)/8) + 2;
	#else
	  //Yhmmm Jesper - It isn't first Dir sector but cluster !!!
	  FirstDirSector 	= bpb->bpbRootClust; 
	  FirstDataSector 	= bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
	  FirstDataSector      += first_sec;	  
	#endif
		
	
	Sectors_Per_Cluster     = bpb->bpbSecPerClust;
	
	Bytes_Per_Sector 	= bpb->bpbBytesPerSec;
	
	//pierwszy sektor FATu zarezerwowane + offset
	FirstFATSector 		= bpb->bpbResSectors + first_sec;

	return 0;	
}

Next modyfication in u32 next_cluster(u32 cluster)
{
    #ifdef FAT16
    	u16 FatOffset = cluster << 1;
    #else
	u32 FatOffset = cluster << 2;	
    #endif
	
	u32 sector    = FirstFATSector + (FatOffset / Bytes_Per_Sector);
	u16 offset    = FatOffset % Bytes_Per_Sector;

	if (sector != FatInCache)
	{
		// read sector
	    while (ATA_Read_Sectors_LBA(DRIVE0,	sector,	1, (u08*)FATCACHE) != 0)
	    {
	    	ATA_SW_Reset();
	    };

	FatInCache = sector;
    }
           	                
#ifdef FAT16
	FatOffset =  (*((u16*) &((char*)FATCACHE)[offset])) & FAT16_MASK;
	if ( FatOffset >= (CLUST_EOFS_FAT16 & FAT16_MASK) )	FatOffset = 0;
#else
	FatOffset =  (*((u32*) &((char*)FATCACHE)[offset])) & FAT32_MASK;
	if ( FatOffset >= (CLUST_EOFS_FAT32 & FAT32_MASK) )	FatOffset = 0;
#endif
	return FatOffset;
}


In fat.h I added:
#define CLUST_EOFS_FAT32	0xfffffff8      /* start of eof cluster range for FAT32 */
#define CLUST_EOFS_FAT16	0xfff8		/* start of eof cluster range for FAT16 */

Thats all folks. Thanks to Jesper and other people which built this yampp :)
I'm planning to add USB to yampp 3 - Philips PDIUSBD12D. I've got 50% done.
Counter 

Last modyfication 17.05.2004