home *** CD-ROM | disk | FTP | other *** search
- /*=============================================================================
-
- The INSTALL program source code, object code, sample script files,
- executable program, and documentation are subject to copyright
- protection under the laws of the United States and other countries.
-
- This software is licensed, not sold, and may only be redistributed
- in executable format and only in accordance with the provisions of
- the INSTALL Source Code License Agreement.
-
- INSTALL is Copyright(C) 1987-1989 by Knowledge Dynamics Corp
- Highway Contract 4 Box 185-H, Canyon Lake, TX (USA) 78133-3508
- 512-964-3994 (Voice) 512-964-3958 (24-hr FAX)
-
- All rights reserved worldwide.
-
- ===============================================================================
-
- FILENAME:
- format.c
-
- AUTHOR:
- eric jon heflin
-
- PUBLIC FUNCTIONS:
- format() - format a disk
- is_formatted() - test for a formatted disk
-
- LOCAL FUNCTIONS:
- bios_disk_fn() - int13 safe interface
- show_bdpt() - debugging routing to dump BIOS Disk Parameter Table
- pause() - pause for input
- bell() - ring the bell
- main() - function for standalone version of format
- retry() - retry an operation three times
- do_format() - actual formatting routine
-
- DESCRIPTION:
- This file implements IBM-PC ROM BIOS-based floppy disk formatting
- functions. Only the four most common formats are supported (360K, 720K,
- 1.2M, and 1.44M), but others could be implemented if there was a reason
- to do so.
-
- REVISION HISTORY:
- DATE: AUTHOR: DESCRIPTION OF CHANGES:
- 891230 ejh converted generic version to INSTALL
- 900102 ejh Completed conversion to INSTALL, and minor cosmetic
- changes.
-
- ==============================================================================*/
-
- #include <ctype.h>
- #include "install.h"
- #include <string.h>
- #include <stdio.h>
- #include <dos.h>
- #ifndef InstantC
- #include <assert.h>
- #include <stdlib.h>
- #else
- #define assert(c) if(!c) _()
- #endif
-
- /* disk format types */
- #define FMT360K (1)
- #define FMT720K (2)
- #define FMT1200K (3)
- #define FMT1440K (4)
-
-
- /* defines for the int 0x13 functions the formating routines use */
- #define DISK_RESET (0x0)
- #define DISK_STATUS (0x1)
- #define DISK_READ (0x2)
- #define DISK_WRITE (0x3)
- #define DISK_VERIFY (0x4)
- #define DISK_FORMAT (0x5)
- #define DISK_GET_PARMS (0X8)
- #define DISK_GET_CHANGE (0x16)
- #define DISK_SET_BANDWIDTH (0x17)
- #define DISK_SET_MEDIA (0x18)
-
-
- /* disk parms */
- #define MAX_TRIES (3) /* how many times to RE-TRY things */
- #define BYTES_PER_SECTOR (512)
- #define MAX_TRACKS (80)
- #define MAX_SECTORS (18)
-
- /* local prototypes */
- static int retry(word, int);
- static unsigned bios_disk_fn(word function, word drive, word head, word track, word sector, word num_secs, byte *buf);
- int format(int drive, int type);
- int is_formatted(int drive);
- int kbhit(void);
-
- #ifdef STANDALONE
- #define output printf
- #else
- #define output sputs
- #endif
-
- #ifdef FORMAT_ALLOWED
- static int do_format(int, int, int);
- #endif
-
-
- #ifdef DEBUG
- static void show_bdpt(byte *bdpt);
- #endif
-
-
- /* global vars for this file */
- /* IMPORTANT: some funcs assume trk_fmt is statically allocated */
- byte trk_fmt[MAX_TRACKS * MAX_SECTORS * 2 * 4];
-
-
-
- /*
- * This function implements a compiler-independent method of invoking
- * the ROM BIOS disk interrupt function. If the carry flag is set
- * (indicating an error) then this function returns the contents of the
- * al register (except for DISK_STATUS when the contents of the ah reg are
- * returned). Otherwise, a zero is returned indicating success.
- *
- * This function attempts to diagnose many types of parameter errors.
- */
-
- static unsigned bios_disk_fn(function, drive, head, track, sector, num_secs, buf)
- word function; /* the function number, value checked */
- word drive; /* the drive number 0 - 7, value checked */
- word head; /* the head number, 0 - 1, value checked */
- word track; /* the cylinder number 0 - 79, value checked */
- word sector; /* the PHYSICAL sector number, 0 - 18, value checked */
- word num_secs; /* number of sectors, 0 - 18, value checked */
- byte *buf;
- { /* bios_disk_fn */
- unsigned ret;
- union REGS input_regs, output_regs;
- struct SREGS seg_regs;
-
- if (function == DISK_GET_PARMS ||
- function > 0x18 || drive > 7 || head > 1 ||
- track > 79 || sector > 18 || num_secs > 18)
- {
- wputs(error_w, "Diagnostic error: bios_disk_fn: invalid parameter");
- wputs(error_w, "%d %d %d %d %d %d", function, drive, head, track, sector, num_secs);
- put_error(error_w);
- bye();
- }
-
- /* these parms are the same for each function */
- input_regs.h.ah = (byte) function;
- input_regs.h.al = (byte) num_secs;
- input_regs.h.ch = (byte) track;
- input_regs.h.cl = (byte) sector;
- input_regs.h.dh = (byte) head;
- input_regs.h.dl = (byte) drive;
- input_regs.x.bx = fp_off(buf);
- seg_regs.es = fp_seg(buf);
-
- ret = int80x86(0x13, &input_regs, &output_regs, &seg_regs);
-
- if (function == DISK_SET_MEDIA)
- {
- /* fill buf with new BDPT */
- # ifndef LATTICE
- movedata(seg_regs.es, output_regs.x.di, fp_seg(buf), fp_off(buf), 11);
- # else
- printf("function not implemented in bios_disk_fn()\n\n\n\n\n");
- pause();
- # endif
- }
-
- if (!(ret & 1))
- return 0;
- if (function != DISK_STATUS)
- return (unsigned)output_regs.h.ah;
- return (unsigned)output_regs.h.al;
- } /* bios_disk_fn */
-
-
- int format(d, t)
- {
- if(d == t)
- return 0;
- return 0;
- }
-
-
-
- /*
- * Returns: 0 if disk is not formatted.
- * 1 if disk is formatted.
- * -1 if end-user hit [Esc], or we couldn't tell if the
- * disk was formatted or not.
- */
-
- int is_formatted(drive)
- {
- int tries;
- unsigned ret;
- byte *s;
- dos_file_t dta;
-
- byte pattern[10];
-
- drive = toupper(drive);
- if (drive >= 'A')
- drive -= 'A';
-
- /*
- * First, make certain that the drive letter is valid.
- */
- s = getdrives();
- if (!s[drive])
- {
- wputs(error_w, "Invalid drive letter %c", drive + 'A');
- put_error(error_w);
- bye();
- }
-
-
- /*
- * Since most networks are setup to disallow physical device access
- * to remote devices, we will never attempt to format a network
- * drive even though formatting may be allowed.
- */
- if (ckremote(drive + 1) > 0)
- {
- return 1;
- }
-
- /*
- * If execution gets here, the drive letter is valid. We must see
- * if the disk is already formatted.
- *
- * Since the access could be restricted, we need to try several
- * techniques.
- */
- sprintf(pattern, "%c:\\*.*", drive + 'A');
- if (findfirst(pattern, &dta, _A_HIDDEN | _A_RDONLY | _A_SYSTEM | _A_SUBDIR | _A_ARCH) == 0)
- return 1;
-
- forever
- {
- for (tries = 0, ret = 0xFFFF; (tries < 3) && ret; ++tries)
- {
- ret = bios_disk_fn(DISK_VERIFY, drive, 0, 0, 1, 1, trk_fmt);
- if (ret)
- bios_disk_fn(DISK_RESET, drive, 0, 0, 0, 0, trk_fmt);
- }
- if (!ret)
- return 1; /* a disk is in the drive */
- if (ret == 2 || ret == 4)
- {
- /* unformatted */
- return 0;
- }
- if (!retry(ret, drive))
- return -1; /* abort */
- }
- }
-
-
- /*
- * Returns:
- * TRUE = retry operation,
- * FALSE = abort operation.
- */
-
- static int retry(word ret, int drive)
- {
- int retry = FALSE;
-
- wputs(yes_w, "Drive %c:", drive + 'A');
- wputs(error_w, "Drive %c:", drive + 'A');
- /* diagnose error */
- switch (ret)
- {
- case 0x01:
- wputs(error_w, "Disk Drive Controller Bad Request.");
- break;
- case 0x02:
- wputs(error_w, "Address Mark Not Found On Disk.");
- break;
- case 0x03:
- wputs(yes_w, "Write Attempt On Write-Protected Disk.");
- retry = TRUE;
- break;
- case 0x04:
- wputs(error_w, "Disk Sector Not Found.");
- break;
- case 0x05:
- wputs(error_w, "Disk Drive Reset Failed.");
- break;
- case 0x06:
- wputs(yes_w, "Floppy Disk Removed.");
- retry = TRUE;
- break;
- case 0x07:
- wputs(error_w, "Bad Disk Parameter Table.");
- break;
- case 0x08:
- wputs(error_w, "Disk Drive DMA Overflow.");
- break;
- case 0x09:
- wputs(error_w, "Disk Drive DMA Crossed 64 KB Boundary.");
- break;
- case 0x0a:
- wputs(error_w, "Disk Bad Sector Flag.");
- break;
- case 0x10:
- wputs(error_w, "Uncorrectable CRC Or ECC Disk Data Error.");
- break;
- case 0x11:
- wputs(error_w, "Disk ECC Corrected Data Error.");
- break;
- case 0x20:
- wputs(error_w, "Disk Drive Controller Failed.");
- break;
- case 0x40:
- wputs(error_w, "Disk Drive Seek Error.");
- break;
- case 0x80:
- wputs(yes_w, "Time Out Error. The Disk Drive Door May Be Open.");
- retry = TRUE;
- break;
- case 0xaa:
- wputs(yes_w, "Drive Not Ready Error. The Disk Drive Door May Be Open");
- retry = TRUE;
- break;
- case 0xcc:
- wputs(error_w, "Write Fault On Drive.");
- break;
- case 0xe0:
- wputs(error_w, "Disk Drive Status Error.");
- break;
- case 0xbb:
- default:
- wputs(error_w, "Undefined Disk Error.");
- break;
- }
-
- if (retry)
- {
- wcls(error_w);
- forever
- {
- wputs(yes_w, "Would you like to retry (Y/N)?");
- if (!put_yes(yes_w))
- return FALSE;
- return TRUE;
- }
- }
- /* no retry attempt is feasible */
- put_error(error_w);
- wcls(yes_w);
- return FALSE; /* could not correct */
- }
-
- /* end-of-file */
-