VLSI Solution Oy VS1103 VLSI Solution Karaoke, MIDI and ADPCM Player Source Code Documentation

Main Page | Class List | File List | Class Members | File Members | Related Pages

filesys.c

Go to the documentation of this file.
00001 
00005 #include "board.h"
00006 #include "filesys.h"
00007 #include "storage.h"
00008 #include "noconsole.h"
00009 #include "mmc.h"
00010 #include "lcd.h"
00011 
00012 /* This needs display to put file name directly to display buffer */
00013 /* It's not pretty but it saves a lot of memory! */
00014 #include "display.h"
00015 
00017 data  unsigned long fatStart;
00019 data unsigned long rootStart;
00023 data unsigned long dataStart;
00025 data unsigned char fatSectorsPerCluster;
00026 
00027 
00029 typedef struct diskInfoStruct {
00031   unsigned long fatStart;
00033   unsigned long rootStart;
00037   unsigned long dataStart;
00039   unsigned char fatSectorsPerCluster;
00040 } diskInfo;
00041 
00042 xdata diskInfo disk[2];
00043 bit currentDisk = 0;
00044 
00046 xdata struct fragmentEntry {
00047   unsigned long start; 
00048   unsigned long length; 
00049 } fragment[MAX_NUMBER_FRAGMENTS];
00050 
00051 xdata struct fragmentEntry midiFragment[MAX_NUMBER_FRAGMENTS];
00052 xdata struct fragmentEntry waveFragment[MAX_NUMBER_FRAGMENTS];
00053 
00054 
00056 xdata unsigned long fileSize;
00057 
00059 #define MAX_NUMBER_SUBDIRECTORIES 5
00060 
00062 xdata struct directoryStack {
00063   unsigned long sector; 
00064   unsigned char entry;  
00065 } dirStack[MAX_NUMBER_SUBDIRECTORIES];
00066 
00068 xdata unsigned char dirLevel = 0;
00069 
00071 xdata unsigned long freeSector = 0;
00072 
00074 xdata char currentFileName[12];
00075 
00077 bit IS_FAT_12 = 0;
00078 
00079 
00081 void PConvertSectorToCluster(unsigned long *sector){
00082   *sector-=dataStart;
00083   *sector/=fatSectorsPerCluster;
00084 }
00085 
00087 void PConvertClusterToSector(unsigned long *cluster){
00088   *cluster*=fatSectorsPerCluster;
00089   *cluster+=dataStart;
00090 }
00091 
00092 
00094 unsigned long GetFatEntry(unsigned long clusterNumber){
00095   unsigned char entryNumber; /* entry number inside page */
00096 
00097   if (!IS_FAT_32){ //FAT16
00098     entryNumber = clusterNumber & 0xff; 
00099     clusterNumber >>= 8; 
00100   }else{ //FAT32
00101     entryNumber = clusterNumber & 0x7f;
00102     clusterNumber >>= 7; 
00103   }
00104   clusterNumber += fatStart;
00105   if (sectorAddress.l != clusterNumber){
00106     sectorAddress.l = clusterNumber;
00107     ReadDiskSector(sectorAddress.l);
00108   }
00109   if (IS_FAT_32){
00110     clusterNumber=diskSect.Fat32Table[entryNumber];
00111     return clusterNumber;
00112   }
00113   if ((clusterNumber=diskSect.Fat16Table[entryNumber])==0xffff) return 0xffffffff;
00114   return clusterNumber;
00115 }
00116 
00117 
00118 
00119 
00139 unsigned char ScanForFreeSector(){
00140   if ((freeSector) && (freeSector-dataStart+1)%fatSectorsPerCluster){
00141     freeSector++;
00142     return 1;
00143   }  
00144   
00145   if (freeSector){
00146     freeSector++;
00147     PConvertSectorToCluster(&freeSector); //Sector converted to cluster
00148   }else{
00149     freeSector=3; //First Cluster# to start search
00150   }
00151 
00152   //scan until free entry is found
00153   while(GetFatEntry(freeSector)){    
00154     freeSector++;
00155   }
00156 
00157   PConvertClusterToSector(&freeSector); //Converted back to sector
00158   return 1;
00159 }
00160 
00161 
00162 #define NEEDEDSIZE 60000
00163 xdata unsigned long freeStart;
00164 xdata unsigned long freeEnd;
00165 
00166 void LocateFreeBlock(){
00167   unsigned long prevFree;
00168   unsigned int neededSize;
00169   
00170   neededSize = NEEDEDSIZE;
00171   freeSector = 0;
00172   ScanForFreeSector();
00173   prevFree = freeSector;
00174   freeStart = freeSector;
00175   while (neededSize--){
00176     ScanForFreeSector();
00177     if (freeSector != (prevFree+1)){ //Gap in free area, restart
00178       freeStart = freeSector;
00179       neededSize = NEEDEDSIZE;
00180     }
00181     prevFree = freeSector;    
00183   }
00184   freeEnd = freeSector; 
00185 
00186   ConsoleWrite("\rFree disk space from ");
00187   ConsolePutUInt(freeStart);
00188   ConsoleWrite(" to ");
00189   ConsolePutUInt(freeEnd);
00190   ConsolePutChar(13);
00191 
00192 }
00193 
00194 
00195 
00196 
00197 
00205 unsigned long GetNextSector(unsigned long currentSector){
00206   addressType fatSector;
00207   unsigned char entryNumber;
00208   
00209   /* how manyth sector from start of data area -> fatsector */
00210   fatSector.l = currentSector - dataStart;
00211   
00212   /* Check for cluster boundary */
00213   /* if we're not in cluster boundary then return currentsector + 1 */
00214   if ((fatSector.b.b0 + 1) % fatSectorsPerCluster){
00215     return currentSector + 1;
00216   }
00217   
00218   /* is the value negative? then return currentSector + 1 */
00219   if (fatSector.b.b3 & 0x80) {
00220     return currentSector + 1;
00221   }    
00222 
00223   /* The trivial conditions are not met, we actually do need to 
00224      look up the next sector info from FAT tables in the disk.*/
00225 
00226   /* convert fatSector from CurrentSectorN to currentClusterN */
00227   fatSector.l /= fatSectorsPerCluster;
00228 
00229   /* calculate which page (fatSector) and entry of FAT table correspond
00230      to current sector */
00231    
00232   if (!IS_FAT_32){ //FAT16
00233     entryNumber = fatSector.b.b0; /* 256 entries / page in FAT16 table */
00234     fatSector.l >>= 8; /* Divide by 256 (n of entries/page in FAT32 table */
00235   }else{ //FAT32
00236     entryNumber =(fatSector.b.b0 & 0x7f); /* 128 entries/page in FAT32 tbl */
00237     fatSector.l >>= 7; /* Divide by 128 (n of entries/sector in FAT32 table */
00238   }
00239   
00240   /* Get sector address for the needed page */
00241   fatSector.l += fatStart;
00242   
00243   /* Load (if needed) table page from disk */
00244   if (sectorAddress.l != fatSector.l){
00245     sectorAddress.l = fatSector.l; /* (not needed because mmc.c does this) */
00246     ReadDiskSector(fatSector.l);
00247     
00248     ConsolePutChar('n');
00249     
00250     
00251   }
00252   /* Now there should be correct FAT entry page in memory... */
00253   
00254   if (!IS_FAT_32){ //FAT16
00255     fatSector.l = diskSect.Fat16Table[entryNumber];
00256     /* Check for FAT16 end-of-file condition */
00257     if ((fatSector.b.b1 == 0xff) && (fatSector.b.b0 == 0xff)){
00258       /* End of file */
00259       fatSector.b.b3 = 0xff; /* return a large value (fat32 compatible) */
00260       return fatSector.l;
00261     }
00262   }else{ //FAT32
00263     fatSector.l = diskSect.Fat32Table[entryNumber] & 0x0fffffff;
00264     /* Check for FAT32 end-of-file condition */
00265     if ((fatSector.b.b3&0x08) //Quick test
00266         && (fatSector.l>0x0ffffff0)){ //Complete test
00267       /* End of file */
00268       return 0xffffffff; /* return EOF*/
00269     }
00270   }
00271   
00272 
00273   /* now fatSector.l contains the proper next cluster value */
00274 
00275   fatSector.l *= fatSectorsPerCluster;
00276   /* now fatSector.l contains the next sector value */
00277 
00278   fatSector.l += dataStart;
00279   /* now fatSector.l contains the proper absolute sector address */
00280 
00281   return fatSector.l;
00282 }
00283 
00284 
00303 Public unsigned char BuildFragmentTable(){
00304 
00305   unsigned char c=0;
00306   addressType this,next;
00307   addressType fatSector;
00308   unsigned char entryNumber;
00309 
00310   // First clear fragment table
00311   for (c=0; c<MAX_NUMBER_FRAGMENTS; c++){
00312     fragment[c].start = 0;
00313     fragment[c].length = 0;
00314   }
00315   c=0;
00316 
00317 
00318   if (IS_FAT_12){
00319     ConsoleWrite("Single fragment support for FAT12");
00320     fragment[0].start = sectorAddress.l;
00321     fragment[0].length = fileSize/512;
00322     return(1); //Return 1 fragment
00323   }
00324 
00325 
00326   //as long as the sectorAddress is "sane"...
00327   while (!(sectorAddress.b.b3 & 0x80)){
00328         
00329     fragment[c].start = sectorAddress.l;
00330     fragment[c].length = fatSectorsPerCluster;
00331     
00332     /* Find cluster entry for the current sector */
00333     
00334     /* in how manyth sector from start of data area are we? ->this */
00335     this.l = sectorAddress.l - dataStart;
00336     /* convert from CurrentSectorN to currentClusterN */
00337     this.l /= fatSectorsPerCluster;
00338     /* this.l is now the current cluster number */
00339     
00340     
00341     /* now let's find the FAT entry for this.l cluster */
00342     if (!IS_FAT_32){ //FAT16
00343       entryNumber = this.b.b0; /* 256 entries / page in FAT16 table */
00344       fatSector.l = this.l >> 8; /* Div by n of entries/page in FAT16 tbl*/
00345     }else{ //FAT32
00346       entryNumber = (this.b.b0 & 0x7f); /* 128 entries/page in FAT32 table */
00347       fatSector.l = this.l >> 7; /* Div by n of entries/page in FAT32 tbl*/
00348     }
00349     fatSector.l += fatStart;
00350     /* fatSector.l is now the DISK SECTOR NUMBER CONTAINING THE FAT table */
00351     /* read this page into memory */
00352     ReadDiskSector(fatSector.l);    
00353     
00354     if (!IS_FAT_32){ //FAT16
00355       next.l = diskSect.Fat16Table[entryNumber]; /* get next cluster n */
00356       /* Check for FAT16 end-of-file condition */
00357       if ((next.b.b1 == 0xff) && (next.b.b0 == 0xff)){
00358         /* FAT16 End of file */
00359         next.b.b3 = 0xff; /* return a large value (fat32 compatible) */
00360       }
00361     }else{ //FAT32
00362       next.l = diskSect.Fat32Table[entryNumber]&0x0fffffff;
00363     }
00364     /* next.l is the FAT entry (next cluster number) */
00365     
00366     
00367     ConsoleWrite("\rFragment start: cluster ");
00368     ConsolePutUInt(this.l);
00369     ConsoleWrite("sector ");
00370     ConsolePutUInt(fragment[c].start);
00371 
00372     while (next.l==(this.l+1)){
00373       //Not a fragment break -- continue to next entry 
00374 
00375       //in this temp.l is used only to allow compiler memory spilling to temp
00376       temp.l = fragment[c].length;
00377       temp.l += fatSectorsPerCluster;
00378       fragment[c].length = temp.l;
00379 
00380       entryNumber++;
00381 
00382       // --- Check for a page break
00383       if (entryNumber==0){ //entryNumber has rolled over!!!! (8bit char)
00384         //FAT16 table page border is reached
00385         fatSector.l++; //Advance to next page;
00386         entryNumber=0;
00387         ReadDiskSector(fatSector.l);
00388       }
00389       if (IS_FAT_32 && (entryNumber==128)){
00390         //FAT32 table page border is reached
00391         fatSector.l++;
00392         entryNumber=0;
00393         ReadDiskSector(fatSector.l);
00394       }
00395       
00396       // --- Advance to next cluster
00397       this.l = next.l;
00398       
00399       if (!IS_FAT_32){
00400         //FAT16 get next cluster n
00401         next.l = diskSect.Fat16Table[entryNumber];       
00402         if ((next.b.b1==0xff)&&(next.b.b0==0xff)){
00403           //FAT16 end-of-file
00404           next.b.b3 = 0xff; //mark end-of-file (FAT32 compatible)
00405         }
00406       }else{
00407         //FAT32 get next cluster n
00408         next.l = diskSect.Fat32Table[entryNumber];
00409       }
00410     }//This repeats until there is a discontinuity
00411     
00412     /* next.l now has the cluster entry for last cluster in fragment
00413        it has a high value if eof (see FAT spec) */
00414 
00415     
00416     ConsoleWrite("Size: ");
00417     ConsolePutUInt(fragment[c].length);
00418     ConsoleWrite("sectors.");
00419 
00420     //EOF test
00421     if ((next.b.b3&0x08) //Quick test
00422         && ((next.l>0x0ffffff0) | !IS_FAT_32)){ //Complete test
00423       //EOF
00424       ConsoleWrite(" <EOF>\r");
00425       sectorAddress.b.b3 = 0xff;
00426     }else{
00427       
00428       //Determine next physical sector for next fragment
00429       sectorAddress.l = next.l;
00430       sectorAddress.l *= fatSectorsPerCluster;
00431       sectorAddress.l += dataStart;
00432     }
00433     
00434     c++; //Advance to next fragment number
00435     
00436     if (c==MAX_NUMBER_FRAGMENTS-1){
00437       //End of RAM space allocated for fragment table
00438       //Force end-of-file
00439       sectorAddress.b.b3=0xff;
00440     }
00441     
00442   }//break or continue to next cluster
00443   
00444 
00445   ConsolePutChar(13);
00446   for (c=0; c<MAX_NUMBER_FRAGMENTS; c++){
00447     ConsolePutUInt(fragment[c].start);
00448     ConsolePutUInt(fragment[c].length);
00449   }
00450   ConsolePutChar(13);
00451 
00452 
00453 
00454 
00455   return c; //Return number of fragments;
00456 }
00457 
00458 
00459 
00461 unsigned char LoadNextSector(){
00462   sectorAddress.l = GetNextSector(sectorAddress.l);
00463   if (sectorAddress.b.b1 & 0x80){
00465     return 0x0d; /*EOF*/
00466   }
00467   if (ReadDiskSector(sectorAddress.l)){
00468     return 0x0d; /*EOF*/
00469   }
00470   return 0; /* All OK return */
00471 }
00472   
00481 Public unsigned char FGetChar(){
00482 
00483   if (!fileSize) return 0; //return 0 for end-of-file
00484 
00485   if (dataBufPtr==0){
00486     /* A file has been opened but not read from yet, so read the first
00487        sector. */
00488     ReadDiskSector(sectorAddress.l);
00489     dataBufPtr = diskSect.raw.buf;
00490   }
00491 
00492   if (dataBufPtr>diskSect.raw.buf+511){
00493     /* An end of sector has been reached, read the next sector */    
00494     if (LoadNextSector()){
00495       /* Error, end-of-file according to FAT records */
00496       return 0; /* must return something */
00497     }
00498     dataBufPtr=diskSect.raw.buf;
00499   }
00500 
00501   /* Everything should now be ok for reading a byte. */
00502 
00503   fileSize--;
00504   return (*dataBufPtr++);
00505 }
00506 
00507 
00508 
00530  unsigned char OpenFile(unsigned int fileNumber,
00531                         unsigned char ext1, 
00532                         unsigned char ext2, 
00533                         unsigned char ext3){
00534   char tempc;
00535 
00536   ConsoleWrite("\rFilesystem: Looking for file ");
00537   ConsolePutUInt(fileNumber);
00538   ConsoleWrite("... ");
00539   
00540   /* Start at the start of root directory. */
00541   dirLevel = 0; /* At root directory */
00542   dirStack[dirLevel].sector=rootStart;
00543   dirStack[dirLevel].entry=0;
00544 
00545 
00546   if (fileNumber==0){
00547     fileNumber = 32766; //use max-1 value for scanning for free entry
00548   }
00549  
00550   while (fileNumber){
00551     ConsolePutChar('f');
00552     if (dirStack[dirLevel].entry==0){
00553       /* At the start of new dir, load first disk sector */
00554       while (ReadDiskSector(dirStack[dirLevel].sector)){
00555         ConsolePutChar('i');
00556         InitMMC;
00557         ConsolePutChar('I');
00558       }
00559     }
00560     temp.c = dirStack[dirLevel].entry;
00561 
00562     /* We are now looking at FAT directory structure. */
00563 
00564     /* Does current entry point to a valid regular file
00565        with the correct first character of extension ? */
00566     /* Attributes: NO directory, NO volume id, NO system, NO hidden */
00567     if (((diskSect.dir[temp.c].entry.Attr & 222) == 0) 
00568         && (diskSect.dir[temp.c].entry.Name[0] != 0xe5) 
00569         && (diskSect.dir[temp.c].entry.Name[8] == ext1)  
00570         && (diskSect.dir[temp.c].entry.Name[9] == ext2)  
00571         && (diskSect.dir[temp.c].entry.Name[10] == ext3)
00572         ){
00573       
00574       /* It is a regular file. */
00575       if (!(--fileNumber)){
00576         
00577         /* ------------ FILE FOUND ------------- */
00578 
00579         sectorAddress.l = 
00580           ((unsigned long)diskSect.dir[temp.c].entry.FstClusHi<<16) 
00581           + diskSect.dir[temp.c].entry.FstClusLo;
00582         sectorAddress.l *= fatSectorsPerCluster;
00583         sectorAddress.l += dataStart;
00584         
00585         fileSize = diskSect.dir[temp.c].entry.FileSize;
00586         dataBufPtr = 0; /* Reset data buffer ptr for FGetChar */
00587 
00588         ConsoleWrite("found, FAT name is \"");
00589         for (tempc=0; tempc<11; tempc++){
00590           ConsolePutChar(diskSect.dir[temp.c].entry.Name[tempc]);
00591         }
00592 
00593         //Store file name nicely for displaying on screen :)
00594         for (tempc=0; tempc<8; tempc++){
00595           currentFileName[tempc]=diskSect.dir[temp.c].entry.Name[tempc];
00596         }
00597         currentFileName[8]='.';
00598         currentFileName[9]=diskSect.dir[temp.c].entry.Name[8];
00599         currentFileName[10]=diskSect.dir[temp.c].entry.Name[9];
00600         currentFileName[11]=diskSect.dir[temp.c].entry.Name[10];
00601 #if 0   
00602         displayText[0]=' ';
00603         for (tempc=0; tempc<12; tempc++){
00604           displayText[tempc+1]=currentFileName[tempc];
00605         }
00606 #endif
00607         ConsoleWrite("\"\rFile size: ");
00608         ConsolePutUInt(fileSize);
00609         ConsoleWrite("bytes. ");
00610 
00611         ConsoleWrite("Start cluster: ");
00612         ConsolePutHex8(diskSect.dir[temp.c].entry.FstClusHi);
00613         ConsolePutHex8(diskSect.dir[temp.c].entry.FstClusLo);
00614         ConsoleWrite("h, sector ");
00615         ConsolePutUInt(sectorAddress.l);
00616         ConsoleWrite("decimal.\r");
00617         
00618         return 0; /* File found, All OK return */
00619       }
00620     } /* it was a regular file */
00621     
00622 
00623 
00624     /* Is it a subdirectory? */
00625     if (((diskSect.dir[temp.c].entry.Attr & 16) != 0) 
00626         && (diskSect.dir[temp.c].entry.Name[0] != '.') /* skip . and .. */ 
00627         && (diskSect.dir[temp.c].entry.Name[0] != 0xe5) 
00628         && (diskSect.dir[temp.c].entry.Name[0] != 0)  ){
00629 
00630       /* It is a subdirectory. */
00631 
00632       if (dirLevel<MAX_NUMBER_SUBDIRECTORIES-1){
00633         /* Yes, we have room in dirStack to traverse deeper. */
00634         dirLevel++; /* Advance to next directory level */       
00635         sectorAddress.l = 
00636           ((unsigned long)diskSect.dir[temp.c].entry.FstClusHi<<16) 
00637           + diskSect.dir[temp.c].entry.FstClusLo;
00638         sectorAddress.l *= fatSectorsPerCluster;
00639         sectorAddress.l += dataStart;
00640       
00641         /* Prepare for loading. */
00642         dirStack[dirLevel].sector = sectorAddress.l;
00643         dirStack[dirLevel].entry = 255; /* Magic number */
00644                 
00645       } /* we had room in dirStack */      
00646     } /* it was a subdirectory */
00647       
00648 
00649     /* Have we reached the end of the directory? */
00650     if (diskSect.dir[temp.c].entry.Name[0] == 0){
00651       /* It's the end of directory. */
00652 
00653       /* Is it the end of root directory? */
00654       if (dirLevel == 0){
00655         /* End of root directory, end of all files in volume */
00656         ConsoleWrite("File not found.\r");
00657         sectorAddress.l = dataStart; 
00658         /* when in error point to start of data */
00659         return 0x0c; /* File Not Found return */
00660       } 
00661 
00662       /* End of subdirectory, return from subdirectory */
00663       dirLevel--;
00664       ReadDiskSector(dirStack[dirLevel].sector);
00665       /* restore temp entry pointer */
00666       temp.c = dirStack[dirLevel].entry;
00667 
00668     } /* it was end of directory */
00669 
00670 
00671     /* Advance to next entry */
00672     temp.c++;
00673     
00674     /* If we just went to a subdir, set temp entry pointer to 0 */
00675     if (dirStack[dirLevel].entry == 255){
00676       /* Magic Number 255: we have gone to a subdirectory */
00677       temp.c=0;
00678     }
00679       
00680     if (temp.c==16){ /* End of sector */
00681       /* Prepare to load next sector */
00682       dirStack[dirLevel].sector = GetNextSector (dirStack[dirLevel].sector);
00683       temp.c=0;
00684     }
00685 
00686     dirStack[dirLevel].entry = temp.c;
00687   }
00688 
00689   /* Control should never reach this far, end of root directory should
00690      occur first. */
00691 
00692   sectorAddress.l = dataStart; /* when in error point to start of data */
00693   return 0x0c; /* File Not Found return */
00694 }
00695 
00696 
00697 
00700 unsigned char FatInitGlobals(){
00701 
00702   ConsoleWrite("Formatter signature:");
00703   for (temp.c=0; temp.c<8; temp.c++){
00704     ConsolePutChar(diskSect.fat.BS_OEMName[temp.c]);
00705   }
00706   ConsoleWrite("\rBytes per sector: ");
00707   ConsolePutUInt(diskSect.fat.BPB_BytsPerSec);
00708   ConsoleWrite("\rSectors per Cluster: ");
00709   ConsolePutUInt(diskSect.fat.BPB_SecPerClus);
00710   ConsoleWrite("\rReserved sectors: ");
00711   ConsolePutUInt(diskSect.fat.BPB_RsvdSecCnt);
00712   ConsoleWrite("\rNumber of FATs: ");
00713   ConsolePutUInt(diskSect.fat.BPB_NumFATs);
00714   ConsoleWrite("\rRoot entries: ");
00715   ConsolePutUInt(diskSect.fat.BPB_RootEntCnt);
00716   ConsoleWrite("\rTotal Sectors 16: ");
00717   ConsolePutUInt(diskSect.fat.BPB_TotSec16);
00718   ConsoleWrite("\rFat Size 16: ");
00719   ConsolePutUInt(diskSect.fat.BPB_FATSz16);
00720   ConsoleWrite("\rHidden Sectors: ");
00721   ConsolePutUInt(diskSect.fat.BPB_HiddSec);
00722   ConsoleWrite("\rTotal Sectors 32: ");
00723   ConsolePutUInt(diskSect.fat.BPB_TotSec32);
00724   
00725 
00726 
00727   /* Determine FAT Type (16/32) */
00728   /* This should be done better, but it'll do for now. */
00729   IS_FAT_32 = 1;
00730   if (diskSect.fat.BPB_RootEntCnt) 
00731     IS_FAT_32 = 0; /* FAT32 does not have separate root entries. */
00732   
00733   ConsoleWrite("\rFile system is ");
00734   if (IS_FAT_32){
00735     ConsoleWrite("FAT32");
00736   } else {
00737     ConsoleWrite("FAT16");
00738   }
00739 
00740   ConsoleWrite("\rFile system signature is ");
00741   for (temp.c=0;temp. c<8; temp.c++)
00742     if (IS_FAT_32){
00743       ConsolePutChar(diskSect.fat.ext._32.BS_FilSysType[temp.c]);
00744     } else {
00745       ConsolePutChar(diskSect.fat.ext._16.BS_FilSysType[temp.c]);
00746     }
00747 
00748   if (!IS_FAT_32){
00749     if (diskSect.fat.ext._16.BS_FilSysType[4]=='2'){
00750       IS_FAT_12 = 1;
00751       ConsoleWrite("Well, actually it's FAT12 filesystem.\r");
00752     }
00753   }    
00754   
00755 
00756   ConsoleWrite("\rVolume Label is ");
00757   for (temp.c=0; temp.c<11; temp.c++)
00758     if (IS_FAT_32){
00759       ConsolePutChar(diskSect.fat.ext._32.BS_VolLab[temp.c]);
00760     } else {
00761       ConsolePutChar(diskSect.fat.ext._16.BS_VolLab[temp.c]);
00762     }
00763   /* OK, let's calculate */
00764   /* First, let's get rid of the idea that we have byte addresses
00765      in the file system. Nope, let's only deal in physical disk
00766      sectors of 512 bytes. First we convert the FAT byter per sector
00767      value to "512B disk sectors per fat sector" value. */
00768 
00769   diskSect.fat.BPB_BytsPerSec /= 512;
00770 
00771   /* Then we adjust the Sector per Cluster to mean physical disk
00772      sectors. in 99% of the cases it is already so because bytes
00773      per sector almost always is 512 in FAT. Maximum cluster size
00774      is 65536 bytes (128 disk sectors). */
00775 
00776   fatSectorsPerCluster =
00777     diskSect.fat.BPB_SecPerClus *= diskSect.fat.BPB_BytsPerSec;
00778   /* Note: BPB_BytsPerSec has already been divided by 512 */  
00779 
00780   ConsoleWrite("\rSectors per Cluster: ");
00781   ConsolePutUInt(fatSectorsPerCluster);
00782   
00783   fatStart = (unsigned long)sectorAddress.l
00784     + (unsigned long)diskSect.fat.BPB_RsvdSecCnt 
00785     * (unsigned long)diskSect.fat.BPB_BytsPerSec;
00786 
00787   ConsoleWrite("\rFAT Start sector: ");
00788   ConsolePutUInt(fatStart);
00789 
00790   rootStart = diskSect.fat.BPB_FATSz16;
00791   if (rootStart==0){
00792     if (!IS_FAT_32) 
00793       return 0x0b; /* should be FAT32; can not find root directory */
00794     rootStart = diskSect.fat.ext._32.BPB_FATSz32;
00795   }
00796   rootStart *= diskSect.fat.BPB_NumFATs;
00797   rootStart *= diskSect.fat.BPB_BytsPerSec; /* ADJUSTED BytsPerSec! */
00798   rootStart += fatStart;
00799 
00800   ConsoleWrite("\rRoot start sector: ");
00801   ConsolePutUInt(rootStart);
00802 
00803   dataStart = diskSect.fat.BPB_RootEntCnt >> 4;
00804   dataStart += rootStart;
00805   dataStart -= (fatSectorsPerCluster*2); /*first cluster is cluster 2*/
00806 
00807   ConsoleWrite("\rData start sector: ");
00808   ConsolePutUInt(dataStart);
00809   ConsolePutChar(13);
00810 
00811   return 0;
00812 }
00813 
00817 unsigned char SelectDisk(unsigned char n){
00818   unsigned char oldDisk;
00819   if (n>1) return 1;
00820   oldDisk = currentDisk;
00821 
00822   disk[oldDisk].fatStart = fatStart;
00823   disk[oldDisk].rootStart = rootStart; 
00824   disk[oldDisk].dataStart = dataStart; 
00825   disk[oldDisk].fatSectorsPerCluster = fatSectorsPerCluster;
00826   
00827   fatStart = disk[n].fatStart;
00828   rootStart = disk[n].rootStart;
00829   dataStart = disk[n].dataStart;
00830   fatSectorsPerCluster = disk[n].fatSectorsPerCluster;
00831   if (n==0) {
00832     currentDisk = 0;
00833   }else{
00834     currentDisk = 1;
00835   }
00836   return 0;
00837 }
00838 
00839 
00840 
00841 unsigned char RealInitFileSystem(){
00842   unsigned char c;
00843   
00844   /* Initialize variables to sane values in case of error exit. */
00845   fatStart = 0;
00846   rootStart = 0;
00847   dataStart = 0;
00848   freeSector = 0;
00849 
00850 
00851   ConsoleWrite("Init: Filesystem; supports: MBR, FAT16, FAT32\r");
00852 
00853   ConsoleWrite("Trying to bring up storage...\r");
00854   /* Initialize the storage system */
00855   if ((c=InitStorage())){
00856     ConsoleWrite("Storage init returns error ");
00857     ConsolePutUInt(c);
00858     ConsolePutChar(13);
00859     return c; /* Error in InitStorage */
00860   }
00861 
00862   ConsoleWrite("Storage ok.\rSector 0 read...");
00863 
00864   /* Load MBR */
00865   sectorAddress.l = 0; /* the first sector on disk */
00866   ReadDiskSector(0);
00867 
00868 
00869 
00870 
00871   ConsoleWrite("ok.\rSector signature...");
00872   
00873   /* Ok, it should be a MBR sector. Let's verify */
00874   if (diskSect.raw.buf[510] != 0x55)
00875     return 8; /* sector 0 is not MBR. */
00876   if (diskSect.raw.buf[511] != 0xaa)
00877     return 8; /* sector 0 is not MBR. */
00878 
00879   ConsoleWrite("ok.\rPartition 1...");
00880 
00881 
00882   if (!((diskSect.raw.buf[0x036]=='F')
00883       &&(diskSect.raw.buf[0x037]=='A')
00884       &&(diskSect.raw.buf[0x038]=='T'))){
00885    
00886     /* This checks that partition 1 is active. Alter code to allow
00887      * other partition configurations. */
00888     if (diskSect.raw.buf[0x1be] == 0x80){
00889       sectorAddress.b.b0 = diskSect.raw.buf[0x1c6];
00890       sectorAddress.b.b1 = diskSect.raw.buf[0x1c7];
00891       sectorAddress.b.b2 = diskSect.raw.buf[0x1c8];
00892       sectorAddress.b.b3 = diskSect.raw.buf[0x1c9];
00893       ConsoleWrite (" active");
00894     }else{
00895       //-------- DEBUG: Uncomment if you want to explore the sector
00896       //DumpDiskSector();
00897       //while (!KEY_BUTTON);
00898       sectorAddress.b.b0 = diskSect.raw.buf[0x1c6];
00899       sectorAddress.b.b1 = diskSect.raw.buf[0x1c7];
00900       sectorAddress.b.b2 = diskSect.raw.buf[0x1c8];
00901       sectorAddress.b.b3 = diskSect.raw.buf[0x1c9];
00902             
00903     }
00904     
00905     //    return 9; /* No active partition*/
00906     
00907   }
00908   
00909   ConsoleWrite(" at sector ");
00910   ConsolePutHex8(sectorAddress.b.b3);
00911   ConsolePutHex8(sectorAddress.b.b2);
00912   ConsolePutHex8(sectorAddress.b.b1);
00913   ConsolePutHex8(sectorAddress.b.b0);
00914   ConsolePutChar('\r');
00915 
00916 
00917   /* Now leave MBR and load sector 0 of partition */
00918   //SeekDiskSectorToRead();
00919   //ReadDiskSector(); /* to global buffer */
00920   
00921   ReadDiskSector(sectorAddress.l);
00922 
00923   if (FatInitGlobals()){
00924     return 0x0a; /* FAT init failed */
00925   }
00926 
00927   return 0; /* All ok return */
00928 
00929 }
00930 
00931 unsigned char InitFileSystem(){
00932   currentDisk = 0;
00933   SelectDisk(0);
00934   LcdReset();
00935   LcdPutConstantString("Insert Card for Drive A:");
00936   RealInitFileSystem();
00937   SelectDisk(1);
00938   LcdLocateHome();
00939   LcdPutConstantString("Insert Card for Drive B:");
00940   RealInitFileSystem();
00941   LcdReset();
00942   SelectDisk(0);
00943   return 0;
00944 }
00945 
00946 
00947 
00948 

All software copyright 2000-2004 VLSI Solution OY. Redistribution of these software modules is limited to VLSI Solution Oy chip promotional use only. Free or commercial use of these software modules in MP3 players is ok if the product includes chip(s) from VLSI. You can request the complete (compilable) package from mp3@vlsi.fi. This exampe code is provided with good faith to assist You in code development, but under no circumstances will VLSI offer any guarantees on the usability or functionality of any example software or its fitness for any purpose.