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