📄 floppy.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, ®s, ®s, &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, ®s, ®s, &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, ®s, ®s, &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, ®s, ®s);
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, ®s, ®s);
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 + -