MPFS2.c

Go to the documentation of this file.
00001 
00002 
00003 
00023 /*********************************************************************
00024  * Software License Agreement
00025  *
00026  * Copyright (C) 2002-2008 Microchip Technology Inc.  All rights 
00027  * reserved.
00028  *
00029  * Microchip licenses to you the right to use, modify, copy, and 
00030  * distribute: 
00031  * (i)  the Software when embedded on a Microchip microcontroller or 
00032  *      digital signal controller product ("Device") which is 
00033  *      integrated into Licensee's product; or
00034  * (ii) ONLY the Software driver source files ENC28J60.c and 
00035  *      ENC28J60.h ported to a non-Microchip device used in 
00036  *      conjunction with a Microchip ethernet controller for the 
00037  *      sole purpose of interfacing with the ethernet controller. 
00038  *
00039  * You should refer to the license agreement accompanying this 
00040  * Software for additional information regarding your rights and 
00041  * obligations.
00042  *
00043  * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT 
00044  * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT 
00045  * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A 
00046  * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL 
00047  * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR 
00048  * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF 
00049  * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS 
00050  * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE 
00051  * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER 
00052  * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT 
00053  * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
00054  *
00055  *
00056  * Author               Date        Comment
00057  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00058  * Elliott Wood         07/2007     Complete rewrite as MPFS2
00059  * E. Wood              04/2008     Updated as MPFS2.1
00060  ********************************************************************/
00061 #define __MPFS2_C
00062 
00063 #include "TCPIP.h"
00064 
00065 #if defined(STACK_USE_MPFS2)
00066 
00067 // MODIFIX: Added inlude for huffman decoding support:
00068 #include "huffman.h"
00069 
00070 
00071 //Supports long file names to 64 characters
00072 #define MAX_FILE_NAME_LEN   (64u)
00073 
00074 /*
00075  * MPFS Structure:
00076  *     [M][P][F][S]
00077  *     [BYTE Ver Hi][BYTE Ver Lo][WORD Number of Files]
00078  *     [Name Hash 0][Name Hash 1]...[Name Hash N]
00079  *     [File Record 0][File Record 1]...[File Record N]
00080  *     [String 0][String 1]...[String N]
00081  *     [File Data 0][File Data 1]...[File Data N]
00082  *
00083  * Name Hash (2 bytes):
00084  *     hash = 0
00085  *     for each(byte in name)
00086  *         hash += byte
00087  *         hash <<= 1
00088  *
00089  *     Technically this means the hash only includes the 
00090  *     final 15 characters of a name.
00091  *
00092  * File Record Structure (22 bytes):
00093  *     [DWORD String Ptr][DWORD Data Ptr]
00094  *     [DWORD Len][DWORD Timestamp][DWORD Microtime]
00095  *     [WORD Flags]
00096  *
00097  *     Pointers are absolute addresses within the MPFS image.
00098  *     Timestamp is the UNIX timestamp
00099  *     Microtime is currently unimplemented
00100  *
00101  * String Structure (1 to 64 bytes):
00102  *     ["path/to/file.ext"][0x00]
00103  *
00104  * File Data Structure (arbitrary length):
00105  *      [File Data]
00106  *
00107  * Unlike previous versions, there are no delimiters.
00108  *
00109  * Name hash is calculated as follows:
00110  *      hash = 0
00111  *      for each(byte in name)
00112  *          hash += byte, hash <<= 1
00113  *
00114  * When a file has an index, that index file has no file name,
00115  * but is accessible as the file immediately following in the image.
00116  *
00117  * Current version is 2.1
00118  */
00119 
00120 /****************************************************************************
00121   Section:
00122     Module-Only Globals and Functions
00123   ***************************************************************************/
00124   
00125 // Track the MPFS File Handles
00126 // MPFSStubs[0] is reserved for internal use (FAT access)
00127 static MPFS_STUB MPFSStubs[MAX_MPFS_HANDLES+1];
00128 
00129 // Allows the MPFS to be locked, preventing access during updates
00130 static BOOL isMPFSLocked;
00131 
00132 // FAT record cache
00133 static MPFS_FAT_RECORD fatCache;
00134 
00135 // ID of currently loaded fatCache
00136 static WORD fatCacheID;
00137 
00138 // Number of files in this MPFS image
00139 static WORD numFiles;
00140 
00141 
00142 static void _LoadFATRecord(WORD fatID);
00143 static void _Validate(void);
00144 
00145 /****************************************************************************
00146   Section:
00147     EEPROM vs Flash Storage Settings
00148   ***************************************************************************/
00149   
00150 #if defined(MPFS_USE_EEPROM)
00151 
00152     // Beginning address of MPFS Image
00153     #define MPFS_HEAD       MPFS_RESERVE_BLOCK
00154 
00155     // Track the last read address to prevent unnecessary
00156     // data overhead to switch locations.
00157     MPFS_PTR lastRead;
00158 
00159 
00160 #elif defined(MPFS_USE_SPI_FLASH)
00161 
00162     // Beginning address of MPFS Image
00163     #define MPFS_HEAD       MPFS_RESERVE_BLOCK
00164     
00165 #else
00166 
00167     // An address where MPFS data starts in program memory.
00168     #if defined(__18CXX) || defined(__C32__)
00169         extern ROM BYTE MPFS_Start[];
00170         #define MPFS_HEAD       ((DWORD)(&MPFS_Start[0]))
00171     #else
00172         extern DWORD MPFS_Start;
00173         #define MPFS_HEAD       MPFS_Start;
00174     #endif
00175     
00176 #endif
00177 
00178 /****************************************************************************
00179   Section:
00180     Stack-Level Functions
00181   ***************************************************************************/
00182 
00183 /*****************************************************************************
00184   Function:
00185     void MPFSInit(void)
00186 
00187   Summary:
00188     Initializes the MPFS module.
00189 
00190   Description:
00191     Sets all MPFS handles to closed, and initializes access to the EEPROM
00192     if necessary.
00193 
00194   Precondition:
00195     None
00196 
00197   Parameters:
00198     None
00199 
00200   Returns:
00201     None
00202     
00203   Remarks:
00204     This function is called only one during lifetime of the application.
00205   ***************************************************************************/
00206 void MPFSInit(void)
00207 {
00208     BYTE i;
00209     
00210     for(i = 1; i <= MAX_MPFS_HANDLES; i++)
00211     {
00212         MPFSStubs[i].addr = MPFS_INVALID;
00213     }
00214     
00215     #if defined(MPFS_USE_EEPROM)
00216     // Initialize the EEPROM access routines.
00217     XEEInit();
00218     lastRead = MPFS_INVALID;
00219     #endif
00220     
00221     #if defined(MPFS_USE_SPI_FLASH)
00222     // Initialize SPI Flash access routines.
00223     SPIFlashInit();
00224     #endif
00225 
00226     // Validate the image and load numFiles
00227     _Validate();
00228 
00229     isMPFSLocked = FALSE;
00230 
00231 }
00232 
00233 /****************************************************************************
00234   Section:
00235     Handle Management Functions
00236   ***************************************************************************/
00237 
00238 /*****************************************************************************
00239   Function:
00240     MPFS_HANDLE MPFSOpen(BYTE* cFile)
00241 
00242   Description:
00243     Opens a file in the MPFS2 file system.
00244     
00245   Precondition:
00246     None
00247 
00248   Parameters:
00249     cFile - a null terminated file name to open
00250 
00251   Returns:
00252     An MPFS_HANDLE to the opened file if found, or MPFS_INVALID_HANDLE
00253     if the file could not be found or no free handles exist.
00254   ***************************************************************************/
00255 MPFS_HANDLE MPFSOpen(BYTE* cFile)
00256 {
00257     MPFS_HANDLE hMPFS;
00258     WORD nameHash, i;
00259     WORD hashCache[8];
00260     BYTE *ptr, c;
00261     
00262     // Initialize c to avoid "may be used uninitialized" compiler warning
00263     c = 0;
00264     
00265     // Make sure MPFS is unlocked and we got a filename
00266     if(*cFile == '\0' || isMPFSLocked == TRUE)
00267         return MPFS_INVALID_HANDLE;
00268 
00269     // Calculate the name hash to speed up searching
00270     for(nameHash = 0, ptr = cFile; *ptr != '\0'; ptr++)
00271     {
00272         nameHash += *ptr;
00273         nameHash <<= 1;
00274     }
00275     
00276     // Find a free file handle to use
00277     for(hMPFS = 1; hMPFS <= MAX_MPFS_HANDLES; hMPFS++)
00278         if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
00279             break;
00280     if(hMPFS == MAX_MPFS_HANDLES)
00281         return MPFS_INVALID_HANDLE;
00282         
00283     // Read in hashes, and check remainder on a match.  Store 8 in cache for performance
00284     for(i = 0; i < numFiles; i++)
00285     {
00286         // For new block of 8, read in data
00287         if((i & 0x07) == 0)
00288         {
00289             MPFSStubs[0].addr = 8 + i*2;
00290             MPFSStubs[0].bytesRem = 16;
00291             MPFSGetArray(0, (BYTE*)hashCache, 16);
00292         }
00293         
00294         // If the hash matches, compare the full filename
00295         if(hashCache[i&0x07] == nameHash)
00296         {
00297             _LoadFATRecord(i);
00298             MPFSStubs[hMPFS].addr = fatCache.string;
00299             MPFSStubs[hMPFS].bytesRem = 255;
00300             MPFSStubs[hMPFS].offset = 0;    // MODIFIX: Added for huffman decoding.
00301 
00302             // Loop over filename to perform comparison
00303             for(ptr = cFile; *ptr != '\0'; ptr++)
00304             {
00305                 MPFSGet(hMPFS, &c);
00306                 if(*ptr != c)
00307                     break;
00308             }
00309             
00310             MPFSGet(hMPFS, &c);
00311 
00312             if(c == '\0' && *ptr == '\0')
00313             {// Filename matches, so return true
00314                 MPFSStubs[hMPFS].addr = fatCache.data;
00315                 MPFSStubs[hMPFS].bytesRem = fatCache.len;
00316                 MPFSStubs[hMPFS].fatID = i;
00317                 
00318                 // MODIFIX: Added the following lines for huffman encoding support.
00319                 if (fatCache.flags & MPFS2_FLAG_ISCOMPRESSED)
00320                 {
00321                     MPFSStubs[hMPFS].offset = 0x01;
00322                 }
00323                 else
00324                 {
00325                     MPFSStubs[hMPFS].offset = 0;
00326                 }
00327                 // MODIFIX: END
00328 
00329                 return hMPFS;
00330             }
00331         }
00332     }
00333     
00334     // No file name matched, so return nothing
00335     return MPFS_INVALID_HANDLE;
00336 }
00337 
00338 /*****************************************************************************
00339   Function:
00340     MPFS_HANDLE MPFSOpenROM(ROM BYTE* cFile) 
00341 
00342   Description:
00343     Opens a file in the MPFS2 file system.
00344     
00345   Precondition:
00346     None
00347 
00348   Parameters:
00349     cFile - a null terminated file name to open
00350 
00351   Returns:
00352     An MPFS_HANDLE to the opened file if found, or MPFS_INVALID_HANDLE
00353     if the file could not be found or no free handles exist.
00354 
00355   Remarks:
00356     This function is aliased to MPFSOpen on non-PIC18 platforms.
00357   ***************************************************************************/
00358 #if defined(__18CXX)
00359 MPFS_HANDLE MPFSOpenROM(ROM BYTE* cFile) 
00360 {
00361     MPFS_HANDLE hMPFS;
00362     WORD nameHash, i;
00363     WORD hashCache[8];
00364     ROM BYTE *ptr;
00365     BYTE c;
00366     
00367     // Make sure MPFS is unlocked and we got a filename
00368     if(*cFile == '\0' || isMPFSLocked == TRUE)
00369         return MPFS_INVALID_HANDLE;
00370 
00371     // Calculate the name hash to speed up searching
00372     for(nameHash = 0, ptr = cFile; *ptr != '\0'; ptr++)
00373     {
00374         nameHash += *ptr;
00375         nameHash <<= 1;
00376     }
00377     
00378     // Find a free file handle to use
00379     for(hMPFS = 1; hMPFS <= MAX_MPFS_HANDLES; hMPFS++)
00380         if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
00381             break;
00382     if(hMPFS == MAX_MPFS_HANDLES)
00383         return MPFS_INVALID_HANDLE;
00384         
00385     // Read in hashes, and check remainder on a match.  Store 8 in cache for performance
00386     for(i = 0; i < numFiles; i++)
00387     {
00388         // For new block of 8, read in data
00389         if((i & 0x07) == 0)
00390         {
00391             MPFSStubs[0].addr = 8 + i*2;
00392             MPFSStubs[0].bytesRem = 16;
00393             MPFSGetArray(0, (BYTE*)hashCache, 16);
00394         }
00395         
00396         // If the hash matches, compare the full filename
00397         if(hashCache[i&0x07] == nameHash)
00398         {
00399             _LoadFATRecord(i);
00400             MPFSStubs[hMPFS].addr = fatCache.string;
00401             MPFSStubs[hMPFS].bytesRem = 255;
00402             MPFSStubs[hMPFS].offset = 0;    // MODIFIX: Added for huffman decoding.
00403 
00404             // Loop over filename to perform comparison
00405             for(ptr = cFile; *ptr != '\0'; ptr++)
00406             {
00407                 MPFSGet(hMPFS, &c);
00408                 if(*ptr != c)
00409                     break;
00410             }
00411             
00412             MPFSGet(hMPFS, &c);
00413 
00414             if(c == '\0' && *ptr == '\0')
00415             {// Filename matches, so return true
00416                 MPFSStubs[hMPFS].addr = fatCache.data;
00417                 MPFSStubs[hMPFS].bytesRem = fatCache.len;
00418                 MPFSStubs[hMPFS].fatID = i;
00419 
00420                 // MODIFIX: Added the following lines for huffman encoding support.
00421                 if (fatCache.flags & MPFS2_FLAG_HASINDEX)
00422                 {
00423                     MPFSStubs[hMPFS].offset = 0x01;
00424                 }
00425                 else
00426                 {
00427                     MPFSStubs[hMPFS].offset = 0;
00428                 }
00429                 // MODIFIX: END
00430 
00431                 return hMPFS;
00432             }
00433         }
00434     }
00435     
00436     // No file name matched, so return nothing
00437     return MPFS_INVALID_HANDLE;
00438 }
00439 #endif
00440 
00441 /*****************************************************************************
00442   Function:
00443     MPFS_HANDLE MPFSOpenID(WORD hFatID)
00444 
00445   Summary:
00446     Quickly re-opens a file.
00447 
00448   Description:
00449     Quickly re-opens a file in the MPFS2 file system.  Use this function
00450     along with MPFSGetID() to quickly re-open a file without tying up
00451     a permanent MPFSStub.
00452     
00453   Precondition:
00454     None
00455 
00456   Parameters:
00457     hFatID - the ID of a previous opened file in the FAT
00458 
00459   Returns:
00460     An MPFS_HANDLE to the opened file if found, or MPFS_INVALID_HANDLE
00461     if the file could not be found or no free handles exist.
00462   ***************************************************************************/
00463 MPFS_HANDLE MPFSOpenID(WORD hFatID)
00464 {
00465     MPFS_HANDLE hMPFS;
00466     
00467     // Make sure MPFS is unlocked and we got a valid id
00468     if(isMPFSLocked == TRUE || hFatID > numFiles)
00469         return MPFS_INVALID_HANDLE;
00470 
00471     // Find a free file handle to use
00472     for(hMPFS = 1; hMPFS <= MAX_MPFS_HANDLES; hMPFS++)
00473         if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
00474             break;
00475     if(hMPFS == MAX_MPFS_HANDLES)
00476         return MPFS_INVALID_HANDLE;
00477     
00478     // Load the FAT record
00479     _LoadFATRecord(hFatID);
00480         
00481     // Set up the file handle
00482     MPFSStubs[hMPFS].fatID = hFatID;
00483     MPFSStubs[hMPFS].addr = fatCache.data;
00484     MPFSStubs[hMPFS].bytesRem = fatCache.len;
00485     
00486 
00487     // MODIFIX: Added the following lines for huffman encoding support.
00488     if (fatCache.flags & MPFS2_FLAG_HASINDEX)
00489     {
00490         MPFSStubs[hMPFS].offset = 0x01;
00491     }
00492     else
00493     {
00494         MPFSStubs[hMPFS].offset = 0;
00495     }
00496     // MODIFIX: END
00497 
00498 
00499     return hMPFS;
00500 }
00501 
00502 /*****************************************************************************
00503   Function:
00504     void MPFSClose(MPFS_HANDLE hMPFS)
00505 
00506   Summary:
00507     Closes a file.
00508 
00509   Description:
00510     Closes a file and releases its stub back to the pool of available 
00511     handles.
00512     
00513   Precondition:
00514     None
00515 
00516   Parameters:
00517     hMPFS - the file handle to be closed
00518 
00519   Returns:
00520     None
00521   ***************************************************************************/
00522 void MPFSClose(MPFS_HANDLE hMPFS)
00523 {
00524     if(hMPFS != 0u && hMPFS <= MAX_MPFS_HANDLES)
00525         MPFSStubs[hMPFS].addr = MPFS_INVALID;
00526 }
00527 
00528 
00529 /****************************************************************************
00530   Section:
00531     Data Reading Functions
00532   ***************************************************************************/
00533 
00534 // MODIFIX: Added the following function!
00535 void MPFSGetArrayHuffman(MPFS_HANDLE hMPFS, BYTE* cData, WORD wLen)
00536 {
00537     BYTE currentValue;
00538     BYTE offset = MPFSStubs[hMPFS].offset;
00539     ROM BYTE* addr;
00540     BYTE bytesRead = 0;
00541 
00542     MPFSStubs[hMPFS].bytesRem -= wLen;
00543     addr = (ROM BYTE*)(MPFSStubs[hMPFS].addr + MPFS_HEAD);
00544     currentValue = *addr;
00545 
00546     while(wLen)
00547     {
00548         HUFFMAN_CODE_TYPE mask = MAX_HUFFMAN_CODE_MASK;
00549         HUFFMAN_CODE_TYPE code = 0;
00550         BYTE codeLength = 1;
00551         BYTE codeIndex = 0;
00552 
00553         while(1)
00554         {
00555             if (offset & currentValue)
00556             {
00557                 code |= mask;
00558             }
00559     
00560             offset = offset << 1;
00561             if (offset == 0)
00562             {
00563                 addr++;
00564                 currentValue = *addr;
00565                 bytesRead++;
00566                 offset = 0x01;
00567             }
00568     
00569     
00570             if (HuffmanCode[codeIndex].CodeLength == codeLength)
00571             {
00572                 if (HuffmanCode[codeIndex].StartCode <= code)
00573                 {
00574                     break;
00575                 }
00576     
00577                 codeIndex++;
00578             }
00579     
00580     
00581             codeLength++;
00582             mask = mask >> 1; 
00583         }
00584 
00585 
00586         if (cData)
00587         {
00588             // Fetch the character from the table:
00589             BYTE index = HuffmanCode[codeIndex].CharacterIndex;
00590             code = (code - HuffmanCode[codeIndex].StartCode);
00591             
00592             while(code)
00593             {
00594                 code -= mask;
00595                 index++;
00596             }
00597     
00598             *cData = HuffmanCharacter[index];
00599             cData++;
00600         }
00601 
00602         wLen--;
00603     }
00604 
00605 
00606     MPFSStubs[hMPFS].offset = offset;
00607     MPFSStubs[hMPFS].addr += bytesRead;
00608 }
00609 // MODIFIX: END
00610 
00611 
00612 /*****************************************************************************
00613   Function:
00614     BOOL MPFSGet(MPFS_HANDLE hMPFS, BYTE* c)
00615 
00616   Description:
00617     Reads a byte from a file.
00618     
00619   Precondition:
00620     The file handle referenced by hMPFS is already open.
00621 
00622   Parameters:
00623     hMPFS - the file handle from which to read
00624     c - Where to store the byte that was read
00625 
00626   Return Values:
00627     TRUE - The byte was successfully read
00628     FALSE - No byte was read because either the handle was invalid or
00629             the end of the file has been reached.
00630   ***************************************************************************/
00631 BOOL MPFSGet(MPFS_HANDLE hMPFS, BYTE* c)
00632 {
00633     // Make sure we're reading a valid address
00634     if(hMPFS > MAX_MPFS_HANDLES)
00635         return FALSE;
00636     if( MPFSStubs[hMPFS].addr == MPFS_INVALID ||
00637         MPFSStubs[hMPFS].bytesRem == 0u)
00638         return FALSE;
00639 
00640     // MODIFIX: Added the following lines for huffman decoding support:
00641     if (MPFSStubs[hMPFS].offset)
00642     {
00643         MPFSGetArrayHuffman(hMPFS, c, 1);
00644         return TRUE;
00645     }
00646     // MODIFIX: END
00647 
00648     if(c == NULL)
00649     {
00650         MPFSStubs[hMPFS].addr++;
00651         MPFSStubs[hMPFS].bytesRem--;
00652         return TRUE;
00653     }
00654 
00655 
00656     // Read function for EEPROM
00657     #if defined(MPFS_USE_EEPROM)
00658         // For performance, cache the last read address
00659         if(MPFSStubs[hMPFS].addr != lastRead+1)
00660             XEEBeginRead(MPFSStubs[hMPFS].addr + MPFS_HEAD);
00661         *c = XEERead();
00662         lastRead = MPFSStubs[hMPFS].addr;
00663         MPFSStubs[hMPFS].addr++;
00664     #elif defined(MPFS_USE_SPI_FLASH)
00665         SPIFlashReadArray(MPFSStubs[hMPFS].addr + MPFS_HEAD, c, 1);
00666         MPFSStubs[hMPFS].addr++;
00667     #else
00668         #if defined(__C30__)
00669         {
00670             DWORD addr;
00671             DWORD_VAL read;
00672             BYTE i;
00673     
00674             // MPFS Images are addressed by the byte; Program memory by the word.
00675             //
00676             // Flash program memory is 24 bits wide and only even words are
00677             // implemented.  The upper byte of the upper word is read as 0x00.
00678             // Address in program memory of any given byte is (MPFSAddr * 2) / 3
00679             //
00680             // We will read 24 bits at a time, but need to support using only 
00681             // fractions of the first and last byte.
00682             
00683             // Find the beginning address in program memory.
00684             addr = (MPFSStubs[hMPFS].addr / 3) << 1;
00685             
00686             // Find where to start in that first 3 bytes
00687             read.Val = (addr * 3) >> 1;
00688             if(read.Val == MPFSStubs[hMPFS].addr)
00689                 i = 0;
00690             else if(read.Val+1 == MPFSStubs[hMPFS].addr)
00691                 i = 1;
00692             else
00693                 i = 2;
00694     
00695             // Add in the MPFS starting address offset
00696             addr += MPFS_HEAD;
00697             
00698             // Update the MPFS Handle
00699             MPFSStubs[hMPFS].addr++;
00700             
00701             // Read the DWORD 
00702             read.Val = ReadProgramMemory(addr & 0x00FFFFFF);
00703             *c = read.v[i];
00704             
00705         }
00706         #else
00707         {
00708             DWORD dwHITECHWorkaround = MPFS_HEAD;
00709         *c = *((ROM BYTE*)(MPFSStubs[hMPFS].addr+dwHITECHWorkaround));
00710             MPFSStubs[hMPFS].addr++;
00711         }
00712         #endif
00713     #endif
00714     
00715     MPFSStubs[hMPFS].bytesRem--;
00716     return TRUE;
00717 }
00718 
00719 /*****************************************************************************
00720   Function:
00721     WORD MPFSGetArray(MPFS_HANDLE hMPFS, BYTE* cData, WORD wLen)
00722 
00723   Description:
00724     Reads a series of bytes from a file.
00725     
00726   Precondition:
00727     The file handle referenced by hMPFS is already open.
00728 
00729   Parameters:
00730     hMPFS - the file handle from which to read
00731     cData - where to store the bytes that were read
00732     wLen - how many bytes to read
00733 
00734   Returns:
00735     The number of bytes successfully read.  If this is less than wLen, 
00736     an EOF occurred while attempting to read.
00737   ***************************************************************************/
00738 WORD MPFSGetArray(MPFS_HANDLE hMPFS, BYTE* cData, WORD wLen)
00739 {   
00740     // Make sure we're reading a valid address
00741     if(hMPFS > MAX_MPFS_HANDLES)
00742         return 0;
00743         
00744     // Determine how many we can actually read
00745     if(wLen > MPFSStubs[hMPFS].bytesRem)
00746         wLen = MPFSStubs[hMPFS].bytesRem;
00747 
00748     // Make sure we're reading a valid address
00749     if(MPFSStubs[hMPFS].addr == MPFS_INVALID || wLen == 0)
00750         return 0;
00751 
00752     // MODIFIX: Added the following lines for huffman decoding support:
00753     if (MPFSStubs[hMPFS].offset)
00754     {
00755         MPFSGetArrayHuffman(hMPFS, cData, wLen);
00756         return wLen;
00757     }
00758     // MODIFIX: END
00759 
00760         
00761     if(cData == NULL)
00762     {
00763         MPFSStubs[hMPFS].addr += wLen;
00764         MPFSStubs[hMPFS].bytesRem -= wLen;
00765         return wLen;
00766     }
00767     
00768     // Read the data
00769     #if defined(MPFS_USE_EEPROM)
00770         XEEReadArray(MPFSStubs[hMPFS].addr+MPFS_HEAD, cData, wLen);
00771         MPFSStubs[hMPFS].addr += wLen;
00772         MPFSStubs[hMPFS].bytesRem -= wLen;
00773         lastRead = MPFS_INVALID;
00774     #elif defined(MPFS_USE_SPI_FLASH)
00775         SPIFlashReadArray(MPFSStubs[hMPFS].addr+MPFS_HEAD, cData, wLen);
00776         MPFSStubs[hMPFS].addr += wLen;
00777         MPFSStubs[hMPFS].bytesRem -= wLen;
00778     #else
00779         #if defined(__C30__)
00780         {
00781             DWORD addr;
00782             DWORD_VAL read;
00783             WORD count;
00784             BYTE i;
00785     
00786             // MPFS Images are addressed by the byte; Program memory by the word.
00787             //
00788             // Flash program memory is 24 bits wide and only even words are
00789             // implemented.  The upper byte of the upper word is read as 0x00.
00790             // Address in program memory of any given byte is (MPFSAddr * 2) / 3
00791             //
00792             // We will read 24 bits at a time, but need to support using only 
00793             // fractions of the first and last byte.
00794             
00795             // Find the beginning address in program memory.
00796             addr = (MPFSStubs[hMPFS].addr / 3) << 1;
00797             
00798             // Find where to start in that first 3 bytes
00799             read.Val = (addr * 3) >> 1;
00800             if(read.Val == MPFSStubs[hMPFS].addr)
00801                 i = 0;
00802             else if(read.Val+1 == MPFSStubs[hMPFS].addr)
00803                 i = 1;
00804             else
00805                 i = 2;
00806     
00807             // Add in the MPFS starting address offset
00808             addr += MPFS_HEAD;
00809             
00810             // Update the MPFS Handle
00811             MPFSStubs[hMPFS].addr += wLen;
00812             MPFSStubs[hMPFS].bytesRem -= wLen;
00813     
00814             // Read the first DWORD 
00815             read.Val = ReadProgramMemory(addr & 0x00FFFFFF);
00816             addr += 2;
00817     
00818             // Copy values as needed
00819             for(count = wLen; count > 0; cData++, count--)
00820             {
00821                 // Copy the next value in
00822                 *cData = read.v[i++];
00823                 
00824                 // Check if a new DWORD is needed
00825                 if(i == 3 && count != 1)
00826                 {// Read in a new DWORD
00827                     read.Val = ReadProgramMemory(addr & 0x00FFFFFF);
00828                     addr += 2;
00829                     i = 0;
00830                 }
00831             }
00832             
00833         }
00834         #else
00835         {
00836             DWORD dwHITECHWorkaround = MPFS_HEAD;
00837             memcpypgm2ram(cData, (ROM void*)(MPFSStubs[hMPFS].addr + dwHITECHWorkaround), wLen);
00838             MPFSStubs[hMPFS].addr += wLen;
00839             MPFSStubs[hMPFS].bytesRem -= wLen;
00840         }
00841         #endif
00842     #endif
00843     
00844     return wLen;
00845 }
00846 
00847 /*****************************************************************************
00848   Function:
00849     BOOL MPFSGetLong(MPFS_HANDLE hMPFS, DWORD* ul)
00850 
00851   Description:
00852     Reads a DWORD or Long value from the MPFS.
00853     
00854   Precondition:
00855     The file handle referenced by hMPFS is already open.
00856 
00857   Parameters:
00858     hMPFS - the file handle from which to read
00859     ul - where to store the DWORD or long value that was read
00860 
00861   Returns:
00862     TRUE - The byte was successfully read
00863     FALSE - No byte was read because either the handle was invalid or
00864             the end of the file has been reached.
00865   ***************************************************************************/
00866 BOOL MPFSGetLong(MPFS_HANDLE hMPFS, DWORD* ul)
00867 {
00868     return ( MPFSGetArray(hMPFS, (BYTE*)ul, 4) == 4 );
00869 }
00870 
00871 /*****************************************************************************
00872   Function:
00873     BOOL MPFSSeek(MPFS_HANDLE hMPFS, DWORD dwOffset, MPFS_SEEK_MODE tMode)
00874 
00875   Description:
00876     Moves the current read pointer to a new location.
00877     
00878   Precondition:
00879     The file handle referenced by hMPFS is already open.
00880 
00881   Parameters:
00882     hMPFS - the file handle to seek with
00883     dwOffset - offset from the specified position in the specified direction
00884     tMode - one of the MPFS_SEEK_MODE constants
00885 
00886   Returns:
00887     TRUE - the seek was successful
00888     FALSE - either the new location or the handle itself was invalid
00889   ***************************************************************************/
00890 BOOL MPFSSeek(MPFS_HANDLE hMPFS, DWORD dwOffset, MPFS_SEEK_MODE tMode)
00891 {
00892     DWORD temp;
00893     
00894     // Make sure a valid file is open
00895     if(hMPFS > MAX_MPFS_HANDLES)
00896         return FALSE;
00897     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
00898         return FALSE;
00899 
00900     switch(tMode)
00901     {
00902         // Seek offset bytes from start
00903         case MPFS_SEEK_START:
00904             temp = MPFSGetSize(hMPFS);
00905             if(dwOffset > temp)
00906                 return FALSE;
00907             
00908             MPFSStubs[hMPFS].addr = MPFSGetStartAddr(hMPFS) + dwOffset;
00909             MPFSStubs[hMPFS].bytesRem = temp - dwOffset;
00910             return TRUE;
00911         
00912         // Seek forwards offset bytes
00913         case MPFS_SEEK_FORWARD:
00914             if(dwOffset > MPFSStubs[hMPFS].bytesRem)
00915                 return FALSE;
00916             
00917             MPFSStubs[hMPFS].addr += dwOffset;
00918             MPFSStubs[hMPFS].bytesRem -= dwOffset;
00919             return TRUE;
00920         
00921         // Seek backwards offset bytes
00922         case MPFS_SEEK_REWIND:
00923             temp = MPFSGetStartAddr(hMPFS);
00924             if(MPFSStubs[hMPFS].addr < temp + dwOffset)
00925                 return FALSE;
00926             
00927             MPFSStubs[hMPFS].addr -= dwOffset;
00928             MPFSStubs[hMPFS].bytesRem += dwOffset;
00929             return TRUE;
00930         
00931         // Seek so that offset bytes remain in file
00932         case MPFS_SEEK_END:
00933             temp = MPFSGetSize(hMPFS);
00934             if(dwOffset > temp)
00935                 return FALSE;
00936             
00937             MPFSStubs[hMPFS].addr = MPFSGetEndAddr(hMPFS) - dwOffset;
00938             MPFSStubs[hMPFS].bytesRem = dwOffset;
00939             return TRUE;
00940         
00941         default:
00942             return FALSE;
00943     }
00944 }
00945 
00946 
00947 /****************************************************************************
00948   Section:
00949     Data Writing Functions
00950   ***************************************************************************/
00951 
00952 /*****************************************************************************
00953   Function:
00954     MPFS_HANDLE MPFSFormat(void)
00955     
00956   Summary:
00957     Prepares the MPFS image for writing.
00958 
00959   Description:
00960     Prepares the MPFS image for writing and locks the image so that other
00961     processes may not access it.
00962     
00963   Precondition:
00964     None
00965 
00966   Parameters:
00967     None
00968 
00969   Returns:
00970     An MPFS handle that can be used for MPFSPut commands, or 
00971     MPFS_INVALID_HANDLE when the EEPROM failed to initialize for writing.
00972 
00973   Remarks:
00974     In order to prevent misreads, the MPFS will be inaccessible until 
00975     MPFSClose is called.  This function is not available when the MPFS 
00976     is stored in internal Flash program memory.
00977   ***************************************************************************/
00978 #if defined(MPFS_USE_EEPROM) || defined(MPFS_USE_SPI_FLASH)
00979 MPFS_HANDLE MPFSFormat(void)
00980 {
00981 
00982     BYTE i;
00983     
00984     // Close all files
00985     for(i = 0; i < MAX_MPFS_HANDLES; i++)
00986         MPFSStubs[i].addr = MPFS_INVALID;
00987     
00988     // Lock the image
00989     isMPFSLocked = TRUE;
00990     
00991     #if defined(MPFS_USE_EEPROM)
00992         // Set FAT ptr for writing
00993         MPFSStubs[0].addr = 0;
00994         MPFSStubs[0].fatID = 0xffff;
00995         MPFSStubs[0].bytesRem = MPFS_WRITE_PAGE_SIZE - ( ((BYTE)MPFSStubs[0].addr+MPFS_HEAD) & (MPFS_WRITE_PAGE_SIZE-1) );
00996         
00997         // Set up EEPROM for writing
00998         if( XEEBeginWrite(MPFSStubs[0].addr+MPFS_HEAD) == XEE_SUCCESS )
00999             return 0x00;
01000     
01001         return MPFS_INVALID_HANDLE;
01002     #else
01003         // Set up SPI Flash for writing
01004         SPIFlashBeginWrite(MPFS_HEAD);
01005         return 0x00;
01006     #endif
01007 }
01008 #endif
01009     
01010 /*****************************************************************************
01011   Function:
01012     WORD MPFSPutArray(MPFS_HANDLE hMPFS, BYTE *cData, WORD wLen)
01013 
01014   Description:
01015     Writes an array of data to the MPFS image.
01016     
01017   Precondition:
01018     MPFSFormat was sucessfully called.
01019 
01020   Parameters:
01021     hMPFS - the file handle for writing
01022     cData - the array of bytes to write
01023     wLen - how many bytes to write
01024 
01025   Returns:
01026     The number of bytes successfully written.
01027 
01028   Remarks:
01029     For EEPROM, the actual write may not initialize until the internal write 
01030     page is full.  To ensure that previously written data gets stored, 
01031     MPFSPutEnd must be called after the last call to MPFSPutArray.
01032   ***************************************************************************/
01033 #if defined(MPFS_USE_EEPROM) || defined(MPFS_USE_SPI_FLASH)
01034 WORD MPFSPutArray(MPFS_HANDLE hMPFS, BYTE* cData, WORD wLen)
01035 {
01036     #if defined(MPFS_USE_EEPROM)
01037         // Write to the EEPROM
01038         WORD count;
01039         
01040         for(count = 0; count < wLen; count++)
01041         {
01042             XEEWrite(cData[count]);
01043             
01044             MPFSStubs[hMPFS].addr++;
01045             MPFSStubs[hMPFS].bytesRem--;
01046             
01047             if(MPFSStubs[hMPFS].bytesRem == 0)
01048             {
01049                 MPFSPutEnd(FALSE);
01050                 isMPFSLocked = TRUE;
01051                 XEEBeginWrite(MPFSStubs[hMPFS].addr+MPFS_HEAD);
01052                 MPFSStubs[hMPFS].bytesRem = MPFS_WRITE_PAGE_SIZE;
01053             }
01054         }
01055         
01056         return count;
01057     
01058     #else
01059         // Write to the SPI Flash
01060         SPIFlashWriteArray(cData, wLen);
01061     #endif
01062 }
01063 #endif
01064 
01065 /*****************************************************************************
01066   Function:
01067     void MPFSPutEnd(void)
01068 
01069   Description:
01070     Finalizes an MPFS writing operation.
01071     
01072   Precondition:
01073     MPFSFormat and MPFSPutArray were sucessfully called.
01074 
01075   Parameters:
01076     final - TRUE if the application is done writing, FALSE if MPFS2 called
01077         this function locally.
01078 
01079   Returns:
01080     None
01081   ***************************************************************************/
01082 #if defined(MPFS_USE_EEPROM) || defined(MPFS_USE_SPI_FLASH)
01083 void MPFSPutEnd(BOOL final)
01084 {
01085     isMPFSLocked = FALSE;
01086     
01087     #if defined(MPFS_USE_EEPROM)
01088         XEEEndWrite();
01089         while(XEEIsBusy());
01090     #endif
01091     
01092     if(final)
01093         _Validate();
01094 }
01095 #endif
01096 
01097 
01098 /****************************************************************************
01099   Section:
01100     Meta Data Accessors
01101   ***************************************************************************/
01102 
01103 /*****************************************************************************
01104   Function:
01105     static void _LoadFATRecord(WORD fatID)
01106 
01107   Description:
01108     Loads the FAT record for a specified handle.
01109     
01110   Precondition:
01111     None
01112 
01113   Parameters:
01114     fatID - the ID of the file whose FAT is to be loaded
01115 
01116   Returns:
01117     None
01118 
01119   Remarks:
01120     The FAT record will be stored in fatCache.
01121   ***************************************************************************/
01122 static void _LoadFATRecord(WORD fatID)
01123 {
01124     if(fatID == fatCacheID || fatID >= numFiles)
01125         return;
01126     
01127     // Read the FAT record to the cache
01128     MPFSStubs[0].bytesRem = 22;
01129     MPFSStubs[0].addr = 8 + numFiles*2 + fatID*22;
01130     MPFSStubs[0].offset = 0;    // MODIFIX: Added this line for initialize.
01131     MPFSGetArray(0, (BYTE*)&fatCache, 22);
01132     fatCacheID = fatID;
01133 }
01134 
01135 /*****************************************************************************
01136   Function:
01137     DWORD MPFSGetTimestamp(MPFS_HANDLE hMPFS)
01138 
01139   Description:
01140     Reads the timestamp for the specified file.
01141     
01142   Precondition:
01143     The file handle referenced by hMPFS is already open.
01144 
01145   Parameters:
01146     hMPFS - the file handle from which to read the metadata
01147 
01148   Returns:
01149     The timestamp that was read as a DWORD
01150   ***************************************************************************/
01151 DWORD MPFSGetTimestamp(MPFS_HANDLE hMPFS)
01152 {
01153     // Make sure a valid file is open
01154     if(hMPFS > MAX_MPFS_HANDLES)
01155         return 0x00000000;
01156     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01157         return 0x00000000;
01158     
01159     // Move to the point for reading
01160     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01161     return fatCache.timestamp;
01162 }
01163 
01164 /*****************************************************************************
01165   Function:
01166     DWORD MPFSGetMicrotime(MPFS_HANDLE hMPFS)
01167 
01168   Description:
01169     Reads the microtime portion of a file's timestamp.
01170     
01171   Precondition:
01172     The file handle referenced by hMPFS is already open.
01173 
01174   Parameters:
01175     hMPFS - the file handle from which to read the metadata
01176 
01177   Returns:
01178     The microtime that was read as a DWORD
01179   ***************************************************************************/
01180 DWORD MPFSGetMicrotime(MPFS_HANDLE hMPFS)
01181 {
01182     // Make sure a valid file is open
01183     if(hMPFS > MAX_MPFS_HANDLES)
01184         return 0x00000000;
01185     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01186         return 0x00000000;
01187     
01188     // Move to the point for reading
01189     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01190     return fatCache.microtime;
01191 }
01192 
01193 /*****************************************************************************
01194   Function:
01195     WORD MPFSGetFlags(MPFS_HANDLE hMPFS)
01196 
01197   Description:
01198     Reads a file's flags.
01199     
01200   Precondition:
01201     The file handle referenced by hMPFS is already open.
01202 
01203   Parameters:
01204     hMPFS - the file handle from which to read the metadata
01205 
01206   Returns:
01207     The flags that were associated with the file
01208   ***************************************************************************/
01209 WORD MPFSGetFlags(MPFS_HANDLE hMPFS)
01210 {
01211     // Make sure a valid file is open
01212     if(hMPFS > MAX_MPFS_HANDLES)
01213         return 0x0000;
01214     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01215         return 0x0000;
01216     
01217     //move to the point for reading
01218     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01219     return fatCache.flags;
01220 }
01221 
01222 /*****************************************************************************
01223   Function:
01224     DWORD MPFSGetSize(MPFS_HANDLE hMPFS)
01225 
01226   Description:
01227     Reads the size of a file.
01228     
01229   Precondition:
01230     The file handle referenced by hMPFS is already open.
01231 
01232   Parameters:
01233     hMPFS - the file handle from which to read the metadata
01234 
01235   Returns:
01236     The size that was read as a DWORD
01237   ***************************************************************************/
01238 DWORD MPFSGetSize(MPFS_HANDLE hMPFS)
01239 {
01240     // Make sure a valid file is open
01241     if(hMPFS > MAX_MPFS_HANDLES)
01242         return 0x00000000;
01243     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01244         return 0x00000000;
01245     
01246     // Move to the point for reading
01247     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01248     return fatCache.len;
01249 }
01250 
01251 /*****************************************************************************
01252   Function:
01253     DWORD MPFSGetBytesRem(MPFS_HANDLE hMPFS)
01254 
01255   Description:
01256     Determines how many bytes remain to be read.
01257     
01258   Precondition:
01259     The file handle referenced by hMPFS is already open.
01260 
01261   Parameters:
01262     hMPFS - the file handle from which to read the metadata
01263 
01264   Returns:
01265     The number of bytes remaining in the file as a DWORD
01266   ***************************************************************************/
01267 #if 0
01268 DWORD MPFSGetBytesRem(MPFS_HANDLE hMPFS)
01269 {
01270     // Make sure a valid file is open
01271     if(hMPFS > MAX_MPFS_HANDLES)
01272         return 0x00000000;
01273     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01274         return 0x00000000;
01275         
01276     return MPFSStubs[hMPFS].bytesRem;   
01277 }
01278 #endif
01279 
01280 /*****************************************************************************
01281   Function:
01282     MPFS_PTR MPFSGetStartAddr(MPFS_HANDLE hMPFS)
01283 
01284   Description:
01285     Reads the starting address of a file.
01286     
01287   Precondition:
01288     The file handle referenced by hMPFS is already open.
01289 
01290   Parameters:
01291     hMPFS - the file handle from which to read the metadata
01292 
01293   Returns:
01294     The starting address of the file in the MPFS image
01295   ***************************************************************************/
01296 MPFS_PTR MPFSGetStartAddr(MPFS_HANDLE hMPFS)
01297 {
01298     // Make sure a valid file is open
01299     if(hMPFS > MAX_MPFS_HANDLES)
01300         return 0;
01301     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01302         return MPFS_INVALID;
01303     
01304     // Move to the point for reading
01305     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01306     return fatCache.data;
01307 }
01308 
01309 /*****************************************************************************
01310   Function:
01311     MPFS_PTR MPFSGetEndAddr(MPFS_HANDLE hMPFS)
01312 
01313   Description:
01314     Determines the ending address of a file.
01315     
01316   Precondition:
01317     The file handle referenced by hMPFS is already open.
01318 
01319   Parameters:
01320     hMPFS - the file handle from which to read the metadata
01321 
01322   Returns:
01323     The address just after the file ends (start address of next file)
01324   ***************************************************************************/
01325 MPFS_PTR MPFSGetEndAddr(MPFS_HANDLE hMPFS)
01326 {
01327     // Make sure a valid file is open
01328     if(hMPFS > MAX_MPFS_HANDLES)
01329         return MPFS_INVALID;
01330     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01331         return MPFS_INVALID;
01332     
01333     // Move to the point for reading
01334     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01335     return fatCache.data + fatCache.len;
01336 }
01337 
01338 /*****************************************************************************
01339   Function:
01340     BOOL MPFSGetFilename(MPFS_HANDLE hMPFS, BYTE* cName, WORD wLen)
01341 
01342   Description:
01343     Reads the file name of a file that is already open.
01344     
01345   Precondition:
01346     The file handle referenced by hMPFS is already open.
01347 
01348   Parameters:
01349     hMPFS - the file handle from which to determine the file name
01350     cName - where to store the name of the file
01351     wLen - the maximum length of data to store in cName
01352 
01353   Return Values:
01354     TRUE - the file name was successfully located
01355     FALSE - the file handle provided is not currently open
01356   ***************************************************************************/
01357 BOOL MPFSGetFilename(MPFS_HANDLE hMPFS, BYTE* cName, WORD wLen)
01358 {
01359     DWORD addr;
01360     
01361     // Make sure a valid file is open
01362     if(hMPFS > MAX_MPFS_HANDLES)
01363         return FALSE;
01364     if(MPFSStubs[hMPFS].addr == MPFS_INVALID)
01365         return FALSE;
01366     
01367     // Move to the point for reading
01368     _LoadFATRecord(MPFSStubs[hMPFS].fatID);
01369     addr = fatCache.string;
01370     MPFSStubs[0].addr = addr;
01371     MPFSStubs[0].bytesRem = 255;
01372     
01373     // Read the value and return
01374     MPFSGetArray(0, cName, wLen);
01375     return TRUE;
01376 }
01377 
01378 /*****************************************************************************
01379   Function:
01380     DWORD MPFSGetPosition(MPFS_HANDLE hMPFS)
01381 
01382   Description:
01383     Determines the current position in the file
01384     
01385   Precondition:
01386     The file handle referenced by hMPFS is already open.
01387 
01388   Parameters:
01389     hMPFS - the file handle for which to determine position
01390 
01391   Returns:
01392     The position in the file as a DWORD (or MPFS_PTR)
01393 
01394   Remarks:
01395     Calling MPFSSeek(hMPFS, pos, MPFS_SEEK_START) will return the pointer
01396     to this position at a later time.  (Where pos is the value returned by
01397     this function.)
01398   ***************************************************************************/
01399 DWORD MPFSGetPosition(MPFS_HANDLE hMPFS)
01400 {
01401     return MPFSStubs[hMPFS].addr - MPFSGetStartAddr(hMPFS);
01402 }
01403 
01404 /*****************************************************************************
01405   Function:
01406     WORD MPFSGetID(MPFS_HANDLE hMPFS)
01407 
01408   Description:
01409     Determines the ID in the FAT for a file.
01410     
01411   Precondition:
01412     The file handle referenced by hMPFS is already open.
01413 
01414   Parameters:
01415     hMPFS - the file handle from which to read the metadata
01416 
01417   Returns:
01418     The ID in the FAT for this file
01419 
01420   Remarks:
01421     Use this function in association with MPFSOpenID to quickly access file
01422     without permanently reserving a file handle.
01423   ***************************************************************************/
01424 WORD MPFSGetID(MPFS_HANDLE hMPFS)
01425 {
01426     return MPFSStubs[hMPFS].fatID;
01427 }
01428 
01429 
01430 /****************************************************************************
01431   Section:
01432     Utility Functions
01433   ***************************************************************************/
01434 
01435 /*****************************************************************************
01436   Function:
01437     void _Validate(void)
01438 
01439   Summary:
01440     Validates the MPFS Image
01441 
01442   Description:
01443     Verifies that the MPFS image is valid, and reads the number of 
01444     available files from the image header.  This function is called on
01445     boot, and again after any image is written.
01446 
01447   Precondition:
01448     None
01449 
01450   Parameters:
01451     None
01452 
01453   Returns:
01454     None
01455   ***************************************************************************/
01456 static void _Validate(void)
01457 {
01458     // Validate the image and update numFiles
01459     MPFSStubs[0].addr = 0;
01460     MPFSStubs[0].bytesRem = 8;
01461     MPFSStubs[0].offset = 0;    // MODIFIX: Added this line for huffman decoding.
01462     MPFSGetArray(0, (BYTE*)&fatCache, 6);
01463     if(!memcmppgm2ram((void*)&fatCache, (ROM void*)"MPFS\x02\x01", 6))
01464         MPFSGetArray(0, (BYTE*)&numFiles, 2);
01465     else
01466         numFiles = 0;
01467     fatCacheID = MPFS_INVALID_FAT;
01468 }   
01469 #endif //#if defined(STACK_USE_MPFS2)

Generated on Sun Nov 27 20:02:38 2011 for eWicht by  doxygen 1.5.5