Better (for FAT32) and simpler FAT default value calculations.

Also use 16-bit instead of 32-bit quantities where possible to save code size.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@743 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2003-12-13 03:07:49 +00:00
parent f1f51592ba
commit b92f552a57

View File

@ -381,7 +381,6 @@ void printCHS(char *title, struct CHS *chs)
*/ */
VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem) VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
{ {
ULONG fatlength, maxclust, clust;
UBYTE maxclustsize; UBYTE maxclustsize;
ULONG fatdata; ULONG fatdata;
@ -408,31 +407,30 @@ VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
case FAT12: case FAT12:
case FAT12_LBA: case FAT12_LBA:
{
unsigned fatdat, fatlength, clust, maxclust;
/* in DOS, FAT12 defaults to 4096kb (8 sector) - clusters. */ /* in DOS, FAT12 defaults to 4096kb (8 sector) - clusters. */
defbpb->bpb_nsector = 8; defbpb->bpb_nsector = 8;
/* Force maximal fatdata=32696 sectors since with our only possible sector /* Force maximal fatdata=32696 sectors since with our only possible sector
size (512 bytes) this is the maximum for 4k clusters. size (512 bytes) this is the maximum for 4k clusters.
#clus*secperclus+#fats*fatlength= 4077 * 8 + 2 * 12 = 32640. #clus*secperclus+#fats*fatlength= 4077 * 8 + 2 * 12 = 32640.
max FAT12 size for FreeDOS = 16,728,064 bytes */ max FAT12 size for FreeDOS = 16,728,064 bytes */
fatdat = (unsigned)fatdata;
if (fatdata > 32640) if (fatdata > 32640)
fatdata = 32640; fatdat = 32640;
/* The factor 2 below avoids cut-off errors for nr_fats == 1. /* The "+2*defbpb->bpb_nsector" is for the reserved first two FAT entries */
* The "defbpb->bpb_nfat*3" is for the reserved first two FAT entries */ fatlength = cdiv(fatdat + 2 * defbpb->bpb_nsector,
clust = defbpb->bpb_nbyte * 2 * defbpb->bpb_nsector / 3 +
2 * ((ULONG) fatdata * defbpb->bpb_nbyte + defbpb->bpb_nfat);
defbpb->bpb_nfat * 3) / (2 * (ULONG) defbpb->bpb_nsector * /* Need to calculate number of clusters, since the unused parts of the
defbpb->bpb_nbyte +
defbpb->bpb_nfat * 3);
fatlength = cdiv(((clust + 2) * 3 + 1) >> 1, defbpb->bpb_nbyte);
/* Need to recalculate number of clusters, since the unused parts of the
* FATS and data area together could make up space for an additional, * FATS and data area together could make up space for an additional,
* not really present cluster. */ * not really present cluster. */
clust = clust =
(fatdata - defbpb->bpb_nfat * fatlength) / defbpb->bpb_nsector; (fatdat - defbpb->bpb_nfat * fatlength) / defbpb->bpb_nsector;
maxclust = (fatlength * 2 * defbpb->bpb_nbyte) / 3; maxclust = (fatlength * 2 * defbpb->bpb_nbyte) / 3;
if (maxclust > FAT12MAX) if (maxclust > FAT12MAX)
maxclust = FAT12MAX; maxclust = FAT12MAX;
DebugPrintf(("FAT12: #clu=%lu, fatlen=%lu, maxclu=%lu, limit=%u\n", DebugPrintf(("FAT12: #clu=%u, fatlength=%u, maxclu=%u, limit=%u\n",
clust, fatlength, maxclust, FAT12MAX)); clust, fatlength, maxclust, FAT12MAX));
if (clust > maxclust - 2) if (clust > maxclust - 2)
{ {
@ -442,10 +440,13 @@ VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
defbpb->bpb_nfsect = fatlength; defbpb->bpb_nfsect = fatlength;
fmemcpy(pddt->ddt_fstype, MSDOS_FAT12_SIGN, 8); fmemcpy(pddt->ddt_fstype, MSDOS_FAT12_SIGN, 8);
break; break;
}
case FAT16SMALL: case FAT16SMALL:
case FAT16LARGE: case FAT16LARGE:
case FAT16_LBA: case FAT16_LBA:
{
unsigned fatlength;
unsigned long clust, maxclust;
/* FAT16: start at 4 sectors per cluster */ /* FAT16: start at 4 sectors per cluster */
defbpb->bpb_nsector = 4; defbpb->bpb_nsector = 4;
/* Force maximal fatdata=8387584 sectors (NumSectors=8387617) /* Force maximal fatdata=8387584 sectors (NumSectors=8387617)
@ -460,13 +461,10 @@ VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
DebugPrintf(("Trying with %d sectors/cluster:\n", DebugPrintf(("Trying with %d sectors/cluster:\n",
defbpb->bpb_nsector)); defbpb->bpb_nsector));
clust = fatlength = (unsigned)cdiv(fatdata + 2 * defbpb->bpb_nsector,
((ULONG) fatdata * defbpb->bpb_nbyte + (ULONG)defbpb->bpb_nbyte * defbpb->bpb_nsector / 2 +
defbpb->bpb_nfat * 4) / ((ULONG) defbpb->bpb_nsector * defbpb->bpb_nfat);
defbpb->bpb_nbyte + /* Need to calculate number of clusters, since the unused parts of the
defbpb->bpb_nfat * 2);
fatlength = cdiv((clust + 2) * 2, defbpb->bpb_nbyte);
/* Need to recalculate number of clusters, since the unused parts of the
* FATS and data area together could make up space for an additional, * FATS and data area together could make up space for an additional,
* not really present cluster. */ * not really present cluster. */
clust = clust =
@ -474,7 +472,7 @@ VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
maxclust = (fatlength * defbpb->bpb_nbyte) / 2; maxclust = (fatlength * defbpb->bpb_nbyte) / 2;
if (maxclust > FAT16MAX) if (maxclust > FAT16MAX)
maxclust = FAT16MAX; maxclust = FAT16MAX;
DebugPrintf(("FAT16: #clu=%lu, fatlen=%lu, maxclu=%lu, limit=%u\n", DebugPrintf(("FAT16: #clu=%lu, fatlen=%u, maxclu=%lu, limit=%u\n",
clust, fatlength, maxclust, FAT_MAGIC16)); clust, fatlength, maxclust, FAT_MAGIC16));
if (clust > maxclust - 2) if (clust > maxclust - 2)
{ {
@ -496,24 +494,23 @@ VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
defbpb->bpb_nfsect = fatlength; defbpb->bpb_nfsect = fatlength;
fmemcpy(pddt->ddt_fstype, MSDOS_FAT16_SIGN, 8); fmemcpy(pddt->ddt_fstype, MSDOS_FAT16_SIGN, 8);
break; break;
}
#ifdef WITHFAT32 #ifdef WITHFAT32
case FAT32: case FAT32:
case FAT32_LBA: case FAT32_LBA:
{
unsigned long fatlength, clust, maxclust;
/* For FAT32, use 4k clusters on sufficiently large file systems, /* For FAT32, use 4k clusters on sufficiently large file systems,
* otherwise 1 sector per cluster. This is also what M$'s format * otherwise 1 sector per cluster. This is also what M$'s format
* command does for FAT32. */ * command does for FAT32. */
defbpb->bpb_nsector = (NumSectors >= 512 * 1024ul ? 8 : 1); defbpb->bpb_nsector = (NumSectors >= 512 * 1024ul ? 8 : 1);
do do
{ {
/* simple calculation - no long long available */ fatlength = cdiv(fatdata + 2 * defbpb->bpb_nsector,
clust = (ULONG) fatdata / defbpb->bpb_nsector; (ULONG)defbpb->bpb_nbyte * defbpb->bpb_nsector / 4 +
/* this calculation below yields a smaller value - the above is non-optimal defbpb->bpb_nfat);
but should not be dangerous */ /* Need to calculate number of clusters, since the unused parts of the
/* clust = ((long long) fatdata *defbpb->bpb_nbyte + defbpb->bpb_nfat*8) /
((int) defbpb->bpb_nsector * defbpb->bpb_nbyte + defbpb->bpb_nfat*4); */
fatlength = cdiv((clust + 2) * 4, defbpb->bpb_nbyte);
/* Need to recalculate number of clusters, since the unused parts of the
* FATS and data area together could make up space for an additional, * FATS and data area together could make up space for an additional,
* not really present cluster. */ * not really present cluster. */
clust = clust =
@ -543,6 +540,7 @@ VOID CalculateFATData(ddt FAR * pddt, ULONG NumSectors, UBYTE FileSystem)
defbpb->bpb_xbackupsec = 6; defbpb->bpb_xbackupsec = 6;
fmemcpy(pddt->ddt_fstype, MSDOS_FAT32_SIGN, 8); fmemcpy(pddt->ddt_fstype, MSDOS_FAT32_SIGN, 8);
break; break;
}
#endif #endif
} }
pddt->ddt_fstype[8] = '\0'; pddt->ddt_fstype[8] = '\0';