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 >
C/C++ Source or Header  |  1991-08-26  |  11KB  |  471 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by Olaf Barthel & MXM
  4.  *
  5.  *    Name .....: OldFormat.c
  6.  *    Created ..: Wednesday 29-May-91 17:06
  7.  *    Revision .: 1
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    29-May-91       Olsen           Created this file!
  12.  *
  13.  ****************************************************************************
  14.  *
  15.  *    This file contains disk initialization routines written for
  16.  *    Kickstart 1.2 and 1.3. They will probably work with Kickstart 2.0
  17.  *    and above and require that the approriate filing system is
  18.  *    `inhibited' before any write access takes place. Manx and Arp
  19.  *    have different routines to pass the the approriate Dos packet,
  20.  *    so this part of the formatting process is omitted.
  21.  *
  22.  *    The main routine (EraseDisk) is extensively documented, the rest
  23.  *    lacks a decent description. Nevertheless, these routines work
  24.  *    like the Format dos.library call available under Kickstart 2.0
  25.  *
  26.  * $Revision Header ********************************************************/
  27.  
  28. #include <libraries/filehandler.h>
  29. #include <libraries/dosextens.h>
  30. #include <devices/trackdisk.h>
  31. #include <exec/memory.h>
  32.  
  33. #include <clib/alib_protos.h>
  34. #include <clib/exec_protos.h>
  35. #include <clib/dos_protos.h>
  36.  
  37. struct BitmapBlock
  38. {
  39.     ULONG            Checksum;
  40.     ULONG            Bitmap[127];
  41. };
  42.  
  43. struct BitmapExtension
  44. {
  45.     ULONG            BitmapPointers[127];
  46.     ULONG            BitmapExtension;
  47. };
  48.  
  49. struct RootDirectory
  50. {
  51.     ULONG            PrimaryType;
  52.     ULONG            HeaderKey;
  53.  
  54.     ULONG            WhoKnows0;
  55.     ULONG            HashTableSize;
  56.     ULONG            WhoKnows1;
  57.  
  58.     ULONG            Checksum;
  59.  
  60.     ULONG            HashTable[72];
  61.  
  62.     ULONG            BitmapFlag;
  63.  
  64.     ULONG            BitmapPointers[25];
  65.     ULONG            BitmapExtension;
  66.  
  67.     struct DateStamp    LastRootChange;
  68.  
  69.     UBYTE            DiskName[32];
  70.  
  71.     ULONG            WhoKnows2[2];
  72.  
  73.     struct DateStamp    LastDiskChange;
  74.     struct DateStamp    CreationDate;
  75.  
  76.     ULONG            NextHash;
  77.     ULONG            ParentDir;
  78.  
  79.     ULONG            WhoKnows3;
  80.  
  81.     ULONG            SecondaryType;
  82. };
  83.  
  84. STATIC UBYTE
  85. Local2Upper(UBYTE c)
  86. {
  87.     return((UBYTE)((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : (c)));
  88. }
  89.  
  90. STATIC LONG
  91. StrCmp(UBYTE *a,UBYTE *b)
  92. {
  93.     for( ; Local2Upper(*a) == Local2Upper(*b) ; a++, b++)
  94.     {
  95.         if(!(*a))
  96.             return(0);
  97.     }
  98.  
  99.     return((LONG)(Local2Upper(*a) - Local2Upper(*b)));
  100. }
  101.  
  102. STATIC struct FileSysStartupMsg *
  103. FindDevice(UBYTE *DevName)
  104. {
  105.     extern struct DosLibrary *DOSBase;
  106.  
  107.     UBYTE            *Pointer,i,Name[40];
  108.     struct DeviceNode    *DevInfo;
  109.  
  110.     Forbid();
  111.  
  112.     DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
  113.  
  114.     while(DevInfo)
  115.     {
  116.         if(DevInfo -> dn_Type == DLT_DEVICE)
  117.         {
  118.             Pointer = (UBYTE *)BADDR(DevInfo -> dn_Name);
  119.  
  120.             for(i = 0 ; i < Pointer[0] ; i++)
  121.                 Name[i] = Pointer[i + 1];
  122.  
  123.             Name[Pointer[0]    ] = ':';
  124.             Name[Pointer[0] + 1] = 0;
  125.  
  126.             if(!StrCmp(Name,DevName))
  127.             {
  128.                 Permit();
  129.  
  130.                 return(BADDR(DevInfo -> dn_Startup));
  131.             }
  132.         }
  133.  
  134.         DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  135.     }
  136.  
  137.     Permit();
  138.  
  139.     return(NULL);
  140. }
  141.  
  142. STATIC ULONG
  143. Checksum(ULONG *DiskSector)
  144. {
  145.     ULONG Sum;
  146.     SHORT i;
  147.  
  148.     for(Sum = 0, i = 0 ; i < (TD_SECTOR >> 2) ; i++)
  149.         Sum += DiskSector[i];
  150.  
  151.     return(Sum);
  152. }
  153.  
  154. STATIC LONG
  155. WriteBlock(struct IOExtTD *DevRequest,APTR Buffer,ULONG Offset)
  156. {
  157.     DevRequest -> iotd_Req . io_Command    = CMD_WRITE;
  158.     DevRequest -> iotd_Req . io_Data    = Buffer;
  159.     DevRequest -> iotd_Req . io_Length    = TD_SECTOR;
  160.     DevRequest -> iotd_Req . io_Offset    = Offset * TD_SECTOR;
  161.  
  162.     return((LONG)DoIO(DevRequest));
  163. }
  164.  
  165. STATIC LONG
  166. EraseDisk(UBYTE *DiskName,struct IOExtTD *DevRequest,ULONG FirstBlock,ULONG Blocks,ULONG Reserved,ULONG DosType)
  167. {
  168.     STATIC ULONG Bits[32] =
  169.     {
  170.         0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFB,0xFFFFFFF7,
  171.         0xFFFFFFEF,0xFFFFFFDF,0xFFFFFFBF,0xFFFFFF7F,
  172.         0xFFFFFEFF,0xFFFFFDFF,0xFFFFFBFF,0xFFFFF7FF,
  173.         0xFFFFEFFF,0xFFFFDFFF,0xFFFFBFFF,0xFFFF7FFF,
  174.         0xFFFEFFFF,0xFFFDFFFF,0xFFFBFFFF,0xFFF7FFFF,
  175.         0xFFEFFFFF,0xFFDFFFFF,0xFFBFFFFF,0xFF7FFFFF,
  176.         0xFEFFFFFF,0xFDFFFFFF,0xFBFFFFFF,0xF7FFFFFF,
  177.         0xEFFFFFFF,0xDFFFFFFF,0xBFFFFFFF,0x7FFFFFFF
  178.     };
  179.  
  180.     ULONG            *Bitmap,AllocSize;
  181.     APTR             Buffer;
  182.     struct BitmapBlock    *BitmapBlock;
  183.     struct BitmapExtension    *BitmapExtension;
  184.     struct RootDirectory    *RootDirectory;
  185.     LONG             i,Count,Root,Len;
  186.     LONG             BitmapCount,BitmapBlocks;
  187.     LONG             ExtensionCount,ExtensionBlocks = 0;
  188.     LONG             Error;
  189.  
  190.         /* Number of long words to allocate for the bitmap. */
  191.  
  192.     AllocSize = (Blocks - Reserved + 31) / 32;
  193.  
  194.         /* Allocate a block-sized buffer. */
  195.  
  196.     if(Buffer = AllocMem(TD_SECTOR,MEMF_PUBLIC|MEMF_CHIP))
  197.     {
  198.             /* Clear the buffer. */
  199.  
  200.         memset(Buffer,0,TD_SECTOR);
  201.  
  202.             /* Enough space to write the boot block? */
  203.  
  204.         if(Reserved)
  205.         {
  206.                 /* Put the DOS type field into the first longword. */
  207.  
  208.             *(ULONG *)Buffer = DosType;
  209.  
  210.                 /* And write it. */
  211.  
  212.             if(Error = WriteBlock(DevRequest,Buffer,0 + FirstBlock))
  213.                 return(Error);
  214.  
  215.             memset(Buffer,0,TD_SECTOR);
  216.  
  217.                 /* Clear the rest. */
  218.  
  219.             for(i = 1 ; i < Reserved ; i++)
  220.             {
  221.                 if(Error = WriteBlock(DevRequest,Buffer,FirstBlock + i))
  222.                     return(Error);
  223.             }
  224.         }
  225.  
  226.             /* Allocate space for the bitmap. */
  227.  
  228.         if(Bitmap = (ULONG *)AllocMem(sizeof(ULONG) * AllocSize,MEMF_PUBLIC))
  229.         {
  230.                 /* Mark all blocks as `unused'. */
  231.  
  232.             for(i = 0 ; i < AllocSize ; i++)
  233.                 Bitmap[i] = ~0;
  234.  
  235.                 /* Determine number of bitmap blocks. */
  236.  
  237.             Count = BitmapBlocks = (AllocSize + 126) / 127;
  238.  
  239.                 /* If there are more than 25 bitmap blocks to create,
  240.                  * we will need at least one bitmap extension block.
  241.                  */
  242.  
  243.             if(Count > 25)
  244.             {
  245.                     /* The old filing system doesn't support bitmap
  246.                      * extension blocks.
  247.                      */
  248.  
  249.                 if(DosType == ID_DOS_DISK)
  250.                     return(-1);
  251.  
  252.                     /* Subtract 25 blocks since they will fit into the
  253.                      * root block.
  254.                      */
  255.  
  256.                 Count -= 25;
  257.  
  258.                     /* Add the extension blocks. */
  259.  
  260.                 do
  261.                 {
  262.                     ExtensionBlocks++;
  263.  
  264.                         /* Subtract the blocks that will fit into the
  265.                          * extension block.
  266.                          */
  267.  
  268.                     if(Count > 127)
  269.                         Count -= 127;
  270.                     else
  271.                         Count = 0;
  272.                 }
  273.                 while(Count);
  274.             }
  275.  
  276.                 /* Calculate the root block offset. */
  277.  
  278.             Root = Blocks >> 1;
  279.  
  280.             RootDirectory = Buffer;
  281.  
  282.             memset(RootDirectory,0,TD_SECTOR);
  283.  
  284.                 /* Fill in the root directory data. */
  285.  
  286.             RootDirectory -> PrimaryType    = 2;
  287.             RootDirectory -> HashTableSize    = 128 - 56;
  288.             RootDirectory -> BitmapFlag    = DOSTRUE;
  289.  
  290.             DateStamp(&RootDirectory -> LastRootChange);
  291.  
  292.             if((Len = strlen(DiskName)) > 31)
  293.                 Len = 31;
  294.  
  295.             RootDirectory -> DiskName[0]    = Len;
  296.  
  297.             CopyMem(DiskName,&RootDirectory -> DiskName[1],Len);
  298.  
  299.             DateStamp(&RootDirectory -> LastDiskChange);
  300.             DateStamp(&RootDirectory -> CreationDate);
  301.  
  302.             RootDirectory -> SecondaryType    = 1;
  303.  
  304.                 /* Fill in the bitmap block pointers. */
  305.  
  306.             for(i = 0 ; i < BitmapBlocks ; i++)
  307.             {
  308.                 if(i == 25)
  309.                     break;
  310.                 else
  311.                     RootDirectory -> BitmapPointers[i] = Root + 1 + i + FirstBlock;
  312.             }
  313.  
  314.                 /* If there are more than 25 bitmap blocks, fill in the
  315.                  * pointer to the first bitmap extension block.
  316.                  */
  317.  
  318.             if(BitmapBlocks > 25)
  319.                 RootDirectory -> BitmapExtension = Root + 1 + 25 + FirstBlock;
  320.  
  321.                 /* Calculate the block checksum. */
  322.  
  323.             RootDirectory -> Checksum = - Checksum((ULONG *)RootDirectory);
  324.  
  325.                 /* And write the block. */
  326.  
  327.             if(Error = WriteBlock(DevRequest,RootDirectory,Root + FirstBlock))
  328.                 return(Error);
  329.  
  330.                 /* The blocks to be occupied by the root block, the bitmap
  331.                  * blocks and the extension blocks are to be marked as
  332.                  * being `in use'.
  333.                  */
  334.  
  335.             for(i = Root - Reserved ; i < Root - Reserved + 1 + BitmapBlocks + ExtensionBlocks ; i++)
  336.                 Bitmap[i / 32] &= Bits[i % 32];
  337.  
  338.             BitmapBlock = Buffer;
  339.  
  340.                 /* The root block has been written, now continue with the
  341.                  * bitmap blocks.
  342.                  */
  343.  
  344.             for(i = 0 ; i < BitmapBlocks ; i++)
  345.             {
  346.                     /* Copy the bitmap data. */
  347.  
  348.                 CopyMem(&Bitmap[127 * i],&BitmapBlock -> Bitmap[0],127 * sizeof(ULONG));
  349.  
  350.                     /* Calculate the block checksum. */
  351.  
  352.                 BitmapBlock -> Checksum = 0;
  353.                 BitmapBlock -> Checksum = - Checksum((ULONG *)BitmapBlock);
  354.  
  355.                     /* And write the block. */
  356.  
  357.                 if(Error = WriteBlock(DevRequest,BitmapBlock,Root + 1 + i + FirstBlock))
  358.                     return(Error);
  359.             }
  360.  
  361.             BitmapExtension = Buffer;
  362.  
  363.                 /* If there are any bitmap extension blocks, create them. */
  364.  
  365.             if(ExtensionBlocks)
  366.             {
  367.                     /* Remember the first blocks to deal with. */
  368.  
  369.                 BitmapCount    = Root + 1 + FirstBlock;
  370.                 ExtensionCount    = BitmapCount + BitmapBlocks;
  371.  
  372.                     /* Subtract the first 25 blocks. */
  373.  
  374.                 BitmapBlocks -= 25;
  375.  
  376.                     /* As long as there are any blocks, put them into
  377.                      * the extension blocks.
  378.                      */
  379.  
  380.                 while(BitmapBlocks)
  381.                 {
  382.                     memset(BitmapExtension,0,TD_SECTOR);
  383.  
  384.                         /* Fill in the bitmap pointers. */
  385.  
  386.                     for(i = 0 ; i < (BitmapBlocks < 127 ? BitmapBlocks : 127) ; i++)
  387.                         BitmapExtension -> BitmapPointers[i] = BitmapCount++;
  388.  
  389.                         /* Subtract the bitmap blocks bound to the extension
  390.                          * block.
  391.                          */
  392.  
  393.                     if(BitmapBlocks > 127)
  394.                         BitmapBlocks -= 127;
  395.                     else
  396.                         BitmapBlocks = 0;
  397.  
  398.                         /* If there are any bitmap blocks left, chain
  399.                          * this bitmap extension block to the next one.
  400.                          */
  401.  
  402.                     if(BitmapBlocks)
  403.                         BitmapExtension -> BitmapExtension = ExtensionCount + 1;
  404.  
  405.                         /* And write it. */
  406.  
  407.                     if(Error = WriteBlock(DevRequest,BitmapExtension,ExtensionCount++))
  408.                         return(Error);
  409.                 }
  410.             }
  411.  
  412.                 /* Free the data. */
  413.  
  414.             FreeMem(Bitmap,sizeof(ULONG) * AllocSize);
  415.             FreeMem(Buffer,TD_SECTOR);
  416.  
  417.             return(0);
  418.         }
  419.  
  420.         FreeMem(Buffer,TD_SECTOR);
  421.     }
  422.  
  423.     return(-1);
  424. }
  425.  
  426. LONG
  427. Format(UBYTE *Drive,UBYTE *Name,ULONG DosType)
  428. {
  429.     struct FileSysStartupMsg    *Startup;
  430.     struct DosEnvec            *DosEnvec;
  431.     LONG                 Success = FALSE;
  432.  
  433.     if(Startup = FindDevice(Drive))
  434.     {
  435.         struct IOExtTD    *DevRequest;
  436.         struct MsgPort    *DevPort;
  437.  
  438.         if(DevPort = CreatePort(NULL,0))
  439.         {
  440.             if(DevRequest = (struct IOExtTD *)CreateExtIO(DevPort,sizeof(struct IOExtTD)))
  441.             {
  442.                 if(!OpenDevice(&((UBYTE *)BADDR(Startup -> fssm_Device))[1],Startup -> fssm_Unit,DevRequest,Startup -> fssm_Flags))
  443.                 {
  444.                     DosEnvec = (struct DosEnvec *)BADDR(Startup -> fssm_Environ);
  445.  
  446.                     DevRequest -> iotd_Req . io_Command    = TD_MOTOR;
  447.                     DevRequest -> iotd_Req . io_Length    = 1;
  448.  
  449.                     DoIO(DevRequest);
  450.  
  451.                     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))
  452.                         Success = TRUE;
  453.  
  454.                     DevRequest -> iotd_Req . io_Command    = TD_MOTOR;
  455.                     DevRequest -> iotd_Req . io_Length    = 0;
  456.  
  457.                     DoIO(DevRequest);
  458.  
  459.                     CloseDevice(DevRequest);
  460.                 }
  461.  
  462.                 DeleteExtIO(DevRequest);
  463.             }
  464.  
  465.             DeletePort(DevPort);
  466.         }
  467.     }
  468.  
  469.     return(Success);
  470. }
  471.