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