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
558
 // DEBUG-Info:
559
 printf("Beginn GDI\r\n");
560
561
 U8 by;
562
 U32 DataSec,TotSec;
563
 U32 bootSecOffset;
564
 U32 FATSz; // FATSize
565
 U8 loop;
566
567
#ifdef USE_FAT32
568
  U32 CountofClusters;
569
#else
570
//  U16 CountofClusters;  // for standard division
571
  U32 CountofClusters;    // for shifting division
572
#endif
573
574
 U16  RootEntrys;
575
576
 struct MBR *mbr;
577
 struct BootSec *boot;
578
  
579
 by=IdentifyMedia(); //LaufwerksInformationen holen
580
581
 // DEBUG-Info:
582
 printf("GDI: Laufwerksinfo geholt\r\n");
583
584
 if(by==0)
585
  {
586
   FATtype=0; //Unknown FAT type
587
   bootSecOffset=0; //erstmal
588
589
   by=ReadSector(0,iob); //Lese den MBR. Erster Sektor auf der Platte
590
                       //enthält max. 4 Partitionstabellen mit jeweils 16Bytes
591
                       //Die erste fängt bei 0x01BE an, und nur die nehme ich !
592
593
   //Erstmal checken ob wir nicht schon einen Bootsektor gelesen haben.
594
   boot=(struct BootSec *)iob;
595
596
   loop=0;
597
   do
598
    {
599
     // Jetzt checke ich doch den FAT-String im Bootsektor um den Typ der FAT
600
     // zu bestimmen. Einen besseren Weg sehe ich im Moment nicht.
601
     if(   boot->eb.rm.BS_FilSysType[0]=='F'
602
//        && boot->eb.rm.BS_FilSysType[1]=='A'
603
//        && boot->eb.rm.BS_FilSysType[2]=='T'
604
        && boot->eb.rm.BS_FilSysType[3]=='1'  )
605
      {
606
       //Wenn ich hier ankomme habe ich entweder FAT12 oder FAT16
607
608
    // DEBUG-Info:
609
    printf("GDI: FAT identifiziert.\r\n");
610
611
#ifdef USE_FAT12
612
       if(boot->eb.rm.BS_FilSysType[4]=='2') FATtype=FAT12;
613
#endif
614
#ifdef USE_FAT16
615
       if(boot->eb.rm.BS_FilSysType[4]=='6') FATtype=FAT16;
616
#endif
617
      }
618
     else
619
      {
620
#ifdef USE_FAT32
621
       if(   boot->eb.rm32.BS_FilSysType[0]=='F'
622
//          && boot->eb.rm32.BS_FilSysType[1]=='A'
623
//          && boot->eb.rm32.BS_FilSysType[2]=='T'
624
          && boot->eb.rm32.BS_FilSysType[3]=='3'
625
          && boot->eb.rm32.BS_FilSysType[4]=='2'
626
         )
627
        {
628
         FATtype=FAT32;
629
        }
630
       else //war kein Bootsektor, also feststellen wo der liegt
631
#endif
632
        {
633
         mbr=(struct MBR *)iob; //Pointer auf die Partitionstabelle
634
         bootSecOffset=mbr->part1.bootoffset; //Nur den brauche ich
635
636
         by=ReadSector(bootSecOffset,iob);      //read bootsector
637
         boot=(struct BootSec *)iob;
638
        } 
639
      }
640
641
     loop++;
642
    }while(loop<2 && FATtype==0); //Bis zu zwei Versuche den Bootsektor zu lesen
643
644
    // DEBUG-Info:
645
    printf("GDI: Versuche Bootsektor zu lesen.\r\n");
646
647
   if(FATtype==0)
648
    {
649
#ifdef FAT_DEBUG_SHOW_FAT_INFO
650
     puts("FAT unknown\n");
651
     // DEBUG-Info:
652
    printf("GDI: FAT unbekannt.\r\n");
653
#endif
654
     return F_ERROR; // FAT-Typ nicht erkannt
655
    }
656
657
   secPerCluster=boot->BPB_SecPerClus; //Sectors per Cluster
658
   RootEntrys=boot->BPB_RootEntCnt;    //32 Byte Root Directory Entrys
659
   RootDirSectors = (unsigned char)( ((RootEntrys * 32) + (BYTE_PER_SEC - 1)) / BYTE_PER_SEC);
660
661
//Number of sectors for FAT
662
   if(boot->BPB_FATSz16 != 0) FATSz = boot->BPB_FATSz16;
663
   else FATSz = boot->eb.rm32.BPB_FATSz32; //Für FAT32
664
665
   if(boot->BPB_TotSec16 != 0) TotSec = boot->BPB_TotSec16;
666
   else TotSec = boot->BPB_TotSec32;
667
668
   FATFirstSector= bootSecOffset + boot->BPB_RsvdSecCnt;
669
   FirstRootSector = FATFirstSector + (boot->BPB_NumFATs * FATSz);
670
671
//Number of data sectors
672
   DataSec = TotSec - (boot->BPB_RsvdSecCnt + (boot->BPB_NumFATs * FATSz) + RootDirSectors);
673
674
   FirstDataSector = FirstRootSector + RootDirSectors;
675
676
//Number of valid clusters
677
   //CountofClusters = DataSec / secPerCluster;
678
   U8 temp;
679
680
   // secPerCluster is always power of two 
681
   temp = secPerCluster>>1; // don't divide by 1 ;)
682
   CountofClusters = DataSec;
683
   
684
   while(temp)
685
    {
686
     CountofClusters >>= 1;
687
     temp >>= 1;
688
    }
689
690
   maxcluster = CountofClusters + 2;
691
692
//Note also that the CountofClusters value is exactly that: the count of data clusters
693
//starting at cluster 2. The maximum valid cluster number for the volume is
694
//CountofClusters + 1, and the "count of clusters including the two reserved clusters"
695
// is CountofClusters + 2.
696
697
   FirstDirCluster=0; // for FAT12 and FAT16
698
699
#ifdef USE_FAT12
700
   if(FATtype==FAT12)
701
    {
702
     endofclusterchain=EOC12;
703
    } 
704
#endif
705
#ifdef USE_FAT16
706
   if(FATtype==FAT16)
707
    {
708
     endofclusterchain=EOC16;
709
    } 
710
#endif
711
#ifdef USE_FAT32
712
   if(FATtype==FAT32)
713
    {
714
     endofclusterchain=EOC32;
715
     FAT32RootCluster=boot->eb.rm32.BPB_RootClus;
716
     FirstDirCluster=FAT32RootCluster;
717
     FirstRootSector=GetFirstSectorOfCluster(FAT32RootCluster);
718
    }
719
#endif
720
721
  }
722
 else
723
  {
724
   return F_ERROR; // CF gives no answer
725
       // DEBUG-Info:
726
    printf("GDI: Karte reagiert nicht.\r\n");
727
  } 
728
729
 FileFirstCluster=0;
730
 FileSize=0;
731
 FileFlag=0;
732
733
 BytesPerCluster=BYTE_PER_SEC * secPerCluster; //bytes per cluster
734
735
 FATCurrentSector=FATFirstSector;
736
737
// for debugging only
738
#ifdef FAT_DEBUG_SHOW_FAT_INFO
739
 if(FATtype==FAT12) puts("FAT12\n");
740
 if(FATtype==FAT16) puts("FAT16\n");
741
 if(FATtype==FAT32) puts("FAT32\n");
742
743
 printf("bootSecOffset %lu\n",bootSecOffset);
744
 printf("Reserved Sectors %u\n",boot->BPB_RsvdSecCnt);
745
 printf("FAT Sectors %lu\n",FATSz);
746
 printf("Num. of FAT's %u\n",(U16)boot->BPB_NumFATs);
747
 printf("secPerCluster %u\n",(U16)secPerCluster);
748
749
#ifdef USE_64k_CLUSTERS
750
 printf("BytesPerCluster %lu\n",BytesPerCluster);
751
#else
752
 printf("BytesPerCluster %u\n",BytesPerCluster);
753
#endif
754
755
 printf("FATFirstSector %lu\n",FATFirstSector);
756
 printf("FirstRootSector %lu\n",FirstRootSector);
757
 printf("RootDirSectors %u\n",(U16)RootDirSectors);
758
 printf("FirstDataSector %lu\n",FirstDataSector);
759
 printf("maxsect %lu\n",maxsect);
760
#ifdef USE_FAT32
761
 printf("FirstDirCluster %lu\n",FirstDirCluster);
762
 printf("maxcluster %lu\n",maxcluster);
763
#else
764
 printf("FirstDirCluster %u\n",FirstDirCluster);
765
 printf("maxcluster %u\n",maxcluster);
766
#endif
767
768
#endif //#ifdef FAT_DEBUG_SHOW_FAT_INFO
769
770
 #ifdef DOS_WRITE
771
  FATStatus=0; // nothing to write til here
772
 #endif
773
774
 ReadFATSector(FATCurrentSector,FAT_IO_BUFFER); //read first FAT sector
775
776
 return F_OK;
777
}
778
779
#ifndef USE_FATBUFFER
780
#ifdef DOS_WRITE
781
//#########################################################################
782
U8 WriteFATSector(U32 sector, U8 *buf)
783
//#########################################################################
784
{
785
 iob_status=IOB_FAT; // we have to track this
786
 return WriteSector(sector,buf); //write sector
787
}
788
#endif
789
790
//#########################################################################
791
U8 ReadFATSector(U32 sector, U8 *buf)
792
//#########################################################################
793
{
794
 iob_status=IOB_FAT; // we have to track this
795
 return ReadSector(sector,buf); //read sector
796
}
797
798
#ifdef DOS_WRITE // Better keep this as a function !
799
//#########################################################################
800
U8 WriteDirSector(U32 sector, U8 *buf)
801
//#########################################################################
802
{
803
 iob_status=IOB_DIR; // we have to track this
804
 return WriteSector(sector,buf); //write sector
805
}
806
#endif
807
808
//#########################################################################
809
U8 ReadDirSector(U32 sector, U8 *buf)
810
//#########################################################################
811
{
812
 iob_status=IOB_DIR; // we have to track this
813
 return ReadSector(sector,buf); //read sector
814
}
815
816
#ifdef DOS_WRITE // This has to be a function for Fwrite(), Fclose() !
817
//#########################################################################
818
U8 WriteFileSector(U32 sector, U8 *buf)
819
//#########################################################################
820
{
821
 iob_status=IOB_DATA; // we have to track this
822
 return WriteSector(sector,buf); //write sector
823
}
824
#endif
825
826
//#########################################################################
827
U8 ReadFileSector(U32 sector, U8 *buf)
828
//#########################################################################
829
{
830
 iob_status=IOB_DATA; // we have to track this
831
 return ReadSector(sector,buf); //read sector
832
}
833
834
#endif //#ifndef USE_FATBUFFER
835
//@}