mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.5 KiB
163 lines
4.5 KiB
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
|
|
|
|
|