home *** CD-ROM | disk | FTP | other *** search
- ; RESOLVE.MAC RESOLVE ZCPR3 COMMAND LINE
- ;
- ;
- ; This utility will resolve a multiple-command line passed to it and place
- ; that command line in the Multiple-Command Line Buffer in memory.
- ; It will resolve references to shell variables, registers, and System
- ; File names. Each of these is signalled by a flag as follows.
- ;
- ; Flag Meaning
- ; ---- -------
- ; %<text> Shell variable name.
- ; $R<n> Register number. (n = 1-9)
- ; $D Current disk letter.
- ; $U Current user number.
- ; $F<n> System File name. (n = 1-4)
- ; $N<n> System File name, chars 1-8 only. (n = 1-4)
- ; $T<n> System File name, extension only. (n = 1-4)
- ; $| Substitute multiple-command separator.
- ;
- ; The QUIET flag is adhered to; the program will not print its sign-on
- ; message or error messages if the QUIET flag is set.
- ;
- ; If there is no room for the command-line generated, the ERROR flag will
- ; be set, and an error message may be printed, depending upon the state
- ; of the QUIET flag. Uninterpretable '$' parameters will also cause the
- ; error flag to be set.
- ;
- ; Author: Dreas Nielsen
- ;
- ; Shell variable file manipulation routines are adapted from Richard Conn's
- ; 'SH.MAC'
- ;
- ; History --
- ; Version Date Comment
- ; ------- ---- -------
- ; 1.0 3/2/86 Up and running -- RDN
- ; 1.1 1/13/87 Fixed error in which a shell variable reference
- ; in the first character of another shell
- ; variable wasn't being expanded. Also changed
- ; so that a single '$', when followed by an
- ; unrecognized flag, is not dropped.
- ;
- ;
- VERS EQU 11
- ;
- ;
- PARMFL EQU '/' ; flag indicating parameter follows
- SUBCH EQU '%' ; shell-variable reference flag
- SYSFLG EQU '$' ; System File reference flag
- SUBSEP EQU '|'
- CMDSEP EQU ';'
- LECNT EQU 20 ;number of pointers on String Ptr Stack
- SYSNAM EQU 0052H ;offset of system file names from Z3ENV
- CTRLZ EQU 1AH ;^Z for EOF
- FCB EQU 5CH
- TBUFF EQU 80H
- BDOS EQU 5
- CR EQU 0DH
- LF EQU 0AH
- ;
- CMDLIN EQU 80H ; CP/M's command line buffer
- ;
- ;
- ; SYSLIB and Z3LIB routines
- ;
- EXT Z3INIT,PUTER2,GETREG,PUTCL,QPRINT,ROOT
- EXT SKSP,PUTUD,LOGUD,INITFCB,MAFDC,FILLB,GETFN1
- EXT PRINT,F$OPEN,GETUD,F$CLOSE,CAPS,PRINT,CODEND
- ;
- ; Z3VARS routines
- ;
- EXT VARLOAD, VARDEF
- ;
- ;
- ; Program beginning
- ;
- DB 'Z3ENV'
- DB 1
- Z3ENV: DW 00
- DB VERS ;embed version number
- ;
- ; Initialize environment for Z3 routines
- START: LD HL,(Z3ENV)
- CALL Z3INIT
- ;
- ; Print signon message
- CALL QPRINT
- ; DB 'RESOLVE v. ',(VERS/10)+'0','.',(VERS MOD 10)+'0',CR,LF,0
- DB 'RESOLVE v. ',[VERS/10]+'0','.',[VERS MOD 10]+'0',CR,LF,0
- ;
- ; Reset error flag
- XOR A
- CALL PUTER2
- ;
- ; Save stack and set new one
- LD H,A
- LD L,A
- ADD HL,SP
- LD (SAVESP),HL
- LD HL,STACK
- LD SP,HL
- ;
- ; Set Pointers
- CALL CODEND ;find scratch area
- LD (INTLINE),HL ;set ptr to internal line buffer
- LD DE,200H ;reserve 200H bytes
- ADD HL,DE
- LD (VARLIST),HL ;set ptr to variable list
- ;
- ; Point to CP/M's command line
- LD HL,CMDLIN
- ;
- ; Quit if no command line passed
- LD A,(HL)
- OR A
- JP Z,HELP
- ;
- ; Otherwise, store a null at end of command line
- INC HL
- LD E,A
- XOR A
- LD D,A
- ADD HL,DE
- LD (HL),A
- ;
- ; Now parse command line.
- ; First look for option character. Only option is help, which is exclusive.
- LD HL,CMDLIN+1
- CALL SKSP
- LD A,(HL)
- CP PARMFL
- JP Z,HELP
- CP '?'
- JP Z,HELP
- ;
- ; Expand Command Line pointed to by HL, performing variable
- ; substitutions
- ;
- ; On exit, Z=command line overflow and Line Pted to by HL
- ;
- EXPAND:
- EX DE,HL ;DE pts to line
- ;
- ; Init String Pointer Stack
- ;
- LD A,LECNT ;set local element count
- LD (LOCELT),A
- LD HL,LOCSTK ;set local stack
- LD (LOCADR),HL
- LD HL,0 ;set done code on stack
- CALL LOCPUSH ;push HL
- ;
- ; Set Ptrs
- ;
- LD HL,(INTLINE) ;pt to internal line
- EX DE,HL ;DE pts to internal line, HL pt next char
- LD B,0 ;256 chars max
- ;
- ; Analyze Next Char
- ;
- EXP1:
- LD A,(HL) ;get next char
- CP SYSFLG ;system file or directory substitution?
- JR NZ,TEST2
- CALL SYSFIL
- DEC C
- JR Z,EXP1 ;no error on return
- JR EXP2 ;error on return - store offending char in CL
- ;
- TEST2:
- CP SUBCH ;substitution char?
- JR NZ,EXP2
- ;
- ; Process Shell Variable
- ;
- CALL EXPVAR ;resolve variable
- DEC C ;error?
- JR Z,EXP1 ;resume if none
- ;
- ;
- ; Store Next Char
- ;
- EXP2:
- LD (DE),A ;store char
- INC HL ;point to next
- INC DE
- DEC B ;count down
- JR Z,EXPERR ;error if at 0
- ;
- OR A ;done? (was last char stored a null?)
- JR NZ,EXP1
- INC B ;increment count (not counting last 0)
- DEC DE ;pt to null in case another string to analyze
- ;
- ; Pop String Ptr Stack and Check for Analysis Complete
- ;
- CALL LOCPOP ;get ptr to previous string
- LD A,H ;done?
- OR L
- JR NZ,EXP1 ;resume
- DEC A ;set NZ
- ;
- ; Expansion Complete
- ; On entry, Z Flag is Set Accordingly (Z=Error)
- ;
- EXPERR: CALL Z,SETERR
- LD HL,(INTLINE) ;pt to internal line
- CALL PUTCL
- JR NZ,EXIT
- ;
- ; Print overflow message and set error flag
- CALL QPRINT
- DB CR,LF,'Command Line Overflow',CR,LF,0
- CALL SETERR
- ;
- ; Return to ZCPR3
- ;
- EXIT:
- LD HL,(SAVESP)
- LD SP,HL
- RET
- ;
- ; Expand Variable
- ; Return with HL pting to next char, A=char, C=1 if OK, C=2 if error
- ;
- EXPVAR:
- LD (VARPTR),HL ;save ptr to variable
- INC HL ;get next char
- LD C,2 ;prep for error return
- LD A,(HL) ;get it
- OR A ;EOL?
- RET Z
- CP SUBCH ;double sub char?
- RET Z ;place one sub char in line if so
- ;
- ; Place Variable Into SHVAR
- ;
- PUSH BC ;save counter
- PUSH DE ;save ptr to next char
- PUSH HL ;save ptr to shell variable
- LD HL,SHVAR ;pt to shell variable buffer
- LD B,8 ;8 chars max
- LD A,' ' ;space fill
- CALL FILLB
- EX DE,HL ;DE pts to shell variable buffer
- POP HL ;pt to shell variable
- LD B,8 ;8 chars max
- ;
- ; Place Shell Variable into Buffer
- ;
- EXPV1:
- LD A,(HL) ;get char
- CALL DELCK ;check for delimiter
- JR Z,EXPV3 ;done if delimiter
- LD (DE),A ;save char
- INC HL ;pt to next
- INC DE
- DJNZ EXPV1
- ;
- ; Flush Overflow of Shell Variable
- ;
- EXPV2:
- LD A,(HL) ;get char
- INC HL ;pt to next
- CALL DELCK ;check for delimiter
- JR NZ,EXPV2
- DEC HL ;pt to delimiter
- ;
- ; Shell Variable in buffer SHVAR
- ; HL pts to delimiter after variable in user line
- ;
- EXPV3:
- CALL LOCPUSH ;stack ptr to next char in current string
- JR Z,EXPV4 ;error in stack
- LD HL,(VARLIST)
- CALL VARLOAD ;load shell variable list
- JR NZ,EXPV4 ;failure
- LD HL,SHVAR
- CALL VARDEF ;resolve named variable reference
- JR Z,EXPV5 ;name found - resolve
- ;
- ; Shell Variable Not Resolved - Restore Ptr to It
- ;
- EXPV4:
- CALL LOCPOP ;restore ptr
- POP DE
- POP BC
- LD C,2 ;error
- LD HL,(VARPTR) ;pt to variable
- LD A,(HL)
- RET
- ;
- ; Entry Point for OK Return
- ;
- EXPV5:
- LD A,(HL) ;get char
- POP DE ;pt to target
- POP BC ;get counter
- LD C,1
- RET
-
- ;
- ; Push HL onto String Ptr Stack
- ; Return with Z if Stack Overflow
- ;
- LOCPUSH:
- LD A,(LOCELT) ;get count
- DEC A ;full?
- RET Z
- LD (LOCELT),A ;set count
- PUSH DE ;save DE
- EX DE,HL ;DE pts to old string
- LD HL,(LOCADR) ;get ptr to top of stack
- LD (HL),E ;store low
- INC HL
- LD (HL),D ;store high
- INC HL ;pt to next
- LD (LOCADR),HL
- EX DE,HL ;restore HL
- POP DE ;restore DE
- XOR A ;return NZ
- DEC A
- RET
- ;
- ; Pop HL from String Ptr Stack
- ;
- LOCPOP:
- PUSH DE
- LD A,(LOCELT) ;increment element count
- INC A
- LD (LOCELT),A
- LD HL,(LOCADR) ;get address
- DEC HL ;pt to high
- LD D,(HL) ;get high
- DEC HL ;pt to low
- LD E,(HL) ;get low
- LD (LOCADR),HL ;set address
- EX DE,HL ;restore ptr
- POP DE
- RET
- ;
- ; Check to see if char in A is a delimiter
- ; Return with Z if so
- ;
- DELCK:
- PUSH HL ;pt to table
- PUSH BC ;save BC
- CALL CAPS ;capitalize char
- LD B,A ;char in B
- LD HL,DTABLE ;pt to delimiter table
- DELCK1:
- LD A,(HL) ;get delimiter
- OR A ;done?
- JR Z,NOTDEL
- CP B ;compare
- JR Z,YESDEL
- INC HL ;pt to next
- JR DELCK1
- NOTDEL:
- LD A,B ;get char
- OR A ;set Z if null, else NZ
- YESDEL:
- LD A,B ;restore char
- POP BC ;restore regs
- POP HL
- RET
- ;
- ; Delimiter Table
- ;
- DTABLE:
- DB '<>;:,.=-_ ',0
- ;
- ;
- ;
- ; Print help message and exit.
- HELP: CALL PRINT
- DB 'Resolve command line -- the following flags are '
- DB 'interpreted:',CR,LF
- DB ' Flag Meaning',CR,LF
- DB ' ---- -------',CR,LF
- DB ' %<text> Shell variable name.',CR,LF
- DB ' $R<n> Register number. (n = 1-9)',CR,LF
- DB ' $D Current drive letter.',CR,LF
- DB ' $U Current user number.',CR,LF
- DB ' $F<n> System File name. (n = 1-4)',CR,LF
- DB ' $N<n> System File, name only.',CR,LF
- DB ' $T<n> System File, extension only.',CR,LF
- DB ' $| Substitute command separator (;)',CR,LF
- DB 0
- JP EXIT
- ;
- ;
- ; EXPANSION ROUTINES
- ; The following routines each expand a particular kind of reference.
- ; Inputs : HL contains a pointer to the command line being interpreted;
- ; DE points to the string being built.
- ; Outputs: C contains an error flag: 2=error, 1=OK
- ; HL points to the next char in the CL to interpret if no error (C=1)
- ; points to last char interpreted if error (C=2)
- ; DE points to the next location to fill in the CL being built
- ; If any of the flags are followed by incorrect parameters, the entire
- ; token, INCLUDING the leading dollar sign, is copied to the command line
- ; being built.
- ;
- SYSFIL:
- INC HL ;point to next character
- LD C,1 ;prepare for no-error return
- LD A,(HL) ;get character
- OR A ;end of line?
- JR NZ,SYSF2
- INC C ;indicate error
- LD A,SYSFLG
- LD (DE),A
- INC DE
- XOR A
- RET
- ;
- SYSF2: CP 'F' ;full filename?
- JR Z,FFNAME
- CP 'N' ;just the name?
- JR Z,FNAME
- CP 'T' ;just the type?
- JR Z,FTYPE
- CP 'D' ;current drive?
- JP Z,CDRIV
- CP 'U' ;current useer?
- JP Z,CUSR
- CP 'R' ;register number?
- JP Z,REGR
- CP SUBSEP
- JP Z,SUBCHR
- CALL SETERR ;otherwise, set Z3 error byte
- PUSH AF
- LD A,SYSFLG ;transfer '$' to output
- LD (DE),A
- INC DE
- POP AF
- INC C ;and return with error indicator
- RET
- ;
- ; Character is flag for full filename. Get number of filename, get filename,
- ; and insert in command line being built.
- ;
- FFNAME:
- INC HL ;get number
- LD A,(HL)
- OR A
- JR Z,FFERR
- ;
- FFNAM2: CALL FNCHEK ;check that number is in range 1-4
- JR Z,FFERR ;quit if not
- ;
- SUB 31H ;convert to binary 0-3
- PUSH HL
- CALL FNADDR ;get address of filename in HL
- LD A,(HL) ;check for defined name
- CP ' '
- JR NZ,FFNAM4
- ;
- POP HL
- INC HL
- LD C,1 ;don't store char on return
- RET
- ;
- FFNAM4: PUSH BC
- CALL TRANS8 ;transfer 1st 8 chars of filename
- ;
- FFNAM6: LD A,'.' ;name transferred, now do period
- LD (DE),A
- INC DE
- ;
- CALL TRANS3 ;transfer filetype
- POP BC
- POP HL
- INC HL
- LD C,1 ;indicate all OK
- RET
- ;
- FFERR: ;erroneous file number
- LD A,SYSFLG
- LD (DE),A
- INC DE
- DEC HL ;point to char after SYSFLG
- LD A,(HL)
- LD C,2 ;store char on return
- RET
- ;
- ;
- ; Character is flag for filename (8 chars only). Get filename, issue error
- ; message if number is outside range 1-4 or if filename is not defined.
- ;
- FNAME:
- INC HL ;get number
- LD A,(HL)
- OR A
- JR Z,FFERR
- CALL FNCHEK ;is number in range 1-4?
- JR Z,FFERR
- ;
- SUB 31H ;make binary 0-3
- PUSH HL
- CALL FNADDR ;get address of filename in HL
- LD A,(HL)
- CP ' '
- JR NZ,FNAME2
- LD C,1
- POP HL
- INC HL
- RET
- ;
- FNAME2: PUSH BC
- CALL TRANS8
- POP BC
- POP HL
- INC HL
- LD C,1 ;indicate all is OK
- RET
- ;
- ;
- ; Character is flag for filetype (3 chars only).
- ;
- FTYPE:
- INC HL ;get number
- LD A,(HL)
- OR A
- JR Z,FFERR
- CALL FNCHEK ;check that number is in range 1-4
- JR Z,FFERR ;quit if not
- ;
- SUB 31H ;convert to binary 0-3
- PUSH HL
- CALL FNADDR ;get address of filename in HL
- LD A,(HL) ;check for defined name
- CP ' '
- JR NZ,FTYP2
- ;
- POP HL
- INC HL
- LD C,1
- RET
- ;
- FTYP2: PUSH BC
- PUSH DE
- LD DE,8
- ADD HL,DE
- POP DE
- CALL TRANS3
- POP BC
- POP HL
- INC HL
- LD C,1 ;indicate all is OK
- RET
- ;
- ;
- ; ================ FILENAME TRANSFER UTILITIES ================
- ;
- ;
- ; Check whether char in A is in ASCII range '1'-'4'. Set the error flag and
- ; return with Z set if out of range.
- ;
- FNCHEK: CP '1' ;less than one?
- JR C,FNERR
- CP '5' ; greater than four?
- JR NC,FNERR
- OR A ;force NZ
- RET
- ;
- FNERR: CALL SETERR
- CP A ;set Z without disturbing A
- RET
- ;
-
- ; Compute address of System File name. Number of file is passed in A, address
- ; of name is returned in HL. No other registers are affected.
- ;
- FNADDR: PUSH BC
- PUSH DE
- LD B,A ;multiply by 11 to compute offset of name
- ADD A,A ;x2
- LD C,A
- ADD A,A ;x4
- ADD A,A ;x8
- ADD A,C ;x10
- ADD A,B ;x11
- LD E,A
- LD D,0
- LD HL,(Z3ENV)
- ADD HL,DE
- LD DE,SYSNAM ;offset of filenames from ENV
- ADD HL,DE ;HL now points to fname
- POP DE
- POP BC
- RET
- ;
-
- ; Transfer 8 characters of filename from (HL) to (DE). If fewer than 8 chars,
- ; increment HL to point past eighth anyway. BC also used, not saved.
- ;
- TRANS8: LD B,8 ;# of chars in name
- TR82: LD A,(HL)
- CP ' '
- JR Z,TR83
- LD (DE),A
- INC HL
- INC DE
- DJNZ TR82
- TR83: LD A,B ;were 8 chars transferred?
- OR A
- RET Z
- TR84: INC HL
- DJNZ TR84
- RET
- ;
-
- ; Transfer 3 characters of filename from (HL) to (DE). BC is also used,
- ; not saved. HL is NOT incremented past filename.
- ;
- TRANS3: LD B,3 ;transfer filetype
- TR32: LD A,(HL)
- CP ' '
- RET Z
- LD (DE),A
- INC HL
- INC DE
- DJNZ TR32
- RET
- ; ================ END OF FILENAME TRANSFER UTILITIES ================
- ;
- ;
- ; Character is substitute command-line separator. If next character is the
- ; same, preserve one of them. Otherwise, replace it with the real command
- ; separator.
- ;
- SUBCHR: LD C,2 ;prepare for 'error' return
- INC HL ;get next char
- LD A,(HL)
- OR A ;premature end of CL?
- RET Z
- ;
- SUBCH2: CP SUBSEP ;also sub. cmd. sep?
- RET Z ;if so, return it
- DEC HL ;else point before it
- LD A,CMDSEP ;and return the real cmd. sep.
- RET ;('error' status will have it stored)
- ;
- ; Return current drive.
- ;
- CDRIV: PUSH HL
- PUSH DE
- LD C,19H
- CALL BDOS
- ADD A,'A'
- POP DE
- POP HL
- LD C,2 ;use char in A
- RET
- ;
- ; Return current user #.
- ;
- CUSR: PUSH HL
- PUSH DE
- LD C,20H
- LD E,0FFH
- CALL BDOS ;user # in A
- POP DE
- CALL MAFDC ;up to 3 dec. digits stored at DE
- POP HL
- INC HL
- LD C,1
- RET
- ;
- ; Get register #.
- ;
- REGR: LD C,2 ;prepare for error
- INC HL
- LD A,(HL) ;get reg #
- OR A ;premature end of CL?
- RET Z
- ;
- REGR2: SUB '0'
- LD B,A ;register # in B
- PUSH HL
- CALL GETREG ;register value now in A
- CALL MAFDC ;up to 3 dec. digits stored at DE
- POP HL
- INC HL
- LD C,1
- RET
- ;
- ;
- ; Set transient error code byte.
- ;
- SETERR: PUSH AF
- XOR A
- DEC A
- CALL PUTER2
- POP AF
- RET
- ;
- ;
- ; Buffers
- ;
- SAVESP: DS 2
- DS 48
- STACK: DS 2
- SHVAR:
- DB ' '
- LOCELT:
- DS 1 ;string stack element count
- LOCADR:
- DS 2 ;ptr to next entry on stack
- LOCSTK:
- DS LECNT*2 ;string ptr stack
- VARPTR:
- DS 2 ;ptr to current variable in line
- INTLINE:
- DS 2 ;ptr internal expansion line
- VARLIST:
- DS 2 ;list of shell variables.
-
- END START