home *** CD-ROM | disk | FTP | other *** search
-
- /*
- Western Digital Corp. Format Routine
-
- Author: Dave Evans
-
- Creation Date: 08/08/86
- Revision Date: 05/08/87
- Revision: 1.01
-
- Formats drive based on #cylinders, #heads, #sectors, and
- interleave entered at command line. 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 -- 05/08/87 -- 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 precomp-cyl
- */
- #include <stdio.h>
- #include <\c\ctype.h>
- #include <\c\math.h>
- #include <\c\limits.h>
-
- #define begin {
- #define end }
- #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 char_ready pckchk()
-
- /* Global variables:
-
- Command parser modifies the tables, and global flags
- indicate to the Main routine the requested action.
-
- */
-
- struct htable
- begin
- 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;
- end hd_table;
-
- struct tfile
- begin
- int error;
- int secnt;
- int sector;
- int cyllo;
- int cylhi;
- int SDH;
- int status;
- int secstat;
- int DIR;
- end task_file;
-
- struct esfile
- begin
- int xfrlo;
- int xfrhi;
- int plo;
- int gap;
- int stat;
- end;
-
-
- char *rd_buffer, *wr_buffer, *fmt_buffer;
-
- struct error
- begin
- int cyl;
- int head;
- end;
-
- struct error err_table[100];
-
- int err_count, errcnt;
-
- main(argc, argv)
-
- int argc;
- char *argv[];
-
- begin
-
- char *malloc();
- char resp, temp_str[8];
- int bad_count, num_reads;
-
- wr_buffer = malloc(buf_length);
- rd_buffer = malloc(buf_length);
- fmt_buffer = malloc(buf_length);
-
- hd_table.sec_number = 1;
- 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;
-
-
- argc--;
-
- if (argc > 0)
- begin
- sscanf(*++argv, "%d", &hd_table.drv_number);
- argc--;
- end;
-
- if (argc > 0)
- begin
- sscanf(*++argv, "%d", &hd_table.max_cyl);
- argc--;
- end;
-
- if (argc > 0)
- begin
- sscanf(*++argv, "%d", &hd_table.max_head);
- argc--;
- end;
-
- if (argc > 0)
- begin
- sscanf(*++argv, "%d", &hd_table.max_sec);
- argc--;
- end;
-
- if (argc > 0)
- begin
- sscanf(*++argv, "%d", &hd_table.ileave);
- argc--;
- end;
-
- if (argc > 0)
- begin
- sscanf(*++argv, "%d", &hd_table.precomp);
- argc--;
- end;
-
- clr_scrn();
- printf(" *** Western Digital Corporation ***\n");
- printf(" Disk Format Utility\n");
- printf(" Rev. 1.01\n\n\n");
- printf(" Current parameters are:\n\n");
- printf(" Formatting will occur on drive: %d\n\n", hd_table.drv_number);
- printf(" Cylinders: %4d Heads: %2d\n",
- hd_table.max_cyl, hd_table.max_head);
- printf(" Sectors: %4d Interleave: %2d\n",
- hd_table.max_sec, hd_table.ileave);
- printf(" Precomp: %4d\n\n\n", hd_table.precomp);
- printf(" To enter new parameters, return to DOS and\n");
- printf(" enter a new command line as follows:\n\n");
- printf(" WDFMT <drv # (0/1)> <# cyls> <# heads> <# sectors> <interleave> <precomp cyl.>");
- bell; bell;
- printf("\n\n\n Warning!!!! All data on drive %c will be destroyed",
- (char)('C' + hd_table.drv_number));
- printf("\n Press ESC to return to DOS, F to start format");
-
- resp = cget();
- while (toupper(resp) != 'F')
- begin
- if (resp == esc)
- exit(0);
- else
- bell;
- resp = cget();
- end
-
- hd_table.max_cyl--;
- hd_table.max_head--;
- hd_table.precomp = (int)(hd_table.precomp/4);
- at_reset();
- while(at_ckbsy());
-
- load_task_file();
- at_setp(hd_table.max_sec, hd_table.max_head);
- while(at_ckbsy());
-
- at_rest();
- while(at_ckbsy());
- if (at_ckerr())
- show_error();
-
-
- do_ilt(0);
- hd_table.blk_size = hd_table.max_sec;
-
- curs(20, 12);
- printf("Formatting cylinder: ");
- curs(20, 40);
- printf("head:");
- for(hd_table.cyl_number = 0; hd_table.cyl_number <= hd_table.max_cyl;
- hd_table.cyl_number++)
- begin
- 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++)
- begin
- load_task_file();
- at_fmt();
- at_wrbfr(0, wr_buffer);
- while (at_ckbsy());
- if (at_ckerr())
- show_error();
- curs(20, 46);
- printf("%2d", hd_table.head_number);
- end
- end
-
- hd_table.blk_size = hd_table.max_sec;
- err_count = 1;
- curs(20, 12);
- printf("Verifying ");
- for(hd_table.cyl_number = 0; hd_table.cyl_number <= hd_table.max_cyl;
- hd_table.cyl_number++)
- begin
- 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++)
- begin
- for(num_reads = 0; num_reads < 3; num_reads++)
- begin
- load_task_file();
- at_rdver(0);
- while (at_ckbsy());
- if (at_ckerr())
- begin
- if (err_count < 100)
- begin
- err_table[err_count].cyl = hd_table.cyl_number;
- err_table[err_count].head = hd_table.head_number;
- err_count++;
- end
- else
- begin
- bell;
- printf("\n\nError count exceeded 100 errors!!!");
- end
- break;
- end
- end
- curs(20, 46);
- printf("%2d", hd_table.head_number);
- end
- end
-
- if (err_count > 1)
- begin
- do_errors();
- printf("\n\nDo you wish to mark these blocks bad? (y/n)");
- resp = cget();
- while (toupper(resp) != 'Y')
- begin
- if (toupper(resp) == 'N')
- begin
- err_count = 1;
- break;
- end
- else
- bell;
- resp = cget();
- end
- end
-
- 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++)
- begin
- 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)
- begin
- bell;
- err_count--;
- end
- end
-
- if (err_count > 1)
- begin
- 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++)
- begin
- hd_table.cyl_number = err_table[errcnt].cyl;
- hd_table.head_number = err_table[errcnt].head;
- load_task_file();
- at_fmt();
- at_wrbfr(0, wr_buffer);
- while (at_ckbsy());
- bad_count++;
- end
- end
-
- printf("\n\nFormat complete.....");
- if (bad_count > 0)
- printf("Bad blocks marked");
- printf("\n\nRestart system before doing FDISK");
-
- end
-
- do_ilt(block_mark)
- char block_mark;
- begin
-
- 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)
- begin
- ileave = hd_table.ileave - 8;
- sec_count = 0;
- maxcnt = hd_table.max_sec - 1;
- end
- else
- begin
- ileave = hd_table.ileave;
- sec_count = 1;
- maxcnt = hd_table.max_sec;
- end;
-
- offset = 0;
-
- while ( sec_count <= maxcnt )
- begin
- if (hd_table.ileave > 8)
- begin
- if ( offset > maxcnt ) offset = 0;
- end
- else
- begin
- if ( offset >= maxcnt ) offset = 0;
- end
- p = wr_buffer + ( offset * 2 ) + 1;
- if ( *p == 0xff )
- begin
- *p = sec_count;
- *--p = block_mark;
- offset += ileave;
- sec_count++;
- end
- else offset++;
- end;
- end
-
-
- load_task_file()
- begin
- 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);
- end
-
- show_error()
- begin
- printf("\nError!!... Cyl. %4d Head %2d Status %2x Error %2x",
- hd_table.cyl_number, hd_table.head_number,
- at_rstat(), at_rderr());
- end
-
-
- clr_scrn()
- begin
-
- char window[4];
- window[0]=0; window[1]=0;
- window[2]=79; window[3]=24;
-
- pcvsu(window,0,7);
- curs(1,1);
-
- end
-
- do_errors()
- begin
- clr_scrn();
- printf("Errors will be marked at the following cylinder/head locations:");
- printf("\n\n");
- for (errcnt = 1; errcnt < err_count; errcnt++)
- begin
- printf(" %4d/%2d", err_table[errcnt].cyl,
- err_table[errcnt].head);
- if ((errcnt % 5) == 0)
- printf ("\n");
- end
- end
-
- dump_5lines(buffer)
-
- char *buffer;
-
- begin
- int num_bytes, count;
-
- for (count = 0; count < 80; count++)
- begin
- if ((count % 16) == 0)
- printf("\n%04x ", count);
- printf("%02x ", buffer[count]);
- end;
- printf("\n");
- end
-