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