fat.c


1
/*! \file fat.c \brief FAT-Functions */
2
//###########################################################
3
///  \ingroup singlefat
4
///  \defgroup FAT FAT-Functions (fat.c)
5
///  \code #include "fat.h" \endcode
6
///  \code #include "dos.h" \endcode
7
///  \par Uebersicht
8
//###########################################################
9
// For FAT12, FAT16 and FAT32
10
// Only for first Partition
11
// Only for drives with 512 bytes per sector (the most)
12
//
13
// Based on a White Paper from MS
14
// FAT: General Overview of On-Disk Format
15
// Version 1.03, December 6, 2000
16
//
17
// MBR MasterBootRecord
18
// PC intern 4
19
// M.Tischer
20
// Data Becker
21
//
22
// 17.09.2007 Removed most #ifdef USE_FATBUFFER. See dos.h.
23
//            Sourcecode looks much better now.
24
//
25
// 11.10.2006 Replaced "% BYTE_PER_SEC" with "& (BYTE_PER_SEC-1)".
26
//            Typecast variables from "unsigned long" to "unsigned int" before:
27
//            secoffset = (unsigned int)fatoffset & (BYTE_PER_SEC-1);
28
//            Use "unsigned int" for indexing arrays. Does not really speed up,
29
//            but reduces code size ;)
30
//
31
// 25.09.2006 Initialize all global variables to zero for better compatibility
32
//            with other compilers.
33
//
34
// Benutzung auf eigene Gefahr !
35
//
36
// Use at your own risk !
37
//
38
//#########################################################################
39
// Last change: 17.09.2007
40
//#########################################################################
41
// hk@holger-klabunde.de
42
// http://www.holger-klabunde.de/index.html
43
//#########################################################################
44
// Compiler: AVR-GCC 4.1.1
45
//#########################################################################
46
//@{
47
#include <stdlib.h>
48
#include <string.h>
49
#include <ctype.h>
50
51
#include "dos.h"
52
53
#if defined (FAT_DEBUG_SHOW_FAT_INFO) || defined (FAT_DEBUG_RW_HITS) || defined (FAT_DEBUG_CLUSTERS)
54
 #include "serial.h" //for testing only
55
 #include "printf.h" //for testing only
56
#endif
57
58
U8 iob[BYTE_PER_SEC];      //file i/o buffer
59
60
U32 FirstDataSector=0; 
61
U32 FirstRootSector=0; 
62
U32 FATFirstSector=0;  
63
U8 FATtype=0;         
64
65
#ifdef USE_FAT32
66
 U32 FAT32RootCluster=0;
67
 U32 endofclusterchain=0; //value for END_OF_CLUSTERCHAIN 
68
 U32 maxcluster=0;   // last usable cluster+1
69
70
 #ifdef FAT_DEBUG_RW_HITS
71
  U32 FATWRHits=0;
72
  U32 FATRDHits=0;
73
 #endif
74
75
#else
76
 U16 endofclusterchain=0; //value for END_OF_CLUSTERCHAIN 
77
 U16 maxcluster=0;   // last usable cluster+1
78
79
 #ifdef FAT_DEBUG_RW_HITS
80
  U16 FATWRHits=0;
81
  U16 FATRDHits=0;
82
 #endif
83
#endif
84
85
U8 iob_status=0;
86
U32 FATCurrentSector=0;
87
88
#ifdef DOS_WRITE
89
  U8 FATStatus=0; // only for FAT write buffering
90
#endif
91
92
#ifdef USE_FATBUFFER
93
 U8 fatbuf[BYTE_PER_SEC];   //buffer for FAT sectors
94
#endif
95
96
U8 secPerCluster=0;
97
98
#ifdef USE_64k_CLUSTERS
99
 U32 BytesPerCluster=0;   //bytes per cluster
100
#else
101
 U16 BytesPerCluster=0;   //bytes per cluster
102
#endif
103
104
//U32 RootDirSectors=0; // to big !
105
//U16 RootDirSectors=0;   // maybe U8 is enough.
106
U8 RootDirSectors=0;   // never saw more then 32 sectors
107
108
109
//############################################################
110
/*!\brief Decide if we have to write a used fat sector or read a new fat sector
111
 * \param    newsector Actual sector number
112
 * \return     Nothing
113
 */
114
void UpdateFATBuffer(U32 newsector)
115
//############################################################
116
{
117
#ifdef USE_FATBUFFER
118
#else
119
 if(iob_status!=IOB_FAT) // We have to read a FAT sector first if this is true
120
 {
121
   ReadFATSector(newsector,iob); //read FAT sector
122
   #ifdef FAT_DEBUG_RW_HITS
123
    FATRDHits++;
124
   #endif
125
   FATCurrentSector=newsector;
126
 }
127
#endif //#ifdef USE_FATBUFFER
128
129
 if(newsector!=FATCurrentSector) // do we need to update the FAT buffer ?
130
  {
131
#ifdef DOS_WRITE
132
   if(FATStatus>0)
133
    {
134
     WriteFATSector(FATCurrentSector,FAT_IO_BUFFER); // write the old FAT buffer
135
     #ifdef FAT_DEBUG_RW_HITS
136
      FATWRHits++;
137
     #endif
138
     FATStatus=0; // flag FAT buffer is save
139
    } 
140
#endif
141
   ReadFATSector(newsector,FAT_IO_BUFFER); //read FAT sector
142
   #ifdef FAT_DEBUG_RW_HITS
143
    FATRDHits++;
144
   #endif
145
146
   FATCurrentSector=newsector;
147
  } 
148
}
149
150
//############################################################
151
/*!\brief Get back next cluster number from fat cluster chain
152
 * \param    cluster  Actual cluster number
153
 * \return     Next cluster number
154
 */
155
#ifdef USE_FAT32
156
 U32 GetNextClusterNumber(U32 cluster)
157
#else
158
 U16 GetNextClusterNumber(U16 cluster)
159
#endif
160
//############################################################
161
{
162
#ifdef USE_FAT12
163
 U16 tmp, secoffset;
164
 U8 fatoffset;
165
#endif
166
167
 union Convert *cv;
168
169
#ifdef FAT_DEBUG_CLUSTERS
170
 #ifdef USE_FAT32
171
  printf("GNCN %lu\n",cluster);
172
 #else
173
  printf("GNCN %u\n",cluster);
174
 #endif
175
#endif
176
177
 if(cluster<maxcluster) //we need to check this ;-)
178
  {
179
180
#ifdef USE_FAT12
181
   if(FATtype==FAT12)
182
    {
183
     // FAT12 has 1.5 Bytes per FAT entry
184
     // FAT12 can only have 4085 clusters. So cluster * 3 is 16 bit 
185
     tmp = ((U16)cluster * 3) >>1 ; //multiply by 1.5 (rounds down)
186
     secoffset = (U16)tmp & (BYTE_PER_SEC-1); //we need this for later
187
188
     // FAT12 4085 Cluster * 1.5Bytes = 6127.5 Bytes => max 12 FAT sectors
189
     // FAT sector offset is 8 Bit 
190
//     fatoffset = (U8)(tmp / BYTE_PER_SEC); //sector offset from FATFirstSector
191
     fatoffset = (U8)(tmp >> 9); //sector offset from FATFirstSector
192
 
193
     UpdateFATBuffer(FATFirstSector + fatoffset); //read FAT sector
194
195
     if(secoffset == (BYTE_PER_SEC-1)) //if this is the case, cluster number is
196
                                   //on a sector boundary. read the next sector too
197
      {
198
       tmp = FAT_IO_BUFFER[BYTE_PER_SEC-1]; //keep first part of cluster number
199
       UpdateFATBuffer(FATFirstSector + fatoffset +1 ); //read next FAT sector
200
       tmp += (U16)FAT_IO_BUFFER[0] << 8; //second part of cluster number
201
      }
202
     else
203
      {
204
       cv=(union Convert *)&FAT_IO_BUFFER[secoffset];
205
       tmp=cv->ui;
206
      } 
207
208
     if((U8)cluster & 0x01) tmp>>=4; //shift to right position
209
     else               tmp&=0xFFF; //delete high nibble
210
211
     return (tmp);
212
    }//if(FATtype==FAT12)
213
#endif //#ifdef USE_FAT12
214
215
#ifdef USE_FAT16
216
   if(FATtype==FAT16)
217
    {
218
     //two bytes per FAT entry
219
//     UpdateFATBuffer(FATFirstSector + ((U32)cluster * 2) / BYTE_PER_SEC);
220
//     UpdateFATBuffer(FATFirstSector + ((unsigned int)cluster) / (BYTE_PER_SEC/2));
221
222
     UpdateFATBuffer(FATFirstSector + (U8)( (U16)cluster >> 8 ));
223
224
     // Buffer index is max 511. So in any case we loose upper bits. typecast cluster to U16
225
//     cv=(union Convert *)&fatbuf[((U32)cluster * 2) % BYTE_PER_SEC];
226
     cv=(union Convert *)&FAT_IO_BUFFER[((U16)cluster << 1) & (BYTE_PER_SEC-1)];
227
     return(cv->ui);
228
    }//if(FATtype==FAT16)
229
#endif //#ifdef USE_FAT16
230
231
#ifdef USE_FAT32
232
   if(FATtype==FAT32)
233
    {
234
     //four bytes per FAT entry
235
//     UpdateFATBuffer(FATFirstSector + (cluster * 4) / BYTE_PER_SEC);
236
//     UpdateFATBuffer(FATFirstSector + cluster / (BYTE_PER_SEC/4));
237
238
     UpdateFATBuffer(FATFirstSector + ( cluster >> 7 ));
239
240
     // Buffer index is max 511. So in any case we loose upper bits. typecast cluster to U16
241
     cv=(union Convert *)&FAT_IO_BUFFER[((U16)cluster << 2) & (BYTE_PER_SEC-1)];
242
     return( cv->ul & 0x0FFFFFFF );
243
    }//if(FATtype==FAT32) 
244
#endif //#ifdef USE_FAT32
245
  }
246
  
247
 return DISK_FULL; //return impossible cluster number
248
}
249
250
//###########################################################
251
/*!\brief Get back number of first sector of cluster
252
 * \param    cluster  Actual cluster number
253
 * \return     Sector number
254
 */
255
#ifdef USE_FAT32
256
 U32 GetFirstSectorOfCluster(U32 cluster)
257
#else
258
 U32 GetFirstSectorOfCluster(U16 cluster)
259
#endif
260
//###########################################################
261
{
262
// Komische Sache: Die Schieberei hier bringt bei ATmega32 ca. 200 Byte weniger Code.
263
// Bei ATmega644 wird der Code dadurch ca. 20 Bytes größer !
264
265
 U8 temp;
266
 U32 templong;
267
 
268
 templong = cluster-2;
269
270
 // secPerCluster is always power of two 
271
 temp = secPerCluster>>1; // don't multiply with 1 ;)
272
 
273
 while(temp)
274
  {
275
   templong <<= 1;
276
   temp >>= 1;
277
  }
278
 
279
 return (templong + FirstDataSector);
280
281
// return (((U32)(cluster - 2) * secPerCluster) + FirstDataSector);
282
}
283
284
#ifdef DOS_WRITE
285
//###########################################################
286
/*!\brief Allocate a new cluster in cluster chain
287
 * \param    currentcluster  Actual cluster number
288
 * \return     New cluster number or DISK_FULL
289
 */
290
#ifdef USE_FAT32
291
 U32 AllocCluster(U32 currentcluster)
292
#else
293
 U16 AllocCluster(U16 currentcluster)
294
#endif
295
//###########################################################
296
{
297
#ifdef USE_FAT32
298
 U32 cluster;
299
#else
300
 U16 cluster;
301
#endif
302
303
// do this if you want to search from beginning of FAT
304
// cluster=FindFreeCluster(0); //get next free cluster number
305
 cluster=FindFreeCluster(currentcluster); // get next free cluster number
306
 if(cluster!=DISK_FULL && cluster<=maxcluster) // disk full ?
307
  {
308
    // insert new cluster number into chain
309
    // currentcluster=0 means: this is a new cluster chain
310
    if(currentcluster>0) WriteClusterNumber(currentcluster,cluster);
311
312
   // mark end of cluster chain
313
#ifdef USE_FAT12
314
   if(FATtype==FAT12) WriteClusterNumber(cluster,0xFFF); 
315
#endif
316
#ifdef USE_FAT16
317
   if(FATtype==FAT16) WriteClusterNumber(cluster,0xFFFF); 
318
#endif
319
#ifdef USE_FAT32
320
   if(FATtype==FAT32) WriteClusterNumber(cluster,0x0FFFFFFF); 
321
#endif
322
  }
323
324
#ifdef USE_FATBUFFER
325
#else
326
   // We should flush the temporary fatbuffer now because next action is
327
   // filling iob[] with new data !
328
   if(FATStatus>0)
329
    {
330
     WriteFATSector(FATCurrentSector,iob); // write the FAT buffer
331
     #ifdef FAT_DEBUG_RW_HITS
332
      FATWRHits++;
333
     #endif
334
     FATStatus=0; // flag FAT buffer is save
335
    } 
336
#endif
337
338
 return cluster;
339
}
340
#endif //DOS_WRITE
341
342
#ifdef DOS_WRITE
343
//###########################################################
344
/*!\brief Find a free cluster in FAT
345
 * \param    currentcluster  Actual cluster number
346
 * \return     Number of a free cluster or DISK_FULL
347
 */
348
#ifdef USE_FAT32
349
 U32 FindFreeCluster(U32 currentcluster)
350
#else
351
 U16 FindFreeCluster(U16 currentcluster)
352
#endif
353
//###########################################################
354
{
355
#ifdef USE_FAT32
356
 U32 cluster;
357
#else
358
 U16 cluster;
359
#endif
360
361
 cluster=currentcluster+1; // its a good idea to look here first
362
                           // maybe we do not need to search the whole FAT
363
                           // and can speed up free cluster search
364
                           // if you do not want this call FindFreeCluster(0)
365
// search til end of FAT
366
 while(cluster<maxcluster)
367
  {
368
   if(GetNextClusterNumber(cluster)==0) break;
369
   cluster++;
370
  }
371
372
// if we have not found a free cluster til end of FAT
373
// lets start a new search at beginning of FAT
374
 if(cluster>=maxcluster)
375
  {
376
   cluster=2; // first possible free cluster
377
   while(cluster<=currentcluster) // search til we come to where we have started
378
    {
379
     if(GetNextClusterNumber(cluster)==0) break;
380
     cluster++;
381
    }
382
383
   if(cluster>=currentcluster) return DISK_FULL; // no free cluster found
384
  }
385
  
386
 if(cluster>=maxcluster) return DISK_FULL;
387
    
388
 return cluster;
389
}
390
#endif //DOS_WRITE
391
392
#ifdef DOS_WRITE
393
//############################################################
394
/*!\brief Insert a new cluster number into cluster chain
395
 * \param    cluster  Actual cluster number
396
 * \param    number  Cluster number to append to cluster chain
397
 * \return     Nothing til now (0)
398
 */
399
#ifdef USE_FAT32
400
 U8 WriteClusterNumber(U32 cluster, U32 number)
401
#else
402
 U8 WriteClusterNumber(U16 cluster, U16 number)
403
#endif
404
//############################################################
405
{
406
#ifdef USE_FAT12
407
 U16 tmp, secoffset;
408
 U8 fatoffset;
409
 U8 lo,hi;
410
 U32 sector;
411
#endif
412
413
 U8 *p;
414
 
415
#ifdef FAT_DEBUG_CLUSTERS
416
#ifdef USE_FAT32
417
 printf("WCN %lu\n",cluster);
418
#else
419
 printf("WCN %u\n",cluster);
420
#endif
421
#endif
422
423
 if(cluster<maxcluster) //we need to check this ;-)
424
  {
425
426
#ifdef USE_FAT12
427
   if(FATtype==FAT12)
428
    {
429
     //FAT12 has 1.5 Bytes per FAT entry
430
     // FAT12 can only have 4085 clusters. So cluster * 3 is 16 bit 
431
     tmp= ((U16)cluster * 3) >>1 ; //multiply by 1.5 (rounds down)
432
     secoffset = (U16)tmp & (BYTE_PER_SEC-1); //we need this for later
433
     // FAT12 4085 Cluster * 1.5Bytes = 6127.5 Bytes => max 12 FAT sectors
434
     // FAT sector offset is 8 Bit 
435
//     fatoffset = (U8)(tmp / BYTE_PER_SEC); //sector offset from FATFirstSector
436
     fatoffset = (U8)(tmp >> 9); //sector offset from FATFirstSector
437
     sector=FATFirstSector + fatoffset;
438
439
     tmp=(U16)number;
440
     if((U8)cluster & 0x01) tmp<<=4; //shift to right position
441
     lo=(U8)tmp;
442
     hi=(U8)(tmp>>8);
443
     
444
     UpdateFATBuffer(sector); //read FAT sector
445
446
     if(secoffset == (BYTE_PER_SEC-1)) //if this is the case, cluster number is
447
                                   //on a sector boundary. read the next sector too
448
      {
449
450
       p = &FAT_IO_BUFFER[BYTE_PER_SEC-1]; //keep first part of cluster number
451
452
       if((U8)cluster & 0x01)
453
        {
454
         *p&=0x0F;
455
         *p|=lo;
456
        }
457
       else *p=lo;
458
        
459
       FATStatus=1; // we have made an entry, so write before next FAT sector read
460
       UpdateFATBuffer(sector+1); //read FAT sector
461
462
       p = &FAT_IO_BUFFER[0]; //second part of cluster number
463
464
       if((U8)cluster & 0x01) *p=hi;
465
       else
466
        {
467
         *p&=0xF0;
468
         *p|=hi;
469
        }
470
471
       FATStatus=1; // we have made an entry, so write before next FAT sector read
472
      }
473
     else
474
      {
475
       p = &FAT_IO_BUFFER[secoffset];
476
477
       if((U8)cluster & 0x01)
478
        {
479
         *p&=0x0F;
480
         *p++|=lo;
481
         *p=hi;
482
        } 
483
       else
484
        {
485
         *p++=lo;
486
         *p&=0xF0;
487
         *p|=hi;
488
        } 
489
490
       FATStatus=1; // we have made an entry, so write before next FAT sector read
491
      } 
492
493
    }//if(FATtype==FAT12)
494
#endif
495
496
#ifdef USE_FAT16
497
   if(FATtype==FAT16)
498
    {
499
     //two bytes per FAT entry
500
//     sector=FATFirstSector + ((U32)cluster * 2) / BYTE_PER_SEC;
501
//     sector=FATFirstSector + ((unsigned int)cluster) / (BYTE_PER_SEC/2);
502
     UpdateFATBuffer(FATFirstSector + (U8)( (U16)cluster >> 8 ));
503
504
     // Buffer index is max 511. So in any case we loose upper bits. typecast cluster to U16
505
     p = &FAT_IO_BUFFER[((U16)cluster << 1) & (BYTE_PER_SEC-1)];
506
507
     *p++ = (U8)(number);
508
     *p   = (U8)(number >> 8);
509
510
     FATStatus=1; // we have made an entry, so write before next FAT sector read
511
    }// if(FATtype==FAT16)
512
#endif //#ifdef USE_FAT16
513
514
#ifdef USE_FAT32
515
   if(FATtype==FAT32)
516
    {
517
     //four bytes per FAT entry
518
//     sector=FATFirstSector + (cluster * 4) / BYTE_PER_SEC;
519
//     sector=FATFirstSector + cluster / (BYTE_PER_SEC/4);
520
     UpdateFATBuffer(FATFirstSector + ( cluster >> 7 ));
521
522
     // Buffer index is max 511. So in any case we loose upper bits. typecast cluster to U16
523
     p = &FAT_IO_BUFFER[((U16)cluster << 2) & (BYTE_PER_SEC-1)];
524
525
     number&=0x0FFFFFFF;
526
     
527
     *p++ = (U8)( number);
528
     *p++ = (U8)(number >> 8);
529
     *p++ = (U8)(number >> 16);
530
     *p   = (U8)(number >> 24);
531
532
     FATStatus=1; // we have made an entry, so write before next FAT sector read
533
534
    }// if(FATtype==FAT32) 
535
#endif //#ifdef USE_FAT32
536
  } // if(cluster<maxcluster) //we need to check this ;-)
537
538
 return 0;
539
}
540
#endif //DOS_WRITE
541
542
//###########################################################
543
/*!\brief Get drive informations
544
 * \return     F_OK if successfull, F_ERROR if not
545
 *
546
 * This function is most important for the FAT filesystem.
547
 * Following values will be read out:
548
 * Type of the FAT filesystem.
549
 * Number of sectors for the partition (if there is one).
550
 * Number of clusters of the drive.
551
 * Where is the rootdirectory. And many more.
552
 * When using MMC/SD cards, call MMC_IO_Init() BEFORE GetDriveInformation() !
553
 */
554
U8 GetDriveInformation(void)
555
//###########################################################
556
{
557
 U8 by;
558
 U32 DataSec,TotSec;
559
 U32 bootSecOffset;
560
 U32 FATSz; // FATSize
561
 U8 loop;
562
563
#ifdef USE_FAT32
564
  U32 CountofClusters;
565
#else
566
//  U16 CountofClusters;  // for standard division
567
  U32 CountofClusters;    // for shifting division
568
#endif
569
570
 U16  RootEntrys;
571
572
 struct MBR *mbr;
573
 struct BootSec *boot;
574
  
575
 by=IdentifyMedia(); //LaufwerksInformationen holen
576
 if(by==0)
577
  {
578
   FATtype=0; //Unknown FAT type
579
   bootSecOffset=0; //erstmal
580
581
   by=ReadSector(0,iob); //Lese den MBR. Erster Sektor auf der Platte
582
                       //enthält max. 4 Partitionstabellen mit jeweils 16Bytes
583
                       //Die erste fängt bei 0x01BE an, und nur die nehme ich !
584
585
   //Erstmal checken ob wir nicht schon einen Bootsektor gelesen haben.
586
   boot=(struct BootSec *)iob;
587
588
   loop=0;
589
   do
590
    {
591
     // Jetzt checke ich doch den FAT-String im Bootsektor um den Typ der FAT
592
     // zu bestimmen. Einen besseren Weg sehe ich im Moment nicht.
593
     if(   boot->eb.rm.BS_FilSysType[0]=='F'
594
//        && boot->eb.rm.BS_FilSysType[1]=='A'
595
//        && boot->eb.rm.BS_FilSysType[2]=='T'
596
        && boot->eb.rm.BS_FilSysType[3]=='1'  )
597
      {
598
       //Wenn ich hier ankomme habe ich entweder FAT12 oder FAT16
599
#ifdef USE_FAT12
600
       if(boot->eb.rm.BS_FilSysType[4]=='2') FATtype=FAT12;
601
#endif
602
#ifdef USE_FAT16
603
       if(boot->eb.rm.BS_FilSysType[4]=='6') FATtype=FAT16;
604
#endif
605
      }
606
     else
607
      {
608
#ifdef USE_FAT32
609
       if(   boot->eb.rm32.BS_FilSysType[0]=='F'
610
//          && boot->eb.rm32.BS_FilSysType[1]=='A'
611
//          && boot->eb.rm32.BS_FilSysType[2]=='T'
612
          && boot->eb.rm32.BS_FilSysType[3]=='3'
613
          && boot->eb.rm32.BS_FilSysType[4]=='2'
614
         )
615
        {
616
         FATtype=FAT32;
617
        }
618
       else //war kein Bootsektor, also feststellen wo der liegt
619
#endif
620
        {
621
         mbr=(struct MBR *)iob; //Pointer auf die Partitionstabelle
622
         bootSecOffset=mbr->part1.bootoffset; //Nur den brauche ich
623
624
         by=ReadSector(bootSecOffset,iob);      //read bootsector
625
         boot=(struct BootSec *)iob;
626
        } 
627
      }
628
629
     loop++;
630
    }while(loop<2 && FATtype==0); //Bis zu zwei Versuche den Bootsektor zu lesen
631
632
   if(FATtype==0)
633
    {
634
#ifdef FAT_DEBUG_SHOW_FAT_INFO
635
     puts("FAT unknown\n");
636
#endif
637
     return F_ERROR; // FAT-Typ nicht erkannt
638
    }
639
640
   secPerCluster=boot->BPB_SecPerClus; //Sectors per Cluster
641
   RootEntrys=boot->BPB_RootEntCnt;    //32 Byte Root Directory Entrys
642
   RootDirSectors = (unsigned char)( ((RootEntrys * 32) + (BYTE_PER_SEC - 1)) / BYTE_PER_SEC);
643
644
//Number of sectors for FAT
645
   if(boot->BPB_FATSz16 != 0) FATSz = boot->BPB_FATSz16;
646
   else FATSz = boot->eb.rm32.BPB_FATSz32; //Für FAT32
647
648
   if(boot->BPB_TotSec16 != 0) TotSec = boot->BPB_TotSec16;
649
   else TotSec = boot->BPB_TotSec32;
650
651
   FATFirstSector= bootSecOffset + boot->BPB_RsvdSecCnt;
652
   FirstRootSector = FATFirstSector + (boot->BPB_NumFATs * FATSz);
653
654
//Number of data sectors
655
   DataSec = TotSec - (boot->BPB_RsvdSecCnt + (boot->BPB_NumFATs * FATSz) + RootDirSectors);
656
657
   FirstDataSector = FirstRootSector + RootDirSectors;
658
659
//Number of valid clusters
660
   //CountofClusters = DataSec / secPerCluster;
661
   U8 temp;
662
663
   // secPerCluster is always power of two 
664
   temp = secPerCluster>>1; // don't divide by 1 ;)
665
   CountofClusters = DataSec;
666
   
667
   while(temp)
668
    {
669
     CountofClusters >>= 1;
670
     temp >>= 1;
671
    }
672
673
   maxcluster = CountofClusters + 2;
674
675
//Note also that the CountofClusters value is exactly that: the count of data clusters
676
//starting at cluster 2. The maximum valid cluster number for the volume is
677
//CountofClusters + 1, and the "count of clusters including the two reserved clusters"
678
// is CountofClusters + 2.
679
680
   FirstDirCluster=0; // for FAT12 and FAT16
681
682
#ifdef USE_FAT12
683
   if(FATtype==FAT12)
684
    {
685
     endofclusterchain=EOC12;
686
    } 
687
#endif
688
#ifdef USE_FAT16
689
   if(FATtype==FAT16)
690
    {
691
     endofclusterchain=EOC16;
692
    } 
693
#endif
694
#ifdef USE_FAT32
695
   if(FATtype==FAT32)
696
    {
697
     endofclusterchain=EOC32;
698
     FAT32RootCluster=boot->eb.rm32.BPB_RootClus;
699
     FirstDirCluster=FAT32RootCluster;
700
     FirstRootSector=GetFirstSectorOfCluster(FAT32RootCluster);
701
    }
702
#endif
703
704
  }
705
 else
706
  {
707
   return F_ERROR; // CF gives no answer
708
  } 
709
710
 FileFirstCluster=0;
711
 FileSize=0;
712
 FileFlag=0;
713
714
 BytesPerCluster=BYTE_PER_SEC * secPerCluster; //bytes per cluster
715
716
 FATCurrentSector=FATFirstSector;
717
718
// for debugging only
719
#ifdef FAT_DEBUG_SHOW_FAT_INFO
720
 if(FATtype==FAT12) puts("FAT12\n");
721
 if(FATtype==FAT16) puts("FAT16\n");
722
 if(FATtype==FAT32) puts("FAT32\n");
723
724
 printf("bootSecOffset %lu\n",bootSecOffset);
725
 printf("Reserved Sectors %u\n",boot->BPB_RsvdSecCnt);
726
 printf("FAT Sectors %lu\n",FATSz);
727
 printf("Num. of FAT's %u\n",(U16)boot->BPB_NumFATs);
728
 printf("secPerCluster %u\n",(U16)secPerCluster);
729
730
#ifdef USE_64k_CLUSTERS
731
 printf("BytesPerCluster %lu\n",BytesPerCluster);
732
#else
733
 printf("BytesPerCluster %u\n",BytesPerCluster);
734
#endif
735
736
 printf("FATFirstSector %lu\n",FATFirstSector);
737
 printf("FirstRootSector %lu\n",FirstRootSector);
738
 printf("RootDirSectors %u\n",(U16)RootDirSectors);
739
 printf("FirstDataSector %lu\n",FirstDataSector);
740
 printf("maxsect %lu\n",maxsect);
741
#ifdef USE_FAT32
742
 printf("FirstDirCluster %lu\n",FirstDirCluster);
743
 printf("maxcluster %lu\n",maxcluster);
744
#else
745
 printf("FirstDirCluster %u\n",FirstDirCluster);
746
 printf("maxcluster %u\n",maxcluster);
747
#endif
748
749
#endif //#ifdef FAT_DEBUG_SHOW_FAT_INFO
750
751
 #ifdef DOS_WRITE
752
  FATStatus=0; // nothing to write til here
753
 #endif
754
755
 ReadFATSector(FATCurrentSector,FAT_IO_BUFFER); //read first FAT sector
756
757
 return F_OK;
758
}
759
760
#ifndef USE_FATBUFFER
761
#ifdef DOS_WRITE
762
//#########################################################################
763
U8 WriteFATSector(U32 sector, U8 *buf)
764
//#########################################################################
765
{
766
 iob_status=IOB_FAT; // we have to track this
767
 return WriteSector(sector,buf); //write sector
768
}
769
#endif
770
771
//#########################################################################
772
U8 ReadFATSector(U32 sector, U8 *buf)
773
//#########################################################################
774
{
775
 iob_status=IOB_FAT; // we have to track this
776
 return ReadSector(sector,buf); //read sector
777
}
778
779
#ifdef DOS_WRITE // Better keep this as a function !
780
//#########################################################################
781
U8 WriteDirSector(U32 sector, U8 *buf)
782
//#########################################################################
783
{
784
 iob_status=IOB_DIR; // we have to track this
785
 return WriteSector(sector,buf); //write sector
786
}
787
#endif
788
789
//#########################################################################
790
U8 ReadDirSector(U32 sector, U8 *buf)
791
//#########################################################################
792
{
793
 iob_status=IOB_DIR; // we have to track this
794
 return ReadSector(sector,buf); //read sector
795
}
796
797
#ifdef DOS_WRITE // This has to be a function for Fwrite(), Fclose() !
798
//#########################################################################
799
U8 WriteFileSector(U32 sector, U8 *buf)
800
//#########################################################################
801
{
802
 iob_status=IOB_DATA; // we have to track this
803
 return WriteSector(sector,buf); //write sector
804
}
805
#endif
806
807
//#########################################################################
808
U8 ReadFileSector(U32 sector, U8 *buf)
809
//#########################################################################
810
{
811
 iob_status=IOB_DATA; // we have to track this
812
 return ReadSector(sector,buf); //read sector
813
}
814
815
#endif //#ifndef USE_FATBUFFER
816
//@}