mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
672 lines
21 KiB
Plaintext
672 lines
21 KiB
Plaintext
1File: FILEIO.C Page 1
|
|
1
|
|
2 /****************************************************************
|
|
3 * *
|
|
4 * CP/M-68K BDOS File I/O Module *
|
|
5 * *
|
|
6 * This module contains all file handling BDOS functions *
|
|
7 * except for read and write for CP/M-68K. Included are: *
|
|
8 * *
|
|
9 * seldsk() - select disk *
|
|
10 * openfile() - open file *
|
|
11 * close_fi() - close file *
|
|
12 * search() - search for first/next file match *
|
|
13 * create() - create file *
|
|
14 * delete() - delete file *
|
|
15 * rename() - rename file *
|
|
16 * set_attr() - set file attributes *
|
|
17 * getsize() - get file size *
|
|
18 * setran() - set random record field *
|
|
19 * free_sp() - get disk free space *
|
|
20 * move() - general purpose byte mover *
|
|
21 * *
|
|
22 * *
|
|
23 * Compiled with Alcyon C on the VAX *
|
|
24 * *
|
|
25 ****************************************************************/
|
|
26
|
|
27 #include "bdosinc.h" /* Standard I/O declarations */
|
|
28
|
|
29 #include "bdosdef.h" /* Type and structure declarations for BDOS */
|
|
30
|
|
31 #include "pktio.h" /* Packet I/O definitions */
|
|
32
|
|
33 /* declare external fucntions */
|
|
34 EXTERN UWORD dirscan(); /* directory scanning routine */
|
|
35 EXTERN UWORD error(); /* disk error routine */
|
|
36 EXTERN UWORD ro_err(); /* read-only file error routine */
|
|
37 EXTERN UWORD do_phio(); /* packet disk i/o handler */
|
|
38 EXTERN clraloc(); /* clear bit in allocation vector */
|
|
39 EXTERN setaloc(); /* set bit in allocation vector */
|
|
40 EXTERN UWORD swap(); /* assembly language byte swapper */
|
|
41 EXTERN UWORD dir_wr(); /* directory write routine */
|
|
42 EXTERN tmp_sel(); /* temporary select disk routine */
|
|
43 EXTERN UWORD calcext(); /* calc max extent allocated for fcb */
|
|
44 EXTERN UWORD udiv(); /* unsigned divide routine */
|
|
45
|
|
46
|
|
47 /* declare external variables */
|
|
48 EXTERN UWORD log_dsk; /* logged-on disk vector */
|
|
49 EXTERN UWORD ro_dsk; /* read-only disk vector */
|
|
50 EXTERN UWORD crit_dsk; /* vector of disks in critical state */
|
|
51
|
|
52
|
|
53 /************************************
|
|
54 * This function passed to dirscan *
|
|
55 * from seldsk (below) *
|
|
56 ************************************/
|
|
57
|
|
58 BOOLEAN alloc(fcbp, dirp, dirindx)
|
|
59 /* Set up allocation vector for directory entry pointed to by dirp */
|
|
1File: FILEIO.C Page 2
|
|
60
|
|
61 struct fcb *fcbp; /* not used in this function */
|
|
62 REG struct dirent *dirp; /* pointer to directory entry */
|
|
63 WORD dirindx; /* index into directory for *dirp */
|
|
64 {
|
|
65 REG WORD i; /* loop counter */
|
|
66 BSETUP
|
|
67
|
|
68 if ( UBWORD(dirp->entry) < 0x10 ) /* skip MP/M 2.x and CP/M 3.x XFCBs */
|
|
69 {
|
|
70 (GBL.dphp)->hiwater = dirindx; /* set up high water mark for disk */
|
|
71 i = 0;
|
|
72 if ((GBL.parmp)->dsm < 256)
|
|
73 {
|
|
74 do setaloc( UBWORD(dirp->dskmap.small[i++]) );
|
|
75 while (i <= 15);
|
|
76 }
|
|
77 else
|
|
78 {
|
|
79 do setaloc(swap(dirp->dskmap.big[i++]));
|
|
80 while (i <= 7);
|
|
81 }
|
|
82 }
|
|
83 }
|
|
84
|
|
85
|
|
86 /************************
|
|
87 * seldsk entry point *
|
|
88 ************************/
|
|
89
|
|
90 seldsk(dsknum)
|
|
91
|
|
92 REG UBYTE dsknum; /* disk number to select */
|
|
93
|
|
94 {
|
|
95 struct iopb selpkt;
|
|
96 REG WORD i;
|
|
97 UWORD j;
|
|
98 REG UBYTE logflag;
|
|
99 BSETUP
|
|
100
|
|
101 logflag = ~(log_dsk >> dsknum) & 1;
|
|
102 if ((GBL.curdsk != dsknum) || logflag)
|
|
103 { /* if not last used disk or not logged on */
|
|
104 selpkt.iofcn = sel_info;
|
|
105 GBL.curdsk = (selpkt.devnum = dsknum);
|
|
106 if (UBWORD(dsknum) > 15) error(2);
|
|
107 selpkt.ioflags = logflag ^ 1;
|
|
108 do
|
|
109 {
|
|
110 do_phio(&selpkt); /* actually do the disk select */
|
|
111 if ( (GBL.dphp = selpkt.infop) != NULL ) break;
|
|
112 } while ( ! error(3) );
|
|
113
|
|
114 GBL.dirbufp = (GBL.dphp)->dbufp;
|
|
115 /* set up GBL copies of dir_buf and dpb ptrs */
|
|
116 GBL.parmp = (GBL.dphp)->dpbp;
|
|
117 }
|
|
118 if (logflag)
|
|
1File: FILEIO.C Page 3
|
|
119 { /* if disk not previously logged on, do it now */
|
|
120 LOCK /* must lock the file system while messing with alloc vec */
|
|
121 i = (GBL.parmp)->dsm;
|
|
122 do clraloc(i); while (i--); /* clear the allocation vector */
|
|
123 i = udiv( (LONG)(((GBL.parmp)->drm) + 1),
|
|
124 4 * (((GBL.parmp)->blm) + 1), &j);
|
|
125 /* calculate nmbr of directory blks */
|
|
126 if (j) i++; /* round up */
|
|
127 do setaloc(--i); while (i); /* alloc directory blocks */
|
|
128 dirscan(alloc, NULL, 0x0e); /* do directory scan & alloc blocks */
|
|
129 log_dsk |= 1 << dsknum; /* mark disk as logged in */
|
|
130 }
|
|
131 }
|
|
132
|
|
133
|
|
134 /*******************************
|
|
135 * General purpose byte mover *
|
|
136 *******************************/
|
|
137
|
|
138 move(p1, p2, i)
|
|
139
|
|
140 REG BYTE *p1;
|
|
141 REG BYTE *p2;
|
|
142 REG WORD i;
|
|
143 {
|
|
144 while (i--)
|
|
145 *p2++ = *p1++;
|
|
146 }
|
|
147
|
|
148
|
|
149 /*************************************
|
|
150 * General purpose filename matcher *
|
|
151 *************************************/
|
|
152
|
|
153 BOOLEAN match(p1, p2, chk_ext)
|
|
154
|
|
155 REG UBYTE *p1;
|
|
156 REG UBYTE *p2;
|
|
157 BOOLEAN chk_ext;
|
|
158 {
|
|
159 REG WORD i;
|
|
160 REG UBYTE temp;
|
|
161 BSETUP
|
|
162
|
|
163 i = 12;
|
|
164 do
|
|
165 {
|
|
166 temp = (*p1 ^ '?');
|
|
167 if ( ((*p1++ ^ *p2++) & 0x7f) && temp )
|
|
168 return(FALSE);
|
|
169 i -= 1;
|
|
170 } while (i);
|
|
171 if (chk_ext)
|
|
172 {
|
|
173 if ( (*p1 != '?') && ((*p1 ^ *p2) & ~((GBL.parmp)->exm)) )
|
|
174 return(FALSE);
|
|
175 p1 += 2;
|
|
176 p2 += 2;
|
|
177 if ((*p1 ^ *p2) & 0x3f) return(FALSE);
|
|
1File: FILEIO.C Page 4
|
|
178 }
|
|
179 return(TRUE);
|
|
180 }
|
|
181
|
|
182
|
|
183 /************************
|
|
184 * openfile entry point *
|
|
185 ************************/
|
|
186
|
|
187 BOOLEAN openfile(fcbp, dirp, dirindx)
|
|
188
|
|
189 REG struct fcb *fcbp; /* pointer to fcb for file to open */
|
|
190 struct dirent *dirp; /* pointer to directory entry */
|
|
191 WORD dirindx;
|
|
192
|
|
193 {
|
|
194 REG UBYTE fcb_ext; /* extent field from fcb */
|
|
195 REG BOOLEAN rtn;
|
|
196 BSETUP
|
|
197
|
|
198 if ( rtn = match(fcbp, dirp, TRUE) )
|
|
199 {
|
|
200 fcb_ext = fcbp->extent; /* save extent number from user's fcb */
|
|
201 move(dirp, fcbp, sizeof *dirp);
|
|
202 /* copy dir entry into user's fcb */
|
|
203 fcbp->extent = fcb_ext;
|
|
204 fcbp->s2 |= 0x80; /* set hi bit of S2 (write flag) */
|
|
205 crit_dsk |= 1 << (GBL.curdsk);
|
|
206 }
|
|
207 return(rtn);
|
|
208 }
|
|
209
|
|
210
|
|
211 /*************************/
|
|
212 /* flush buffers routine */
|
|
213 /*************************/
|
|
214
|
|
215 UWORD flushit()
|
|
216 {
|
|
217 REG UWORD rtn; /* return code from flush buffers call */
|
|
218 struct iopb flushpkt; /* I/O packet for flush buffers call */
|
|
219
|
|
220 flushpkt.iofcn = flush;
|
|
221 while ( rtn = do_phio(&flushpkt) )
|
|
222 if ( error(1) ) break;
|
|
223 return(rtn);
|
|
224 }
|
|
225
|
|
226
|
|
227 /*********************************
|
|
228 * file close routine for dirscan *
|
|
229 *********************************/
|
|
230
|
|
231 BOOLEAN close(fcbp, dirp, dirindx)
|
|
232
|
|
233 REG struct fcb *fcbp; /* pointer to fcb */
|
|
234 REG struct dirent *dirp; /* pointer to directory entry */
|
|
235 WORD dirindx; /* index into directory */
|
|
236
|
|
1File: FILEIO.C Page 5
|
|
237 {
|
|
238 REG WORD i;
|
|
239 REG UBYTE *fp;
|
|
240 REG UBYTE *dp;
|
|
241 REG UWORD fcb_ext;
|
|
242 REG UWORD dir_ext;
|
|
243 BSETUP
|
|
244
|
|
245 if ( match(fcbp, dirp, TRUE) )
|
|
246 { /* Note that FCB merging is done here as a final
|
|
247 confirmation that disks haven't been swapped */
|
|
248 LOCK
|
|
249 fp = &(fcbp->dskmap.small[0]);
|
|
250 dp = &(dirp->dskmap.small[0]);
|
|
251 if ((GBL.parmp)->dsm < 256)
|
|
252 { /* Small disk map merge routine */
|
|
253 i = 16;
|
|
254 do
|
|
255 {
|
|
256 if (*dp)
|
|
257 {
|
|
258 if (*fp)
|
|
259 {
|
|
260 if (*dp != *fp) goto badmerge;
|
|
261 }
|
|
262 else *fp = *dp;
|
|
263 }
|
|
264 else *dp = *fp;
|
|
265 fp += 1;
|
|
266 dp += 1;
|
|
267 i -= 1;
|
|
268 } while (i);
|
|
269 }
|
|
270 else
|
|
271 { /* Large disk map merge routine */
|
|
272 i = 8;
|
|
273 do
|
|
274 {
|
|
275 if (*(UWORD *)dp)
|
|
276 {
|
|
277 if (*(UWORD *)fp)
|
|
278 {
|
|
279 if (*(UWORD *)dp != *(UWORD *)fp) goto badmerge;
|
|
280 }
|
|
281 else *(UWORD *)fp = *(UWORD *)dp;
|
|
282 }
|
|
283 else *(UWORD *)dp = *(UWORD *)fp;
|
|
284 (UWORD *)fp += 1;
|
|
285 (UWORD *)dp += 1;
|
|
286 i -= 1;
|
|
287 } while (i);
|
|
288 }
|
|
289 /* Disk map merging complete */
|
|
290 fcb_ext = calcext(fcbp); /* calc max extent for fcb */
|
|
291 dir_ext = (UWORD)(dirp->extent) & 0x1f;
|
|
292 if ( (fcb_ext > dir_ext) ||
|
|
293 ((fcb_ext == dir_ext) &&
|
|
294 (UBWORD(fcbp->rcdcnt) > UBWORD(dirp->rcdcnt))) )
|
|
295 /* if fcb points to larger file than dirp */
|
|
1File: FILEIO.C Page 6
|
|
296 {
|
|
297 dirp->rcdcnt = fcbp->rcdcnt; /* set up rc, ext from fcb */
|
|
298 dirp->extent = (BYTE)fcb_ext;
|
|
299 }
|
|
300 dirp->s1 = fcbp->s1;
|
|
301 if ( (dirp->ftype[robit]) & 0x80) ro_err(fcbp,dirindx);
|
|
302 /* read-only file error */
|
|
303 dirp->ftype[arbit] &= 0x7f; /* clear archive bit */
|
|
304 dir_wr(dirindx >> 2);
|
|
305 UNLOCK
|
|
306 return(TRUE);
|
|
307
|
|
308 badmerge:
|
|
309 UNLOCK
|
|
310 ro_dsk |= (1 << GBL.curdsk);
|
|
311 return(FALSE);
|
|
312 }
|
|
313 else return(FALSE);
|
|
314 }
|
|
315
|
|
316
|
|
317 /************************
|
|
318 * close_fi entry point *
|
|
319 ************************/
|
|
320
|
|
321 UWORD close_fi(fcbp)
|
|
322
|
|
323 struct fcb *fcbp; /* pointer to fcb for file to close */
|
|
324 {
|
|
325 flushit(); /* first, flush the buffers */
|
|
326 if ((fcbp->s2) & 0x80) return(0); /* if file write flag not on,
|
|
327 don't need to do physical close */
|
|
328 return( dirscan(close, fcbp, 0)); /* call dirscan with close function */
|
|
329 }
|
|
330
|
|
331
|
|
332 /************************
|
|
333 * search entry point *
|
|
334 ************************/
|
|
335
|
|
336 /* First two functions for dirscan */
|
|
337
|
|
338 BOOLEAN alltrue(p1, p2, i)
|
|
339 UBYTE *p1;
|
|
340 UBYTE *p2;
|
|
341 WORD i;
|
|
342 {
|
|
343 return(TRUE);
|
|
344 }
|
|
345
|
|
346 BOOLEAN matchit(p1, p2, i)
|
|
347 UBYTE *p1;
|
|
348 UBYTE *p2;
|
|
349 WORD i;
|
|
350 {
|
|
351 return(match(p1, p2, TRUE));
|
|
352 }
|
|
353
|
|
354
|
|
1File: FILEIO.C Page 7
|
|
355 /* search entry point */
|
|
356 UWORD search(fcbp, dsparm, p)
|
|
357
|
|
358 REG struct fcb *fcbp; /* pointer to fcb for file to search */
|
|
359 REG UWORD dsparm; /* parameter to pass through to dirscan */
|
|
360 UBYTE *p; /* pointer to pass through to tmp_sel */
|
|
361
|
|
362 {
|
|
363 REG UWORD rtn; /* return value */
|
|
364 BSETUP
|
|
365
|
|
366 if (fcbp->drvcode == '?')
|
|
367 {
|
|
368 seldsk(GBL.dfltdsk);
|
|
369 rtn = dirscan(alltrue, fcbp, dsparm);
|
|
370 }
|
|
371 else
|
|
372 {
|
|
373 tmp_sel(p); /* temporarily select disk */
|
|
374 if (fcbp->extent != '?') fcbp->extent = 0;
|
|
375 fcbp->s2 = 0;
|
|
376 rtn = dirscan(matchit, fcbp, dsparm);
|
|
377 }
|
|
378 move( GBL.dirbufp, GBL.dmaadr, SECLEN);
|
|
379 return(rtn);
|
|
380 }
|
|
381
|
|
382
|
|
383 /************************
|
|
384 * create entry point *
|
|
385 ************************/
|
|
386
|
|
387 BOOLEAN create(fcbp, dirp, dirindx)
|
|
388
|
|
389 REG struct fcb *fcbp; /* pointer to fcb for file to create */
|
|
390 REG struct dirent *dirp; /* pointer to directory entry */
|
|
391 REG WORD dirindx; /* index into directory */
|
|
392
|
|
393 {
|
|
394 REG BYTE *p;
|
|
395 REG WORD i;
|
|
396 REG BOOLEAN rtn;
|
|
397 BSETUP
|
|
398
|
|
399 if ( rtn = ((dirp->entry) == 0xe5) )
|
|
400 {
|
|
401 p = &(fcbp->rcdcnt);
|
|
402 i = 17;
|
|
403 do
|
|
404 { /* clear fcb rcdcnt and disk map */
|
|
405 *p++ = 0;
|
|
406 i -= 1;
|
|
407 } while (i);
|
|
408 move(fcbp, dirp, sizeof *dirp); /* move the fcb to the directory */
|
|
409 dir_wr(dirindx >> 2); /* write the directory sector */
|
|
410 if ( dirindx > (GBL.dphp)->hiwater )
|
|
411 (GBL.dphp)->hiwater = dirindx;
|
|
412 crit_dsk |= 1 << (GBL.curdsk);
|
|
413 }
|
|
1File: FILEIO.C Page 8
|
|
414 return(rtn);
|
|
415 }
|
|
416
|
|
417
|
|
418 /************************
|
|
419 * delete entry point *
|
|
420 ************************/
|
|
421
|
|
422 BOOLEAN delete(fcbp, dirp, dirindx)
|
|
423
|
|
424 REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
|
425 REG struct dirent *dirp; /* pointer to directory entry */
|
|
426 REG WORD dirindx; /* index into directory */
|
|
427
|
|
428 {
|
|
429 REG WORD i;
|
|
430 REG BOOLEAN rtn;
|
|
431 BSETUP
|
|
432
|
|
433 if ( rtn = match(fcbp, dirp, FALSE) )
|
|
434 {
|
|
435 if ( (dirp->ftype[robit]) & 0x80 ) ro_err(fcbp,dirindx);
|
|
436 /* check for read-only file */
|
|
437 dirp->entry = 0xe5;
|
|
438 LOCK
|
|
439 dir_wr(dirindx >> 2);
|
|
440 /* Now free up the space in the allocation vector */
|
|
441 if ((GBL.parmp)->dsm < 256)
|
|
442 {
|
|
443 i = 16;
|
|
444 do clraloc(UBWORD(dirp->dskmap.small[--i]));
|
|
445 while (i);
|
|
446 }
|
|
447 else
|
|
448 {
|
|
449 i = 8;
|
|
450 do clraloc(swap(dirp->dskmap.big[--i]));
|
|
451 while (i);
|
|
452 }
|
|
453 UNLOCK
|
|
454 }
|
|
455 return(rtn);
|
|
456 }
|
|
457
|
|
458
|
|
459 /************************
|
|
460 * rename entry point *
|
|
461 ************************/
|
|
462
|
|
463 BOOLEAN rename(fcbp, dirp, dirindx)
|
|
464
|
|
465 REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
|
466 REG struct dirent *dirp; /* pointer to directory entry */
|
|
467 REG WORD dirindx; /* index into directory */
|
|
468
|
|
469 {
|
|
470 REG UWORD i;
|
|
471 REG BYTE *p; /* general purpose pointers */
|
|
472 REG BYTE *q;
|
|
1File: FILEIO.C Page 9
|
|
473 REG BOOLEAN rtn;
|
|
474 BSETUP
|
|
475
|
|
476 if ( rtn = match(fcbp, dirp, FALSE) )
|
|
477 {
|
|
478 if ( (dirp->ftype[robit]) & 0x80 ) ro_err(fcbp,dirindx);
|
|
479 /* check for read-only file */
|
|
480 p = &(fcbp->dskmap.small[1]);
|
|
481 q = &(dirp->fname[0]);
|
|
482 i = 11;
|
|
483 do
|
|
484 {
|
|
485 *q++ = *p++ & 0x7f;
|
|
486 i -= 1;
|
|
487 } while (i);
|
|
488 dir_wr(dirindx >> 2);
|
|
489 }
|
|
490 return(rtn);
|
|
491 }
|
|
492
|
|
493
|
|
494 /************************
|
|
495 * set_attr entry point *
|
|
496 ************************/
|
|
497
|
|
498 BOOLEAN set_attr(fcbp, dirp, dirindx)
|
|
499
|
|
500 REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
|
501 REG struct dirent *dirp; /* pointer to directory entry */
|
|
502 REG WORD dirindx; /* index into directory */
|
|
503
|
|
504 {
|
|
505 REG BOOLEAN rtn;
|
|
506 BSETUP
|
|
507
|
|
508 if ( rtn = match(fcbp, dirp, FALSE) )
|
|
509 {
|
|
510 move(&fcbp->fname[0], &dirp->fname[0], 11);
|
|
511 dir_wr(dirindx >> 2);
|
|
512 }
|
|
513 return(rtn);
|
|
514 }
|
|
515
|
|
516
|
|
517 /****************************
|
|
518 * utility routine used by *
|
|
519 * setran and getsize *
|
|
520 ****************************/
|
|
521
|
|
522 LONG extsize(fcbp)
|
|
523 /* Return size of extent pointed to by fcbp */
|
|
524 REG struct fcb *fcbp;
|
|
525
|
|
526 {
|
|
527 return( ((LONG)(fcbp->extent & 0x1f) << 7)
|
|
528 | ((LONG)(fcbp->s2 & 0x3f) << 12) );
|
|
529 }
|
|
530
|
|
531
|
|
1File: FILEIO.C Page 10
|
|
532 /************************
|
|
533 * setran entry point *
|
|
534 ************************/
|
|
535
|
|
536 setran(fcbp)
|
|
537
|
|
538 REG struct fcb *fcbp; /* pointer to fcb for file to set ran rec */
|
|
539
|
|
540 {
|
|
541 struct
|
|
542 {
|
|
543 BYTE b3;
|
|
544 BYTE b2;
|
|
545 BYTE b1;
|
|
546 BYTE b0;
|
|
547 };
|
|
548 LONG random;
|
|
549
|
|
550 random = (LONG)UBWORD(fcbp->cur_rec) + extsize(fcbp);
|
|
551 /* compute random record field */
|
|
552 fcbp->ran0 = random.b2;
|
|
553 fcbp->ran1 = random.b1;
|
|
554 fcbp->ran2 = random.b0;
|
|
555 }
|
|
556
|
|
557
|
|
558 /**********************************/
|
|
559 /* fsize is a funtion for dirscan */
|
|
560 /* passed from getsize */
|
|
561 /**********************************/
|
|
562
|
|
563 BOOLEAN fsize(fcbp, dirp, dirindx)
|
|
564
|
|
565 REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
|
566 REG struct dirent *dirp; /* pointer to directory entry */
|
|
567 WORD dirindx; /* index into directory */
|
|
568
|
|
569 {
|
|
570 REG BOOLEAN rtn;
|
|
571 struct
|
|
572 {
|
|
573 BYTE b3;
|
|
574 BYTE b2;
|
|
575 BYTE b1;
|
|
576 BYTE b0;
|
|
577 };
|
|
578 LONG temp;
|
|
579
|
|
580 if ( rtn = match(fcbp, dirp, FALSE) )
|
|
581 {
|
|
582 temp = (LONG)UBWORD(dirp->rcdcnt) + extsize(dirp);
|
|
583 /* compute file size */
|
|
584 fcbp->ran0 = temp.b2;
|
|
585 fcbp->ran1 = temp.b1;
|
|
586 fcbp->ran2 = temp.b0;
|
|
587 }
|
|
588 return(rtn);
|
|
589 }
|
|
590
|
|
1File: FILEIO.C Page 11
|
|
591 /************************
|
|
592 * getsize entry point *
|
|
593 ************************/
|
|
594
|
|
595 getsize(fcbp)
|
|
596 /* get file size */
|
|
597 REG struct fcb *fcbp; /* pointer to fcb to get file size for */
|
|
598
|
|
599 {
|
|
600 LONG maxrcd;
|
|
601 LONG temp;
|
|
602 REG WORD dsparm;
|
|
603 struct
|
|
604 {
|
|
605 BYTE b3;
|
|
606 BYTE b2;
|
|
607 BYTE b1;
|
|
608 BYTE b0;
|
|
609 };
|
|
610
|
|
611 maxrcd = 0;
|
|
612 dsparm = 0;
|
|
613 temp = 0;
|
|
614 while ( dirscan(fsize, fcbp, dsparm) < 255 )
|
|
615 { /* loop until no more matches */
|
|
616 temp.b2 = fcbp->ran0;
|
|
617 temp.b1 = fcbp->ran1;
|
|
618 temp.b0 = fcbp->ran2;
|
|
619 if (temp > maxrcd) maxrcd = temp;
|
|
620 dsparm = 1;
|
|
621 }
|
|
622 fcbp->ran0 = maxrcd.b2;
|
|
623 fcbp->ran1 = maxrcd.b1;
|
|
624 fcbp->ran2 = maxrcd.b0;
|
|
625 }
|
|
626
|
|
627
|
|
628 /************************
|
|
629 * free_sp entry point *
|
|
630 ************************/
|
|
631
|
|
632 free_sp(dsknum)
|
|
633
|
|
634 UBYTE dsknum; /* disk number to get free space of */
|
|
635 {
|
|
636 REG LONG records;
|
|
637 REG UWORD *alvec;
|
|
638 REG UWORD bitmask;
|
|
639 REG UWORD alvword;
|
|
640 REG WORD i;
|
|
641 BSETUP
|
|
642
|
|
643 seldsk(dsknum); /* select the disk */
|
|
644 records = (LONG)0; /* initialize the variables */
|
|
645 alvec = (GBL.dphp)->alv;
|
|
646 bitmask = 0;
|
|
647 for (i = 0; i <= (GBL.parmp)->dsm; i++) /* for loop to compute */
|
|
648 {
|
|
649 if ( ! bitmask)
|
|
1File: FILEIO.C Page 12
|
|
650 {
|
|
651 bitmask = 0x8000;
|
|
652 alvword = ~(*alvec++);
|
|
653 }
|
|
654 if ( alvword & bitmask)
|
|
655 records += (LONG)( ((GBL.parmp)->blm) + 1 );
|
|
656 bitmask >>= 1;
|
|
657 }
|
|
658 *(LONG *)GBL.dmaadr = records; /* move # records to DMA address */
|
|
659 }
|