⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floppy.c

📁 可以格式化超过200G硬盘的格式化工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    param.sides = 2; /* the default (initialize value!) */
    }

  if (param.four==TRUE)
    {
    /* (also need special SETUP for 360k disk in 1200k drive) */
    param.sectors = 9;
    param.cylinders = 40;
    param.t = TRUE; /* trigger media type search */
    }

  if (param.eight==TRUE)
    {
    /* (this is only for 120k and 320k DOS 1.0 formats) */
    param.sectors = 8;
    param.cylinders = 40;
    param.t = TRUE; /* trigger media type search */
    }

  if (  (param.t==TRUE) /* user wanted a certain number of cylinders (tracks) */
     || (param.f==TRUE) /* user wanted a certain size */
     )
    {
    int index = 0; /* find matching media type from list */
    do
      {

      if ( (  (param.f==TRUE)
           && (param.size == (drive_specs[index].total_sectors >> 1))
           ) ||
           (  (param.t==TRUE)
           && (param.cylinders == drive_specs[index].cylinders)
           && (param.sectors   == drive_specs[index].sectors_per_cylinder)
           && (param.sides     == drive_specs[index].number_of_heads)
           )
         )
	{
	param.media_type = index;

        /* size is always found in the drive_specs, even if already given */
        param.size = drive_specs[index].total_sectors >> 1;

        if (/* *** param.f== *** */ TRUE) /* size given, geometry wanted */
          {
          param.cylinders = drive_specs[index].cylinders;
          param.sectors   = drive_specs[index].sectors_per_cylinder;
          param.sides     = drive_specs[index].number_of_heads;
          }

        printf("Formatting to %ldk (Cyl=%ld Head=%ld Sec=%2ld)\n",
          param.size, param.cylinders, param.sides, param.sectors);
	index = -10; /* break out of the loop */
        } /* end "if match" */
      else
        {
        index++;
        } /* search on if no match */

      } while ( (index>=0) && (drive_specs[index].bytes_per_sector==512) );

    if (index>0)
      {
      if (param.f==TRUE) /* only size given */
        {
        printf("No media type found for %ldk format\n", param.size);
        }
      else /* geometry given */
        {
        param.size = (param.cylinders * param.sides * param.sectors) >> 1;
        printf("No media type found for %ldk format (Cyl=%ld Head=%ld Sec=%2ld)\n",
        param.size, param.cylinders, param.sides, param.sectors);
        }
      exit(50); /* cannot continue anyway, media type needed later! */
      }
    }

  drive_number = param.drive_number;

  /* IF the user gave ANY size indication, we already know which */
  /* media_type the user wants, so we check drive capabilities now! */

  if (TRUE) /* just limiting variable scope */
    {
    int drive_number  = param.drive_number;
    int preferredsize = 0;

      regs.h.ah = 0x08;
      regs.h.dl = drive_number;
      int86(0x13, &regs, &regs);

      drive_type = regs.h.bl;
      preferredsize = 0; /* drive not installed */

    switch (drive_type)
      {
      case 1: preferredsize = 360;
        break;
      case 2: preferredsize = 1200;
        break;
      case 3: preferredsize = 720;
        break;
      case 4: preferredsize = 1440;
        break;
      case 5:
      case 6: preferredsize = 2880;
        break;
        /* Type 5 is originally for floppy tape drives */
      }

    if (param.media_type==UNKNOWN) /* do auto-detection of size! */
      {
      int index = 0; /* find matching media type from list */
      param.size = preferredsize;
      do
        {

        if (param.size == (drive_specs[index].total_sectors >> 1))
	  {
	  param.media_type = index;
          param.cylinders  = drive_specs[index].cylinders;
          param.sectors    = drive_specs[index].sectors_per_cylinder;
          param.sides      = drive_specs[index].number_of_heads;

          printf("Using drive default: %ldk (Cyl=%ld Head=%ld Sec=%2ld)\n",
            param.size, param.cylinders, param.sides, param.sectors);
	  index = -10;
	  }
        else
          {
          index++;
          }

        } while ( (index>=0) && (drive_specs[index].bytes_per_sector==512) );

      if (index >= 0)
        {
        printf("Internal error: default geometry for size %ldk unknown!\n",
          param.size);
        exit(51);
        }
      }
    else
      {
      if (param.size > preferredsize)
        {
        if (param.size > (preferredsize + (preferredsize >> 2)))
          {
          printf("You are trying to go format to more than 125 percent of the\n");
          printf("standard disk size for this drive. You must be kidding.\n");
          printf("Your size: %ldk Standard for this drive: %dk\n",
            param.size, preferredsize);
          exit(43);
          }
        printf("Formatting to more than 100 percent of the standard size\n");
        printf("for this drive: %ldk instead of only %dk. Good luck!\n",
          param.size, preferredsize);
        }
      }
    } /* variable scope end */

  number_of_cylinders  = drive_specs[param.media_type].cylinders;
  sectors_per_cylinder = drive_specs[param.media_type].sectors_per_cylinder;
  /* cannot configure drive for "number of heads" - only used in formatting */

    /* useful cases: 360k in 1200k, 1200k in 1200k, ... */
    /* formats >= 1440k are only set up by int 13.17, not here. */
    /* we already aborted if the format is ABOVE possible range */

    switch (drive_type)
      {
      case 1: /*  360k */
        regs.h.al = 1; /* mode 1: 160, 180, 320, 360, 400k */
        break;
      case 2: /* 1200k */
        regs.h.al = (param.size > 400) ? 3 : 2;
        /* mode 2: like 1, but in 1200k drive. mode 3: 1200k */
        /* mode 3 is probably only for 1220k, but we allow smaller */
        break;
      case 3: /*  720k */
        regs.h.al = 4; /* mode 3: 720, 800k */
        if (param.four || param.one || param.eight)
          {
          printf("This is a 720k drive which does not support /1, /4 or /8\n");
          exit(44);
          }
        if (param.size < 720)
          {
          printf("Minimum size for this drive type is 720k\n");
          exit(44);
          }
        break;
      case 4: /* 1440k */
        regs.h.al = 4; /* standard mode!? (int 13.18 sets details) */
        if (param.four || param.one || param.eight)
          {
          printf("This is an 1440k drive which does not support /1, /4 or /8\n");
          exit(45);
          }
        if ((param.size < 720) || (param.size == 1200))
          {
          printf("Minimum size for this drive type is 720k. 1200k not allowed.\n");
          exit(45);
          }
        break;
      case 5: /* 2880k */
      case 6: /* 2880k */
      default:
        regs.h.al = 0xff; /* no mode setting needed (?) */
        if (param.four || param.one || param.eight)
          {
          printf("This is a 2880k drive which does not support /1, /4 or /8\n");
          exit(46);
          }
        if ((param.size < 720) || (param.size == 1200))
          {
          printf("Minimum size for this drive type is 720k. 1200k not allowed.\n");
          exit(46);
          }
        break;
      }
    if (regs.h.al != 0xff)
      {
      int sizeclass = regs.h.al;

      do
        {
        regs.h.ah = 0x17; /* set disk mode, e.g "360k disk in 1200k drive */
        /* regs.x.cx = 0xffff; */ /* unused */
        regs.h.dl = drive_number;
        regs.x.cflag = 0;
        int86(0x13, &regs, &regs);
        } while ((regs.x.cflag != 0) && (regs.h.ah == 6));
      /* retry if error is only "disk changed" */

      if (regs.x.cflag != 0)
        {
        printf("Drive mode (size class %d) setting failed, error %2.2x (hex)\n",
          sizeclass, regs.h.ah);
        if (regs.h.ah == 0x80)
          {
          printf("No disk in drive!\n");
          exit(42);
          }
        else
          {
          printf("Continuing anyway.\n");
          }
        }
      }

#if 0
    /* why should we not set this now already???: */
    ddpt->sectors_per_cylinder = sectors_per_cylinder;
#endif

    /* only more modern drives / BIOSes support this at all, probably. */
    /* we may not give non-standard geometries NOW - no BIOS support.  */

    regs.h.ah = 0x18; /* set geometry, apart from head count of course */
    regs.h.ch = (number_of_cylinders > 43) ? 79 : 39;
    regs.h.cl = sectors_per_cylinder;

    if (regs.h.cl >= 36)
      {
      regs.h.cl = 36; /* 2.88M or oversized -> 2.88M */
      }
    else
      {
      if (regs.h.cl >= 18)
        {
        regs.h.cl = 18; /* 1.44M or oversized -> 1.44M */
        }
      else
        {
        if (regs.h.cl >= 15)
          {
          regs.h.cl = 15; /* 1.2M or oversized -> 1.2M */
          }
        else
          {
          regs.h.cl = (regs.h.cl > 9) ? 9 : (regs.h.cl);
          /* 720k or 360k or oversized -> 720k or 360k */
          }
        }
      }

    regs.h.dl = drive_number;

    if ((regs.h.cl > 15) || (regs.h.cl < 9) ||
        (ddpt->sectors_per_cylinder != regs.h.cl)
       )
      {
      int86x(0x13, &regs, &regs, &sregs);
      /* 40x[1,2]x8 (?), 80x2x[18,36]: 120, 320, 1440, 2880k */
      if (regs.x.cflag==0)
        {
        regs.h.ah = 0; /* ensure "ok" */
        }
      else
        {
        if (regs.h.ah == 0)
          regs.h.ah = 0x0c; /* ensure "invalid geometry" */
        }
      }
    else
      {
      if (debug_prog==TRUE)
        {
        printf("[DEBUG] Not setting geometry - disk mode should say it all already\n");
        /* 40x[1,2]x9, 80x2x[9,15]: 180, 360, 720, 1200k */
        }
      regs.h.ah = 1; /* "not supported by BIOS" (ignore errors) */
      }

    if (regs.h.ah != 0)
      {

#if 0
      /* try setting sectors per cylinder via DDPT !?!?: */
      ddpt->sectors_per_cylinder = sectors_per_cylinder;
#endif

      if (regs.h.ah==0x80)
        {
        printf("No disk in drive!\n");
        exit(42);
        }

      if (regs.h.ah==1)
        {
        /* BIOS simply does not support 13.18, bad luck */
        }
      else
        {
        printf("Media type %ldk  (%d x %ld x %2d)  not supported by this drive!\n",
          param.size, number_of_cylinders, param.sides, sectors_per_cylinder);
        printf("Geometry set (int 13.18) error (%2.2x). Giving up.\n",
          regs.h.ah);
        exit(24);
        }

      }
    else /* if geometry setting did work */
      {
      /* ES:DI points to an array to which the int 1E vectors should point! */
      /* (added this! -ea) */
      ddpt = MK_FP(sregs.es, regs.x.di); /* WE should know the update, too */
      regs.h.ah = 0x25;
      regs.h.al = 0x1e;
      regs.x.dx = regs.x.di;
      sregs.ds  = sregs.es;
      intdosx(&regs,&regs,&sregs);

      /* if we had COPIED the DDPT, we could actually EDIT (tune) it now */
      /* *** NON-standard formats only work by editing the DDPT *** */
      /* if we COPY the DDPT, we must make sure to RESET it at EXIT */

      if (debug_prog==TRUE)
        {
        printf("[DEBUG] New INT 1E (DDPT) vector: %4.4x:%4.4x.\n",
          sregs.es, regs.x.di);
        }
      }


#if 0
  printf("Media type: %d\n",param.media_type);
#endif


  if (drive_specs[param.media_type].interleave_factor != 1)
    /* could use OTHER marking for "non-standard format" here!      */
    /* e.g.: cylinders not 40 or 80, sectors not 8, 9, 15, 18 or 36 */
    {

    /* Adjust for non-standard formats. */ /* *** TODO *** */
    /* if we had COPIED the DDPT, we could actually EDIT (tune) it now */
    /* *** NON-standard formats only work by editing the DDPT *** */
    /* if we COPY the DDPT, we must make sure to RESET it at EXIT */
    /* The DDPT is what the INT 1E vector points to... */

    if (debug_prog==TRUE)
      {
      printf("Using non-standard (oversized) format. Good luck...\n");
      }

    printf("*** DDPT tweaking for oversized formats not yet possible ***\n");
    exit(88);

    }

  drive_statistics.bytes_total_disk_space =
    ((unsigned long)drive_specs[param.media_type].bytes_per_sector *
    (unsigned long)drive_specs[param.media_type].total_sectors) -
    ((1+(2*(unsigned long)drive_specs[param.media_type].sectors_per_fat) +
    ((unsigned long)drive_specs[param.media_type].root_directory_entries/16)) *
    (unsigned long)drive_specs[param.media_type].bytes_per_sector);

  drive_statistics.bytes_available_on_disk =
    drive_statistics.bytes_total_disk_space;

  drive_statistics.bytes_in_each_allocation_unit =
    (unsigned long)drive_specs[param.media_type].sectors_per_cluster *
    (unsigned long)drive_specs[param.media_type].bytes_per_sector;

  /* Copy BPB into bpb_standard structure. */
  memcpy(&bpb_standard, &drive_specs[param.media_type].bytes_per_sector, 37);

  Compute_Interleave_Factor();

  if (debug_prog==TRUE)
    {
    printf("\n[DEBUG]  Configured Disk Drive Parameter Table Values:\n");
    ddptPrinter();
    }

  if (debug_prog==TRUE)
    {
    char ch;
    printf("-- press ENTER to start formatting or ESCAPE to abort --\n");
    do
      {
      regs.h.ah = 7;
      intdos(&regs, &regs);
      ch = regs.h.al;
      }
      while ((ch != 13) && (ch != 27));
    /* (avoids important information scrolling away) */
    if (ch != 13)
      exit(1);
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -