home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0020 - 0029 / ibm0020-0029 / ibm0028.tar / ibm0028 / INSTALL2.TD0 / SOURCES.LIF / FORMAT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-27  |  9.2 KB  |  363 lines

  1. /*=============================================================================
  2.  
  3.      The INSTALL program source code, object code, sample  script files,
  4.      executable  program,  and  documentation  are  subject to copyright
  5.      protection under the laws of the United States and other countries.
  6.  
  7.      This software is licensed, not sold, and may only be  redistributed
  8.      in  executable format and only in accordance with the provisions of
  9.      the INSTALL Source Code License Agreement.
  10.  
  11.         INSTALL is Copyright(C) 1987-1989 by Knowledge Dynamics Corp
  12.        Highway Contract 4 Box 185-H, Canyon Lake, TX (USA) 78133-3508
  13.               512-964-3994 (Voice)   512-964-3958 (24-hr FAX)
  14.  
  15.                       All rights reserved worldwide.
  16.  
  17. ===============================================================================
  18.  
  19. FILENAME:
  20.     format.c
  21.  
  22. AUTHOR:
  23.     eric jon heflin
  24.  
  25. PUBLIC FUNCTIONS:
  26.     format()       - format a disk
  27.     is_formatted() - test for a formatted disk
  28.  
  29. LOCAL FUNCTIONS:
  30.     bios_disk_fn() - int13 safe interface
  31.     show_bdpt()    - debugging routing to dump BIOS Disk Parameter Table
  32.     pause()        - pause for input
  33.     bell()         - ring the bell
  34.     main()         - function for standalone version of format
  35.     retry()        - retry an operation three times
  36.     do_format()    - actual formatting routine
  37.  
  38. DESCRIPTION:
  39.     This file implements IBM-PC ROM BIOS-based floppy disk formatting
  40.     functions.  Only the four most common formats are supported (360K, 720K,
  41.     1.2M, and 1.44M), but others could be implemented if there was a reason
  42.     to do so.
  43.  
  44. REVISION HISTORY:
  45.     DATE:    AUTHOR:        DESCRIPTION OF CHANGES:
  46.     891230     ejh            converted generic version to INSTALL
  47.     900102    ejh            Completed conversion to INSTALL, and minor cosmetic
  48.                         changes.
  49.  
  50. ==============================================================================*/
  51.  
  52. #include <ctype.h>
  53. #include "install.h"
  54. #include <string.h>
  55. #include <stdio.h>
  56. #include <dos.h>
  57. #ifndef InstantC
  58. #include <assert.h>
  59. #include <stdlib.h>
  60. #else
  61. #define assert(c) if(!c) _()
  62. #endif
  63.  
  64. /* disk format types */
  65. #define FMT360K        (1)
  66. #define FMT720K        (2)
  67. #define FMT1200K    (3)
  68. #define FMT1440K    (4)
  69.  
  70.  
  71. /* defines for the int 0x13 functions the formating routines use */
  72. #define DISK_RESET          (0x0)
  73. #define DISK_STATUS            (0x1)
  74. #define DISK_READ            (0x2)
  75. #define DISK_WRITE            (0x3)
  76. #define DISK_VERIFY         (0x4)
  77. #define DISK_FORMAT         (0x5)
  78. #define DISK_GET_PARMS      (0X8)
  79. #define DISK_GET_CHANGE        (0x16)
  80. #define DISK_SET_BANDWIDTH  (0x17)
  81. #define DISK_SET_MEDIA      (0x18)
  82.  
  83.  
  84. /* disk parms */
  85. #define    MAX_TRIES            (3)        /* how many times to RE-TRY things */
  86. #define    BYTES_PER_SECTOR    (512)
  87. #define MAX_TRACKS          (80)
  88. #define MAX_SECTORS         (18)
  89.  
  90. /* local prototypes */
  91. static int retry(word, int);
  92. static unsigned bios_disk_fn(word function, word drive, word head, word track, word sector, word num_secs, byte *buf);
  93. int format(int drive, int type);
  94. int is_formatted(int drive);
  95. int kbhit(void);
  96.  
  97. #ifdef STANDALONE
  98. #define output printf
  99. #else
  100. #define output sputs
  101. #endif
  102.  
  103. #ifdef FORMAT_ALLOWED
  104. static int do_format(int, int, int);
  105. #endif
  106.  
  107.  
  108. #ifdef DEBUG
  109. static void show_bdpt(byte *bdpt);
  110. #endif
  111.  
  112.  
  113. /* global vars for this file */
  114. /* IMPORTANT: some funcs assume trk_fmt is statically allocated */
  115. byte trk_fmt[MAX_TRACKS * MAX_SECTORS * 2 * 4];
  116.  
  117.  
  118.  
  119. /*
  120.  *    This function implements a compiler-independent method of invoking
  121.  *  the ROM BIOS disk interrupt function.  If the carry flag is set
  122.  *  (indicating an error) then this function returns the contents of the
  123.  *  al register (except for DISK_STATUS when the contents of the ah reg are
  124.  *    returned).  Otherwise, a zero is returned indicating success.
  125.  *
  126.  *  This function attempts to diagnose many types of parameter errors.
  127.  */
  128.  
  129. static unsigned bios_disk_fn(function, drive, head, track, sector, num_secs, buf)
  130. word function;        /* the function number, value checked */
  131. word drive;            /* the drive number 0 - 7, value checked */
  132. word head;            /* the head number, 0 - 1, value checked */
  133. word track;            /* the cylinder number 0 - 79, value checked */
  134. word sector;        /* the PHYSICAL sector number, 0 - 18, value checked */
  135. word num_secs;        /* number of sectors, 0 - 18, value checked */
  136. byte *buf;
  137.     {                    /* bios_disk_fn */
  138.     unsigned ret;
  139.     union REGS input_regs, output_regs;
  140.     struct SREGS seg_regs;
  141.  
  142.     if (function == DISK_GET_PARMS ||
  143.         function > 0x18 || drive > 7 || head > 1 ||
  144.         track > 79 || sector > 18 || num_secs > 18)
  145.         {
  146.         wputs(error_w, "Diagnostic error: bios_disk_fn: invalid parameter");
  147.         wputs(error_w, "%d %d %d %d %d %d", function, drive, head, track, sector, num_secs);
  148.         put_error(error_w);
  149.         bye();
  150.         }
  151.  
  152.     /* these parms are the same for each function */
  153.     input_regs.h.ah = (byte) function;
  154.     input_regs.h.al = (byte) num_secs;
  155.     input_regs.h.ch = (byte) track;
  156.     input_regs.h.cl = (byte) sector;
  157.     input_regs.h.dh = (byte) head;
  158.     input_regs.h.dl = (byte) drive;
  159.     input_regs.x.bx = fp_off(buf);
  160.     seg_regs.es = fp_seg(buf);
  161.  
  162.     ret = int80x86(0x13, &input_regs, &output_regs, &seg_regs);
  163.  
  164.     if (function == DISK_SET_MEDIA)
  165.         {
  166.         /* fill buf with new BDPT */
  167. #        ifndef LATTICE
  168.         movedata(seg_regs.es, output_regs.x.di, fp_seg(buf), fp_off(buf), 11);
  169. #        else
  170.         printf("function not implemented in bios_disk_fn()\n\n\n\n\n");
  171.         pause();
  172. #        endif
  173.         }
  174.  
  175.     if (!(ret & 1))
  176.         return 0;
  177.     if (function != DISK_STATUS)
  178.         return (unsigned)output_regs.h.ah;
  179.     return (unsigned)output_regs.h.al;
  180.     }                   /* bios_disk_fn */
  181.  
  182.  
  183. int format(d, t)
  184.     {
  185.     if(d == t)
  186.         return 0;
  187.     return 0;
  188.     }
  189.  
  190.  
  191.  
  192. /*
  193.  *    Returns:  0 if disk is not formatted.
  194.  *              1 if disk is formatted.
  195.  *             -1 if end-user hit [Esc], or we couldn't tell if the
  196.  *                disk was formatted or not.
  197.  */
  198.  
  199. int is_formatted(drive)
  200.     {
  201.     int tries;
  202.     unsigned ret;
  203.     byte *s;
  204.     dos_file_t dta;
  205.  
  206.     byte pattern[10];
  207.  
  208.     drive = toupper(drive);
  209.     if (drive >= 'A')
  210.         drive -= 'A';
  211.  
  212.     /*
  213.      *    First, make certain that the drive letter is valid.
  214.      */
  215.     s = getdrives();
  216.     if (!s[drive])
  217.         {
  218.         wputs(error_w, "Invalid drive letter %c", drive + 'A');
  219.         put_error(error_w);
  220.         bye();
  221.         }
  222.  
  223.  
  224.     /*
  225.      *    Since most networks are setup to disallow physical device access
  226.      *    to remote devices, we will never attempt to format a network
  227.      *    drive even though formatting may be allowed.
  228.      */
  229.     if (ckremote(drive + 1) > 0)
  230.         {
  231.         return 1;
  232.         }
  233.  
  234.     /*
  235.      *    If execution gets here, the drive letter is valid.  We must see
  236.      *    if the disk is already formatted.
  237.      *
  238.      *    Since the access could be restricted, we need to try several
  239.      *    techniques.
  240.      */
  241.     sprintf(pattern, "%c:\\*.*", drive + 'A');
  242.     if (findfirst(pattern, &dta, _A_HIDDEN | _A_RDONLY | _A_SYSTEM | _A_SUBDIR | _A_ARCH) == 0)
  243.         return 1;
  244.  
  245.     forever
  246.         {
  247.         for (tries = 0,  ret = 0xFFFF;  (tries < 3) && ret;  ++tries)
  248.             {
  249.             ret = bios_disk_fn(DISK_VERIFY, drive, 0, 0, 1, 1, trk_fmt);
  250.             if (ret)
  251.                 bios_disk_fn(DISK_RESET, drive, 0, 0, 0, 0, trk_fmt);
  252.             }
  253.         if (!ret)
  254.             return 1;    /* a disk is in the drive */
  255.         if (ret == 2 || ret == 4)
  256.             {
  257.             /* unformatted */
  258.             return 0;
  259.             }
  260.         if (!retry(ret, drive))
  261.             return -1;    /* abort */
  262.         }
  263.     }
  264.  
  265.  
  266. /*
  267.  *    Returns:
  268.  *        TRUE = retry operation,
  269.  *        FALSE = abort operation.
  270.  */
  271.  
  272. static int retry(word ret, int drive)
  273.     {
  274.     int retry = FALSE;
  275.  
  276.     wputs(yes_w, "Drive %c:", drive + 'A');
  277.     wputs(error_w, "Drive %c:", drive + 'A');
  278.     /* diagnose error */
  279.     switch (ret)
  280.         {
  281.     case 0x01:
  282.         wputs(error_w, "Disk Drive Controller Bad Request.");
  283.         break;
  284.     case 0x02:
  285.         wputs(error_w, "Address Mark Not Found On Disk.");
  286.         break;
  287.     case 0x03:
  288.         wputs(yes_w, "Write Attempt On Write-Protected Disk.");
  289.         retry = TRUE;
  290.         break;
  291.     case 0x04:
  292.         wputs(error_w, "Disk Sector Not Found.");
  293.         break;
  294.     case 0x05:
  295.         wputs(error_w, "Disk Drive Reset Failed.");
  296.         break;
  297.     case 0x06:
  298.         wputs(yes_w, "Floppy Disk Removed.");
  299.         retry = TRUE;
  300.         break;
  301.     case 0x07:
  302.         wputs(error_w, "Bad Disk Parameter Table.");
  303.         break;
  304.     case 0x08:
  305.         wputs(error_w, "Disk Drive DMA Overflow.");
  306.         break;
  307.     case 0x09:
  308.         wputs(error_w, "Disk Drive DMA Crossed 64 KB Boundary.");
  309.         break;
  310.     case 0x0a:
  311.         wputs(error_w, "Disk Bad Sector Flag.");
  312.         break;
  313.     case 0x10:
  314.         wputs(error_w, "Uncorrectable CRC Or ECC Disk Data Error.");
  315.         break;
  316.     case 0x11:
  317.         wputs(error_w, "Disk ECC Corrected Data Error.");
  318.         break;
  319.     case 0x20:
  320.         wputs(error_w, "Disk Drive Controller Failed.");
  321.         break;
  322.     case 0x40:
  323.         wputs(error_w, "Disk Drive Seek Error.");
  324.         break;
  325.     case 0x80:
  326.         wputs(yes_w, "Time Out Error. The Disk Drive Door May Be Open.");
  327.         retry = TRUE;
  328.         break;
  329.     case 0xaa:
  330.         wputs(yes_w, "Drive Not Ready Error.  The Disk Drive Door May Be Open");
  331.         retry = TRUE;
  332.         break;
  333.     case 0xcc:
  334.         wputs(error_w, "Write Fault On Drive.");
  335.         break;
  336.     case 0xe0:
  337.         wputs(error_w, "Disk Drive Status Error.");
  338.         break;
  339.     case 0xbb:
  340.     default:
  341.         wputs(error_w, "Undefined Disk Error.");
  342.         break;
  343.         }
  344.  
  345.     if (retry)
  346.         {
  347.         wcls(error_w);
  348.         forever
  349.             {
  350.             wputs(yes_w, "Would you like to retry (Y/N)?");
  351.             if (!put_yes(yes_w))
  352.                 return FALSE;
  353.             return TRUE;
  354.             }
  355.         }
  356.     /* no retry attempt is feasible */
  357.     put_error(error_w);
  358.     wcls(yes_w);
  359.     return FALSE;        /* could not correct */
  360.     }
  361.  
  362. /* end-of-file */
  363.