Home | History | Annotate | Line # | Download | only in misc
rawrite.c revision 1.1.2.2
      1 /*
      2  rawrite.c	Write a binary image to a 360K diskette.
      3 		By Mark Becker
      4 
      5  Usage:
      6 	MS-DOS prompt> RAWRITE
      7 
      8 	And follow the prompts.
      9 
     10 History
     11 -------
     12 
     13   1.0	-	Initial release
     14   1.1	-	Beta test (fixing bugs)				4/5/91
     15   		Some BIOS's don't like full-track writes.
     16   1.101	-	Last beta release.				4/8/91
     17   		Fixed BIOS full-track write by only
     18 		writing 3 sectors at a time.
     19   1.2	-	Final code and documentation clean-ups.		4/9/91
     20 */
     21 #include <alloc.h>
     22 #include <bios.h>
     23 #include <ctype.h>
     24 #include <dir.h>
     25 #include <dos.h>
     26 #include <io.h>
     27 #include <fcntl.h>
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 
     31 #define FALSE	0
     32 #define TRUE	(!FALSE)
     33 
     34 #define SECTORSIZE	512
     35 
     36 #define	RESET	0
     37 #define	LAST	1
     38 #define	READ	2
     39 #define	WRITE	3
     40 #define	VERIFY	4
     41 #define	FORMAT	5
     42 
     43 int	done;
     44 
     45 /*
     46  Catch ^C and ^Break.
     47 */
     48 int	handler(void)
     49 {
     50   done = TRUE;
     51   return(0);
     52 }
     53 void msg(char (*s))
     54 {
     55 	fprintf(stderr, "%s\n", s);
     56 	_exit(1);
     57 }
     58 /*
     59  Identify the error code with a real error message.
     60 */
     61 void Error(int (status))
     62 {
     63   switch (status) {
     64     case 0x00:	msg("Operation Successful");				break;
     65     case 0x01:	msg("Bad command");					break;
     66     case 0x02:	msg("Address mark not found");				break;
     67     case 0x03:	msg("Attempt to write on write-protected disk");	break;
     68     case 0x04:	msg("Sector not found");				break;
     69     case 0x05:	msg("Reset failed (hard disk)");			break;
     70     case 0x06:	msg("Disk changed since last operation");		break;
     71     case 0x07:	msg("Drive parameter activity failed");			break;
     72     case 0x08:	msg("DMA overrun");					break;
     73     case 0x09:	msg("Attempt to DMA across 64K boundary");		break;
     74     case 0x0A:	msg("Bad sector detected");				break;
     75     case 0x0B:	msg("Bad track detected");				break;
     76     case 0x0C:	msg("Unsupported track");				break;
     77     case 0x10:	msg("Bad CRC/ECC on disk read");			break;
     78     case 0x11:	msg("CRC/ECC corrected data error");			break;
     79     case 0x20:	msg("Controller has failed");				break;
     80     case 0x40:	msg("Seek operation failed");				break;
     81     case 0x80:	msg("Attachment failed to respond");			break;
     82     case 0xAA:	msg("Drive not ready (hard disk only");			break;
     83     case 0xBB:	msg("Undefined error occurred (hard disk only)");	break;
     84     case 0xCC:	msg("Write fault occurred");				break;
     85     case 0xE0:	msg("Status error");					break;
     86     case 0xFF:	msg("Sense operation failed");				break;
     87   }
     88   _exit(1);
     89 }
     90 
     91 /*
     92  Identify what kind of diskette is installed in the specified drive.
     93  Return the number of sectors per track assumed as follows:
     94  9	-	360 K and 720 K 5.25".
     95 15	-	1.2 M HD	5.25".
     96 18	-	1.44 M		3.5".
     97 */
     98 int nsects(int (drive))
     99 {
    100   static	int	nsect[] = {18, 15, 9};
    101 
    102   char	*buffer;
    103   int	i, status;
    104 /*
    105  Read sector 1, head 0, track 0 to get the BIOS running.
    106 */
    107   buffer = (char *)malloc(SECTORSIZE);
    108   biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
    109   status = biosdisk(READ, drive, 0, 10, 1, 1, buffer);
    110   if (status == 0x06)			/* Door signal change?	*/
    111   status = biosdisk(READ, drive, 0, 0, 1, 1, buffer);
    112 
    113   for (i=0; i < sizeof(nsect)/sizeof(int); ++i) {
    114     biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
    115     status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
    116     if (status == 0x06)
    117       status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
    118       if (status == 0x00) break;
    119     }
    120     if (i == sizeof(nsect)/sizeof(int)) {
    121       msg("Can't figure out how many sectors/track for this diskette.");
    122     }
    123     free(buffer);
    124     return(nsect[i]);
    125 }
    126 
    127 void main(void)
    128 {
    129   char	 fname[MAXPATH];
    130   char	*buffer, *pbuf;
    131   int	 count, fdin, drive, head, track, status, spt, buflength, ns;
    132 
    133   puts("RaWrite 1.2 - Write disk file to raw floppy diskette\n");
    134   ctrlbrk(handler);
    135   printf("Enter source file name: ");
    136   scanf("%s", fname);
    137   _fmode = O_BINARY;
    138   if ((fdin = open(fname, O_RDONLY)) <= 0) {
    139      perror(fname);
    140      exit(1);
    141   }
    142 
    143   printf("Enter destination drive: ");
    144   scanf("%s", fname);
    145   drive = fname[0];
    146   drive = (islower(drive) ? toupper(drive) : drive) - 'A';
    147   printf("Please insert a formatted diskette into ");
    148   printf("drive %c: and press -ENTER- :", drive + 'A');
    149   while (bioskey(1) == 0) ;				/* Wait...	*/
    150   if ((bioskey(0) & 0x7F) == 3) exit(1);		/* Check for ^C	*/
    151   putchar('\n');
    152   done = FALSE;
    153 /*
    154  * Determine number of sectors per track and allocate buffers.
    155  */
    156   spt = nsects(drive);
    157   buflength = spt * SECTORSIZE;
    158   buffer = (char *)malloc(buflength);
    159   printf("Number of sectors per track for this disk is %d\n", spt);
    160   printf("Writing image to drive %c:.  Press ^C to abort.\n", drive+'A');
    161 /*
    162  * Start writing data to diskette until there is no more data to write.
    163  */
    164    head = track = 0;
    165    while ((count = read(fdin, buffer, buflength)) > 0 && !done) {
    166      pbuf = buffer;
    167      for (ns = 1; count > 0 && !done; ns+=3) {
    168        printf("Track: %02d  Head: %2d Sector: %2d\r", track, head, ns);
    169        status = biosdisk(WRITE, drive, head, track, ns, 3, pbuf);
    170 
    171        if (status != 0) Error(status);
    172 
    173        count -= (3*SECTORSIZE);
    174        pbuf  += (3*SECTORSIZE);
    175      }
    176      if ((head = (head + 1) & 1) == 0) ++track;
    177    }
    178    if (eof(fdin)) {
    179      printf("\nDone.\n");
    180      biosdisk(2, drive, 0, 0, 1, 1, buffer);		/* Retract head	*/
    181    }
    182 }	/* end main */
    183