00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <string.h>
00027
00028 #include "device.h"
00029 #include "rprintf.h"
00030 #include "debug.h"
00031
00032 #include "fat.h"
00033 #include "fatconf.h"
00034
00035
00036
00037
00038
00039
00040
00041 unsigned char SectorBuffer[0x200];
00042 unsigned char FileNameBuffer[0x100];
00043 unsigned char PathNameBuffer[0x100];
00044 unsigned char FatCacheBuffer[0x200];
00045
00046 struct fatFsInfo
00047 {
00048 unsigned long FirstDataSector;
00049 unsigned short BytesPerSector;
00050 unsigned short SectorsPerCluster;
00051 unsigned long FirstFATSector;
00052 unsigned long SectorsPerFat;
00053 unsigned long RootDirStartCluster;
00054 unsigned long FatInCache;
00055 unsigned long FatMask;
00056 unsigned char Fat32Enabled;
00057 unsigned char NumberOfFats;
00058
00059 DevDisk_t devdisk;
00060
00061 } GNUC_PACKED;
00062
00063 typedef struct FatFsInfo FatFsInfo_t;
00064
00065
00066 struct fatFsInfo FatFsInfo;
00067
00068
00069 unsigned long CurrentDirStartCluster;
00070 struct FileInfo_s FileInfo;
00071
00072
00073
00074
00075
00076 unsigned char fatInit(DevDisk_t* devdisk)
00077 {
00078
00079 struct bpb710 *bpb;
00080
00081
00082 FatFsInfo.devdisk = *devdisk;
00083
00084 rprintfProgStrM("DevDisk pointers\r\n");
00085 rprintfu32((unsigned long)devdisk->ReadSector);
00086 rprintfu32((unsigned long)devdisk->WriteSector);
00087 rprintfCRLF();
00088
00089 FatFsInfo.FatInCache = 0;
00090
00091
00092 FatFsInfo.devdisk.ReadSector(0, 1, SectorBuffer);
00093 bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;
00094
00095
00096 if(bpb->bpbFATsecs)
00097 {
00098
00099 FatFsInfo.SectorsPerFat = bpb->bpbFATsecs;
00100
00101
00102 FatFsInfo.RootDirStartCluster = CLUST_FIRST;
00103
00104
00105 FatFsInfo.Fat32Enabled = FALSE;
00106
00107 FatFsInfo.FatMask = FAT16_MASK;
00108 }
00109 else
00110 {
00111
00112 FatFsInfo.SectorsPerFat = bpb->bpbBigFATsecs;
00113
00114
00115 FatFsInfo.RootDirStartCluster = bpb->bpbRootClust;
00116
00117
00118 FatFsInfo.Fat32Enabled = TRUE;
00119
00120 FatFsInfo.FatMask = FAT32_MASK;
00121 }
00122 FatFsInfo.SectorsPerCluster = bpb->bpbSecPerClust;
00123 FatFsInfo.BytesPerSector = bpb->bpbBytesPerSec;
00124 FatFsInfo.FirstFATSector = bpb->bpbResSectors;
00125 FatFsInfo.NumberOfFats = bpb->bpbFATs;
00126 FatFsInfo.FirstDataSector = bpb->bpbResSectors + FatFsInfo.NumberOfFats * FatFsInfo.SectorsPerFat;
00127
00128
00129 CurrentDirStartCluster = FatFsInfo.RootDirStartCluster;
00130 PathNameBuffer[0] = '\\';
00131 PathNameBuffer[1] = 0;
00132
00133
00134 #ifdef DEBUG_FAT
00135 rprintfProgStrM("---------- Disk/Partition Information ----------\r\n");
00136 rprintfProgStrM("Volume/Part Size: "); rprintfu32(FatFsInfo.devdisk.numsectors); rprintfCRLF();
00137 rprintfProgStrM("---------- FAT Volume Information --------------\r\n");
00138 rprintfProgStrM("Reserved Sectors: "); rprintfu16(bpb->bpbResSectors); rprintfCRLF();
00139 rprintfProgStrM("FatSectors : "); rprintfu16(bpb->bpbFATsecs); rprintfCRLF();
00140 rprintfProgStrM("BigFatSectors : "); rprintfu32(bpb->bpbBigFATsecs); rprintfCRLF();
00141 rprintfProgStrM("Bytes/Sector : "); rprintfu16(FatFsInfo.BytesPerSector); rprintfCRLF();
00142 rprintfProgStrM("First Fat Sector: "); rprintfu32(FatFsInfo.FirstFATSector); rprintfCRLF();
00143 rprintfProgStrM("Number of Fats : "); rprintfu08(FatFsInfo.NumberOfFats); rprintfCRLF();
00144 rprintfProgStrM("Sectors/FAT : "); rprintfu32(FatFsInfo.SectorsPerFat); rprintfCRLF();
00145 rprintfProgStrM("First Data Sect : "); rprintfu32(FatFsInfo.FirstDataSector); rprintfCRLF();
00146 rprintfProgStrM("Sectors/Cluster : "); rprintfu08(FatFsInfo.SectorsPerCluster); rprintfCRLF();
00147 rprintfProgStrM("RootDirStartClus: "); rprintfu32(FatFsInfo.RootDirStartCluster); rprintfCRLF();
00148 #endif
00149
00150 return 0;
00151 }
00152
00153
00154
00155
00156 unsigned char fatGetDirEntry(unsigned short entry)
00157 {
00158 unsigned long sector;
00159 struct direntry *de = 0;
00160 struct winentry *we;
00161 unsigned char haveLongNameEntry;
00162 unsigned char gotEntry;
00163 unsigned short b;
00164 int i,index;
00165 char *fnbPtr;
00166 unsigned short entrycount = 0;
00167
00168
00169
00170 sector = fatClusterToSector(CurrentDirStartCluster);
00171
00172 haveLongNameEntry = 0;
00173 gotEntry = 0;
00174
00175 index = 16;
00176
00177
00178 while(1)
00179 {
00180 if(index == 16)
00181 {
00182 FatFsInfo.devdisk.ReadSector(sector++, 1, SectorBuffer);
00183 de = (struct direntry *) SectorBuffer;
00184 index = 0;
00185 }
00186
00187
00188 if(de->deName[0] == 0x00)
00189 {
00190
00191 gotEntry = 0;
00192 break;
00193 }
00194 else if(de->deName[0] == 0xE5)
00195 {
00196
00197
00198 }
00199 else
00200 {
00201
00202
00203 if(de->deAttributes == ATTR_LONG_FILENAME)
00204 {
00205
00206
00207 we = (struct winentry *) de;
00208
00209 b = WIN_ENTRY_CHARS*( (we->weCnt-1) & 0x0f);
00210 fnbPtr = &FileNameBuffer[b];
00211 for (i=0;i<5;i++) *fnbPtr++ = we->wePart1[i*2];
00212 for (i=0;i<6;i++) *fnbPtr++ = we->wePart2[i*2];
00213 for (i=0;i<2;i++) *fnbPtr++ = we->wePart3[i*2];
00214 if (we->weCnt & WIN_LAST) *fnbPtr = 0;
00215 if ((we->weCnt & 0x0f) == 1) haveLongNameEntry = 1;
00216 }
00217 else
00218 {
00219
00220
00221
00222
00223 if(haveLongNameEntry)
00224 {
00225
00226 if(entrycount == entry)
00227 {
00228
00229 gotEntry = 1;
00230 break;
00231 }
00232
00233 haveLongNameEntry = 0;
00234 entrycount++;
00235 }
00236 else
00237 {
00238
00239
00240 fnbPtr = FileNameBuffer;
00241 for (i=0;i<8;i++) *fnbPtr++ = de->deName[i];
00242 *fnbPtr++ = '.';
00243 for (i=0;i<3;i++) *fnbPtr++ = de->deExtension[i];
00244 *fnbPtr = 0;
00245
00246 if(entrycount == entry)
00247 {
00248
00249 gotEntry = 1;
00250 break;
00251 }
00252
00253 entrycount++;
00254 }
00255 }
00256 }
00257
00258 de++;
00259
00260 index++;
00261 }
00262
00263
00264
00265 FileInfo.StartCluster = (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
00266
00267
00268 FileInfo.Size = de->deFileSize;
00269
00270 FileInfo.Attr = de->deAttributes;
00271
00272 FileInfo.CreateTime = de->deCTime[0] | de->deCTime[1]<<8;
00273
00274 FileInfo.CreateTime = de->deCDate[0] | de->deCDate[1]<<8;
00275
00276 return gotEntry;
00277 }
00278
00279 int fatCreateFile(unsigned char* filename, FileInfo_t* fileInfo)
00280 {
00281 unsigned long sector;
00282 struct direntry *de = 0;
00283 unsigned int index;
00284 unsigned char* strptr;
00285 unsigned char i;
00286
00287
00288 sector = fatClusterToSector(CurrentDirStartCluster);
00289
00290 index = DIRENTRIES_PER_SECTOR;
00291
00292 while(1)
00293 {
00294 if(index == DIRENTRIES_PER_SECTOR)
00295 {
00296 FatFsInfo.devdisk.ReadSector(sector++, 1, SectorBuffer);
00297 de = (struct direntry *)SectorBuffer;
00298 index = 0;
00299 }
00300
00301
00302 if(de->deName[0] == SLOT_EMPTY)
00303 {
00304
00305
00306 break;
00307 }
00308 else if(de->deName[0] == SLOT_DELETED)
00309 {
00310
00311 break;
00312 }
00313
00314
00315 de++;
00316 index++;
00317 }
00318
00319
00320 strptr = filename;
00321
00322 for(i=0; i<8; i++)
00323 {
00324 if( (*strptr != '.') && (*strptr != 0) )
00325 de->deName[i] = *strptr++;
00326 else
00327 de->deName[i] = ' ';
00328 }
00329
00330
00331 if(*strptr == '.')
00332 {
00333 strptr++;
00334 de->deExtension[0] = *strptr++;
00335 de->deExtension[1] = *strptr++;
00336 de->deExtension[2] = *strptr++;
00337 }
00338 else
00339 {
00340 de->deExtension[0] = ' ';
00341 de->deExtension[1] = ' ';
00342 de->deExtension[2] = ' ';
00343 }
00344
00345 de->deAttributes = fileInfo->Attr;
00346
00347 de->deLowerCase = 0;
00348
00349 de->deCHundredth = 0;
00350 de->deCTime[0] = fileInfo->CreateTime;
00351 de->deCTime[1] = fileInfo->CreateTime>>8;
00352 de->deCDate[0] = fileInfo->CreateDate;
00353 de->deCDate[1] = fileInfo->CreateDate>>8;
00354 de->deADate[0] = 0;
00355 de->deADate[1] = 0;
00356 de->deMTime[0] = 0;
00357 de->deMTime[1] = 0;
00358 de->deMDate[0] = 0;
00359 de->deMDate[1] = 0;
00360
00361 de->deFileSize = fileInfo->Size;
00362
00363 de->deStartCluster = fileInfo->StartCluster;
00364 de->deHighClust = fileInfo->StartCluster>>16;
00365
00366
00367 FatFsInfo.devdisk.WriteSector(--sector, 1, SectorBuffer);
00368
00369 return 0;
00370 }
00371
00372 int fatFormat(unsigned long volsize)
00373 {
00374 unsigned long i,j,fatsecs;
00375 unsigned long sector;
00376
00377 struct bootsector710 *bs;
00378 struct bpb710* bpb;
00379
00380
00381 rprintfProgStrM("Calculating filesystem parameters\r\n");
00382
00383 memset(SectorBuffer, 0, 512);
00384
00385 bs = (struct bootsector710 *)SectorBuffer;
00386
00387 strcpy(&bs->bsOEMName[0], "MSDOS5.0");
00388
00389 bpb = (struct bpb710*)bs->bsBPB;
00390
00391
00392 bpb->bpbBytesPerSec = 0x200;
00393 bpb->bpbSecPerClust = 8;
00394 bpb->bpbResSectors = 4;
00395 bpb->bpbFATs = 2;
00396 bpb->bpbRootDirEnts = 0x200;
00397 if(volsize < 0x10000)
00398 {
00399
00400 bpb->bpbSectors = volsize;
00401 bpb->bpbHugeSectors = 0;
00402 }
00403 else
00404 {
00405
00406 bpb->bpbSectors = 0;
00407 bpb->bpbHugeSectors = volsize;
00408 }
00409
00410
00411
00412 i = volsize - (bpb->bpbResSectors + (bpb->bpbRootDirEnts+(DIRENTRIES_PER_SECTOR-1))/DIRENTRIES_PER_SECTOR);
00413
00414 j = ((unsigned short)bpb->bpbSecPerClust<<8) + bpb->bpbFATs;
00415
00416 fatsecs = (i+(j-1))/j;
00417
00418
00419
00420
00421
00422
00423
00424 if(fatsecs < 65525)
00425 {
00426
00427 bpb->bpbFATsecs = fatsecs;
00428 }
00429 else
00430 {
00431
00432 bpb->bpbFATsecs = 0;
00433 bpb->bpbBigFATsecs = fatsecs;
00434 }
00435 bpb->bpbMedia = 0xF8;
00436 bpb->bpbSecPerTrack = 63;
00437 bpb->bpbHeads = 255;
00438 bpb->bpbHiddenSecs = 0;
00439
00440 bpb->bpbExtFlags = 0;
00441 bpb->bpbFSVers = FSVERS;
00442
00443
00444 bs->bsBootSectSig0 = 0x55;
00445 bs->bsBootSectSig1 = 0xAA;
00446
00447
00448 rprintfProgStrM("Writing boot sector\r\n");
00449 FatFsInfo.devdisk.WriteSector(0, 1, SectorBuffer);
00450
00451
00452
00453
00454
00455 rprintfProgStrM("Remounting Filesystem...\r\n");
00456 fatInit(&FatFsInfo.devdisk);
00457
00458 memset(SectorBuffer, 0, 512);
00459
00460 rprintfProgStrM("Initializing FAT sectors...\r\n");
00461 for(i=0; i<(FatFsInfo.NumberOfFats*FatFsInfo.SectorsPerFat); i++)
00462 {
00463 rprintfProgStrM("Writing FAT sector: "); rprintfu32(FatFsInfo.FirstFATSector+i); rprintfChar('\r');
00464 FatFsInfo.devdisk.WriteSector(FatFsInfo.FirstFATSector+i, 1, SectorBuffer);
00465 }
00466 rprintfCRLF();
00467
00468
00469 rprintfProgStrM("Creating Root Directory...\r\n");
00470
00471 fatWriteClusterValue(FatFsInfo.RootDirStartCluster, CLUST_EOFE);
00472
00473 sector = fatClusterToSector(FatFsInfo.RootDirStartCluster);
00474
00475 memset(SectorBuffer, 0, 512);
00476
00477 for(i=0; i<FatFsInfo.SectorsPerCluster; i++)
00478 {
00479 rprintfProgStrM("Writing Root Dir sector: "); rprintfu32(sector+i); rprintfChar('\r');
00480 FatFsInfo.devdisk.WriteSector(sector+i, 1, SectorBuffer);
00481 }
00482 rprintfCRLF();
00483
00484
00485 rprintfProgStrM("Creating Volume Label...\r\n");
00486
00487 FileInfo.Attr = ATTR_VOLUME;
00488 FileInfo.Size = 0;
00489 FileInfo.StartCluster = 0;
00490 FileInfo.CreateDate = 0;
00491 FileInfo.CreateTime = 0;
00492
00493 fatCreateFile("MYDISK", &FileInfo);
00494
00495 return 0;
00496 }
00497
00498
00499 unsigned char fatChangeDirectory(unsigned short entry)
00500 {
00501
00502 if( fatGetDirEntry(entry) )
00503 {
00504
00505 if(FileInfo.Attr & ATTR_DIRECTORY)
00506 {
00507
00508
00509 if(FileInfo.StartCluster)
00510 {
00511
00512 CurrentDirStartCluster = FileInfo.StartCluster;
00513 }
00514 else
00515 {
00516
00517
00518
00519 CurrentDirStartCluster = FatFsInfo.RootDirStartCluster;
00520 }
00521
00522
00523 strcat(PathNameBuffer, FileNameBuffer);
00524 strcat(PathNameBuffer, "\\");
00525
00526 return TRUE;
00527 }
00528 else
00529 {
00530
00531 return FALSE;
00532 }
00533 }
00534 else
00535 {
00536
00537 return FALSE;
00538 }
00539 }
00540
00541 void fatPrintDirEntry(void)
00542 {
00543
00544
00545 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_MONTH_MASK)>>DD_MONTH_SHIFT );
00546 rprintfChar('/');
00547 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateDate&DD_DAY_MASK)>>DD_DAY_SHIFT );
00548 rprintfChar('/');
00549 rprintfNum(10, 4, FALSE, '0', (FileInfo.CreateDate&DD_YEAR_MASK)>>DD_YEAR_SHIFT );
00550 rprintfChar(' ');
00551
00552
00553 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_HOURS_MASK)>>DT_HOURS_SHIFT );
00554 rprintfChar(':');
00555 rprintfNum(10, 2, FALSE, '0', (FileInfo.CreateTime&DT_MINUTES_MASK)>>DT_MINUTES_SHIFT );
00556 rprintfChar(':');
00557 rprintfNum(10, 2, FALSE, '0', 2*(FileInfo.CreateTime&DT_2SECONDS_MASK)>>DT_2SECONDS_SHIFT );
00558 rprintfChar(' ');
00559
00560
00561 if(FileInfo.Attr & ATTR_VOLUME) rprintfChar('V'); else rprintfChar('-');
00562 if(FileInfo.Attr & ATTR_DIRECTORY) rprintfChar('D'); else rprintfChar('-');
00563 if(FileInfo.Attr & ATTR_READONLY) rprintfChar('R'); else rprintfChar('-');
00564 if(FileInfo.Attr & ATTR_HIDDEN) rprintfChar('H'); else rprintfChar('-');
00565 if(FileInfo.Attr & ATTR_SYSTEM) rprintfChar('S'); else rprintfChar('-');
00566 if(FileInfo.Attr & ATTR_ARCHIVE) rprintfChar('A'); else rprintfChar('-');
00567 rprintfChar(' ');
00568
00569
00570 rprintfNum(10, 8, FALSE, ' ', FileInfo.Size);
00571 rprintfChar(' ');
00572
00573
00574 rprintfStr(FileNameBuffer);
00575 }
00576
00577 void fatDumpDirSlot(unsigned short slot)
00578 {
00579 unsigned long sector;
00580
00581
00582 sector = fatClusterToSector(CurrentDirStartCluster);
00583 sector += slot/DIRENTRIES_PER_SECTOR;
00584
00585 rprintf("CurrentDirStartCluster:");
00586 rprintfu32(CurrentDirStartCluster);
00587 rprintfCRLF();
00588 rprintf("Sector access :");
00589 rprintfu32(sector);
00590 rprintfCRLF();
00591
00592
00593 debugPrintHexTable(32, SectorBuffer+(slot<<5) );
00594 }
00595
00596 FileInfo_t* fatGetFileInfo(void)
00597 {
00598 return &FileInfo;
00599 }
00600
00601
00602 unsigned long fatGetFilesize(void)
00603 {
00604 return FileInfo.Size;
00605 }
00606
00607
00608 char* fatGetFilename(void)
00609 {
00610 return FileNameBuffer;
00611 }
00612
00613
00614 char* fatGetDirname(void)
00615 {
00616 return PathNameBuffer;
00617 }
00618
00619
00620 void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
00621 {
00622 register unsigned char i;
00623
00624
00625 for(i=0; i<FatFsInfo.SectorsPerCluster; i++)
00626 {
00627 FatFsInfo.devdisk.ReadSector(fatClusterToSector(cluster)+i, 1, buffer+(i<<9) );
00628
00629
00630
00631 }
00632 }
00633
00634
00635
00636 unsigned long fatNextCluster(unsigned long cluster)
00637 {
00638 unsigned long nextCluster;
00639
00640
00641 nextCluster = fatClusterValue(cluster);
00642
00643
00644 if (nextCluster == (CLUST_EOFE & FatFsInfo.FatMask))
00645 nextCluster = 0;
00646
00647 #ifdef DEBUG_FAT
00648 rprintfProgStrM(">");
00649 rprintfu32(nextCluster);
00650 rprintfCRLF();
00651 #endif
00652
00653 return nextCluster;
00654 }
00655
00656 unsigned long fatNextFreeCluster(void)
00657 {
00658 unsigned long cluster;
00659
00660
00661 cluster = FatFsInfo.RootDirStartCluster;
00662
00663 while( fatClusterValue(cluster) != CLUST_FREE)
00664 {
00665
00666 cluster++;
00667 }
00668 return cluster;
00669 }
00670
00671 unsigned long fatClusterValue(unsigned long cluster)
00672 {
00673
00674 unsigned char* buffer;
00675 unsigned long fatOffset;
00676 unsigned long sector;
00677 unsigned int offset;
00678
00679
00680 if(FatFsInfo.Fat32Enabled)
00681 {
00682
00683 fatOffset = cluster << 2;
00684 }
00685 else
00686 {
00687
00688 fatOffset = cluster << 1;
00689 }
00690
00691
00692 sector = (fatOffset / FatFsInfo.BytesPerSector);
00693
00694 offset = fatOffset % FatFsInfo.BytesPerSector;
00695
00696 buffer = fatGetFatSector( sector );
00697
00698
00699
00700
00701
00702 return (*((unsigned long*) &buffer[offset])) & FatFsInfo.FatMask;
00703 }
00704
00705 int fatWriteClusterValue(unsigned long cluster, unsigned value)
00706 {
00707
00708 unsigned char* buffer;
00709 unsigned long fatOffset;
00710 unsigned long fatSector;
00711 unsigned int offset;
00712
00713
00714 if(FatFsInfo.Fat32Enabled)
00715 {
00716
00717 fatOffset = cluster << 2;
00718 }
00719 else
00720 {
00721
00722 fatOffset = cluster << 1;
00723 }
00724
00725
00726 fatSector = (fatOffset / FatFsInfo.BytesPerSector);
00727
00728 offset = fatOffset % FatFsInfo.BytesPerSector;
00729
00730 buffer = fatGetFatSector( fatSector );
00731
00732
00733
00734
00735
00736 *((unsigned long*) &buffer[offset]) = (value & FatFsInfo.FatMask);
00737
00738
00739 FatFsInfo.devdisk.WriteSector(FatFsInfo.FirstFATSector+fatSector, 1, buffer);
00740
00741 return 0;
00742 }
00743
00744 unsigned char* fatGetFatSector(unsigned long fatsector)
00745 {
00746
00747
00748
00749
00750
00751
00752
00753
00754 if(fatsector != FatFsInfo.FatInCache)
00755 {
00756
00757 while (FatFsInfo.devdisk.ReadSector(FatFsInfo.FirstFATSector+fatsector, 1, FatCacheBuffer) != 0);
00758 FatFsInfo.FatInCache = fatsector;
00759 }
00760 return FatCacheBuffer;
00761 }
00762
00763 unsigned long fatClusterToSector(unsigned long cluster)
00764 {
00765 return ((cluster-2) * FatFsInfo.SectorsPerCluster) + FatFsInfo.FirstDataSector;
00766 }
00767
00768 unsigned int fatClusterSize(void)
00769 {
00770
00771 return FatFsInfo.SectorsPerCluster;
00772 }