title Calculate Free Space On A Drive name ('GETFREE') ; Return the number of unallocated kilobytes ; of space on the currently logged drive bdos equ 5 tbuff equ 0080h entry get_freek entry extmsk ; Enter: a = drive (0=A:, ..., 15=P:) ; Exit: hl = free space on drive, in Kilobytes ; get_freek: ld (spacedrv),a ; save drive ld e,a ld c,14 ; BDOS select disk function call bdos ; ; check for CP/M Plus ; ld c,12 ; get bdos Version call bdos ; if not cp/m 3 System cp 30h jr c,dparams ; ..jump to calculate from alv ; ; calculate free space for CP/M Plus ; ld de,tbuff ; set default dma ld c,26 call bdos ld c,46 ; get disk freespace ld a,(spacedrv) ld e,a ; ..on this drive call bdos ; ; Disk space is returned by CPM+ at dma for 3 bytes. ; ld hl,(tbuff) ; Low to L, Mid to H ld a,(tbuff+2) ; High to A ld b,3 ; Divide by 8 (SHR 3) ; ; Shift everything right into HL (64 MB max reportable) ; div: or a ; Clear carry rra ; High rr h ; Mid rr l ; Low djnz div ret ; hl = space free in Kbytes ; ; For CP/M 2 use this method: ; dparams: ld c,31 ; BDOS get disk parameters function call bdos inc hl ; point to block shift-factor byte inc hl ld a,(hl) ; Get value and ld (blkshf),a ; ..save it inc hl ; point to max data block number inc hl ld a,(hl) ld (extmsk),a ; save it inc hl ld e,(hl) ; Get (word) value into DE inc hl ld d,(hl) inc de ; Add 1 for max number of blocks ; Compute amount of free space left on disk dfree: ld c,27 ; BDOS get allocation vector function push de ; Save BLKMAX value call bdos ; Get allocation vector into ld b,h ; ..BC ld c,l pop hl ; Restore BLKMAX value to HL ld de,0 ; Inititialize count of free blocks ; At this point we have ; BC = allocation vector address ; DE = free block count ; HL = number of data blocks on disk cntfree: push bc ; Save allocation map ptr ld a,(bc) ; Get bit pattern of allocation byte ld b,8 ; Set to process 8 blocks ; cnt2: rla ; Rotate allocated block bit into carry flag jr c,cnt3 ; If set (bit=1), block is allocated inc de ; If not set, block is not allocated, so ; ..increment free block count ; cnt3: ld c,a ; Save remaining allocation bits in C dec hl ; Count down number of blocks on disk ld a,l ; if down to zero or h jr z,cnt4 ; ..branch ld a,c ; Get back current allocation bit pattern djnz cnt2 ; Loop through 8 bits pop bc ; Get ptr to allocation vector inc bc ; Point to next allocation byte jr cntfree ; Process next allocation byte cnt4: pop bc ; clear stack ex de,hl ; Free block count to HL ; ld a,(blkshf) ; Get block shift factor sub 3 ; Convert to log2 of K per block ret z ; Done if 1K per block ; Convert for data blocks of more than 1K each free2k: add hl,hl dec a jr nz,free2k ret ; HL * amount of free space on disk in K ; spacedrv:ds 1 blkshf: ds 1 extmsk: ds 1 end