home *** CD-ROM | disk | FTP | other *** search
- /* FREE command - Dec 1986 - Rev. 2 - for DeSmet C
- Vincent Bly Nanosoft PO Box 409 Ft. Belvoir, VA 22060
-
- *** Returns free disk space or free RAM memory ***
- *** Sets errorlevel if less than spec bytes free ***
-
- Call from DOS or batch file:
- FREE [N[:]] [MINREQ] [+]
-
- Examples:
- FREE (displays free space on current drive)
- FREE A (displays free space on drive A)
- FREE C: (displays free space on drive C)
- FREE B: + (displays free space on drive B & shows disk data)
- FREE M (displays free RAM memory)
- FREE 50000 (displays free space on current drive & sets errorlevel
- to 1 if less than 50,000 bytes are available )
- FREE M 256000 (displays free RAM & sets errorlevel 1 if less than 256K free)
- */
-
- #define DOS_FUNC(n) _rax = ((n) << 8), _doint(0x21)
-
- extern long atol();
- extern unsigned _rax, _rbx, _rcx, _rdx, _rds, _res, _carryf;
- long free_bytes, minval = 0L; /* 0 => default minimum required memory */
- unsigned topram, pspseg; /* used in calculating free RAM memory */
- int verbose = 0; /* extra information flag, set by '+' */
-
- main(argc,argv) /* Returns # of free bytes on drive N or the default drive, */
- int argc; /* or--if drive spec is "M"--returns free RAM memory. If a */
- char *argv[]; /* numeric spec. is given, FREE will set the errorlevel to 1 */
- { /* if this amount of free space or memory is not available. */
- /* If arg of + (plus sign) is included, detailed info given. */
- /* For minimum code size, bind with CSTDIO7.S (no floating */
- /* point is actually used, so this reduces the size of the */
- /* routines bound with printf()). Also, bind with a stack */
- /* size of 400h (bind free -s400). PUBLIC DOMAIN V. T. Bly */
-
- int n, drive = 0; /* 0 => default (current) drive number */
- char c;
-
- for (n = argc - 1; n > 0; n--) { /** Scan command line arguments **/
- c = *argv[n];
- if (isdigit(c)) /* If argument is numeric, set */
- minval = atol(argv[n]); /* minimum required memory value */
- else if (c == '+') /* set verbose if arg is '+' */
- verbose = 1;
- else
- drive = (c & 95) - '@'; /* else, calc. drive number */
- }
- if (drive == 13) {
- /*** CALCULATE FREE RAM MEMORY ***/
- /* Free ram is computed from the value of the PSP segment */
- /* (which starts at the lowest available memory location) */
- /* & top of ram value (stored as the 2nd word in the PSP). */
- /* Shift by 4 (* 16) to convert from paragraphs to bytes. */
- pspseg = _showcs() - 0x10; /* trace back to PSP segment */
- topram = _peek(2, pspseg) + (_peek(3, pspseg) << 8);/* top ram in PSP */
- free_bytes = ((long)topram - pspseg) << 4;/* actual memory available */
- puts("\nRAM memory: ");
- } else {
- /*** CALCULATE FREE DISK SPACE ***/
- _rdx = drive;
- DOS_FUNC(0x36); /* get disk free space */
- if (_rax == 0xffff) {
- puts("\n** Invalid Drive **\n");
- exit(2);
- }
- free_bytes = (long)_rbx * _rax * _rcx;
- /* (free = free clusters * sectors/cluster * bytes/sector) */
- n = _rax; /* save it */
- if (drive == 0) { /* if default drive, calc drive number */
- DOS_FUNC(0x19);
- drive = (_rax & 0xff) + 1;
- }
- _rax = n; /* restore it */
- printf("\nDrive %c: ", (char)drive + '@');
- }
- finish(drive); /* print output data & exit to DOS */
-
- }
-
-
- finish(drive) /* Finish printing free bytes and exit to DOS, giving an error */
- int drive; /* if there are insufficient bytes to meet minimum required. */
- { /* If the verbose flag is set, display additional data */
- long val;
-
- if (verbose) {
- puts("\n");
- if (drive == 13) {
- val = ((long)topram << 4) - 1L;
- printf(" Top of RAM = %7s [%05lx]\n", lngp(val), val);
- val = (long)pspseg << 4;
- printf(" Next free addr = %7s [%05lx]\n", lngp(val), val);
- printf(" Free bytes = %7s [%05lx]\n", lngp(free_bytes), free_bytes);
- } else {
- printf(" Sectors/cluster = %10s [%04x]\n", lngp((long)_rax), _rax);
- printf(" Bytes/sector = %10s [%04x]\n", lngp((long)_rcx), _rcx);
- val = (long)_rax * _rcx;
- printf(" Bytes/cluster = %10s [%04lx]\n", lngp(val), val);
- val = (long)_rax * _rcx * _rdx;
- printf(" Total clusters = %10s [%04x]\n", lngp((long)_rdx), _rdx);
- printf(" Free clusters = %10s [%04x]\n", lngp((long)_rbx), _rbx);
- printf(" Total bytes = %10s [%05lx]\n", lngp(val), val);
- printf(" Free bytes = %10s [%05lx]\n", lngp(free_bytes), free_bytes);
-
- }
- } else {
- printf("%s bytes free\n", lngp(free_bytes));
- }
- exit(free_bytes < minval);
- }
-
-
- lngp(val) /* Format long integer val for printing with commas */
- long val; /* value to be formatted */
- {
- static char fmtn[13]; /* holds formatted number */
- char buff[13]; /* temporary working buffer */
- int d, i, j, l;
-
- sprintf(buff, "%ld", val); /* first, format w/o commas */
- l = strlen(buff);
- d = l % 3;
- for (i = 0, j = 0; i < l; i++) { /* copy into s w/commas inserted */
- fmtn[j + i] = buff[i];
- --d;
- if ((i != (l - 1)) && ((d % 3) == 0)) {
- ++j;
- fmtn[j + i] = ',';
- }
- }
- fmtn[j + i] = '\0'; /* add terminating 0 */
- return(fmtn); /* return pointer to fmtn[0] */
- }