Files
RomWBW/Source/BPBIOS/Z34RCP11/rcpsp.lib
2020-02-14 17:22:56 -08:00

163 lines
4.5 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
page
; Library: RCPSP for Z34RCP
; Author: Carson Wilson
; Version: 1.2
; Date: August 11, 1989
; Changes: CRSPACE does nothing if QUIET is true.
;
; Author: Carson Wilson
; Version: 1.1
; Date: December 30, 1988
; Changes: Calls CPMVER common routine.
; Sets DMA to TBUFF for CP/M Plus in case we chained to SP.
; Author: Carson Wilson
; Version: 1.0
; Date: June 15, 1988
;
; Command: SP
; Function: Shows space remaining on designated drive
; Syntax: SP [DIR:|DU:]
; Comments: This code can be called by several other RCP commands so that
; they can show the space remaining on the disk after their
; operation.
; Now works with CP/M Plus.
if [erasp or cpsp or dirsp]
crspace: ; Used to call space after other subroutines
ld a,(quiet)
or a ; Skip if we're being quiet
ret nz
call crlf ; Start new line
jr space0 ; Skip directory check
endif ;[erasp or cpsp or dirsp]
space:
call dirchek ; Abort to EH on bad dirspec
space0: ld a,(fcb1) ; Determine requested drive
or a ; If drive explicitly selected
jr nz,space1 ; ..then skip
ld a,(cdrv) ; Get current drive from ZCPR 3.4
inc a ; Shift to range 1..16
space1:
dec a ; Shift to range 0..15
ld e,a ; Save in E for selecting disk below
add a,'A' ; Convert to letter and
ld (seldrv),a ; save in message string below
ld c,14 ; BDOS select disk function
call bdos ; Not needed if no drive selected, but smallest
; ..possible code size this way.
; Here we extract the following disk parameter information from the disk
; parameter block (DPB):
; BLKSHF: block shift factor (1 byte)
; BLKMAX: max number of blocks on disk (2 bytes)
call cpmver ; What BDOS is running?
jr nc,isplus
ld c,31 ; BDOS get disk parameters function
call bdos
inc hl ; Advance to block shift factor byte
inc hl
ld a,(hl) ; Get value and
ld (blkshf),a ; ..save it in code below
inc hl ; Advance to max block number word
inc hl
inc hl
ld e,(hl) ; Get value into HL
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 HL
ld b,h ; Copy allocation vector to 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 blocks on disk
free1: push bc ; Save allocation address
ld a,(bc) ; Get bit pattern of allocation byte
ld b,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 de ; If not set, block is not allocated, so
; ..increment free block count
free3: ld c,a ; Save remaining allocation bits in C
dec hl ; Count down number of blocks on disk
ld a,l ; See if we are down to zero
or h
jr z,free4 ; Branch if no more blocks to check
ld a,c ; Get back current allocation bit pattern
djnz free2 ; Loop through 8 bits
pop bc ; Get pointer to allocation vector
inc bc ; Point to next allocation byte
jr free1 ; Continue by processing next allocation byte
free4: pop bc ; Clean up stack
ex de,hl ; Free block count to HL
blkshf equ $+1 ; Pointer for in-the-code modification
ld a,0 ; Get block shift factor
sub 3 ; Convert to log base 2 of K per block
jr z,free6 ; Done if single density (1k per block)
; Convert for blocks of more than 1K each
free5: add hl,hl
dec a
jr nz,free5
; At this point HL = amount of free space on disk in K
; Display decimal value of HL
free6: ld b,0 ; Initialize count of digits already printed
ld de,10000 ; Divisor in DE
call decdsp ; Print digit (or space if leading '0')
ld de,1000
call decdsp
call decdsp3 ; Display hundreds, tens, and units
call print
db 'k free on '
seldrv: db 0 ; Modified above to contain drive letter
db ':'+80h
ret
; CP/M Plus free space calculation
isplus: ld de,tbuff ; We may have chained to SP
call setdma
ld a,(seldrv) ; Get drive letter
sub 'A' ; Convert to BDOS call value
ld e,a
ld c,2eh ; Get free space call
call bdos
; Convert 3 byte count of records to K
ld b,3 ; Total amount to shift
c3fre1: ld hl,tbuff+2 ; Point to buffer start
rr (hl)
dec hl
rr (hl)
dec hl
rr (hl)
djnz c3fre1
ld hl,(tbuff) ; Get free mod 65536k
jr free6
; End RCPSP.LIB