You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
14 KiB
371 lines
14 KiB
/*
|
|
* $Log: V:/Flite/archives/TrueFFS5/Src/DOSFORMT.C_V $
|
|
*
|
|
* Rev 1.7 Feb 19 2002 20:59:12 oris
|
|
* Replaced dosformt.h with blockdev.h
|
|
*
|
|
* Rev 1.6 Jan 29 2002 20:07:56 oris
|
|
* Removed prototype of flBuildGeometry (already found in blockdev.h).
|
|
*
|
|
* Rev 1.5 Jan 28 2002 21:24:58 oris
|
|
* Removed the use of back-slashes in macro definitions.
|
|
*
|
|
* Rev 1.4 Apr 16 2001 13:33:44 oris
|
|
* Removed warrnings.
|
|
*
|
|
* Rev 1.3 Apr 09 2001 15:06:42 oris
|
|
* End with an empty line.
|
|
*
|
|
* Rev 1.2 Apr 01 2001 07:44:48 oris
|
|
* Updated copywrite notice
|
|
*
|
|
* Rev 1.1 Feb 14 2001 02:00:26 oris
|
|
* Added oldFormat.
|
|
*
|
|
* Rev 1.0 Feb 02 2001 13:48:44 oris
|
|
* Initial revision.
|
|
*
|
|
*/
|
|
|
|
/***********************************************************************************/
|
|
/* M-Systems Confidential */
|
|
/* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
|
|
/* All Rights Reserved */
|
|
/***********************************************************************************/
|
|
/* NOTICE OF M-SYSTEMS OEM */
|
|
/* SOFTWARE LICENSE AGREEMENT */
|
|
/* */
|
|
/* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
|
|
/* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
|
|
/* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
|
|
/* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
|
|
/* E-MAIL = [email protected] */
|
|
/***********************************************************************************/
|
|
|
|
#include "fltl.h"
|
|
#ifdef FORMAT_VOLUME
|
|
|
|
#include "blockdev.h"
|
|
|
|
#define FAT12bit (LE4(bpb->totalSectorsInVolume) < 4086LU * bpb->sectorsPerCluster)
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* g e t D r i v e G e o m e t r y */
|
|
/* */
|
|
/* Calculates the geometry parameters for BIOS/DOS media */
|
|
/* */
|
|
/* Parameters: */
|
|
/* vol : Pointer identifying drive */
|
|
/* oldFormat : Format media with coluster size of 1 sector */
|
|
/* */
|
|
/* Returns: */
|
|
/* bpb : volume BIOS parameter block */
|
|
/* cylinders : Number of "cylinders" in volume */
|
|
/* noOfFATs : Number of FAT copies */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static void getDriveGeometry(TL vol,
|
|
BPB FAR2 *bpb,
|
|
dword FAR2 *cylinders,
|
|
unsigned noOfFATs,
|
|
FLBoolean oldFormat)
|
|
{
|
|
dword heads, sectors;
|
|
long int sizeInSectors, noOfClusters;
|
|
int directorySectors, sectorsPerFAT;
|
|
int minClusterSize;
|
|
SectorNo sectorAlignment;
|
|
|
|
SectorNo capacity = vol.sectorsInVolume(vol.rec); /* Volume size in sectors */
|
|
|
|
minClusterSize = ((oldFormat == TRUE) ? 1: MIN_CLUSTER_SIZE);
|
|
|
|
flBuildGeometry( (dword)capacity, (dword FAR2 *)cylinders,
|
|
(dword FAR2 *)&heads, (dword FAR2 *)§ors,oldFormat);
|
|
|
|
if (vol.recommendedClusterInfo)
|
|
vol.recommendedClusterInfo(vol.rec,&minClusterSize,§orAlignment);
|
|
|
|
toLE2(bpb->sectorsPerTrack,(word) sectors);
|
|
toLE2(bpb->noOfHeads,(word) heads);
|
|
toUNAL2(bpb->bytesPerSector,SECTOR_SIZE);
|
|
bpb->noOfFATS = (byte)noOfFATs;
|
|
bpb->mediaDescriptor = 0xf8; /* hard disk */
|
|
toLE4(bpb->noOfHiddenSectors,sectors);
|
|
|
|
sizeInSectors = (long) (*cylinders) * heads * sectors - sectors;
|
|
|
|
toLE4(bpb->totalSectorsInVolume,sizeInSectors);
|
|
toUNAL2(bpb->totalSectorsInVolumeDOS3,
|
|
(word)(sizeInSectors > 65535l ? 0 : sizeInSectors));
|
|
|
|
noOfClusters = sizeInSectors / minClusterSize;
|
|
for (bpb->sectorsPerCluster = (byte)minClusterSize;
|
|
noOfClusters > (!oldFormat && bpb->sectorsPerCluster < 8 ? 32766l : 65534l);
|
|
bpb->sectorsPerCluster <<= 1, noOfClusters >>= 1);
|
|
|
|
if (FAT12bit)
|
|
sectorsPerFAT =
|
|
(word) ((((noOfClusters + 2L) * 3 + 1) / 2 - 1) / SECTOR_SIZE + 1);
|
|
else
|
|
sectorsPerFAT =
|
|
(word) (((noOfClusters + 2L) * 2 - 1) / SECTOR_SIZE + 1);
|
|
toLE2(bpb->sectorsPerFAT,(word)sectorsPerFAT);
|
|
|
|
directorySectors = (int)(capacity / 200);
|
|
if (directorySectors < 1) directorySectors = 1;
|
|
if (directorySectors > 15) directorySectors = 15;
|
|
toUNAL2(bpb->rootDirectoryEntries,
|
|
(word)(directorySectors * (SECTOR_SIZE / sizeof(DirectoryEntry))));
|
|
|
|
if (vol.recommendedClusterInfo) {
|
|
int sectorPadding = (int)((sectorAlignment - (sectors + 1 + noOfFATs * sectorsPerFAT + directorySectors)) % bpb->sectorsPerCluster);
|
|
|
|
if (sectorPadding < 0)
|
|
sectorPadding += bpb->sectorsPerCluster;
|
|
toLE2(bpb->reservedSectors,sectorPadding + 1);
|
|
}
|
|
else
|
|
toLE2(bpb->reservedSectors,1);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* c r e a t e M a s t e r B o o t R e c o r d */
|
|
/* */
|
|
/* Creates the Master Boot Record (Sector 0) */
|
|
/* */
|
|
/* Parameters: */
|
|
/* vol : Pointer identifying drive */
|
|
/* bpb : volume BIOS parameter block */
|
|
/* */
|
|
/* Returns: */
|
|
/* FLStatus : 0 on success, failed otherwise */
|
|
/* cylinders : Number of "cylinders" in volume */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static FLStatus createMasterBootRecord(TL vol,
|
|
BPB *bpb,
|
|
dword cylinders)
|
|
{
|
|
static byte bootCode[] = {
|
|
0xFA, 0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C,
|
|
0x8B, 0xF4, 0x50, 0x07, 0x50, 0x1F, 0xFB, 0xFC,
|
|
0xBF, 0x00, 0x06, 0xB9, 0x00, 0x01, 0xF2, 0xA5,
|
|
0xEA, 0x1D, 0x06, 0x00, 0x00, 0xBE, 0xBE, 0x07,
|
|
0xB3, 0x04, 0x80, 0x3C, 0x80, 0x74, 0x0E, 0x80,
|
|
0x3C, 0x00, 0x75, 0x1C, 0x83, 0xC6, 0x10, 0xFE,
|
|
0xCB, 0x75, 0xEF, 0xCD, 0x18, 0x8B, 0x14, 0x8B,
|
|
0x4C, 0x02, 0x8B, 0xEE, 0x83, 0xC6, 0x10, 0xFE,
|
|
0xCB, 0x74, 0x1A, 0x80, 0x3C, 0x00, 0x74, 0xF4,
|
|
0xBE, 0x8B, 0x06, 0xAC, 0x3C, 0x00, 0x74, 0x0B,
|
|
0x56, 0xBB, 0x07, 0x00, 0xB4, 0x0E, 0xCD, 0x10,
|
|
0x5E, 0xEB, 0xF0, 0xEB, 0xFE, 0xBF, 0x05, 0x00,
|
|
0xBB, 0x00, 0x7C, 0xB8, 0x01, 0x02, 0x57, 0xCD,
|
|
0x13, 0x5F, 0x73, 0x0C, 0x33, 0xC0, 0xCD, 0x13,
|
|
0x4F, 0x75, 0xED, 0xBE, 0xA3, 0x06, 0xEB, 0xD3,
|
|
0xBE, 0xC2, 0x06, 0xBF, 0xFE, 0x7D, 0x81, 0x3D,
|
|
0x55, 0xAA, 0x75, 0xC7, 0x8B, 0xF5, 0xEA, 0x00,
|
|
0x7C, 0x00, 0x00, 0x49, 0x6E, 0x76, 0x61, 0x6C,
|
|
0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
|
|
0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x61, 0x62,
|
|
0x6C, 0x65, 0x00, 0x45, 0x72, 0x72, 0x6F, 0x72,
|
|
0x20, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67,
|
|
0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
|
|
0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
|
|
0x6D, 0x00, 0x4D, 0x69, 0x73, 0x73, 0x69, 0x6E,
|
|
0x67, 0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74,
|
|
0x69, 0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74,
|
|
0x65, 0x6D};
|
|
|
|
/* create partition table */
|
|
PartitionTable partitionTable;
|
|
Partition* ptEntry;
|
|
|
|
tffsset(&partitionTable,0,sizeof partitionTable);
|
|
tffscpy(&partitionTable,bootCode,sizeof bootCode);
|
|
|
|
ptEntry = partitionTable.ptEntry;
|
|
ptEntry->activeFlag = 0x80; /* bootable */
|
|
if (LE2(bpb->noOfHeads) > 1) {
|
|
ptEntry->startingHead = 1;
|
|
toLE2(ptEntry->startingCylinderSector,CYLINDER_SECTOR(0,1));
|
|
}
|
|
else {
|
|
ptEntry->startingHead = 0;
|
|
toLE2(ptEntry->startingCylinderSector,CYLINDER_SECTOR(1,1));
|
|
}
|
|
ptEntry->type = FAT12bit ? 1 : 4;
|
|
ptEntry->endingHead = LE2(bpb->noOfHeads) - 1;
|
|
toLE2(ptEntry->endingCylinderSector,
|
|
(word)CYLINDER_SECTOR((cylinders - 1),LE2(bpb->sectorsPerTrack)));
|
|
toUNAL4(ptEntry->startingSectorOfPartition,LE2(bpb->sectorsPerTrack));
|
|
toUNAL4(ptEntry->sectorsInPartition,LE4(bpb->totalSectorsInVolume));
|
|
|
|
toLE2(partitionTable.signature,PARTITION_SIGNATURE);
|
|
|
|
return vol.writeSector(vol.rec,0,&partitionTable);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* c r e a t e D O S B o o t S e c t o r */
|
|
/* */
|
|
/* Creates the DOS boot sector */
|
|
/* */
|
|
/* Parameters: */
|
|
/* vol : Pointer identifying drive */
|
|
/* bpb : volume BIOS parameter block */
|
|
/* volumeId : 32-bit volume id */
|
|
/* volumeLabel : volume label */
|
|
/* */
|
|
/* Returns: */
|
|
/* FLStatus : 0 on success, failed otherwise */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static FLStatus createDOSbootSector(TL vol,
|
|
BPB *bpb,
|
|
const byte FAR1 *volumeId,
|
|
const byte FAR1 *volumeLabel)
|
|
{
|
|
DOSBootSector bootSector;
|
|
|
|
tffsset(&bootSector,0,sizeof bootSector);
|
|
bootSector.physicalDriveNo = 0x80;
|
|
bootSector.extendedBootSignature = 0x29;
|
|
tffscpy(bootSector.volumeId,volumeId,sizeof bootSector.volumeId);
|
|
tffsset(bootSector.volumeLabel,' ',sizeof bootSector.volumeLabel);
|
|
if (volumeLabel)
|
|
tffscpy(bootSector.volumeLabel,volumeLabel,sizeof bootSector.volumeLabel);
|
|
tffscpy(bootSector.systemId,
|
|
FAT12bit ? "FAT12 " : "FAT16 ",
|
|
sizeof bootSector.systemId);
|
|
|
|
bootSector.bpb = *bpb;
|
|
bootSector.bpb.jumpInstruction[0] = 0xe9;
|
|
tffscpy(bootSector.bpb.OEMname,"MSystems",sizeof bootSector.bpb.OEMname);
|
|
toLE2(bootSector.signature,PARTITION_SIGNATURE);
|
|
|
|
return vol.writeSector(vol.rec,(SectorNo) LE4(bpb->noOfHiddenSectors),&bootSector);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* c r e a t e F A T s */
|
|
/* */
|
|
/* Creates the FAT's */
|
|
/* */
|
|
/* Parameters: */
|
|
/* vol : Pointer identifying drive */
|
|
/* bpb : volume BIOS parameter block */
|
|
/* */
|
|
/* Returns: */
|
|
/* FLStatus : 0 on success, failed otherwise */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static FLStatus createFATs(TL vol, BPB *bpb)
|
|
{
|
|
int iFAT;
|
|
|
|
SectorNo sectorNo = (SectorNo) (LE4(bpb->noOfHiddenSectors) +
|
|
LE2(bpb->reservedSectors));
|
|
|
|
/* create the FATs */
|
|
for (iFAT = 0; iFAT < bpb->noOfFATS; iFAT++) {
|
|
int iSector;
|
|
byte FATEntry[SECTOR_SIZE];
|
|
|
|
for (iSector = 0; iSector < LE2(bpb->sectorsPerFAT); iSector++) {
|
|
tffsset(FATEntry,0,SECTOR_SIZE);
|
|
if (iSector == 0) { /* write the reserved FAT entries */
|
|
FATEntry[0] = bpb->mediaDescriptor;
|
|
FATEntry[1] = 0xff;
|
|
FATEntry[2] = 0xff;
|
|
if (!FAT12bit)
|
|
FATEntry[3] = 0xff;
|
|
}
|
|
checkStatus(vol.writeSector(vol.rec,sectorNo++,FATEntry));
|
|
}
|
|
}
|
|
|
|
return flOK;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* c r e a t e R o o t D i r e c t o r y */
|
|
/* */
|
|
/* Creates the root directory */
|
|
/* */
|
|
/* Parameters: */
|
|
/* vol : Pointer identifying drive */
|
|
/* bpb : volume BIOS parameter block */
|
|
/* volumeLabel : volume label */
|
|
/* */
|
|
/* Returns: */
|
|
/* FLStatus : 0 on success, failed otherwise */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static FLStatus createRootDirectory(TL vol,
|
|
BPB *bpb,
|
|
const byte FAR1 *volumeLabel)
|
|
{
|
|
int iEntry;
|
|
|
|
SectorNo sectorNo = (SectorNo) (LE4(bpb->noOfHiddenSectors) +
|
|
LE2(bpb->reservedSectors) +
|
|
bpb->noOfFATS * LE2(bpb->sectorsPerFAT));
|
|
|
|
/* create the root directory */
|
|
for (iEntry = 0; iEntry < UNAL2(bpb->rootDirectoryEntries);
|
|
iEntry += (SECTOR_SIZE / sizeof(DirectoryEntry))) {
|
|
DirectoryEntry rootDirectorySector[SECTOR_SIZE / sizeof(DirectoryEntry)];
|
|
|
|
tffsset(rootDirectorySector,0,SECTOR_SIZE);
|
|
if (iEntry == 0 && volumeLabel) {
|
|
tffsset(rootDirectorySector[0].name,' ',sizeof rootDirectorySector[0].name);
|
|
tffscpy(rootDirectorySector[0].name,volumeLabel,sizeof rootDirectorySector[0].name);
|
|
rootDirectorySector[0].attributes = 0x28; /* VOL + ARC */
|
|
toLE2(rootDirectorySector[0].updateTime,0);
|
|
toLE2(rootDirectorySector[0].updateDate,0x21); /* 1/1/80 */
|
|
}
|
|
checkStatus(vol.writeSector(vol.rec,sectorNo++,rootDirectorySector));
|
|
}
|
|
|
|
return flOK;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* f l D o s F o r m a t */
|
|
/* */
|
|
/* Writes a DOS-FAT file system on the Flash volume */
|
|
/* */
|
|
/* Parameters: */
|
|
/* vol : Pointer identifying drive */
|
|
/* formatParams : Address of FormatParams structure to use */
|
|
/* */
|
|
/* Returns: */
|
|
/* FLStatus : 0 on success, failed otherwise */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FLStatus flDosFormat(TL vol, BDTLPartitionFormatParams FAR1 *formatParams)
|
|
{
|
|
dword cylinders;
|
|
BPB bpb;
|
|
|
|
getDriveGeometry(&vol,&bpb,&cylinders,formatParams->noOfFATcopies,
|
|
(formatParams->flags & TL_OLD_FORMAT) ? TRUE : FALSE);
|
|
|
|
checkStatus(createMasterBootRecord(&vol,&bpb,cylinders));
|
|
|
|
checkStatus(createDOSbootSector(&vol,&bpb,formatParams->volumeId,formatParams->volumeLabel));
|
|
|
|
checkStatus(createFATs(&vol,&bpb));
|
|
|
|
checkStatus(createRootDirectory(&vol,&bpb,formatParams->volumeLabel));
|
|
|
|
return flOK;
|
|
}
|
|
|
|
#endif
|