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