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