Difference between revisions of "Unit FATFS"

From Ultibo.org
Jump to: navigation, search
Line 341: Line 341:
  
 
=== Type definitions ===
 
=== Type definitions ===
 +
----
 +
 +
'''FATFS specific types'''
 +
 +
{| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;"
 +
|-
 +
| <code>TFATType = (ftNONE,ftFAT12,ftFAT16,ftFAT32);</code>
 +
| style="width: 40%;"|
 +
|-
 +
|}
 +
 +
'''FATFS params'''
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
 +
<code>TFATParams = record </code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: (Not Packed) Block values for various Sector sizes.
 +
|-
 +
| <code>SectorSize:Word;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>FATType:TFATType;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BlockShiftCount:Word;</code>
 +
| &nbsp;
 +
|-
 +
| <code>EntriesPerBlock:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
| <code>SectorsPerBlock:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div> 
 +
 +
'''FATFS geometry''' 
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
 +
<code>TFATGeometry = record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: (Not Packed) FAT12 values for various Floppy Types.
 +
|-
 +
| <code>FloppyType:TFloppyType;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>SectorsPerFat:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
| <code>SectorsPerCluster:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
| <code>RootEntryCount:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
| <code>MediaId:Byte;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
 +
'''FATFS cluster size'''
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
 +
<code>TFATClusterSize = record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: (Not Packed) Sectors per Cluster for various disk sizes (Fixed Disk only).
 +
|-
 +
| <code>SectorCount:LongWord;</code>
 +
| Based on 512 bytes per sector only
 +
|-
 +
| <code>SectorsPerCluster:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
 +
'''FATFS partition type'''
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
 +
<code>TFATPartitionType = record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: (Not Packed) Partition Type for various disk sizes (Fixed Disk only).
 +
|-
 +
| <code>Excluded:Boolean;</code>
 +
| Entry is excluded from FAT Partition Type check
 +
|-
 +
| <code>Extended:Boolean;</code>
 +
| &nbsp;
 +
|-
 +
| <code>SectorCount:LongWord;</code>
 +
| Based on 512 bytes per sector only
 +
|-
 +
| <code>PartitionId:Byte;</code>
 +
| &nbsp;
 +
|-
 +
| <code>LBAType:Byte;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
 +
'''FATFS name'''
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
<code>PFATName = ^TFATName;</code>
 +
 +
<code>TFATName = packed record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: 11 Bytes
 +
|-
 +
| <code>Name:array[0..7] of Char;</code>
 +
| File Name
 +
|-
 +
| <code>Ext:array[0..2] of Char;</code>
 +
| File Extension
 +
|-
 +
|}
 +
</div></div>
 +
 +
'''FATSFS directory'''
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
<code>PFATDirectory = ^TFATDirectory;</code>
 +
 +
<code>TFATDirectory = packed record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: 32 Bytes
 +
|-
 +
| <code>Name:array[0..7] of Char;</code>
 +
| File Name
 +
|-
 +
| <code>Ext:array[0..2] of Char;</code>
 +
| File Extension
 +
|-
 +
| <code>Attribute:Byte;</code>
 +
| File Attributes - See Standard Values
 +
|-
 +
| <code>Reserved:Byte;</code>
 +
| Always 0 (See below)
 +
|-
 +
| <code>CaseFlags:Byte;</code>
 +
| Set to $08 if Name, $10 if Extension or $18 if both
 +
|-
 +
| <code>CreateTimeMsecs:Byte;</code>
 +
| &nbsp;
 +
|-
 +
| <code>CreateTime:Word;</code>
 +
| &nbsp;
 +
|-
 +
| <code>CreateDate:Word;</code>
 +
| &nbsp;
 +
|-
 +
| <code>LastAccessDate:Word;</code>
 +
| &nbsp;
 +
|-
 +
| <code>FirstClusterHigh:Word;</code>
 +
| High word of the start cluster (FAT32 Only)
 +
|-
 +
| <code>WriteTime:Word;</code>
 +
| &nbsp;
 +
|-
 +
| <code>WriteDate:Word;</code>
 +
| &nbsp;
 +
|-
 +
| <code>FirstClusterLow:Word;</code>
 +
| Low Word of Start Cluster all versions
 +
|-
 +
| <code>Length:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div> 
 +
 +
'''LFN directory''' 
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
<code>PLFNDirectory = ^TLFNDirectory;</code>
 +
 +
<code>TLFNDirectory = packed record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|Note: 32 Bytes
 +
|-
 +
| <code>Order:Byte;</code>
 +
| Bit 6 = 1 if last LFN in chain, Bits 5-0 = Order of LFN chunks for this File
 +
|-
 +
| <code>Name1:array[0..4] of WideChar;</code>
 +
| First 5 Characters in this chunk
 +
|-
 +
| <code>Attribute:Byte;</code>
 +
| Always 0Fh - Volume, System, Hidden, ReadOnly
 +
|-
 +
| <code>FileType:Byte;</code>
 +
| Usually 00h
 +
|-
 +
| <code>Checksum:Byte;</code>
 +
| Checksum calculated on 8.3 name
 +
|-
 +
| <code>Name2:array[0..5] of WideChar;</code>
 +
| Next 6 Characters in this chunk
 +
|-
 +
| <code>Reserved:Word;</code>
 +
| Always 0000h - FirstCluster in Standard Entry
 +
|-
 +
| <code>Name3:array[0..1] of WideChar;</code>
 +
| Next 2 Characters in this chunk
 +
|-
 +
|}
 +
</div></div>
 +
 +
'''FATFS info sector'''
 +
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
<code>PFATInfoSector = ^TFATInfoSector;</code>
 +
 +
<code>TFATInfoSector = packed record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>LeadSignature:LongWord;</code>
 +
| Signature "RRaA" or 41615252h
 +
|-
 +
| <code>Reserved1:array[0..479] of Byte;</code>
 +
| Always 0
 +
|-
 +
| <code>StructureSignature:LongWord;</code>
 +
| Signature "rrAa" or 61417272h
 +
|-
 +
| <code>FreeClusterCount:LongWord;</code>
 +
| Free Clusters $FFFFFFFF if unknown
 +
|-
 +
| <code>LastFreeCluster:LongWord;</code>
 +
| Most recently allocated cluster $FFFFFFFF if unknown
 +
|-
 +
| <code>Reserved2:array[0..11] of Byte;</code>
 +
| Always 0
 +
|-
 +
| <code>TrailSignature:LongWord;</code>
 +
| Signature AA550000h
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
 +
=== Class definitions ===
 
----
 
----
  

Revision as of 04:36, 18 January 2017

Return to Unit Reference


Description


Ultibo FAT12/16/32/exFAT interface unit

Notes:

Based on information from numerous sources, primarily the document fatgen103.pdf from Microsoft. FAT Disk Blocks are based on reading a group of sectors into a block at once. The BlockNo of each block is therefore the FAT entry no of the first FAT in the block.

The use of IsEightDotThree and GenerateShortName(Ex) from the UltiboUtils unit should be replaced by internal routines optimised for maximum performance. All Block and Entry Offsets have been expanded to 32bit to avoid 16bit overflow on 64K clusters.

Constants



FATFS specific constants fat*
fatFAT12 = 0;  
fatFAT16 = 1;  
fatFAT32 = 2;  
 
fatDotName = '.';  
fatDotDotName = '..';  
fatBlankName= ;  
fatNameCount = 8;  
fatExtCount = 3;  
 
fatLabelMask = '*';  
fatLabelCount = 11;  
 
fatOemName = 'MSWIN4.1';  
fatDefaultName = 'NO NAME';  
 
fatFlagNone = $00;  
fatFlagName = $08;  
fatFlagExt = $10;  
fatFlagBoth = $18;  
 
lfnMaxName = 2048; Buffer size for lfn handling
lfnMaxAlias = 999999; Max number of lfn aliases (ie ~999999)
lfnMaxNameAlias = 4;  
lfnMaxHashAlias = 999;  
lfnMaxHashShift = 16;  
 
fatMaxFileSize = 4294967295; Max size in bytes of a File (4GB)
fatMaxDirectorySize = 2097152; Max size in bytes of a Directory (2MB = 65536 * 32)
 
fatMinClusterSize = 512;  
fatMaxClusterSize = 65536;  
 
fat12MinClusters = 3;  
fat16MinClusters = 4085; Smallest Number of Clusters on a FAT16 volume, is FAT12 if less
fat32MinClusters = 65525; Smallest Number of Clusters on a FAT32 volume, is FAT16 if less
 
fat12MinSectors = 6; Number of Sectors at which we cannot create a FAT12 (Not possible due to 512 Root entries)
fat12MinSectors = 798; Number of Sectors at which we cannot create a FAT12
fat12MaxSectors = 32623; Number of Sectors at which we insist on creating FAT16
 
fat16MinSectors = 8400; Number of Sectors at which we cannot create a FAT16
fat16MaxSectors = 1048576; Number of Sectors at which we insist on creating FAT32
 
fat32MinSectors = 66600; Number of Sectors at which we cannot create a FAT32
fat32MaxSectors = $FFFFFFFF; No limit on maximum size of a FAT32
 
Note: In FAT12 EOC will be >= $0FF0 due to Media ID on Floppy
fat12EndOfFile = $0FF0; Some Code sets values from $0FF0 - $0FFF as EOF
fat12EndOfFile = $0FF8; Some Code sets values from $0FF8 - $0FFF as EOF
fat12EndOfCluster = $0FFF; EOF Mark, Check for >= $0FF0 - See Above
fat12FreeCluster = $0000; Available for Use
fat12BadCluster = $0FF7; Bad Cluster Mark - Do Not Use
fat12MediaCluster = $0F00; First Cluster - $0F00 + MediaID from BPB Usually $0FF8
fat12Reserved0 = $0FF0; Reserved Cluster Nos - Do Not Use (Due to Media ID on Floppy)
fat12Reserved1 = $0FF1;  
fat12Reserved2 = $0FF2;  
fat12Reserved3 = $0FF3;  
fat12Reserved4 = $0FF4;  
fat12Reserved5 = $0FF5;  
fat12Reserved6 = $0FF6;  
 
fat16EndOfFile = $FFF8; Some Code sets values from $FFF8 - $FFFF as EOF
fat16EndOfCluster = $FFFF; EOF Mark, Check for >= $FFF8 - See Above
fat16FreeCluster = $0000; Available for Use
fat16BadCluster = $FFF7; Bad Cluster Mark - Do Not Use
fat16MediaCluster = $FF00; First Cluster - $FF00 + MediaID from BPB Usually $FFF8
 
fat32EndOfFile = $0FFFFFF8; Some Code sets values from $0FFFFFF8 - $0FFFFFFF as EOF
fat32EndOfCluster = $0FFFFFFF; EOF Mark, Check for >= $0FFFFFF8 - See Above
fat32FreeCluster = $00000000; Available for Use
fat32BadCluster = $0FFFFFF7; Bad Cluster Mark - Do Not Use
fat32MediaCluster = $0FFFFF00; First Cluster - $0FFFFF00 + MediaID from BPB Usually $0FFFFFF8
 
fat16CleanShutdown = $8000; Second Cluster - EndOfCluster + Bits
fat16HardError = $4000; Second Cluster - EndOfCluster + Bits
 
fat32CleanShutdown = $08000000; Second Cluster - EndOfCluster + Bits
fat32HardError = $04000000; Second Cluster - EndOfCluster + Bits
fat32ReservedBits = $F0000000; Bits 31-29 must be preserved on FAT32
 
fatBootSector = 0;  
fatFreeCluster = 0;  
fatStartCluster = 2; Lowest allocatable cluster number
fatUnevenCluster = $00000001;  
fatUnknownCluster = $FFFFFFFF;  
 
fatEntryFree = $E5;  
fatEntryFreeAll = $00;  
fatEntrySpecial = $05; If real first char is $E5
fatEntryPadding = $20; Padded with spaces (32)
 
fatEntrySize = 32; Size of a FAT Directory Entry (or LFNDirectoryEntry)
 
lfnEntryMax= $3F; Maximum count of an LFN entry
lfnEntryLast = $40; Marker for LFN last entry
lfnEntryMask = $BF; Mask for LFN entry count
lfnEntryChars = 13; Number of characters per LFN entry
 
lfnEntryNull = $0000; Null terminator on LFN when applicable
lfnEntryPadding = $FFFF; Empty LFN chars padded with (65535)
 
lfnAttributeMask = (faReadOnly or faHidden or faSysFile or faVolumeID); Not Used - See faLongName
 
fat32LeadSignature = $41615252; RRaA
fat32StructSignature = $61417272; rrAa
fat32TrailSignature = $AA550000; Standard Boot Sector signature
 
fatDotChar:Byte = $2E; Checked separately from Invalid chars due to . and .. entries
fatSpaceChar:Byte = $20;  
fatBaseChars:set of Byte = [$00..$19]; 0..31 (Dont include $20 as that is checked separately)
fatInvalidChars:set of Byte = [$22,$2A,$2B,$2C,$2F,$3A,$3B,$3C,$3D,$3E,$3F,$5B,$5C,$5D,$7C]; 34,42,43,44,47,58,59,60,61,62,63,91,92,93,124 (Dont include $2E as that is checked separately)
fatLowercaseChars:set of Byte = [$61..$7A]; 97..122 (These dont account for the code page)


Type definitions


FATFS specific types

TFATType = (ftNONE,ftFAT12,ftFAT16,ftFAT32);

FATFS params

TFATParams = record

Note: (Not Packed) Block values for various Sector sizes.
SectorSize:Word;  
FATType:TFATType;  
BlockShiftCount:Word;  
EntriesPerBlock:LongWord;  
SectorsPerBlock:LongWord;  

FATFS geometry

TFATGeometry = record

Note: (Not Packed) FAT12 values for various Floppy Types.
FloppyType:TFloppyType;  
SectorsPerFat:LongWord;  
SectorsPerCluster:LongWord;  
RootEntryCount:LongWord;  
MediaId:Byte;  

FATFS cluster size

TFATClusterSize = record

Note: (Not Packed) Sectors per Cluster for various disk sizes (Fixed Disk only).
SectorCount:LongWord; Based on 512 bytes per sector only
SectorsPerCluster:LongWord;  

FATFS partition type

TFATPartitionType = record

Note: (Not Packed) Partition Type for various disk sizes (Fixed Disk only).
Excluded:Boolean; Entry is excluded from FAT Partition Type check
Extended:Boolean;  
SectorCount:LongWord; Based on 512 bytes per sector only
PartitionId:Byte;  
LBAType:Byte;  

FATFS name

PFATName = ^TFATName;

TFATName = packed record

Note: 11 Bytes
Name:array[0..7] of Char; File Name
Ext:array[0..2] of Char; File Extension

FATSFS directory

PFATDirectory = ^TFATDirectory;

TFATDirectory = packed record

Note: 32 Bytes
Name:array[0..7] of Char; File Name
Ext:array[0..2] of Char; File Extension
Attribute:Byte; File Attributes - See Standard Values
Reserved:Byte; Always 0 (See below)
CaseFlags:Byte; Set to $08 if Name, $10 if Extension or $18 if both
CreateTimeMsecs:Byte;  
CreateTime:Word;  
CreateDate:Word;  
LastAccessDate:Word;  
FirstClusterHigh:Word; High word of the start cluster (FAT32 Only)
WriteTime:Word;  
WriteDate:Word;  
FirstClusterLow:Word; Low Word of Start Cluster all versions
Length:LongWord;  

LFN directory

PLFNDirectory = ^TLFNDirectory;

TLFNDirectory = packed record

Note: 32 Bytes
Order:Byte; Bit 6 = 1 if last LFN in chain, Bits 5-0 = Order of LFN chunks for this File
Name1:array[0..4] of WideChar; First 5 Characters in this chunk
Attribute:Byte; Always 0Fh - Volume, System, Hidden, ReadOnly
FileType:Byte; Usually 00h
Checksum:Byte; Checksum calculated on 8.3 name
Name2:array[0..5] of WideChar; Next 6 Characters in this chunk
Reserved:Word; Always 0000h - FirstCluster in Standard Entry
Name3:array[0..1] of WideChar; Next 2 Characters in this chunk

FATFS info sector

PFATInfoSector = ^TFATInfoSector;

TFATInfoSector = packed record

LeadSignature:LongWord; Signature "RRaA" or 41615252h
Reserved1:array[0..479] of Byte; Always 0
StructureSignature:LongWord; Signature "rrAa" or 61417272h
FreeClusterCount:LongWord; Free Clusters $FFFFFFFF if unknown
LastFreeCluster:LongWord; Most recently allocated cluster $FFFFFFFF if unknown
Reserved2:array[0..11] of Byte; Always 0
TrailSignature:LongWord; Signature AA550000h


Class definitions


To be documented

Public variables


None defined

Function declarations



Initialization functions

procedure FATFSInit;
Description: To be documented
Note None documented


procedure FATFSQuit;
Description: To be documented
Note None documented


FATFS helper functions

function FATTypeToString(AType:TFATType):String;
Description: To be documented
Note None documented


Return to Unit Reference