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

📄 floppy.c

📁 format命令的源代码
💻 C
字号:
/*
// Program:  Format
// Version:  0.90
// Written By:  Brian E. Reifsnyder
// Copyright:  2002 under the terms of the GNU GPL, Version 2
// Module:  floppy.c
// Description:  Floppy disk specific functions.
*/

#define FLOP

#include <stdlib.h>

#include "floppy.h"
#include "format.h"
#include "btstrct.h"



void Compute_Interleave_Factor()
{
  int index;
  int starting_sector;


  low_level.interleave_factor=drive_specs[param.media_type].interleave_factor;

  index=1;
  starting_sector=0;
  low_level.interleave_index=0;
  do
    {
    low_level.interleave_map[low_level.interleave_index]=index;
    low_level.interleave_index
     =low_level.interleave_index+low_level.interleave_factor;
    if(low_level.interleave_index>=drive_specs[param.media_type].sectors_per_cylinder)
      {
      starting_sector=starting_sector+1;
      low_level.interleave_index=starting_sector;
      }

    index++;
    }while(index<=drive_specs[param.media_type].sectors_per_cylinder);

  if(debug_prog==TRUE)
    {
    printf("\n[DEBUG]  Initial Interleave Map:  \n          ");

    index=0;
    do
      {
      printf("%d ",low_level.interleave_map[index]);
      index++;
      }while(index<=(drive_specs[param.media_type].sectors_per_cylinder-1));
    printf("\n");
    }
}

void Compute_Sector_Skew()
{
  int carry;
  int index;
  int skew_counter;

  if(drive_specs[param.media_type].sector_skew==0) return;

  skew_counter=0;

  do
    {
    carry
     =low_level.interleave_map[(drive_specs[param.media_type].sectors_per_cylinder-1)];

    index=(drive_specs[param.media_type].sectors_per_cylinder-1);

    do
      {
      low_level.interleave_map[index]=low_level.interleave_map[(index-1)];

      index--;
      }while(index>0);

    low_level.interleave_map[0]=carry;

    skew_counter++;
    }while(skew_counter<drive_specs[param.media_type].sector_skew);

  if(debug_prog==TRUE)
    {
    printf("\n[DEBUG]  Interleave Map After Sector Skew:  \n          ");

    index=0;
    do
      {
      printf("%d ",low_level.interleave_map[index]);
      index++;
      }while(index<=(drive_specs[param.media_type].sectors_per_cylinder-1));
    printf("\n");
    }
}


void Format_Floppy_Cylinder(int cylinder,int head)
{
  int drive_number;
  int sector_index;
  int retry_count;

  unsigned int result;

  /* Set Up Track Address Fields */
  TAF track_address_fields[36];
  void *track_address_fields_p=track_address_fields;

  int index=0;
  do
    {
    track_address_fields[index].cylinder=cylinder;
    track_address_fields[index].head=head;
    track_address_fields[index].sector=low_level.interleave_map[index];
    track_address_fields[index].size_code=0x02;

    index++;
    }while(index<drive_specs[param.media_type].sectors_per_cylinder);

  drive_number=param.drive_number;

  if(debug_prog==TRUE)
    {
    printf("[DEBUG]  Formatting:  Cylinder->  %2d    Head->  %2d\n",cylinder,head);
    }

  /* Format the Track */
  result=0;
  regs.h.ah = 0x05;
  regs.h.ch = cylinder;
  regs.h.dh = head;
  regs.h.dl = drive_number;
  sregs.es  = FP_SEG(track_address_fields_p);
  regs.x.bx = FP_OFF(track_address_fields_p);
  int86x(0x13, &regs, &regs, &sregs);
  result = regs.h.ah;

  if(result!=0) Critical_Error_Handler(BIOS,result);

  if(debug_prog==TRUE)
    {
    printf("[DEBUG]  Result From Interrupt 0x13, Service 0x05->  %X\n",result);
    }

  if(param.verify==TRUE)
    {
    /* Verify the Track */
    result=0;
    regs.h.ah = 0x04;
    regs.h.al = drive_specs[param.media_type].sectors_per_cylinder;
    regs.h.ch = cylinder;
    regs.h.cl = 1;                     /* Start with the first sector. */
    regs.h.dh = head;
    regs.h.dl = drive_number;
    int86x(0x13, &regs, &regs, &sregs);
    result = regs.h.ah;

    if(debug_prog==TRUE)
      {
      printf("[DEBUG]  Result From Interrupt 0x13, Service 0x04->  %X\n",result);
      }

    if(result!=0)
      {
      if(debug_prog==TRUE)
	{
	printf("[DEBUG]  Scanning track for bad sectors\n");
	}

      retry_count=0;
      sector_index=1;

      do
	{
retry:
	if(debug_prog==TRUE)
	  {
	  printf("[DEBUG]  Scanning sector number->  %d\n",sector_index);
	  }

	/* Verify the Track...sector by sector. */
	result=0;
	regs.h.ah = 0x04;
	regs.h.al = 1;
	regs.h.ch = cylinder;
	regs.h.cl = sector_index;
	regs.h.dh = head;
	regs.h.dl = drive_number;
	int86x(0x13, &regs, &regs, &sregs);
	result = regs.h.ah;

	if(result!=0)
	  {
	  if(debug_prog==TRUE)
	    {
	    printf("[DEBUG]  Possible bad sector found...testing.  retry_count->  %d\n",retry_count);
	    }

	  retry_count++;

	  if(retry_count>=3)
	    {
	    /* Record this sector as bad. */
	    bad_sector_map[bad_sector_map_pointer]
	     =( (cylinder * (drive_specs[param.media_type].number_of_heads) )
	      * drive_specs[param.media_type].sectors_per_cylinder)
	      + (head * drive_specs[param.media_type].sectors_per_cylinder)
	      + sector_index;

	    bad_sector_map_pointer++;
	    drive_statistics.bytes_in_bad_sectors
	     =drive_statistics.bytes_in_bad_sectors
	     +drive_specs[param.media_type].bytes_per_sector;

	    if(debug_prog==TRUE)
	      {
	      printf("[DEBUG]  Bad Sector->  %d\n",
	       bad_sector_map[(bad_sector_map_pointer-1)]);
	      }

	    retry_count=0;
	    }
	  else goto retry;   /* Yes, it's a goto.  :-)  Even goto has uses. */
	  }

	sector_index++;
	}while(sector_index<=drive_specs[param.media_type].sectors_per_cylinder);

      }
    }
}


void Set_Floppy_Media_Type()
{
  int drive_number=param.drive_number;
  int number_of_cylinders;
  int sectors_per_cylinder;

  if(debug_prog==TRUE)
    {
    printf("[DEBUG]  Current Disk Drive Parameter Table Values:\n");
    printf("[DEBUG]       Step Rate:                 %d\n",ddpt->step_rate);
    printf("[DEBUG]       Head Unload Time:          %d\n",ddpt->head_unload_time);
    printf("[DEBUG]       DMA Flag:                  %d\n",ddpt->dma_flag);
    printf("[DEBUG]       Post R. T. of Disk Motor:  %d\n",ddpt->post_rt_of_disk_motor);
    printf("[DEBUG]       Sector Size:               %d\n",ddpt->sector_size);
    printf("[DEBUG]       Sectors Per Cylinder:      %d\n",ddpt->sectors_per_cylinder);
    printf("[DEBUG]       Intersector Gap Length:    %d\n",ddpt->gap3_length_rw);
    printf("[DEBUG]       Data Length:               %d\n",ddpt->dtl);
    printf("[DEBUG]       Intersect. Gap Len. Xmat:  %d\n",ddpt->gap3_length_xmat);
    printf("[DEBUG]       Fill Character:            %d\n",ddpt->fill_char_xmat);
    printf("[DEBUG]       Head Settle Time:          %d\n",ddpt->head_settle_time);
    printf("[DEBUG]       Motor start=up time:       %d\n",ddpt->run_up_time);
    }

  param.fat_type=FAT12;

  if(param.f==TRUE)
    {
    /* Standard Format Types */
    if(param.size==160) param.media_type=FD160;
    if(param.size==180) param.media_type=FD180;
    if(param.size==320) param.media_type=FD320;
    if(param.size==360) param.media_type=FD360;
    if(param.size==720) param.media_type=FD720;
    if(param.size==1200) param.media_type=FD1200;
    if(param.size==1440) param.media_type=FD1440;
    if(param.size==2880) param.media_type=FD2880;
    /* Non-Standard Format Types */
    if(param.size==400) param.media_type=FD400;
    if(param.size==800) param.media_type=FD800;
    if(param.size==1680) param.media_type=FD1680;
    if(param.size==3360) param.media_type=FD3360;
    if(param.size==1494) param.media_type=FD1494;
    if(param.size==1743) param.media_type=FD1743;
    if(param.size==3486) param.media_type=FD3486;
    if(param.size==1700) param.media_type=FD1700;
    }

  if(param.t==TRUE)
    {
    int index=0;
    do
      {
      if( (param.cylinders==drive_specs[index].cylinders)
       && (param.sectors==drive_specs[index].sectors_per_cylinder) )
	{
	param.media_type=index;
	index=20;
	}

      index++;
      }while(index<8);
    }

  drive_number=param.drive_number;

  if(param.media_type==UNKNOWN)
    {
    /* Attempt to automatically detect the media type */
    int drive_number=param.drive_number;
    int drive_type=0;

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

      drive_type = regs.h.bl;

    if(drive_type==0x01)
      {
      param.size=360;
      param.media_type=FD360;
      }
    if(drive_type==0x02)
      {
      param.size=1200;
      param.media_type=FD1200;
      }
    if(drive_type==0x03)
      {
      param.size=720;
      param.media_type=FD720;
      }
    if(drive_type==0x04)
      {
      param.size=1440;
      param.media_type=FD1440;
      }
    if(drive_type==0x05)     /* Originally for floppy tape drives */
      {
      param.size=2880;
      param.media_type=FD2880;
      }
    if(drive_type==0x06)
      {
      param.size=2880;
      param.media_type=FD2880;
      }
    }

  number_of_cylinders=drive_specs[param.media_type].cylinders;
  sectors_per_cylinder=drive_specs[param.media_type].sectors_per_cylinder;

    regs.h.ah = 0x18;
    regs.h.ch = number_of_cylinders;
    regs.h.cl = sectors_per_cylinder;
    regs.h.dl = drive_number;

    int86(0x13, &regs, &regs);

    if (regs.x.cflag == 0)
	goto int_supported;


  ddpt->sectors_per_cylinder=sectors_per_cylinder;

  int_supported:

  if(param.media_type>HD)
    {
    /* Adjust for non-standard formats. */

    }

  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");
    printf("[DEBUG]       Step Rate:                 %d\n",ddpt->step_rate);
    printf("[DEBUG]       Head Unload Time:          %d\n",ddpt->head_unload_time);
    printf("[DEBUG]       DMA Flag:                  %d\n",ddpt->dma_flag);
    printf("[DEBUG]       Post R. T. of Disk Motor:  %d\n",ddpt->post_rt_of_disk_motor);
    printf("[DEBUG]       Sector Size:               %d\n",ddpt->sector_size);
    printf("[DEBUG]       Sectors Per Cylinder:      %d\n",ddpt->sectors_per_cylinder);
    printf("[DEBUG]       Intersector Gap Length:    %d\n",ddpt->gap3_length_rw);
    printf("[DEBUG]       Data Length:               %d\n",ddpt->dtl);
    printf("[DEBUG]       Intersect. Gap Len. Xmat:  %d\n",ddpt->gap3_length_xmat);
    printf("[DEBUG]       Fill Character:            %d\n",ddpt->fill_char_xmat);
    printf("[DEBUG]       Head Settle Time:          %d\n",ddpt->head_settle_time);
    printf("[DEBUG]       Motor start=up time:       %d\n",ddpt->run_up_time);
    }
}

⌨️ 快捷键说明

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