home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d535
/
format.lha
/
Format
/
OldFormat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-26
|
11KB
|
471 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by Olaf Barthel & MXM
*
* Name .....: OldFormat.c
* Created ..: Wednesday 29-May-91 17:06
* Revision .: 1
*
* Date Author Comment
* ========= ======== ====================
* 29-May-91 Olsen Created this file!
*
****************************************************************************
*
* This file contains disk initialization routines written for
* Kickstart 1.2 and 1.3. They will probably work with Kickstart 2.0
* and above and require that the approriate filing system is
* `inhibited' before any write access takes place. Manx and Arp
* have different routines to pass the the approriate Dos packet,
* so this part of the formatting process is omitted.
*
* The main routine (EraseDisk) is extensively documented, the rest
* lacks a decent description. Nevertheless, these routines work
* like the Format dos.library call available under Kickstart 2.0
*
* $Revision Header ********************************************************/
#include <libraries/filehandler.h>
#include <libraries/dosextens.h>
#include <devices/trackdisk.h>
#include <exec/memory.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
struct BitmapBlock
{
ULONG Checksum;
ULONG Bitmap[127];
};
struct BitmapExtension
{
ULONG BitmapPointers[127];
ULONG BitmapExtension;
};
struct RootDirectory
{
ULONG PrimaryType;
ULONG HeaderKey;
ULONG WhoKnows0;
ULONG HashTableSize;
ULONG WhoKnows1;
ULONG Checksum;
ULONG HashTable[72];
ULONG BitmapFlag;
ULONG BitmapPointers[25];
ULONG BitmapExtension;
struct DateStamp LastRootChange;
UBYTE DiskName[32];
ULONG WhoKnows2[2];
struct DateStamp LastDiskChange;
struct DateStamp CreationDate;
ULONG NextHash;
ULONG ParentDir;
ULONG WhoKnows3;
ULONG SecondaryType;
};
STATIC UBYTE
Local2Upper(UBYTE c)
{
return((UBYTE)((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : (c)));
}
STATIC LONG
StrCmp(UBYTE *a,UBYTE *b)
{
for( ; Local2Upper(*a) == Local2Upper(*b) ; a++, b++)
{
if(!(*a))
return(0);
}
return((LONG)(Local2Upper(*a) - Local2Upper(*b)));
}
STATIC struct FileSysStartupMsg *
FindDevice(UBYTE *DevName)
{
extern struct DosLibrary *DOSBase;
UBYTE *Pointer,i,Name[40];
struct DeviceNode *DevInfo;
Forbid();
DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
while(DevInfo)
{
if(DevInfo -> dn_Type == DLT_DEVICE)
{
Pointer = (UBYTE *)BADDR(DevInfo -> dn_Name);
for(i = 0 ; i < Pointer[0] ; i++)
Name[i] = Pointer[i + 1];
Name[Pointer[0] ] = ':';
Name[Pointer[0] + 1] = 0;
if(!StrCmp(Name,DevName))
{
Permit();
return(BADDR(DevInfo -> dn_Startup));
}
}
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
}
Permit();
return(NULL);
}
STATIC ULONG
Checksum(ULONG *DiskSector)
{
ULONG Sum;
SHORT i;
for(Sum = 0, i = 0 ; i < (TD_SECTOR >> 2) ; i++)
Sum += DiskSector[i];
return(Sum);
}
STATIC LONG
WriteBlock(struct IOExtTD *DevRequest,APTR Buffer,ULONG Offset)
{
DevRequest -> iotd_Req . io_Command = CMD_WRITE;
DevRequest -> iotd_Req . io_Data = Buffer;
DevRequest -> iotd_Req . io_Length = TD_SECTOR;
DevRequest -> iotd_Req . io_Offset = Offset * TD_SECTOR;
return((LONG)DoIO(DevRequest));
}
STATIC LONG
EraseDisk(UBYTE *DiskName,struct IOExtTD *DevRequest,ULONG FirstBlock,ULONG Blocks,ULONG Reserved,ULONG DosType)
{
STATIC ULONG Bits[32] =
{
0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFB,0xFFFFFFF7,
0xFFFFFFEF,0xFFFFFFDF,0xFFFFFFBF,0xFFFFFF7F,
0xFFFFFEFF,0xFFFFFDFF,0xFFFFFBFF,0xFFFFF7FF,
0xFFFFEFFF,0xFFFFDFFF,0xFFFFBFFF,0xFFFF7FFF,
0xFFFEFFFF,0xFFFDFFFF,0xFFFBFFFF,0xFFF7FFFF,
0xFFEFFFFF,0xFFDFFFFF,0xFFBFFFFF,0xFF7FFFFF,
0xFEFFFFFF,0xFDFFFFFF,0xFBFFFFFF,0xF7FFFFFF,
0xEFFFFFFF,0xDFFFFFFF,0xBFFFFFFF,0x7FFFFFFF
};
ULONG *Bitmap,AllocSize;
APTR Buffer;
struct BitmapBlock *BitmapBlock;
struct BitmapExtension *BitmapExtension;
struct RootDirectory *RootDirectory;
LONG i,Count,Root,Len;
LONG BitmapCount,BitmapBlocks;
LONG ExtensionCount,ExtensionBlocks = 0;
LONG Error;
/* Number of long words to allocate for the bitmap. */
AllocSize = (Blocks - Reserved + 31) / 32;
/* Allocate a block-sized buffer. */
if(Buffer = AllocMem(TD_SECTOR,MEMF_PUBLIC|MEMF_CHIP))
{
/* Clear the buffer. */
memset(Buffer,0,TD_SECTOR);
/* Enough space to write the boot block? */
if(Reserved)
{
/* Put the DOS type field into the first longword. */
*(ULONG *)Buffer = DosType;
/* And write it. */
if(Error = WriteBlock(DevRequest,Buffer,0 + FirstBlock))
return(Error);
memset(Buffer,0,TD_SECTOR);
/* Clear the rest. */
for(i = 1 ; i < Reserved ; i++)
{
if(Error = WriteBlock(DevRequest,Buffer,FirstBlock + i))
return(Error);
}
}
/* Allocate space for the bitmap. */
if(Bitmap = (ULONG *)AllocMem(sizeof(ULONG) * AllocSize,MEMF_PUBLIC))
{
/* Mark all blocks as `unused'. */
for(i = 0 ; i < AllocSize ; i++)
Bitmap[i] = ~0;
/* Determine number of bitmap blocks. */
Count = BitmapBlocks = (AllocSize + 126) / 127;
/* If there are more than 25 bitmap blocks to create,
* we will need at least one bitmap extension block.
*/
if(Count > 25)
{
/* The old filing system doesn't support bitmap
* extension blocks.
*/
if(DosType == ID_DOS_DISK)
return(-1);
/* Subtract 25 blocks since they will fit into the
* root block.
*/
Count -= 25;
/* Add the extension blocks. */
do
{
ExtensionBlocks++;
/* Subtract the blocks that will fit into the
* extension block.
*/
if(Count > 127)
Count -= 127;
else
Count = 0;
}
while(Count);
}
/* Calculate the root block offset. */
Root = Blocks >> 1;
RootDirectory = Buffer;
memset(RootDirectory,0,TD_SECTOR);
/* Fill in the root directory data. */
RootDirectory -> PrimaryType = 2;
RootDirectory -> HashTableSize = 128 - 56;
RootDirectory -> BitmapFlag = DOSTRUE;
DateStamp(&RootDirectory -> LastRootChange);
if((Len = strlen(DiskName)) > 31)
Len = 31;
RootDirectory -> DiskName[0] = Len;
CopyMem(DiskName,&RootDirectory -> DiskName[1],Len);
DateStamp(&RootDirectory -> LastDiskChange);
DateStamp(&RootDirectory -> CreationDate);
RootDirectory -> SecondaryType = 1;
/* Fill in the bitmap block pointers. */
for(i = 0 ; i < BitmapBlocks ; i++)
{
if(i == 25)
break;
else
RootDirectory -> BitmapPointers[i] = Root + 1 + i + FirstBlock;
}
/* If there are more than 25 bitmap blocks, fill in the
* pointer to the first bitmap extension block.
*/
if(BitmapBlocks > 25)
RootDirectory -> BitmapExtension = Root + 1 + 25 + FirstBlock;
/* Calculate the block checksum. */
RootDirectory -> Checksum = - Checksum((ULONG *)RootDirectory);
/* And write the block. */
if(Error = WriteBlock(DevRequest,RootDirectory,Root + FirstBlock))
return(Error);
/* The blocks to be occupied by the root block, the bitmap
* blocks and the extension blocks are to be marked as
* being `in use'.
*/
for(i = Root - Reserved ; i < Root - Reserved + 1 + BitmapBlocks + ExtensionBlocks ; i++)
Bitmap[i / 32] &= Bits[i % 32];
BitmapBlock = Buffer;
/* The root block has been written, now continue with the
* bitmap blocks.
*/
for(i = 0 ; i < BitmapBlocks ; i++)
{
/* Copy the bitmap data. */
CopyMem(&Bitmap[127 * i],&BitmapBlock -> Bitmap[0],127 * sizeof(ULONG));
/* Calculate the block checksum. */
BitmapBlock -> Checksum = 0;
BitmapBlock -> Checksum = - Checksum((ULONG *)BitmapBlock);
/* And write the block. */
if(Error = WriteBlock(DevRequest,BitmapBlock,Root + 1 + i + FirstBlock))
return(Error);
}
BitmapExtension = Buffer;
/* If there are any bitmap extension blocks, create them. */
if(ExtensionBlocks)
{
/* Remember the first blocks to deal with. */
BitmapCount = Root + 1 + FirstBlock;
ExtensionCount = BitmapCount + BitmapBlocks;
/* Subtract the first 25 blocks. */
BitmapBlocks -= 25;
/* As long as there are any blocks, put them into
* the extension blocks.
*/
while(BitmapBlocks)
{
memset(BitmapExtension,0,TD_SECTOR);
/* Fill in the bitmap pointers. */
for(i = 0 ; i < (BitmapBlocks < 127 ? BitmapBlocks : 127) ; i++)
BitmapExtension -> BitmapPointers[i] = BitmapCount++;
/* Subtract the bitmap blocks bound to the extension
* block.
*/
if(BitmapBlocks > 127)
BitmapBlocks -= 127;
else
BitmapBlocks = 0;
/* If there are any bitmap blocks left, chain
* this bitmap extension block to the next one.
*/
if(BitmapBlocks)
BitmapExtension -> BitmapExtension = ExtensionCount + 1;
/* And write it. */
if(Error = WriteBlock(DevRequest,BitmapExtension,ExtensionCount++))
return(Error);
}
}
/* Free the data. */
FreeMem(Bitmap,sizeof(ULONG) * AllocSize);
FreeMem(Buffer,TD_SECTOR);
return(0);
}
FreeMem(Buffer,TD_SECTOR);
}
return(-1);
}
LONG
Format(UBYTE *Drive,UBYTE *Name,ULONG DosType)
{
struct FileSysStartupMsg *Startup;
struct DosEnvec *DosEnvec;
LONG Success = FALSE;
if(Startup = FindDevice(Drive))
{
struct IOExtTD *DevRequest;
struct MsgPort *DevPort;
if(DevPort = CreatePort(NULL,0))
{
if(DevRequest = (struct IOExtTD *)CreateExtIO(DevPort,sizeof(struct IOExtTD)))
{
if(!OpenDevice(&((UBYTE *)BADDR(Startup -> fssm_Device))[1],Startup -> fssm_Unit,DevRequest,Startup -> fssm_Flags))
{
DosEnvec = (struct DosEnvec *)BADDR(Startup -> fssm_Environ);
DevRequest -> iotd_Req . io_Command = TD_MOTOR;
DevRequest -> iotd_Req . io_Length = 1;
DoIO(DevRequest);
if(!EraseDisk(Name,DevRequest,DosEnvec -> de_LowCyl * DosEnvec -> de_BlocksPerTrack * DosEnvec -> de_Surfaces,(DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1) * DosEnvec -> de_BlocksPerTrack * DosEnvec -> de_Surfaces,DosEnvec -> de_Reserved,DosType))
Success = TRUE;
DevRequest -> iotd_Req . io_Command = TD_MOTOR;
DevRequest -> iotd_Req . io_Length = 0;
DoIO(DevRequest);
CloseDevice(DevRequest);
}
DeleteExtIO(DevRequest);
}
DeletePort(DevPort);
}
}
return(Success);
}