summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FDISK/INT13.C
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/FDISK/INT13.C')
-rw-r--r--v4.0/src/CMD/FDISK/INT13.C443
1 files changed, 443 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FDISK/INT13.C b/v4.0/src/CMD/FDISK/INT13.C
new file mode 100644
index 0000000..ded7ff0
--- /dev/null
+++ b/v4.0/src/CMD/FDISK/INT13.C
@@ -0,0 +1,443 @@
1#include "dos.h" /* AN000 */
2#include "fdisk.h" /* AN000 */
3#include "extern.h" /* AN000 */
4#include "subtype.h" /* AN000 */
5#include "fdiskmsg.h" /* AN000 */
6
7#include "string.h"
8#include "stdio.h"
9#include "stdlib.h"
10
11/* int printf(char *, ...); */
12
13/* */
14char get_disk_info()
15
16BEGIN
17
18unsigned char i;
19
20 /* Initialize values */
21 number_of_drives = uc(0); /* AC000 */
22 for (i=uc(0); i < uc(2); i++) /* AC000 */
23 BEGIN
24 total_disk[i] = u(0); /* AC000 */
25 total_mbytes[i] = f(0); /* AC000 */
26 max_sector[i] = uc(0); /* AC000 */
27 max_head[0] = u(0); /* AC004 */
28 END
29
30 /* See how many drives there are */
31 if (get_drive_parameters(uc(0x80))) /* AC000 */
32
33 BEGIN
34 /* Get the drive parameters for all drives */
35 for (i = uc(0); i < number_of_drives;i++) /* AC000 */
36
37 BEGIN
38 if (get_drive_parameters(uc(0x80)+i)) /* AC000 */
39
40 BEGIN
41 /* Save drive parameters */
42 max_sector[i] = ((unsigned char)(regs.h.cl & 0x3F));
43 max_head[i] = ((unsigned)(regs.h.dh +1)); /* AC004 */
44#if IBMCOPYRIGHT
45 total_disk[i] = ((((unsigned)(regs.h.cl & 0xC0 )) & 0x00C0) << 2)+ ((unsigned)regs.h.ch) +1;
46#else
47 total_disk[i] = ((((unsigned)(regs.h.cl & 0xc0)) << 2) | regs.h.ch) + 1;
48#endif
49 total_mbytes[i] = cylinders_to_mbytes(total_disk[i],i); /* AN004 */
50 END
51 else
52 BEGIN
53 good_disk[i] = FALSE;
54 return(FALSE);
55 END
56 END
57 return(TRUE);
58 END
59 else
60 /* No drives present */
61 BEGIN
62 no_fatal_error = FALSE;
63 return(FALSE);
64 END
65END
66
67
68
69/* */
70char write_boot_record(cylinder,which_disk)
71
72unsigned cylinder;
73unsigned char which_disk;
74
75BEGIN
76
77char i;
78char j;
79char far *buffer_pointer = boot_record;
80
81 /* Setup read, always on a cylinder boundary */
82 regs.h.ah = uc(WRITE_DISK); /* AC000 */
83 regs.h.al = uc(1); /* AC000 */
84 regs.h.dh = uc(0); /* AC000 */
85 regs.h.cl = uc(0x01); /* AC000 */
86
87 /* Specify the disk */
88 regs.h.dl = which_disk + 0x80;
89
90 /* Need to scramble CX so that sectors and cyl's are in INT 13 format */
91
92 if (cylinder > u(255)) /* AC000 */
93 BEGIN
94 regs.h.cl = regs.h.cl | ((unsigned char)((cylinder /256) << 6));
95 END
96 regs.h.ch = (unsigned char)(cylinder & 0xFF);
97
98 /* Point at the place to read the boot record */
99 regs.x.bx = FP_OFF(buffer_pointer);
100 segregs.es = FP_SEG(buffer_pointer);
101
102 /* write the boot record */
103 DiskIo(&regs,&regs,&segregs); /* AC000 */
104
105 /* Check for error reading it */
106 if ((regs.x.cflag & 1) != u(1)) /* AC000 */
107 BEGIN
108 return(TRUE);
109 END
110 else
111 BEGIN
112 /* Tell user there was an error */
113 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
114 display(error_2);
115 no_fatal_error = FALSE;
116 return(FALSE);
117 END
118END
119
120/* */
121unsigned verify_tracks(pointer,type)
122
123char pointer;
124char type;
125
126BEGIN
127unsigned i;
128unsigned location;
129unsigned sectors_per_fat;
130unsigned cur_cyl;
131unsigned verify_cyl;
132unsigned num_tracks;
133unsigned long total_sectors;
134char golden_tracks;
135char retry;
136unsigned char cur_head; /* AC004 */
137
138char far *buffer_pointer = boot_record;
139char head;
140
141
142
143 for (i=u(0); i< u(BYTES_PER_SECTOR);i++) /* AC000 */
144 BEGIN
145 /* Put something other then 0's so that unformatted FAT looks full */
146
147 boot_record[i] = uc(0xF6); /* AC000 */
148 END
149
150 /* Get the start cylinder for the sweep */
151 cur_cyl = free_space[pointer].start;
152
153 /* Also keep track of what it is */
154 verify_cyl = cur_cyl;
155
156 /* Initialize the start head -assume 0*/
157 cur_head = uc(0); /* AC004 */
158 if ((type == c(PRIMARY)) && (cur_cyl == u(0))) /* AC000 */
159 BEGIN
160
161 /* It's head 1 - NOTE: This is convience for PC-DOS because it is */
162 /* always this way - This may have to be beefed up for IFS */
163 cur_head = uc(1); /* AC004 */
164 END
165
166 /* Now go figure out the number of golden sectors needed. Use the */
167 /* allocation equation in the fixed disk section of DOS Tech Ref. */
168 /* */
169 /* TS = Free cyl's * sector/track * track/cyl */
170 /* RS = 1 */
171 /* D = 512 */
172 /* BPD = 32 */
173 /* BPS = BYTES_PER_SECTOR */
174 /* CF = 2 */
175 /* SPF = Solve */
176 /* SPC = 4 or 8 */
177 /* BPC = 1.5 or 2 */
178 /* */
179 /* Golden Sectors = RS + 2(SPF) + BPD(D) + (DOSFILES) */
180 /* ÄÄÄÄÄÄ if bootable */
181 /* BPS */
182
183 total_sectors = ((unsigned long)free_space[pointer].space) * max_head[cur_disk] * max_sector[cur_disk];
184
185 /* Chop off one track if it starts on head 1 */
186 if (cur_head == uc(1)) /* AC004 */
187 BEGIN
188 total_sectors = total_sectors - max_sector[cur_disk];
189 END
190
191 /* See if 12 or 16 bit fat */
192 if (total_sectors > (unsigned long)FAT16_SIZE)
193 BEGIN
194 /* 16 bit */
195 sectors_per_fat = ((unsigned)((total_sectors -33)/(2 + ((BYTES_PER_SECTOR *4)/2))));
196 END
197 else
198 BEGIN
199 /* 12 bit */
200 sectors_per_fat = ((unsigned)((total_sectors -33)/(2 + ((BYTES_PER_SECTOR *8)/1.5))));
201 END
202
203 /* Round up one just to handle any rounding errors */
204 sectors_per_fat++;
205
206 /* Now see how many tracks */
207 num_tracks = (sectors_per_fat*2) + 33;
208
209 /* If primary and drive 0, add in enough for system files */
210 if ((type == c(PRIMARY)) && (cur_disk == c(0))) /* AC000 */
211 BEGIN
212 num_tracks = num_tracks + SYSTEM_FILE_SECTORS;
213 END
214
215 #if IBMCOPYRIGHT
216 /* Now convert to tracks */
217 num_tracks = num_tracks/max_sector[cur_disk];
218
219 /* Handle upward rounding */
220 if (num_tracks%max_sector[cur_disk] != u(0)) /* AC000 */
221 BEGIN
222 num_tracks++;
223 END
224 #else
225 /* Handle upward rounding */ /* The problem with the IBM code is */
226 if (num_tracks%max_sector[cur_disk] != u(0)) /* that if num_tracks is < max_sector[cur_disk] */
227 BEGIN /* the num_tracks becomes 0 due to the integer */
228 num_tracks = num_tracks + max_sector[cur_disk]; /* division and num_tracks will not be inc'd . */
229 END /* This section of code overcomes that. */
230
231 /* Now convert to tracks */
232 num_tracks = num_tracks/max_sector[cur_disk];
233 #endif
234
235
236 golden_tracks = FALSE;
237 while (!golden_tracks)
238 BEGIN
239 for (i = u(0);i < num_tracks; i++) /* AC000 */
240 BEGIN
241 retry = c(0); /* AC000 */
242 do
243 BEGIN
244 retry++;
245 /* Specify the operation */
246 regs.h.ah = uc(WRITE_DISK); /* AC000 */
247
248 /* Specify number of sectors */
249 regs.h.al = ((unsigned char)max_sector[cur_disk]);
250
251 /* Specify the start sectors */
252 regs.h.cl = uc(1); /* AC000 */
253
254 /* Need to scramble CX so that sectors and cyl's are in INT 13 format */
255 if (cur_cyl > u(255)) /* AC000 */
256 BEGIN
257 regs.h.cl = regs.h.cl | ((unsigned char)((cur_cyl/256) << 6));
258 END
259 regs.h.ch = ((unsigned char)cur_cyl) & 0xFF;
260
261 /* Specify the disk */
262 regs.h.dl = ((unsigned char)cur_disk) + 0x80;
263
264 /* Specify the head */
265 regs.h.dh = cur_head; /* AC004 */
266
267 /* Point at the place to write */
268 regs.x.bx = FP_OFF(buffer_pointer);
269 segregs.es = FP_SEG(buffer_pointer);
270
271 /* write the track */
272 DiskIo(&regs,&regs,&segregs); /* AC000 */
273
274 END
275 while (((regs.x.cflag & 1) == u(1)) && (retry != c(5))); /* AC000 */
276
277 /* See if we had a good read */
278 if ((regs.x.cflag & 1) != u(1)) /* AC000 */
279 BEGIN
280 golden_tracks = TRUE;
281 /* Get the next head */
282 cur_head++;
283 if (cur_head == (uc(max_head[cur_disk] -1))) /* AC004 */
284 BEGIN
285 /* Up to the next cylinder */
286 cur_head = uc(0); /* AC004 */
287 cur_cyl++;
288
289 /* Check to see if we've reached the end of the free_space*/
290 if (cur_cyl > free_space[pointer].end)
291 BEGIN
292 /* It is, so return with the cyl offset equal to the freespace */
293 return(free_space[pointer].space);
294 END
295 END
296 END
297 else
298 BEGIN
299 /* Get out of the for loop, with a false flag */
300 golden_tracks = FALSE;
301
302 /* Bump up to the next cylinder boundary */
303 cur_cyl++;
304 cur_head = uc(0); /* AC004 */
305
306 /* Save the new verify start point */
307 verify_cyl = cur_cyl;
308
309 break;
310 END
311 END /* for num_tracks */
312 END /* while !golden_tracks */
313
314 /* All done, return the offset from original cyl to the new one */
315 return(verify_cyl - free_space[pointer].start);
316END
317
318
319/* */
320char get_drive_parameters(drive)
321
322unsigned char drive;
323
324BEGIN
325 /* See how many drives there are */
326 regs.h.ah = uc(DISK_INFO); /* AC000 */
327 regs.h.dl = drive;
328 DiskIo(&regs,&regs,&segregs); /* AC000 */
329
330 /* See if any drives exist */
331 if ((regs.h.dl == uc(0)) || ((regs.x.cflag & 1) == u(1))) /* AC000 */
332 BEGIN
333 display(error_1);
334 return(FALSE);
335 END
336 else
337 BEGIN
338 /* Save the number of drives */
339 number_of_drives = regs.h.dl;
340 return(TRUE);
341 END
342END
343
344/* */
345char read_boot_record(cylinder,which_disk,which_head,which_sector) /* AC000 */
346
347unsigned cylinder;
348unsigned char which_disk;
349unsigned char which_head; /* AN000 */
350unsigned char which_sector; /* AN000 */
351
352BEGIN
353
354char far *buffer_pointer = boot_record;
355
356 /* Setup read, always on a cylinder boundary */
357 regs.h.ah = uc(READ_DISK); /* AC000 */
358 regs.h.al = uc(1); /* AC000 */
359 regs.h.dh = which_head; /* AC000 */
360 regs.h.cl = which_sector; /* AC000 */
361
362 /* Specify the disk */
363 regs.h.dl = which_disk + 0x80;
364
365 /* Need to scramble CX so that sectors and cyl's are in INT 13 format */
366
367 if (cylinder > u(255)) /* AC000 */
368 BEGIN
369 regs.h.cl = regs.h.cl | ((char)((cylinder /256) << 6));
370 END
371 regs.h.ch = (unsigned char)(cylinder & 0xFF);
372
373 /* Point at the place to write the boot record */
374 regs.x.bx = FP_OFF(buffer_pointer);
375 segregs.es = FP_SEG(buffer_pointer);
376
377 /* read in the boot record */
378 DiskIo(&regs,&regs,&segregs); /* AC000 */
379 /* Check for error reading it */
380 if ((regs.x.cflag & 1) != u(1)) /* AC000 */
381 BEGIN
382 return(TRUE);
383 END
384 else
385 BEGIN
386 /* Tell user there was an error */
387 good_disk[which_disk] = FALSE;
388 clear_screen(u(0),u(0),u(24),u(79)); /* AC000 */
389 return(FALSE);
390 END
391END
392
393/* */
394void DiskIo(InRegs,OutRegs,SegRegs)
395union REGS *InRegs;
396union REGS *OutRegs;
397struct SREGS *SegRegs;
398
399BEGIN
400
401 char *WritePtr;
402
403#ifdef DEBUG
404
405 switch(InRegs->h.ah)
406 {
407 case 0:
408 case 1:
409 case 2:
410 case 4:
411 case 8:
412 case 15:
413 case 16:
414 int86x((int)DISK,InRegs,OutRegs,SegRegs); /* AC000 */
415 break;
416
417 default:
418 WritePtr = getenv("WRITE");
419 if (strcmpi(WritePtr,"ON") != 0)
420 BEGIN
421 printf("\nDisallowing Disk I/O Request\n");
422 printf("AX:%04X BX:%04X CX:%04X DX:%04X ES:%04X\n",
423 InRegs->x.ax,InRegs->x.bx,InRegs->x.cx,InRegs->x.dx,SegRegs->es);
424
425 OutRegs->h.ah = (unsigned char) 0;
426 OutRegs->x.cflag = (unsigned) 0;
427 END
428 else int86x((int)DISK,InRegs,OutRegs,SegRegs);
429
430 break;
431
432 }
433
434#else
435
436 int86x((int)DISK,InRegs,OutRegs,SegRegs); /* AC000 */
437
438#endif
439
440 return;
441
442END
443