Files
RomWBW/Source/Images/d_bp/u15/PATH.MAC
2020-01-03 20:42:06 -08:00

460 lines
8.6 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.
;
; 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