home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ZSYS
/
SIMTEL20
/
ZCPR3
/
PATH.MAC
< prev
next >
Wrap
Text File
|
2000-06-30
|
9KB
|
460 lines
;
; PROGRAM: PATH
; VERSION: 3.0
; AUTHOR: RICHARD CONN
; DATE: 12 Apr 84
; PREVIOUS VERSIONS: NONE
; DERIVATION: PATH, Version 1.0 (for ZCPR2) of 12 Jan 83
;
VERS EQU 30
z3env SET 0f400h
;
; PATH allows the user to do two things -- display the current path
; and set a new path. Named directories may be used in the definition of
; the new path.
;
; PATH is invoked by the following forms:
; PATH <-- Display Path
; PATH path-expression <-- Set Path
; PATH // <-- Print Help
;
;
; CP/M Constants
;
cpm equ 0 ;base
fcb equ cpm+5ch
tbuff equ cpm+80h
cr equ 0dh
lf equ 0ah
;
; SYSLIB Routines
;
ext z3init,eprint,codend,dirtdu,dutdir
ext cout,epstr,pafdc,retud
ext getpath,getmdisk,getmuser,getwhl
;
; Environment Definition
;
if z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
jmp start
db 'Z3ENV' ;This is a ZCPR3 Utility
db 1 ;External Environment Descriptor
z3eadr:
dw z3env
start:
lhld z3eadr ;pt to ZCPR3 environment
;
else
;
; Internal ZCPR3 Environment Descriptor
;
MACLIB Z3BASE.LIB
MACLIB SYSENV.LIB
z3eadr:
jmp start
SYSENV
start:
lxi h,z3eadr ;pt to ZCPR3 environment
endif
;
; Start of Program -- Initialize ZCPR3 Environment
;
call z3init ;initialize the ZCPR3 Env and the VLIB Env
lxi h,0 ;save stack ptr
dad sp
shld strtstack ; save ptr to original stack
lxi h,tbuff+1 ; pt to command line input
shld cmdline ; save ptr to command line
call retud ; get current disk and user
;
; Print Banner
;
call eprint
db 'PATH Version '
db vers/10+'0','.',(vers mod 10)+'0',0
;
; Check for Help
;
lda fcb+1 ; get first char
cpi '/' ; help?
jnz start1
call eprint
db cr,lf,'Syntax:'
db cr,lf,' PATH <-- Display Path'
db cr,lf,' PATH expr <-- Set Path'
db 0
ret
;
; Check for Error and Continue if not
;
start1:
call getpath ; external path available?
mov a,h ; HL=0 if none
ora l
jnz start2
call eprint
db ' - Abort: No Path',0
ret
start2:
call getwhl ; check for wheel
jnz start3
call eprint
db ' - Abort: No Wheel',0
ret
start3:
lhld cmdline ; check command line for text
call sblank ; skip to non-blank
shld cmdline ; set ptr to next element
ora a ; EOL=display function
jz pdisp
call codend ; set temporary path
shld pathptr ; point to it
;
; **** Set New Path ****
; CMDLINE pts to next element
;
pbuild:
lhld cmdline ; pt to next element
call sblank ; skip to non-blank
mov a,m ; get first char of next element
ora a ; EOL?
jz pbdone ; done if so, store path and display
shld token ; save ptr to first byte
mov a,m ; get first char
cpi '$' ; is it current?
jz pbdu ; DU: form
sui 'A' ; convert to number
jc pbdir ; DIR: form
mov b,a ; save number
call getmdisk ; get max disk number
mov c,a
mov a,b
cmp c ; in range?
jnc pbdir ; DIR: form if not
inx h ; pt to next char -- may be DU or DIR
mov a,m ; get next part of element
cpi '$' ; current?
jz pbdu ; is a DU: form
digtst:
cpi ':' ; colon ends it
jz pbdu ; is a DU: form
cpi ' ' ; space ends it
jz pbdu
ora a ; EOL ends it
jz pbdu
cpi '0' ; must be a digit
jc pbdir ; DIR: form if not in range
cpi '9'+1
jnc pbdir
inx h ; pt to next
mov a,m ; get it
jmp digtst
;
; It is a DU: form
;
pbdu:
lhld pathptr ; pt to path entry
xchg ; ... in DE
lhld token ; pt to token
mov a,m ; current?
cpi '$'
jz pbdu1
sui 'A'-1 ; convert to number from 1 to n
pbdu1:
stax d ; save disk element
inx h ; pt to next
inx d
mov a,m ; current user?
inx h ; pt to after user in case of match to current
cpi '$' ; current?
jz pbdu2
dcx h ; pt to first digit
push d ; save ptr to path
call eval10 ; convert to number in C
jc rangerr
call getmuser ; check for max user
inr a
mov b,a ; place max in B
mov a,c ; value in A
cmp b
jnc rangerr
pop d ; get ptr to path
pbdu2:
stax d ; store user number
inx d
mov a,m ; ending with colon?
cpi ':'
jnz pbdu3
inx h ; skip over colon
pbdu3:
shld cmdline ; save ptr to next command line entry
xchg
shld pathptr ; save ptr to next path entry
jmp pbuild ; continue processing
;
; Build DIR: form
;
pbdir:
lhld token ; pt to name
call dirtdu ; convert to DU in BC
jnz gotud ; process new DU
;
; Entry not found
;
rangerr:
call eprint
db cr,lf,'Bad Expression at ',0
lhld token ; print string starting at token
call epstr
lhld strtstack ; get original stack
sphl ; set stack ptr
ret
;
; Got User and Disk -- Store in Path
;
gotud:
lhld pathptr ; get ptr to path
inr b ; disk A = 1
mov m,b ; store disk
inx h
mov m,c ; store user
inx h ; pt to next
shld pathptr
lhld token ; skip over token
gotud1:
mov a,m ; skip to space or EOL
inx h ; pt to next
ora a ; EOL?
jz gotud2
cpi ' ' ; space?
jnz gotud1
gotud2:
dcx h ; pt to EOL or space
shld cmdline ; set ptr to next element
jmp pbuild ; continue building
;
; Path Building is Done -- CODEND contains new path
;
pbdone:
lhld pathptr ; store ending zero in path
mvi m,0
call getpath ; pt to path
xchg ; ... in DE
call codend ; copy temp path into external path
pcopy:
mov a,m ; get disk
stax d ; put disk
ora a ; end of path?
jz pdisp ; done if so and display
inx h ; pt to user
inx d
mov a,m ; get user
stax d ; put user
inx h ; pt to next disk
inx d
jmp pcopy
;
; **** Display Path Function ****
;
pdisp:
call eprint
db cr,lf,' Symbolic Form: ',0
call getpath ; pt to external path
pdisp1:
mov a,m ; get disk
ora a ; done?
jz adisp
cpi '$' ; current?
jz pdisp2
adi '@' ; convert to letter
pdisp2:
call cout ; print disk letter
inx h ; pt to user
mov a,m ; get user number
cpi '$' ; current?
jnz pdisp3
call cout ; print current indicator
jmp pdisp4
pdisp3:
call pafdc ; print user number
pdisp4:
call colon
inx h ; pt to next element
mov a,m ; done?
ora a ; 0=yes
cnz arrow
jmp pdisp1
;
; Print Absolute Path
;
adisp:
call eprint
db cr,lf,' DU Form: ',0
call retud ; get current user/disk
call getpath ; pt to path
adisp1:
mov a,m ; get disk
ora a ; done?
jz ndisp
cpi '$' ; current?
jnz adisp2
mov a,b ; get current disk
inr a ; adjust to 1 to n
adisp2:
adi '@' ; convert to letter
call cout ; print disk letter
inx h ; pt to user
mov a,m ; get user
cpi '$' ; current?
jnz adisp3
mov a,c ; get current user
adisp3:
call pafdc ; print user
call colon
inx h ; pt to next
mov a,m ; done?
ora a
cnz arrow
jmp adisp1
;
; Print Named Path
;
ndisp:
call eprint
db cr,lf,' DIR Form: ',0
call getpath ; pt to external path
ndisp1:
call retud ; get current user and disk in C and B
mov a,m ; get disk
ora a ; done?
rz
cpi '$' ; current?
jz ndisp2
mov b,a ; disk in B
dcr b ; adjust to 0 to n-1
ndisp2:
inx h ; pt to user
mov a,m ; get it
cpi '$' ; current?
jz ndisp3
mov c,a ; user in C
ndisp3:
inx h ; pt to next
push h ; save ptr
call udscan ; scan dirs for user/disk and print its name
pop h ; get ptr
call colon
mov a,m ; done?
ora a
cnz arrow
jmp ndisp1
;
; **** Utilities ****
;
;
; Convert Chars pted to by HL to Number in C
; Return with Carry Set if Overflow
; If OK, Value in C and HL pts to character after last digit
;
eval10:
mvi c,0 ; set value
eval1:
mov a,m ; get first digit
sui '0' ; convert to binary
jc evalx ; done with value in C
cpi 10 ; range?
jnc evalx ; done with value in C
mov b,a ; digit in B
mov a,c ; multiply by 10
add a ; *2
rc ; error abort
add a ; *4
rc
add c ; *5
rc
add a ; *10
rc
add b ; add value
rc
mov c,a ; value in C
inx h ; pt to next
jmp eval1
evalx:
ora a ; clear carry flag
ret
;
; Print Colon
;
colon:
mvi a,':' ; print colon
jmp cout
;
; Print Arrow
;
arrow:
call eprint
db ' --> ',0
ret
;
; Skip to non-blank
;
sblank:
mov a,m ; get char
inx h ; pt to next
cpi ' ' ; space?
jz sblank
dcx h ; pt to non-blank
ret
;
; Scan directories for user and disk in C and B
; Print name if found or "Noname" if not
;
udscan:
call dutdir ; convert to name
jz udscan1 ; error return if no name
mvi b,8 ; 8 chars max
udsprn:
mov a,m ; get name char
cpi ' ' ; done?
rz
call cout ; print char
inx h ; pt to next
dcr b ; count down
jnz udsprn
ret
udscan1:
call eprint
db 'Noname',0
ret
;
; Buffers
;
cmdline:
ds 2 ; ptr to next char in command line
token:
ds 2 ; ptr to current token
pathptr:
ds 2 ; ptr to next path entry
strtstack:
ds 2 ; ptr to original stack
end