mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 14:11:48 -06:00
163 lines
4.5 KiB
Plaintext
163 lines
4.5 KiB
Plaintext
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
|
||
|
||
|