home *** CD-ROM | disk | FTP | other *** search
- /* $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);
- }
-