home *** CD-ROM | disk | FTP | other *** search
-
-
-
- /*************************************/
- /* */
- /* */
- /* */
- /*************************************/
-
- /*
- Western Digital Corp. Format Routine
-
- Author: Dave Evans
- Edited by Tom Devlin
-
- Creation Date: 08/08/86
- Revision Date: 7/23/87
- Revision: 2.00
-
- Formats drive based on #cylinders, #heads, #sectors, and
- interleave entered at command line or on screen. Does low-level format
- followed by a Read-verify of the entire drive. Shows errors
- detected, then allows user to enter additional blocks to
- format with bad block marks. The program may be aborted
- with an Escape at both the Format prompt and at the Format
- Bad Block prompt.
-
- Rev. 1.01 dle
- Added ability to format drive D:, and also the ability to
- specify the precomp cylinder.
- New command line format:
- WDFMT drive #cyls #heads #sectors interleave precomp-cyl
-
- Rev.2.00 thd
- Added ability to format up to 16 heads.
- fix to enable format of drive 1.
- New drive spec enrty by screen:
-
- */
- #include <\c_lat\comp\dos.h>
- #include <\c_lat\comp\stdio.h>
- #include <\c_lat\comp\ctype.h>
- #include <\c_lat\comp\math.h>
- #include <\c_lat\comp\limits.h>
-
-
-
- #define then
- #define esc '\x1b'
- #define true -1
- #define false 0
-
- #define buf_length (512+10)
- #define hard 1
- #define soft 0
-
- #define curs(a,b) pcvscp((a-1), (b-1))
- #define bell printf("%c", 7)
- #define ARROW printf("%c", 16)
- #define BLANK printf(" ")
- #define char_ready pckchk()
-
- /* Global variables:
-
- Command parser modifies the tables, and global flags
- indicate to the Main routine the requested action.
-
- */
-
- struct htable
- {
- int drv_number;
- int cyl_number;
- int head_number;
- int sec_number;
- int blk_size;
- int max_cyl;
- int max_head;
- int max_sec;
- int precomp;
- int retry;
- int step;
- int ileave;
- int ecc_len;
- float bits_read;
- } hd_table;
-
- struct tfile
- {
- int error;
- int secnt;
- int sector;
- int cyllo;
- int cylhi;
- int SDH;
- int status;
- int secstat;
- int DIR;
- } task_file;
-
- struct esfile
- {
- int xfrlo;
- int xfrhi;
- int plo;
- int gap;
- int stat;
- };
-
- union scan
- {
- int c;
- char ch[2];
- } scan_code;
-
- char *rd_buffer, *wr_buffer, *fmt_buffer;
-
- struct error
- {
- int cyl;
- int head;
- };
-
- struct error err_table[100];
-
- int err_count, errcnt;
- int temp;
-
- main(argc, argv)
-
- int argc;
- char *argv[];
-
- {
-
- char *malloc();
- char resp, temp_str[8];
- int bad_count;
-
- wr_buffer = malloc(buf_length);
- rd_buffer = malloc(buf_length);
- fmt_buffer = malloc(buf_length);
-
- /*************************************/
- /* */
- /* start of main body */
- /* */
- /*************************************/
-
- hd_table.sec_number = 1; /*initialize hd_table to defalt */
- hd_table.blk_size = 1;
- hd_table.max_cyl = 615;
- hd_table.max_head = 4;
- hd_table.max_sec = 17;
- hd_table.precomp = 306;
- hd_table.retry = 0;
- hd_table.step = 0;
- hd_table.ileave = 3;
- hd_table.drv_number = 0;
-
-
- get_spec(argc, argv); /* get specs user typed in when prog called */
- screen_update(); /* out put screen */
- get_2spec(); /* get drive specs from screen */
- get_command(); /* get escape or F from standerd input */
-
- /* set up hd_table with adjusted values */
-
- hd_table.max_cyl--;
- hd_table.max_head--;
- hd_table.precomp = (int)(hd_table.precomp/4);
-
- at_reset(); /* reset hard drive */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* wait untill drive is ready */
-
- load_task_file(); /* load task file */
- at_setp(hd_table.drv_number, hd_table.max_sec, hd_table.max_head); /* set up param on controler */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* wait untill drive is ready */
-
- load_task_file(); /* load task file */
- at_rest(0); /* recal drive */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
- load_task_file(); /* load task file */
- at_rest(0); /* restore drive */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
-
- if (at_ckerr()) /* check if error for recal */
- show_error(); /* show any errors */
-
- do_ilt(0); /* set up interleave for good blocks */
- hd_table.blk_size = hd_table.max_sec; /* do all drive */
-
- format_all(); /* format all of disk */
- verify_all(); /* verify all of disk */
-
- if (err_count > 1)
-
- /*************************************/
- /* */
- /* should we mark bad mark sectors */
- /* */
- /*************************************/
-
- {
- do_errors();
- printf("\n\nDo you wish to mark these blocks bad? (y/n)");
- resp = cget();
- while (toupper(resp) != 'Y')
- {
- if (toupper(resp) == 'N')
- {
- err_count = 1;
- break;
- }
- else
- bell;
- resp = cget();
- }
- }
-
- /*************************************/
- /* */
- /* enter other bad sectors */
- /* */
- /*************************************/
-
-
- clr_scrn();
- printf("\n\nYou may now enter additional blocks to be marked bad.");
- printf("\n\nEnter cylinder and head info (seperated by spaces) at");
- printf("\nthe prompt. To end entry, press ENTER at the prompt\n");
-
- for (; err_count < 100; err_count++)
- {
- printf("Enter <cylinder#> <head#>: ");
- cgets(temp_str);
- if (strcmp(temp_str, "") == 0)
- break;
- if (sscanf(temp_str, "%d %d", &err_table[err_count].cyl,
- &err_table[err_count].head) != 2)
- {
- bell;
- err_count--;
- }
- }
- /*************************************/
-
- if (err_count > 1)
-
- /*************************************/
- /* */
- /* mark bad sectors */
- /* */
- /*************************************/
-
-
- {
- do_errors();
- printf("\n\nReady to format bad blocks...........");
- printf("\n\nPress <ESC> to abort, any other key to continue\n");
- if (cget() == esc)
- exit(0);
- bad_count = 0;
- do_ilt(128);
- for (errcnt = 1; errcnt < err_count; errcnt++)
- {
- hd_table.cyl_number = err_table[errcnt].cyl;
- hd_table.head_number = err_table[errcnt].head;
- load_task_file();
- at_fmt();
- while(!( 0x08 & at_rstat())); /* wait for data request */
- at_wrbfr(0, wr_buffer);
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
- bad_count++;
- }
- }
- /*************************************/
-
- printf("\n\nFormat complete.....");
- if (bad_count > 0)
- printf("Bad blocks marked");
- printf("\n\nRestart system before doing FDISK");
-
-
-
- }
-
- /*************************************/
- /* */
- /* make block mark and sector # */
- /* for one track */
- /* */
- /*************************************/
-
- do_ilt(block_mark)
-
- char block_mark;
-
- {
-
- int offset,sec_count,ileave,maxcnt;
- char *p;
-
- p = wr_buffer;
- for( sec_count=0; sec_count < 512; sec_count++ ) *p++ = 0xff;
- if (hd_table.ileave > 8)
- {
- ileave = hd_table.ileave - 8;
- sec_count = 0;
- maxcnt = hd_table.max_sec - 1;
- }
- else
- {
- ileave = hd_table.ileave;
- sec_count = 1;
- maxcnt = hd_table.max_sec;
- };
-
- offset = 0;
-
- while ( sec_count <= maxcnt )
- {
- if (hd_table.ileave > 8)
- {
- if ( offset > maxcnt ) offset = 0;
- }
- else
- {
- if ( offset >= maxcnt ) offset = 0;
- }
- p = wr_buffer + ( offset * 2 ) + 1;
- if ( *p == 0xff )
- {
- *p = sec_count;
- *--p = block_mark;
- offset += ileave;
- sec_count++;
- }
- else offset++;
- };
- }
-
- /*************************************/
- /* */
- /* set up task file and load it */
- /* */
- /*************************************/
-
- load_task_file()
-
- {
-
- task_file.error = hd_table.precomp;
- task_file.secnt = hd_table.blk_size;
- task_file.sector = hd_table.sec_number;
- task_file.cyllo = (hd_table.cyl_number % 256);
- task_file.cylhi = (hd_table.cyl_number / 256);
- task_file.SDH = (((hd_table.drv_number << 4) & 0x10) +
- (hd_table.head_number & 0xf) + 0xa0);
- at_wtskf(&task_file);
- }
-
- /*************************************/
- /* */
- /* display errors from reisters */
- /* */
- /*************************************/
-
- show_error()
-
- {
- curs(22,1);
- printf(" Error!!... Cyl. %4d Head %2d Status %2x Error %2x",
- hd_table.cyl_number, hd_table.head_number,
- at_rstat(), at_rderr());
- }
-
-
- /*************************************/
- /* */
- /* */
- /* */
- /*************************************/
-
- clr_scrn()
-
- {
- char window[4];
- window[0]=0; window[1]=0;
- window[2]=79; window[3]=24;
-
- pcvsu(window,0,7);
- curs(1,1);
- }
-
- /*************************************/
- /* */
- /* display errors found in error table*/
- /* */
- /*************************************/
-
- do_errors()
- {
- clr_scrn();
- printf("Errors will be marked at the following cylinder/head locations:");
- printf("\n\n");
- for (errcnt = 1; errcnt < err_count; errcnt++)
- {
- printf(" %4d/%2d", err_table[errcnt].cyl,
- err_table[errcnt].head);
- if ((errcnt % 5) == 0)
- printf ("\n");
- }
- }
-
- /*************************************/
- /* */
- /* dimp 5 lines of buffer to screen */
- /* */
- /*************************************/
-
- dump_5lines(buffer)
-
- char *buffer;
-
- {
- int num_bytes, count;
-
- for (count = 0; count < 80; count++)
- {
- if ((count % 16) == 0)
- printf("\n%04x ", count);
- printf("%02x ", buffer[count]);
- };
- printf("\n");
- }
-
- /*************************************/
- /* */
- /* get drive specs */
- /* */
- /*************************************/
-
- get_spec(argc, argv)
-
- int argc;
- char *argv[];
-
-
- {
- argc--;
-
- if (argc > 0)
- { /* get drive # */
- sscanf(*++argv, "%d", &hd_table.drv_number);
- argc--;
- };
-
- if (argc > 0)
- { /* get max cylinder # */
- sscanf(*++argv, "%d", &hd_table.max_cyl);
- argc--;
- };
-
- if (argc > 0)
- { /* get max head # */
- sscanf(*++argv, "%d", &hd_table.max_head);
- argc--;
- };
-
- if (argc > 0)
- { /* get max sectors/track */
- sscanf(*++argv, "%d", &hd_table.max_sec);
- argc--;
- };
-
- if (argc > 0)
- { /* get interleave value */
- sscanf(*++argv, "%d", &hd_table.ileave);
- argc--;
- };
-
- if (argc > 0)
- { /* get precomp cylinder # */
- sscanf(*++argv, "%d", &hd_table.precomp);
- argc--;
- };
- }
-
- /*************************************/
- /* */
- /* screen update */
- /* */
- /*************************************/
-
- screen_update()
-
- {
- clr_scrn();
- printf(" *** Western Digital Corporation ***\n");
- printf(" AT Disk Format Utility\n");
- printf(" Rev. 2.00\n\n\n");
- printf(" Current formatting parameters are:\n\n\n");
- curs(9,1);
- printf(" Drive (0/1) : \n");
- printf(" Cylinders : \n");
- printf(" Heads : \n");
- printf(" Sectors : \n");
- printf(" Interleave : \n");
- printf(" Precomp : \n");
- curs(9, 34);printf(" %4d\n", hd_table.drv_number);
- curs(10,34);printf(" %4d\n", hd_table.max_cyl);
- curs(11,34);printf(" %4d\n", hd_table.max_head);
- curs(12,34);printf(" %4d\n", hd_table.max_sec);
- curs(13,34);printf(" %4d\n", hd_table.ileave);
- curs(14,34);printf(" %4d\n", hd_table.precomp);
-
- }
-
- /*************************************/
- /* */
- /* get_2spec */
- /* */
- /* get drive spects from user */
- /* */
- /*************************************/
-
- get_2spec()
-
- {
- int done;
- char temp_str[8];
-
- done = false;
- while(!done)
- {
-
- curs(17,5);
- printf("Enter drive specification at prompt or <CR> for default. ");
-
- /* get input from screen */
- prompt(9, &hd_table.drv_number);
- prompt(10,&hd_table.max_cyl );
- prompt(11,&hd_table.max_head );
- prompt(12,&hd_table.max_sec );
- prompt(13,&hd_table.ileave );
- prompt(14,&hd_table.precomp );
-
- /* redraw screen */
- curs(9,1);
- printf(" Drive (0/1) : \n");
- printf(" Cylinders : \n");
- printf(" Heads : \n");
- printf(" Sectors : \n");
- printf(" Interleave : \n");
- printf(" Precomp : \n");
- curs(9, 34);printf(" %4d\n", hd_table.drv_number);
- curs(10,34);printf(" %4d\n", hd_table.max_cyl);
- curs(11,34);printf(" %4d\n", hd_table.max_head);
- curs(12,34);printf(" %4d\n", hd_table.max_sec);
- curs(13,34);printf(" %4d\n", hd_table.ileave);
- curs(14,34);printf(" %4d\n", hd_table.precomp);
-
- curs(17,5);
- printf("Enter <CR> if drive specification OK or enter 'C' for more changes : ");
-
- cgets(temp_str); /* get standerd input */
- done=true;
- if (strcmp(temp_str, "")!=0 ) done=false; /* break out if <CR> */
- }; /* end of while */
- curs(17,5);
- printf(" ");
- curs(17,5);
- printf(" Warning!!!! All data will be destroyed on drive : %c ",
- (char)('C' + hd_table.drv_number));
- printf("\n Press ESC to return to DOS, F to start format");
-
- }
-
-
-
- /*************************************/
- /* */
- /* prompt(row,def) */
- /* */
- /* input: */
- /* row : row to display stand input*/
- /* def : pointer to default valvue */
- /* */
- /*************************************/
-
- prompt(row,def)
-
- char row;
- int *def;
-
- {
- char temp_str[8];
-
- curs(row,18);ARROW;
- curs(row,46);
- cgets(temp_str); /* get standerd input */
-
- if (strcmp(temp_str, "") != 0)
- sscanf(temp_str, "%d", def); /*change default if input */
- curs(row,18);BLANK;
- }
-
- /*************************************/
- /* */
- /* get command */
- /* */
- /*************************************/
-
- get_command()
-
- {
-
- char resp;
-
- resp = cget();
- while (toupper(resp) != 'F')
- {
- if (resp == esc)
- exit(0);
- else
- bell;
- resp = cget();
- }
- }
-
- /*************************************/
- /* */
- /* format whole disk */
- /* */
- /*************************************/
- format_all()
-
- {
-
- int start_head,last_head;
-
- curs(20, 12);
- printf("Formatting cylinder: ");
- curs(20, 40);
- printf("head:");
-
- if(hd_table.max_head > 7) last_head = 7;
- else last_head = hd_table.max_head; /* set up last head to format this pass */
- start_head = 0;
- for(hd_table.cyl_number = 0; hd_table.cyl_number <= hd_table.max_cyl;
- hd_table.cyl_number++)
- { /* format heads 0-7 or less */
- format_loop(start_head,last_head); /* do that format */
- }; /* end "for" to format 0-7 */
-
- if(hd_table.max_head > 7)
- { /* if more than 8 heads on disk drive */
- hd_table.head_number = 8; /* set up SDH to trick controler into */
- load_task_file(); /* thinking that this is a new drive */
- at_rest(0); /* recal with 35 micro second rate */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
- for(hd_table.cyl_number = 0; hd_table.cyl_number <= hd_table.max_cyl;
- hd_table.cyl_number++)
- {
- last_head = hd_table.max_head; /* last head to format */
- start_head =8; /* first head to format */
- format_loop(start_head,last_head); /* do that format */
- }; /* end "for" loop */
- }; /* end of if > 8*/
-
- } /*end of format_all */
-
-
- /****************************************************/
- /* */
- /* format_loop */
- /* */
- /* input: start_head; head # to start formating on */
- /* last_head; last head to format */
- /* */
- /****************************************************/
-
- format_loop(start_head,last_head)
-
- int start_head,last_head;
-
- {
- curs(20, 33);
- printf("%4d", hd_table.cyl_number);
- for(hd_table.head_number = start_head;
- hd_table.head_number <= last_head;
- hd_table.head_number++)
- {
- load_task_file();
- at_fmt(); /* send format command */
- while(! (0x08 & at_rstat())); /* wait for data request */
- at_wrbfr(0, wr_buffer);
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
- if (at_ckerr()) show_error();
-
- curs(20, 46);printf("%2d", hd_table.head_number);
- } /* end of for loop */
- } /* end of format_loop */
-
-
-
- /*************************************/
- /* */
- /* verify each sector */
- /* */
- /*************************************/
- verify_all()
-
- { /* start of verify procedure */
-
- int num_reads;
- int stat_byte;
-
- hd_table.blk_size = hd_table.max_sec;
- err_count = 1;
- curs(20, 12);printf("Verifying ");
- load_task_file(); /* thinking that this is a new drive */
- at_rest(0); /* recal with 35 micro second rate */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
- for(hd_table.cyl_number = 0; hd_table.cyl_number <= hd_table.max_cyl;
- hd_table.cyl_number++)
- { /* start of cyclinder loop */
- if(err_count >= 100) break;
- curs(20, 33);printf("%4d", hd_table.cyl_number);
- for(hd_table.head_number = 0;
- hd_table.head_number <= hd_table.max_head;
- hd_table.head_number++)
- { /* start of head loop */
- for(num_reads = 0; num_reads < 3; num_reads++)
- { /* start of 3 trys to read read */
- load_task_file();
- at_rdver(1); /* do that verify with out retry */
- while(at_ckbsy()); /* check busy bit in controler */
- while(at_ckbsy()); /* check busy bit in controler */
- if(at_ckerr())
- { /* start of "if error" */
- if (err_count < 100)
- { /* start of "if error < 100" */
- err_table[err_count].cyl = hd_table.cyl_number;
- err_table[err_count].head = hd_table.head_number;
- err_count++;
- } /* end of "if error < 100" */
- else
- { /* start of if error >= 100" */
- bell;
- printf("\n\nError count exceeded 100 errors!!!");
- } /* end of "if error >= 100" */
- break; /* break out of 3 tries */
- } /* end of "if error" */
- } /* end of 3 tries */
- curs(20, 46);printf("%2d", hd_table.head_number);
- } /* end of head loop */
- } /* end of cyclinder loop */
- } /* end of verify procedure */
- /*************************************/