ded@aplvax.UUCP (12/20/83)
One of these days I'll learn to state my question clearly. I asked for a way to determine how much free space is available on a disk in a CP/M environment. Several nice people resonded with STAT.COM, XDIR.COM, etc. Ah, they were right, but I had meant to ask something different. I want to determine free disk space from the confines of an application program -- through a BDOS call, or some other portable method. So when my programs are going to write to disk, they can first check if enough space if available. One of the major flaws of CP/M is that when things start to go wrong...you're done for. I would like to avoid that if all possible. I could read every directory entry and determine through some simple mathematics how much space is available, but I would prefer something more elegant. -- Don Davis JHU/APL ...decvax!harpo!seismo!umcp-cs!aplvax!ded ...rlgvax!cvl!umcp-cs!aplvax!ded
mem@sii.UUCP (Mark Mallett) (12/22/83)
b In response to the question of how to determine free space under CP/M: CP/M keeps in memory an allocation bitmap for all LOGGED IN drives. The easiest way to determine freespace on a disc is to make sure the drive is logged in, and then to look at the allocation bitmap. This is possible under CP/M 2.2 as you can find out where this bitmap is kept. What follows is an Aztec C routine `frespc' which determines the free space on a given drive (assumed to be logged in). This routine is extracted from my program VDIR (a `dired'-like program for CP/M). Preceding the routine is some definitions from VDIR.H which apply to the routine. I hope that this is useful. -mm ---------------------------------------------------------------------- typedef char BYTE; typedef int BOOL; typedef int WORD; typedef long LONG; #define IND static /* For variables with no allocation dependancies (don't have to be on the stack) */ /* CP/M call codes */ #define _MRICC 1 /* Input console character */ #define _MROCC 2 /* Output console character */ #define _MRPTR 3 /* Read paper tape */ #define _MRPTP 4 /* Write paper tape */ #define _MRLPT 5 /* Write LPT */ #define _MRDCIO 6 /* Direct console I/O */ #define _MRRIO 7 /* Read IO status */ #define _MRSIO 8 /* Write IO status */ #define _MRWCS 9 /* Write string to console */ #define _MRRBC 10 /* Read buffer from console */ #define _MRRCS 11 /* Read console status */ #define _MRLFH 12 /* Lift head */ #define _MRINI 13 /* Init BDOS */ #define _MRSEL 14 /* Select and login a disk */ #define _MROPN 15 /* Open a file */ #define _MRCLS 16 /* Close a file */ #define _MRSFL 17 /* Search for file */ #define _MRSNF 18 /* Search for next file */ #define _MRDEL 19 /* Delete a file */ #define _MRREA 20 /* Read next record */ #define _MRWRT 21 /* Write next record */ #define _MRCRF 22 /* Create file */ #define _MRREN 23 /* Rename file */ #define _MRILV 24 /* Interrogate login vector */ #define _MRIDN 25 /* Get drive number */ #define _MRDMA 26 /* Set DMA address */ #define _MRIAL 27 /* Get allocation vector */ #define _MRWPD 28 /* Write-protect disc */ #define _MRROV 29 /* Get R/O vector */ #define _MRSFA 30 /* Set file attributes */ #define _MRGDP 31 /* Get disc parms */ #define _MRGUC 32 /* Get/set user code */ #define _MRRRR 33 /* Read random record */ #define _MRWRR 34 /* Write random record */ #define _MRCFS 35 /* Compute file size */ #define _MRSRR 36 /* Set random record */ #define _MRWRZ 37 /* Write random record with zero fill */ /* Bios calls */ #define _CBBOOT 0 /* Cold boot */ #define _CBWBOOT 1 /* Warm boot */ #define _CBCNST 2 /* Console status */ #define _CBCNIN 3 /* Console input */ #define _CBCNOUT 4 /* Console out */ #define _CBLIST 5 /* Write to listing */ #define _CBPUN 6 /* Write to punch */ #define _CBRDR 7 /* Read from reader */ #define _CBHOME 8 /* Home the disk */ #define _CBSEL 9 /* Select disc */ #define _CBSTRK 10 /* Set track */ #define _CBSSEC 11 /* Set sector */ #define _CBSDMA 12 /* Set DMA */ #define _CBREAD 13 /* Read sector */ #define _CBWRT 14 /* Write sector */ #define _CBLSST 15 /* List status */ #define _CBSTRN 16 /* Sector translate */ /* Structures used */ /* Disk parameter block */ typedef struct DPBs { WORD DPB_SPT; /* Sectors per track */ BYTE DPB_BSH; /* Allocation shift factor */ BYTE DPB_BLM; /* Allocation mask */ BYTE DPB_EXM; /* Extent mask */ WORD DPB_DSM; /* Storage mask */ WORD DPB_DRM; /* Directory sizer */ BYTE DPB_AL0; BYTE DPB_AL1; WORD DPB_CKS; /* Directory check vector */ WORD DPB_OFF; /* Number of reserved tracks */ } DPB; /* Disc parameter header */ typedef struct DPHs { BYTE *DPH_XLT; /* Translate table */ WORD DPH_SCR[3]; /* Scratch */ BYTE *DPH_DIR; /* Directory scratch */ DPB *DPH_DPB; /* Pointer to DPB */ BYTE *DPH_CSV; /* Checkpoint area */ BYTE *DPH_ALV; /* Allocation area */ } DPH; /* frespc (drvnum) Find free space on drive drvnum Accepts : drvnum Drive number Returns <value> Number of K free on the drive. */ int frespc (drvnum) int drvnum; /* Drive number */ { IND BYTE *Bptr; /* Allocation pointer */ IND DPB *DPBptr; IND DPH *DPHptr; IND int btotl; /* Total blocks */ IND int blib; /* Bits left-in-byte */ IND int i; /* Scratch */ IND WORD albyte; /* Allocation byte */ DPHptr = bioshl (_CBSEL, drvnum, 0); DPBptr = bdoshl (_MRGDP, drvnum); i = DPBptr -> DPB_DSM+1; /* Number of blocks */ btotl = 0; /* Total blocks */ blib = 0; /* Bits-left-in-byte */ Bptr = DPHptr -> DPH_ALV; /* Pointer to allocation byte */ while (i--) /* DO all of them */ { if (blib == 0) { albyte = *Bptr++; blib = 8; } if ((albyte & 0x80)) btotl++; albyte = albyte << 1; blib--; } btotl = DPBptr -> DPB_DSM + 1 - btotl; /* Blocks left */ btotl = btotl * ((DPBptr -> DPB_BLM +1)/8); return (btotl); } ---------------------------------------------------------------------- Mark E. Mallett decvax!sii!mem
rconn%brl@sri-unix.UUCP (12/29/83)
From: Rick Conn <rconn@brl> The DFREE routine in SYSLIB determines free disk space for a CP/M 2.2 system. It is a simple subroutine in assembly language, and you can get the source (make sure it is for SYSLIB 2.7) from SIMTEL20 or SIG/M. Rick