home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
zcpr2
/
ldirz.mac
< prev
next >
Wrap
Text File
|
1994-07-13
|
12KB
|
629 lines
;
; PROGRAM: LDIRZ
; VERSION: 2.0
; AUTHOR: RICHARD CONN
; DATE: 16 JAN 83
; PREVIOUS VERSIONS: 1.0 (12 JAN 83)
;
vers equ 20
;
; LDIRZ prints a sorted directory of the default library file
; (installable via GENINS). The printout gives file name and size.
; It is sorted alphabetically by file name and type. Only one option
; is permitted, and that is a file spec (wild cards are OK). Forms
; of the LDIRZ command are:
;
; LDIRZ <-- All Files
; LDIRZ file.typ <-- Selected Files
; LDIRZ -library file.typ <-- Selected Files in Library
; LDIRZ // <-- Help Message
;
;
; CP/M Constants
;
cpm equ 0 ;base
bdose equ cpm+5
fcb equ cpm+5ch
tbuff equ cpm+80h
cr equ 0dh
lf equ 0ah
;
; SYSLIB Routines
;
ext zgpins,print,zpfind,initfcb,f$open,f$read
ext sort,moveb,putud,logud,shftrh,phldc,codend
ext hmovb,crlf,cout,fname,cline
;
; Branch to Start of Program
;
jmp start
;
;******************************************************************
;
; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
;
; This data block precisely defines the data format for
; initial features of a ZCPR2 system which are required for proper
; initialization of the ZCPR2-Specific Routines in SYSLIB.
;
;
; EXTERNAL PATH DATA
;
EPAVAIL:
DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
EPADR:
DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
;
; INTERNAL PATH DATA
;
INTPATH:
DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT
; DISK = 1 FOR A, '$' FOR CURRENT
; USER = NUMBER, '$' FOR CURRENT
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT
DB 0 ; END OF PATH
;
; MULTIPLE COMMAND LINE BUFFER DATA
;
MCAVAIL:
DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
MCADR:
DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
;
; DISK/USER LIMITS
;
MDISK:
DB 4 ; MAXIMUM NUMBER OF DISKS
MUSER:
DB 31 ; MAXIMUM USER NUMBER
;
; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
;
DOK:
DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
UOK:
DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
;
; PRIVILEGED USER DATA
;
PUSER:
DB 10 ; BEGINNING OF PRIVILEGED USER AREAS
PPASS:
DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS
DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
;
; CURRENT USER/DISK INDICATOR
;
CINDIC:
DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS)
;
; DMA ADDRESS FOR DISK TRANSFERS
;
DMADR:
DW 80H ; TBUFF AREA
;
; NAMED DIRECTORY INFORMATION
;
NDRADR:
DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
NDNAMES:
DB 64 ; MAX NUMBER OF DIRECTORY NAMES
DNFILE:
DB 'NAMES ' ; NAME OF DISK NAME FILE
DB 'DIR' ; TYPE OF DISK NAME FILE
;
; REQUIREMENTS FLAGS
;
EPREQD:
DB 0FFH ; EXTERNAL PATH?
MCREQD:
DB 000H ; MULTIPLE COMMAND LINE?
MXREQD:
DB 000H ; MAX USER/DISK?
UDREQD:
DB 000H ; ALLOW USER/DISK CHANGE?
PUREQD:
DB 000H ; PRIVILEGED USER?
CDREQD:
DB 0FFH ; CURRENT INDIC AND DMA?
NDREQD:
DB 000H ; NAMED DIRECTORIES?
Z2CLASS:
DB 5 ; CLASS 5
DB 'ZCPR2'
DS 10 ; RESERVED
;
; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
;
;******************************************************************
;
library:
DB 'COMMAND ' ; <---change this if you like---
libtyp:
DB 'LBR'
;
; START OF PROGRAM
;
start:
call zgpins ; init ZCPR2 buffers
call putud ; save current user/disk
;
; Print Banner
;
call print
db 'LDIRZ Version '
db vers/10+'0','.',(vers mod 10)+'0',0
;
; Set Default Library Name
;
lxi h,library
lxi d,fcb+1 ; copy into FCB
mvi b,11 ; 11 chars
call moveb
;
; Extract Information
;
lxi h,tbuff ; get command line from buffer
call cline
call sblank ; skip to non-blank
ora a ; EOL?
jz help
cpi '/' ; Help?
jnz start0
;
; Print Help Message
;
help:
call print
db cr,lf,' LDIRZ prints a sorted directory of the current'
db cr,lf,'Library File. It is invoked by one of the forms:'
db cr,lf,' LDIRZ <-- All Files'
db cr,lf,' LDIRZ filename.typ <-- Selected Files'
db cr,lf,' LDIRZ -lib filename.typ <-- Files from LIB'
db cr,lf,' LDIRZ // <-- Print Help'
db cr,lf,' Wild Cards (*,?) are permitted.'
db cr,lf,0
ret
;
; Check for Library Name and Set it if so
;
start0:
cpi '-' ; library follows?
jnz start1
inx h ; pt to library name
lxi d,fcb ; pt to FCB
call fname ; extract library name
call sblank ; skip to non-blank
lxi d,fcb+9 ; check file type
ldax d
cpi ' ' ; none?
jnz start1
push h ; save ptr
lxi h,libtyp ; default type
mvi b,3 ; 3 chars
call moveb ; copy it
pop h ; get ptr
;
; Check for File Spec and Set if so
;
start1:
ora a ; any chars?
jz start2 ; fspec is already wild
lxi d,filesp ; copy into file spec
call fname ; extract file name
;
; Find Library
;
start2:
lxi d,fcb ; pt to FCB
call initfcb
mvi b,0ffh ; search current
call zpfind ; look for library file
jnz start3
call print
db cr,lf,'Library File ',0
lxi h,fcb+1 ; pt to name
call prfn ; print file name
call print
db ' Not Found',0
ret
;
; Read in First Block of Library
;
start3:
call logud ; log into directory
call f$open ; open file
call f$read ; read first block
ora a ; ok?
jz readdir ; extract directory info
call print
db cr,lf,'Library File ',0
lxi h,fcb+1
call prfn
call print
db ' is Empty',0
ret
readdir:
lxi h,tbuff+14 ; pt to dir size
mov a,m
inx h
mov h,m ; HL=size of directory
mov l,a
mov b,h ; BC=number of blocks in dir
mov c,l
lxi h,0 ; set file count
shld filecnt
call codend ; pt to spare buffer
shld bufptr ; set buffer ptr
shld ssbstart ; set starting address of first record
lxi h,tbuff+32 ; pt to first entry
jmp getentry ; get next entry
;
; Read Next Block
;
readblock:
push b ; save count
lxi d,fcb ; pt to FCB
call f$read ; read block
pop b ; restore regs
lxi h,tbuff ; pt to next entry
ora a ; error?
jz getentry ; get next entry
call print
db cr,lf,'Premature End of Library File ',0
lxi h,fcb+1
call prfn
call print
db ' -- Aborting',0
ret
;
; Get next entry from library directory
; On entry, HL pts to entry, BC=count
;
getentry:
push h ; save ptr
push b ; save count
mov a,m ; entry present?
cpi 0ffh ; none?
jz gete1
cpi 0 ; deleted?
jnz gete1
inx h ; pt to file name
push h ; save ptr to entry
lxi d,fspec ; pt to file spec
mvi b,11 ; check 11 bytes
getent1:
ldax d ; check for match with wild cards
mov c,m ; get target char
inx h ; pt to next
inx d
cpi '?' ; wild match?
jz getent2
cmp c ; match?
jnz gete0 ; skip if not
getent2:
dcr b ; count down
jnz getent1
pop h ; file matches -- continue
push h ; save ptr
lhld filecnt ; increment file count
inx h
shld filecnt
pop h
xchg ; ptr to file name in DE
lhld bufptr ; get buffer ptr
mvi b,11 ; 11 bytes
xchg ; HL pts to entry
call hmovb ; copy and affect HL and DE
inx h ; skip index
inx h
mvi b,2 ; copy size
call hmovb
xchg ; get buffer ptr in HL
shld bufptr ; save buffer ptr
xchg ; put back in DE
lhld bdose+1 ; memory full?
mov a,h ; check pages
sui 10 ; below CCP
cmp d ; in range?
jnz gete1
pop b
pop h ; clear stack
call print
db cr,lf,'Memory Overflow',0
ret
gete0:
pop h ; clear stack
gete1:
pop b ; get count
pop h ; get ptr to block
lxi d,32 ; pt to next
dad d
lxi d,tbuff+80h ; pt to end of buffer
mov a,e ; new block if low-order is the same
cmp l
jnz getentry
dcx b ; count down
mov a,b ; done?
ora c
jnz readblock ; continue with next block
;
; Done with Buffer Load
;
lhld filecnt ; set record count
shld ssbcnt
lxi d,ssb ; pt to ssb
call sort ; perform sort
mov a,l ; get low (remainder)
ani 3 ; select remainder
sta remain
call shftrh ; shift right 2 bits
call shftrh
shld loopcnt ; number of loops
xchg ; count in DE
lxi h,0 ; compute sum
lxi b,13 ; bytes/entry
col0:
mov a,d ; done?
ora e
jz col1
dcx d ; count down
dad b ; add in size
jmp col0
col1:
xchg ; DE is size of list
lhld ssbstart ; pt to first entry
shld entry1
dad d ; pt to next entry
lda remain ; add 1?
ora a ; no if zero
jz col2
dad b ; add in another entry
col2:
shld entry2 ; set ptr to 2nd entry
dad d ; pt to next entry
cpi 2 ; remainder >=2?
jc col3
dad b ; add in another entry
col3:
shld entry3 ; set ptr to 3rd entry
dad d ; pt to last entry
cpi 3 ; add 1?
jnz col4
dad b ; add in another entry
col4:
shld entry4
;
; Directory Print -- ENTRYn pts to first element in each col, DE is
; number of loops, and REMAIN is number of extra entries
;
lxi h,0 ; clear sum
shld sum
call print
db cr,lf
db 'Filename.Typ Size '
db 'Filename.Typ Size '
db 'Filename.Typ Size '
db 'Filename.Typ Size'
db cr,lf
db '-------- --- ----- '
db '-------- --- ----- '
db '-------- --- ----- '
db '-------- --- -----',0
lhld loopcnt ; get loop count
xchg ; ... in DE
dirloop:
mov a,d ; Done?
ora e
jz dirdone
dcx d ; count down
call crlf ; new line
lhld entry1 ; print entry
call prentry
shld entry1
lhld entry2
call prentry
shld entry2
lhld entry3
call prentry
shld entry3
lhld entry4
call prentry
shld entry4
jmp dirloop
dirdone:
lda remain ; print last line
ora a ; none?
jz done
mov d,a ; count in D
call crlf ; new line
lhld entry1 ; print first col
call prentry
dcr d ; count down
jz done
lhld entry2 ; print 2nd col
call prentry
dcr d ; count down
jz done
lhld entry3 ; print 3rd col
call prentry
done:
call crlf ; new line
lhld filecnt ; print number of entries
call phldc
call print
db ' Files Selected occupying a Total of ',0
lhld sum ; print sum of sizes
call phldc
call print
db 'K Bytes',0
ret
;
; Print File Name Entry
;
prentry:
push d
push h
push b
call prfn ; print file name
lxi d,11 ; pt to size
dad d
mov c,m ; get size in BC
inx h
mov b,m
mov a,c ; part of a K?
ani 7
sta kpart
mov h,b ; file size in HL
mov l,c
call shftrh ; move right 3 bits for size in K
call shftrh
call shftrh
lda kpart ; add 1 for overflow?
ora a ; 0=no
jz prent1
inx h ; add 1 K
prent1:
call phldc ; print as decimal
mvi a,'K' ; print K
call cout
mvi a,' ' ; print 2 spaces
call cout
call cout
xchg ; size in DE
lhld sum ; add to sum
dad d
shld sum
pop b ; get regs
pop h
lxi d,13 ; pt to next entry
dad d
pop d
ret
;
; Print file name pted to by HL
;
prfn:
push h ; save regs
push b
mvi b,8 ; 8 chars
call prfn1
mvi a,'.'
call cout
mvi b,3 ; 3 chars
call prfn1
pop b ; get regs
pop h
ret
prfn1:
mov a,m ; print chars
inx h ; pt to next
call cout
dcr b ; count down
jnz prfn1
ret
;
; Compare Routine
; Compare (DE) to (HL) and Return with Carry if (DE) < (HL)
;
compare:
push h ; save regs
push d
push b
mvi b,11 ; 11 bytes to compare
comp:
ldax d ; get byte
cmp m ; compare
jnz compd ; done if not same
inx h ; pt to next
inx d
dcr b ; count down
jnz comp
compd:
pop b ; restore regs
pop d
pop h
ret
;
; Skip to Non-Blank
;
sblank:
mov a,m ; skip to non-blank
inx h
cpi ' '
jz sblank
dcx h
ret
;
; Buffers
;
ssb: ; sort specification block
ssbstart:
ds 2 ; ptr to first byte of first record
ssbcnt:
ds 2 ; number of records
dw 13 ; 13 bytes/record
dw compare ; address of compare routine
dw 0 ; no ptr table
db 0,0 ; don't use ptrs
filesp:
db 0
fspec:
db '????????' ; file spec
db '???'
ds 24
remain:
ds 1 ; column remainder
kpart:
ds 1 ; K remainder
filecnt:
ds 2 ; number of files
bufptr:
ds 2 ; scratch buffer ptr
sum:
ds 2 ; sum of file sizes
loopcnt:
ds 2 ; number of lines to print
entry1:
ds 2
entry2:
ds 2
entry3:
ds 2
entry4:
ds 2
end