"FAT32_2.mpas" unit, details.



This unit "Fat32_2.mpas" enables you to handle SD/MMC/CF cards and IDE harddisks formatted in Fat32. It can handle subdirectories and long filenames. It is also capable to handle multiple open files simultaneously, each in their own directory.
It can only be used with the P18Fxxx PIC range and the P24F range, the stack is too deep to run it on a P12 or P16 PIC.
It uses as less as possible ram: the same sectorbuffer is used for the different Fat32 activities.


Table of contents:
Overview of Features
Particularities
The Unit Interface
Usage Templates for SPI, CF and IDE

Overview of features

Particularities

Unit Interface

unit Fat32_2;

//----------------------------------------------------------------------------//
//        ---> Only for P18 and P24 PIC's (stack too deep) <---               //
//----------------------------------------------------------------------------//

// Original: 21-01-2011
// Latest update: 23-10-2014

{
History
21-01-2011: Original version, derived from "Fat32.mpas", but
            - the type "TFileVar" was added to make multiple files open at one time possible
            - the procedure "xxx_Fat32_CopyFile" was added
            - the procedure "xxx_Fat32_Get_File_Size_Sectors" was added
            - the procedure "xxx_Fat32_"Read_File_Sector" was added
            - the procedure "xxx_Fat32_Write_File_Sector" was added
23-07-2012: - Made a "generic" Fat32 version. The "driver" diversity (mmc, cf, SPI1, SPI2, IDE) is gone. All those prefixes have
              been removed. The using program has to provide now 2 extra routines, which are hardware dependant:
              "Fat32_Dev_Read_Sector" and "Fat32_Dev_Write_Sector", called by the Fat32 library when needed.
31-07-2012: - Deleted an error in "MakeNewFile".
            - Changed the signature and usage of "Fat32_Delete": the file needs not to be open before deletion. The name of
              the file to delete is required as function argument now.
02-08-2012: - Uses only one SectorBuffer now: avoids writing conflicts in the same directory area.
            - The routine "Fat32_Write_File_Sector" has been renamed into "Fat32_Replace_File_Sector" (more appropriate)
            - The routine "Fat32_Write_Sector" has been added (same as "Fat32_WriteBuffer" but for whole sectors only).
05-08-2012: - Added the routines "Fat32_RmDir_All", "Fat32_Delete_All" and "Fat32_Delete_Files"
17-08-2012: - Changed the result of the Fat32_xxxSpace_GB routines to type real (too much rounding down errors otherwise)
28-08-2012: - "Fat32_Read_File_Sector" has been made more time efficient
            - Corrected the description of "Fat32_Read_File_Sector" and "Fat32_Replace_File_Sector"
29-08-2012: - Added "Fat32_Seek_Sector" and "Fat32_Read_Sector"
            - Removed "Fat32_Read_File_Sector" and "Fat32_Write_File_Sector" (replaced by "Fat32_Read_Sector" and "Fat32_Write_Sector")
01-09-2012: - Added the routine "Fat32_Append_Sector".
            - Made a "Fat32_Seek_Sector" to the sector after the last one in the file possible.
03-10-2012: - Adapted "Fat32_ReadBuffer" to make it faster for sector aligned 512 byte reads
21-10-2012: - Changed "Fat32_ReadBuffer" and "Fat32_WriteBuffer" (non sector aligned version) for more efficiency (used memcpy now)
28-09-2013: - Added "Fat32_Format" routine (for not pre-formatted cards)
08-10-2013: - Added some extra checks to make sure Fat32_Init detects a Fat32 volume (and only that) properly.
            - Added the creation of the FAT entries 0,1 and 2 to the Fat32_Format routine (was mistakenly ommitted).
            - Adapted the "Calculate Sectors per cluster" code according to the findings of Serkan (thanks!)
09-10-2013: - Removed an error in the "Fat32_Format" routine.
23-10-2014: - Added the routine "Fat32_MkDir_ChDir_FP" (full path make dir and change to it)
}

uses  StrngUtils;

//interface

// -----------------------------------------------------------------------------
// --------------------- Routine to be defined externally ----------------------
// -----------------------------------------------------------------------------

function Fat32_Dev_Read_Sector (Sector: DWord; var Buffer: array[512] of byte): boolean; external; // returns true when successfull
function Fat32_Dev_Write_Sector(Sector: DWord; var Buffer: array[512] of byte): boolean; external; // returns true when successfull

function Fat32_Dev_Capacity_Sectors: DWord; external;

// -----------------------------------------------------------------------------
     
const LongFnLength  = 255; // length of a long filename
      
type TLongFileName  = string[LongFnLength];
     TShortFileName = string[12]; // length of a short filename
     
     TFat32DirItem  =
     record
       FileName      : TLongFileName;  // longfilename if "LongFileNamePresent" is true, else "FileName" (short FileName)
       ShortFileName : TShortFileName; // short filename
       FileAttr      : byte;           // file attributes
       FileSize      : DWord;          // FileSize in bytes
       FindDirEntry  : DWord;          // for internal usage only
     end;
     
     // SectorBuffer variables
var
    SectorBuffer                      : array[512] of byte;  // Databuffer for 1 sector
    SectorInBuffer                    : DWord;               // Number of physical Sector present in databuffer
    DelayedWrite                      : boolean;             // sectordata has to be written (= has been changed)
     
    // FileVar type, an instance of it is needed for each simultaneous open file
Type TFileVar =
     record
       // Current directory variables
       CurrentDirStartCluster            : DWord;               // holds the start Cluster of the current directory
       MaxDirEntries                     : DWord;               // maximum number of dir entries in the current directory
       CurrentLogicalDirCluster          : DWord;               // logical Cluster of the current directory entry
       CurrentActualDirCluster           : DWord;               // actual Cluster of the current directory entry
       PreviousDirStartCluster           : DWord;               // filled before a directory change, remembers the "old" dir cluster
       PushDirStartCluster               : DWord;               // Directorystartcluster that was "pushed"

       // Current open file variables
       CurrentFileAssigned               : boolean;             // true if a file is open ("assigned")
       CurrentFileStartCluster           : DWord;               // holds the start Cluster of the currently assigned file
       CurrentFileEndCluster             : DWord;               // holds the last clusternumber of the currently open file
       OriginalFileSize                  : DWord;               // holds the original file size (in bytes) of the currently assigned file
       CurrentFileSize                   : DWord;               // holds the actual file size (in bytes) of the currently assigned file
       CurrentFileAttributes             : byte;                // current attributes of the currently open file
       OriginalFileAttributes            : byte;                // original attributes of the currently open file
       CurrentFileNrOfSectors            : DWord;               // holds the FileSize in #sectors of the currently assigned file
       CurrentFileNrOfBytesOnCard        : DWord;               // available (allocated) bytes on card for the current file
       CurrentFileNrOfSectorsOnCard      : DWord;               // available (allocated) sectors on card for the current file
       CurrentFilePointer                : DWord;               // holds the number of the next byte to read from or write to
       CurrentLogicalFileCluster         : DWord;               // logical Cluster of the Filepointer
       CurrentActualFileCluster          : DWord;               // actual Cluster of the filepointer
       CurrentFileLongFileNamePresent    : boolean;             // long filename present of the currently assigned file
       CurrentFileFirstDirEntry          : Dword;               // first directory entry of the  currently assigned file
       CurrentFileMainDirEntry           : Dword;               // main directory entry of the  currently assigned file
       LastAssignedFileStartCluster      : DWord;               // holds the startclusternumber of the last file opened

       // output of "FindFirst", "FindNext" and "FileExists"
       TempStartCluster, TempFirstDirEntry, TempMainDirEntry : DWord;
       TempLongFileNamePresent                               : boolean;

       // Other variables
       ClearLongFileName                 : boolean;             // needed for FindFirst and FindNext
       DirectoryDone                     : boolean;             //
       
       // -------------------------------------------------------------------------------------------------
       // -------- This variable contains the result of Fat32_FindFirst/Fat32_FindNext calls --------------
       Fat32_DirItem                     : TFat32DirItem;
       // -------------------------------------------------------------------------------------------------

     end;
     
    
const // file attribute constants to be used in "Fat32_FindFirst", Fat32_FindNext" and "Fat32_FileExists"
      faAnyFile   = $00;
      faReadOnly  = $01; // bit 0
      faHidden    = $02; // bit 1
      faSysFile   = $04; // bit 2
      faVolumeId  = $08; // bit 3
      faDirectory = $10; // bit 4
      faArchive   = $20; // bit 5
      faFile      = $40; // bit 6, not directory, not volumeId
      faCreate    = $80; // bit 7, special attribute to create files
      
      // File attribute Characters for e.g. the directory files
      Fat32_Attrs : string[6] = 'RHSVDA'; // be carefull: mirrored! ("R" is bit 0 in the attributes, "H" is bit 1 etc...)
    
// -----------------------------------------------------------------------------
//                           Basic Routines
// -----------------------------------------------------------------------------
    
function Fat32_Init: boolean;
// initialises the Fat32 filesystem, reads in the basic card/disk data (Fat boot record)
// returns true if success, false on failure
// IMPORTANT: ---> "mmc_Init" (or equivalent) must be done (with success) before this routine can be called! <---

function Fat32_QuickFormat(var VolumeLabel: string[11]): boolean;
// This routine deletes all files and directories and creates a new root directory.
// Returns true if Success, otherwise false
// Also re-inits the Fat32 system (call to Fat32_Init)
//------------------------------------------------------------------------------
// IMPORTANT: this routine only Quick -->RE<-- formats the card/disk.
// ---> It should have been initially formatted on a PC! <--- ,
// the MMC/SD/CF card or disk should already contain a valid Fat boot Record
//------------------------------------------------------------------------------

function Fat32_Format(var VolumeLabel: string[11]): boolean;
// This routines does the same as the Fat32_Quickformat" above , but the card does not
// have to be pre-formatted on a PC. The routine writes a new bootsector and a new FSInfo
// sector.

procedure Fat32_VolumeLabel(var _Label: string);
// Returns the Fat32 Volume Label in "_Label"
// "Fat32_Init" must have been executed with success before this procedure can be used

procedure Fat32_FileVar_Init(var FileVar: TFilevar);
// initialises the FileVar record, the directory is set the main directory
// Important: to be called right after "Fat32_Init" for each variable of type TFileVar

function Fat32_Assign(var FileVar: TFilevar; var LongFn: TLongFileName; file_cre_attr: byte): boolean;
// Opens a file with name "LongFn" and returns true on success.
// Only files can be opened, no directories, VolumeId's etc...
// The file is created (if not already existing) provided "file_cre_attr" contains "faCreate".
// The Filepointer (points to the next byte to be read or written) is set to zero.

procedure Fat32_Close(var FileVar: TFilevar);
// Closes the currently assigned file (flushes the databuffer etc...)
// !!! ---> Always to be called when finishing using a file, except
//     when using a swapfile
//     or "Fat32_Flush" was called after the last write action  <---! !!!

procedure Fat32_Reset(var FileVar: TFilevar; var _Size: DWord);
// Resets the filepointer of the currently assigned file to zero (first byte of the file).
// Upon exit, "_Size" holds the filesize in bytes.

procedure Fat32_Append(var FileVar: TFilevar);
// Sets the filepointer of the currently assigned file to the next place after its last byte

procedure Fat32_Rewrite(var FileVar: TFilevar);
// Discards the content of the currently assigned file (as if it was newly created),
// sets its filesize and FilePointer to 0.

function Fat32_Rename(var FileVar: TFilevar; var OldName, NewName: TLongFileName): boolean;
// Renames the file named "OldName" to "NewName" in the current directory.
// Returns "true" if successful, else "false" (e.g. "OldName" does not exists or "NewName" already exists)
// Attention! !!! this function closes first the currently open file !!!

procedure Fat32_Flush(var FileVar: TFilevar);
// Writes the sectorbuffer of the currently assigned file to the card/disk (if necessary), and
// also writes the (changed) filesize to its directory entry (if necessary).
// Calling this function writes all info as if the file closes, but keeps the file open
// for further access.

procedure Fat32_Seek(var FileVar: TFilevar; Position: DWord);
// Sets the filepointer of the currently open file to "Position".
// If "Position" is outside the file, then it becomes the same as with "Append"

function Fat32_FilePointer(var FileVar: TFilevar): DWord;
// Returns the filepointer value of the currently open file
// The filepointer is the bytenumber in the file that will be read from or written to next.

function Fat32_EOF(var FileVar: TFilevar): boolean;
// Returns true on an end-of-file condition: the filepointer is outside the file
// During "appending" data EOF is always true.

function Fat32_Get_File_Size(var FileVar: TFilevar): DWord;
// Returns the FileSize of the currently assigned file in bytes

function Fat32_Get_File_Size_Sectors(var FileVar: TFilevar): DWord;
// Returns the FileSize of the currently assigned file in Sectors

procedure Fat32_Get_File_Date(var FileVar: TFilevar; var Year: word; var Month: byte; var Day: byte; var Hours: byte; var Mins: byte);
// Gets the "Creation" date and time of the currently assigned file

procedure Fat32_Set_File_Date(var FileVar: TFilevar; Year: word; Month: byte; Day: byte; Hours: byte; Mins: byte);
// Sets the "Creation" date and time of the currently assigned file

procedure Fat32_Get_File_Date_Modified(var FileVar: TFilevar; var Year: word; var Month: byte; var Day: byte; var Hours: byte; var Mins: byte);
// Gets the "Last Modified" date and time of the currently assigned file

procedure Fat32_Set_File_Date_Modified(var FileVar: TFilevar; Year: word; Month: byte; Day: byte; Hours: byte; Mins: byte);
// Sets the "Last Modified" date and time of the currently assigned file

function Fat32_GetAttr(var FileVar: TFilevar): byte;
// returns the attributes of the currently assigned file

procedure Fat32_SetAttr(var FileVar: TFilevar; Attr: byte);
// sets the attributes of the currently assigned file

procedure Fat32_ClearArchiveAttr(var FileVar: TFilevar);
// clears the archive attribute of the currently assigned file

procedure Fat32_SetArchiveAttr(var FileVar: TFilevar);
// Sets the archive attribute of the currently assigned file

procedure Fat32_Read(var FileVar: TFilevar; var _Data: byte);
// Reads 1 byte out of the currently assigned file into "_Data".
// On exit, the CurrentFilePointer points to the next byte in the file to be read

function Fat32_ReadBuffer(var FileVar: TFilevar; var Buffer: array[4096] of byte; DataLen: Word): word;
// Reads at most "DataLen" bytes out of the currently assigned file into "Buffer"
// Upon exit, the CurrentFilePointer points to the next byte in the file to be read
// Returns the actual number of bytes read (reading beyond EOF is not done)

procedure Fat32_Write(var FileVar: TFilevar; _Data: byte);
// Writes 1 byte ("_Data") to the currently assigned file.
// Upon exit, the CurrentFilePointer points to the next byte in the file to be written

procedure Fat32_Write_Const_Buffer(var FileVar: TFilevar; const _Data: ^byte; Len: word);
// writes "Len" bytes out of "_Data" (constant data) to the currently open file at position "CurrentFilePointer"
// Afterwards CurrentFilePointer points to the next byte in the file to be written
// Usage: xxx_Fat32_Write_Const_Buffer(@Constant, NrofConstantbytes);

procedure Fat32_WriteBuffer(var FileVar: TFilevar; var Buffer: array[4096] of byte; DataLen: Word);
// Writes "DataLen" bytes out of "Buffer" to the currently open file at position "CurrentFilePointer"
// Afterwards CurrentFilePointer points to the next byte in the file to be written

procedure Fat32_WriteText(var FileVar: TFilevar; var S: string[4095]);
// Writes string "S" to the currently open file at position "CurrentFilePointer",
// no CR LF written after the string
// Afterwards CurrentFilePointer points to the next byte in the file to be written

procedure Fat32_WriteLine(var FileVar: TFilevar; var S: string[4095]);
// Writes string "S" to the currently open file at position "CurrentFilePointer",
// CR LF additionally written after the string
// Afterwards CurrentFilePointer points to the next byte in the file to be written

procedure Fat32_Seek_Sector(var FileVar: TFileVar;Sector: DWord);
// Sets the filepointer of the currently open file to "Sector * BytesPerSector".
// If "Sector * BytesPerSector" is outside the file, then it becomes the same as with "Append"

procedure Fat32_Write_Sector(var FileVar: TFileVar; var Buffer: array[512] of byte);
// Writes 512 bytes out of "Buffer" to the currently open file at position "CurrentFilePointer"
// Afterwards "CurrentFilePointer" points to the next byte in the file to be written.
// Attention: "CurrentFilePointer" mod 512 must be zero (so, at a sector boundary) when "Fat32_Write_Sector" is called!!!!

function Fat32_Read_Sector(var FileVar: TFileVar; var Buffer: array[512] of byte): DWord;
// Reads one sector (if possible) out of the currently open file at position "CurrentFilePointer" to "Buffer"
// Returns the actual number of bytes read (0..512)
// Afterwards "CurrentFilePointer" points to the next byte in the file to be read.
// Attention: "CurrentFilePointer" mod 512 will be set to zero (so, at a sector boundary) when "Fat32_Read_Sector" is called!!!!

procedure Fat32_Append_Sector(var FileVar: TFileVar);
// Sets the filepointer of the currently assigned file to the next place after its last sector

function Fat32_Delete(var FileVar: TFilevar; var Name: TLongFileName): boolean;
// Deletes file with "Name"
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!

procedure Fat32_Delete_Files(var FileVar: TFileVar);
// Deletes all "Files" in the current directory
// The sub directories in the current directory are not deleted

function Fat32_ChDir(var FileVar: TFilevar; var LongFn: TLongFileName): boolean;
// Changes directory to "LongFn" from within the current directory
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
// "Prevdir" can be used afterwards to return to the original directory (the one before "ChDir")

function Fat32_ChDir_FP(var FileVar: TFilevar; var LongFn: TLongFileName): boolean;
// Changes directory to "LongFn"
// Multiple dirlevels allowed, e.g. "\Directory1\Directory2",
//   but: the different parts of the path themselves can not be longer than 128 bytes!
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
// "Prevdir" can be used afterwards to return to the original directory (the one before "MkDirChDir_FP")

function Fat32_MkDir_ChDir_FP(var FileVar: TFilevar; var LongFn: TLongFileName): boolean;
// Changes directory to "LongFn" and meanwhile create all necessary directories in LonFn.
// Multiple dirlevels allowed, e.g. "\Directory1\Directory2",
//   but: the different parts of the path themselves can not be longer than 128 bytes!
// Returns true if Success, else false
// Attention! !!! this function closes first the currently open file !!!
// "Prevdir" can be used afterwards to return to the original directory (the one before "MkDir_ChDir_FP")

procedure Fat32_PushDir(var FileVar: TFilevar);
// The current directory's start cluster is stored for "PopDir"

procedure Fat32_PopDir(var FileVar: TFilevar);
// The current directory is changed back to the directory wherein the last "PushDir" was executed

procedure Fat32_PrevDir(var FileVar: TFilevar);
// The current directory is changed back to the previously selected directory before the current one

function Fat32_MkDir(var FileVar: TFilevar; var LongFn: TLongFileName): boolean;
// Creates a directory inside the current one if it not already exists
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if success (the directory was created or existed already)
// Attention! !!! this function closes first the currently open file !!!

function Fat32_MkDir_ChDir(var FileVar: TFilevar; var LongFn: TLongFileName): boolean;
// Makes a directory and changes the current directory to it.
// (same as subsequent "MkDir" and "ChDir"

function Fat32_RmDir(var FileVar: TFilevar; var LongFn: TLongFileName): boolean;
// Deletes a directory within the current one.
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if success (the directory was removed or it did not exist already)
// Make sure the directory is empty (except for the '.' and '..' files), otherwise lost clusters will occur
// Attention! !!! this function closes first the currently open file !!!

function Fat32_RmDir_All(var FileVar: TFilevar; var Fn: string): boolean;
// Deletes directory "Fn" - and all of its files, including subdirectories and all of their files - from the current directory.
// No backslashes allowed in "LongFn" (no multiple dirlevels)
// Returns true if success (the directory was removed or it did not exist already)
// Attention! !!! this function closes first the currently open file !!!

function Fat32_Delete_All(var FileVar: TFileVar): boolean;
// Empties the current directory: all files and subdirs are removed.
// Returns true if success (the all flies and directories were removed or it did not exist already)
// Attention! !!! this function closes first the currently open file !!!

procedure Fat32_Curdir(var FileVar: TFilevar; var CurrentDir: TLongFileName);
// Returns the name of the current directory in "CurrentDir".
// Attention! !!! this function closes first the currently open file !!!
// Attention: the actual variable used as CurrentDir must be (at least) of type string[255]!!!

procedure Fat32_Curdir_FP(var FileVar: TFilevar; var CurrentDir: TLongFileName);
// Returns the full path of the current directory in "CurrentDir".
// Attention! !!! this function closes first the currently open file !!!
// Attention: the actual variable used as CurrentDir must be (at least) of type string[255]!!!

procedure Fat32_CleanDir(var FileVar: TFilevar);
// "Cleans" the current directory file: deletes the unused entries at the end, which
// makes it unnecessary to search through them when e.g. testing a file's existance.
// Enhances speed when creating new files, after other files have been deleted (direntries became free)
// Attention! !!! this function closes first the currently open file !!!

procedure Fat32_DefragDir(var FileVar: TFilevar);
// "Defragments" the current directory file: deletes the unused entries "holes" in the directory, which
// makes it unnecessary to search through them when e.g. testing a file's existance.
// Enhances speed when creating new files, after other files have been deleted (direntries became free)
// Does also a "CleanDir"
// Attention! !!! this function closes first the currently open file !!!

function Fat32_FindFirst(var FileVar: TFilevar; FileAttr: byte): boolean;
// Returns true if the routine finds the first file/directory (if any) and puts the result in "Fat32_DirItem".
// Only the current directory is searched.
// If no first file/directory present then the procedure returns false.
// To be called before "Fat32_FindNext" is used.

function Fat32_FindNext(var FileVar: TFilevar; FileAttr: byte): boolean;
// Returns true if the routine finds a next file/directory (if any) and puts the result in "Fat32_DirItem".
// Only the current directory is searched.
// If no next file/directory present then the procedure returns false.
// Not to be called without a previous call to "Fat32_FindFirst"

function Fat32_FindFirst_FN(var FileVar: TFilevar; var LongFN: TLongFileName; FAttr: byte): boolean;
// Same as "Fat32_FindFirst" but with filename ("LongFN") included in the search criteria.
// Allowed wildcard constructions in "LongFn":
// - "FileName.Ext" : Finds only the file/directory with the filename exactly equal to LongFn
// - "*.*"          : Finds any file/directory (= same as "Fat32_FindFirst")
// - "File*.E*:     : Finds all files/directories of which the filename starts with "File" and the
//                    extension starts with "E".
//                    Attention: The "*" can only be used to make the --> tail <-- of the filename or extension "don't care".
// - "FileN?me.E?t  : Finds all files/directories with the same name as LongFn, except the positions holding "?"
//                    which are don't care. "?" only represents 1 character!
// If "LongFn" has no dot ('.') in it, only files/directories with no extension are found

function Fat32_FindNext_FN(var FileVar: TFilevar; var LongFN: TLongFileName; FAttr: byte): boolean;
// Same as "Fat32_FindNext" but with filename ("LongFN") included in the search criteria.
// Allowed wildcard constructions in "LongFn": see "Fat32_FindFirst_FN"

function Fat32_FileExists(var FileVar: TFilevar; var LongFn: TLongFileName; FAttr: byte): boolean;
// returns true if file with name "LongFn" and attribute "FAttr" exists
// No backslashes allowed in "LongFn" (no multiple dirlevels)

function Fat32_Get_Swap_File(var FileVar: TFilevar; NoSectors: dword; var filename : TLongFileName; Attr : byte) : Dword;
{ - This function is used to create a Fat32 file of fixed size (NoSectors sectors) on the MMC/SD media,
    with consequtive sectors, making it possible to use direct sector read/write in the file without using the FAT32 filesystem any further.
  - The function returns the number of the start sector for the newly created swap file, if there was enough free space
    on the MMC/SD/CF card or disk to create file of required size, 0 otherwise.
  - Attention!!! If a file with specified name already exists on the media, it will be emptied, and a attempt will be made to re-use its space on the card/disk.
  - No need to "close" the file after it was created and written to with this function (the file is not open anyway from the filesystem's point of view).
  - Afterwards the swap file can also be opened like a normal file with "Fat32_Assign".
}

// -----------------------------------------------------------------------------
//                           Additional Routines
// -----------------------------------------------------------------------------

procedure Fat32_MakeDirFile(var FileVar: TFilevar; var DirFileName: TLongFileName);
// Makes a text file which holds the directory info
// (e.g. names and sizes of files present) of the current directory

procedure Fat32_MakeDirFileHtm(var FileVar: TFilevar; var DirFileName: TLongFileName);
// Makes a html file which holds the directory info
// (e.g. names and sizes of files present) of the current directory

procedure Fat32_CopyFile(var SourceFile: TFileVar; var SourceFileName: string; var DestinationFile: TFileVar; var DestinationFileName: string);
// Copies file with name "SourceFileName" to a file with name "DestinationFileName"
// Attention! !!! this function closes first the currently open file(s) of "SourceFile" and "DestinationFile" !!!

function Fat32_FileCount(var FileVar: TFilevar; var Names: string[255]; Attr: byte): DWord;
// Count the number of files in the current directory of which the filename is in "Names"
// and the attributes comply with "Attr"
// "Names" is a comma separated list of ambiguous (wildcard) filesnames, like '*.txt, *.log, File*.*',
//    for the allowed wildcard constructions in the filenames: see "Fat32_FindFirst_FN".
// "FAttr" is any of the filetypes defined in unit "Fat32.mpas"
//
// Attention:
//  * upon exit "Names" is an empty string!
//  * the separate untrimmed filenames in "names" should not be longer than 30 characters

function Fat32_TotalSpace: DWord;
// Gives the total space in bytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// Only applicable with cards spaces <= 4 GB

function Fat32_FreeSpace: DWord;
// Gives the free space in bytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// Only applicable with cards spaces <= 4 GB

function Fat32_UsedSpace: DWord;
// Gives the used space in bytes on the Fat32 formatted card.
// Fat32_Init has to be called first.
// Only applicable with cards spaces <= 4 GB

function Fat32_TotalSpace_KB: DWord;
// Gives the total space in Kilobytes on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_FreeSpace_KB: DWord;
// Gives the free space in Kilobytes on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_UsedSpace_KB: DWord;
// Gives the used space in Kilobytes on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_TotalSpace_MB: DWord;
// Gives the total space in Megabytes (rounded down) on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_FreeSpace_MB: DWord;
// Gives the free space in Megabytes (rounded down) on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_UsedSpace_MB: DWord;
// Gives the used space in Megabytes (rounded down) on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_TotalSpace_GB: real;
// Gives the total space in Gigabytes on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_FreeSpace_GB: Real;
// Gives the free space in Gigabytes on the Fat32 formatted card.
// Fat32_Init has to be called first.

function Fat32_UsedSpace_GB: Real;
// Gives the used space in Gigabytes on the Fat32 formatted card.
// Fat32_Init has to be called first.


// --------------------------------------------------------------------------------------------------

implementation

Usage Templates

SPI (SD/MMC) usage template
Compact Flash (CF) usage template
Harddisk (IDE) usage template
-------------------------------------------