; TITLE "SDIR03 - Syslib 4.0" NAME ('DFREE') ;================================================================= ; Copyright (C) 1987,88, By E.T.S. ; Author : Harold F. Bower ; Derived from SDIR03.Z80 Ver 1.5 by Richard Conn ; Date : 17 Sep 89 ; Version : 1.6 ; Module : SDIR03 ; Abstract: This module contains the routine DFREE which com- ; putes the amount of free space left on the currently ; logged disk under CP/M 2.2 and CP/M 3.x (CP/M Plus). The ; DPARAMS routine MUST be called before this routine. ; NOTE: This routine will alter the DMA Address if used under ; CP/M 3.x (CP/M Plus). ; Revision: ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Module Entry Points PUBLIC DFREE ; From SYSLIB Get.. EXT BLKMAX, BLKSHF ; Definitions BDOS EQU 5 ; CP/M, ZRDOS, ZSDOS Entry Point .Z80 CSEG ;=============================================================== ; NAME - DFREE ; Entry: - None ; Exit : DE - Contains the amount of free space left in K ; Uses : DE ; Special Requirements: The DPARAMS routine MUST be called ; before this routine is used under CP/M 2.2 compatible systems ; Side Effects: DMA Address is altered under CP/M 3.x (CP/M Plus) ;=============================================================== DFREE: PUSH BC ; Save regs PUSH HL PUSH AF LD C,12 ; Which CP/M Version do we have? CALL BDOS CP 30H ; Is it 3.0 or later? JR NC,DOCPM3 ; ..jump if so LD C,27 ; Get address of Allocation Vector CALL BDOS EX DE,HL LD HL,(BLKMAX) ; Get length of Allocation Vector LD BC,0 ; Init Block Count to 0 ; BC is Accumulator for Space FREE1: PUSH DE ; Save Allocation Address LD A,(DE) ; Get bit pattern of Allocation Byte LD E,8 ; Set to process 8 blocks FREE2: RLA ; Rotate allocated block bit into carry flag JR C,FREE3 ; ..If set (bit=1), Block is allocated INC BC ; If not set, block not allocated, ; so bump Free Block Count FREE3: LD D,A ; Save remaining Allocation Bits in D DEC HL ; Count down number of blocks on disk LD A,L OR H JR Z,FREE4 ; ..jump Done if no more blocks left LD A,D ; A = Current Allocation Bit Pattern DEC E ; Have all 8 bits been examined? JR NZ,FREE2 ; ..continue if not POP DE ; Get pointer to Allocation Vector INC DE ; Point to next Allocation Byte JR FREE1 ; Continue by processing next Alloc Byte ; BC = Total amount of Free Space in terms of Blocks FREE4: POP DE ; Clear DE from stack LD L,C ; HL = BC = Number of Free Blocks LD H,B LD A,(BLKSHF) ; Get Block Shift Factor SUB 3 ; Convert number of Blocks to K JR Z,FREE6 ; ..jump Done if Single Density (1K/block) ; We are at a more advanced density level; Multiply the number of blocks ; by the size of a block in K FREE5: ADD HL,HL ; 2,4,8,16, etc K/Blk. Block Shift Factor DEC A ; is a power-of-two multiple JR NZ,FREE5 ; ..loop til done ; At this point, HL = amount of free space on disk in K FREE6: EX DE,HL ; DE = Answer POP AF ; Restore regs POP HL POP BC RET ;..... ; This is the way do find out the space under CP/M 3.x DOCPM3: LD DE,BUFF ; Set DMA address to local buffer LD C,26 CALL BDOS ; ..don't forget to change in user pgm LD C,25 ; First find out which disk we have CALL BDOS ; Disk # now in A LD E,A ; ..move to E LD C,46 ; Use CP/M Plus Compute Free Space Call CALL BDOS ; ..ignore errors LD C,3 ; Result is this long GETFR1: LD HL,BUFF+2 ; Answer is located here LD B,3 ; Convert to 'k' length OR A GETFR2: RR (HL) ; ..divide byte by 2 DEC HL DJNZ GETFR2 ; Loop for 3 bytes DEC C JR NZ,GETFR1 ; Shift 3 times (blocks div 8 = K) LD HL,(BUFF) ; ..and get 16-bit result JR FREE6 ; Exit fixing registers up ;..... ; Work space buffer for CP/M 3.x method of getting space DSEG BUFF: DEFS 3 ; Result is 3-byte binary integer END