;
; Program: ALIAS1
; Author: Richard Conn
; Version: 1.1
; Date: 10 June 84
; Previous Versions:  1.0 (5 Mar 84)
;
version equ     11

;
;       The purpose of ALIAS1 is to load the Command Line Buffer with
; a command line stored within ALIAS1, extracting parameters using the
; SUBMIT file convention ($n) as they are referenced in the new command
; line.  Upon successful build, ALIAS1 runs the new command line by simply
; returning to ZCPR3.
;

;
; Macros
;
       MACLIB  Z3BASE.LIB

;
; Basic Equates
;
tbuff   equ     80h

;
; External References
;
       ext     z3init,getefcb,getcl1,getenv,getfn2
       ext     eprint,codend,sksp,retud,caps

;
; 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  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
       jmp     start1  ;skip command line buffer
;
; ALIAS ID at START+9
;
       db      'Z3 ALIAS'
;
; Internal Command Line Buffer
;       This buffer address can be determined from START+17, where the
; value of START is obtained from the 2nd and 3rd bytes of ALIAS1.
;
clbuf:
       db      0       ;set to empty
       ds      255     ;allow 256 bytes
;
; Resume ALIAS1
;
start1:
       call    codend  ;pt to free space in which to build new line
       lxi     d,clbuf ;pt to buffer
       xchg            ;HL pts to target line, DE pts to buffer
;
; Process Next Char from Target Command Line
;
nxtchar:
       mov     a,m     ;get next char
       ora     a       ;end of line?
       jz      done
       cpi     '$'     ;possible passed parameter?
       jz      param
       stax    d       ;store next char
       inx     h       ;pt to next
       inx     d
       jmp     nxtchar
;
; Process Possible Parameter
;
param:
       lxi     b,nxtchar       ;establish return address
       push    b       ;... on stack
       inx     h       ;get parameter char
       mov     a,m
       call    caps    ;capitalize
       cpi     '*'     ;entire tail?
       jz      paraml
       cpi     'D'     ;current disk?
       jz      paramd
       cpi     'U'     ;current user?
       jz      paramu
       cpi     'F'     ;System Filename.Typ?
       jz      paramf
       cpi     'N'     ;System Filename?
       jz      paramn
;       cpi     'T'     ;System Typ?
;       jz      paramt
       sui     '0'     ;convert
       jc      noparam
       cpi     10      ;range?
       jnc     noparam
       ora     a       ;parameter 0 = original name
       jz      oname
       mov     b,a     ;count in B (1 or more)
       inx     h       ;pt to next char
       push    h       ;save ptr
       lxi     h,tbuff+1       ;pt to input line
;
; Advance to Desired Parameter
;
param1:
       call    sksp    ;skip to non-blank
       mov     a,m     ;check for done
       ora     a
       jz      paramx
       dcr     b       ;count down
       jz      param3  ;got it
;
; Skip Over This Parameter
;
param2:
       mov     a,m     ;skip to space or EOL
       inx     h       ;pt to next
       cpi     ' '     ;space
       jz      param1
       ora     a       ;EOL
       jz      paramx
       jmp     param2  ;continue
;
; Extract Parameter Into Target Buffer
;
param3:
       mov     a,m     ;get char
       cpi     ' '+1   ;done?
       jc      paramx
       stax    d       ;store char
       inx     h       ;advance
       inx     d
       jmp     param3
;
; Resume Processing of Target Command
;
paramx:
       pop     h       ;restore ptr to next char
       ret             ;resume at next char
;
; Parameter is for System Filename.typ
;
paramf:
       call    getfnum ;get file number
       rz              ;resume if error
       push    h       ;save ptr to next char
       call    ptfn    ;set ptr to file name
       call    putn    ;put file name
       mvi     a,'.'   ;dot
       stax    d
       inx     d
       call    putt    ;put file type
       pop     h       ;restore ptr
       ret
;
; Parameter is for System Filename
;
paramn:
       call    getfnum ;get file number
       rz              ;resume if error
       push    h       ;save ptr to next char
       call    ptfn    ;set ptr to file name
       call    putn    ;put file name
       pop     h       ;restore ptr
       ret
;
; Parameter is for System Typ
;
;paramt:
;       call    getfnum ;get file number
;       jz      nxtchar ;resume if error
;       push    h       ;save ptr to next char
;       call    ptfn    ;set ptr to file name
;       mvi     a,8     ;add 8 to get to file type
;       add     l
;       mov     l,a
;       mov     a,h
;       aci     0
;       mov     h,a
;       call    putt    ;put file type
;       pop     h       ;restore ptr
;       jmp     nxtchar

;
; Get File Number (1 to 4)
;       If valid number, return with value in A and HL pting to next char
;       If not valid, return with Z and HL pting to next char (the number)
;
getfnum:
       inx     h       ;pt to number
       mov     a,m     ;get char
       sui     '1'     ;convert
       jc      getfne  ;error if less
       cpi     4       ;range?
       jnc     getfne  ;error if more
       inx     h       ;pt to next char
       ret             ;NZ from CPI 4
getfne:
       xra     a       ;return Z
       ret
;
; Pt to File Name whose Number (1-4) is in A
;
ptfn:
       mov     b,a     ;number in B
       call    getfn2  ;pt to file name 2
       push    d       ;save DE
       mov     a,b     ;file 0?
       ora     a
       jz      ptfnx
       lxi     d,11    ;size of file name and type
ptfn1:
       dad     d       ;pt to next
       dcr     b       ;count down
       jnz     ptfn1
ptfnx:
       pop     d       ;restore DE
       ret
;
; Put File Name pted to by HL
;
putn:
       mvi     b,8     ;8 chars
       jmp     putc
;
; Put File Type pted to by HL
;
putt:
       mvi     b,3     ;3 chars
;
; Copy chars from HL to DE for up to 8 bytes - flush if space
;
putc:
       mov     a,m     ;get next char
       cpi     ' '     ;skip spaces
       jz      putc1
       stax    d       ;put next char
       inx     d       ;pt to next
putc1:
       inx     h       ;pt to next
       dcr     b       ;count down
       jnz     putc
       ret
;
; Parameter is for Disk Letter
;
paramd:
       call    retud   ;get DU in BC
       mov     a,b     ;get disk letter
       adi     'A'     ;convert to ASCII
       stax    d       ;store char
       inx     d       ;pt to next
       inx     h       ;pt to next char
       ret
;
; Parameter is for User Number
;
paramu:
       call    retud   ;get DU in BC
       mov     a,c     ;get user number
       mvi     b,10    ;compute 10's
       mvi     c,'0'
pmu1:
       sub     b       ;subtract 10's
       jc      pmu2
       inr     c       ;increment 10's
       jmp     pmu1
pmu2:
       add     b       ;add B back in
       adi     '0'     ;convert to ASCII
       mov     b,a     ;10's in C, 1's in B
       mov     a,c
       cpi     '0'     ;no leading 0's
       jz      pmu3
       stax    d       ;store char
       inx     d       ;pt to next
pmu3:
       mov     a,b     ;get 1's
       stax    d       ;store char
       inx     d       ;pt to next
       inx     h       ;pt to next char
       ret
;
; Parameter is command line tail
;
paraml:
       inx     h       ;pt to char after parameter letter
       push    h       ;save ptr to parameter
       lxi     h,tbuff+1       ;pt to tail
paramt1:
       mov     a,m     ;copy tail into line
       ora     a       ;end of tail?
       jz      paramt2
       stax    d       ;store char
       inx     h       ;pt to next
       inx     d
       jmp     paramt1
paramt2:
       pop     h       ;pt to next char in script
       ret             ;continue processing
;
; Form assumed to be $$
;
noparam:
       mvi     a,'$'   ;store '$'
       stax    d
       inx     d       ;pt to next chars
       inx     h
       ret
;
; $0 - ALIAS Command Name
;
oname:
       inx     h       ;pt to next char
       push    h       ;save ptr
       call    getefcb ;pt to FCB
       jz      paramx  ;skip if no external FCB
       inx     h       ;pt to first char
       mvi     b,8     ;at most 8 chars
on1:
       mov     a,m     ;copy into output line
       cpi     ' '     ;done if space
       jz      paramx
       stax    d       ;store char
       inx     h       ;pt to next
       inx     d
       dcr     b       ;count down
       jnz     on1
       jmp     paramx

;
; Done -- Buffer is Loaded
;
done:
       xra     a       ;store ending 0
       stax    d
       call    codend  ;pt to buffer
       mov     a,m     ;skip if empty line
       ora     a
       rz
;
; Determine if ZCPR3 Environment Support is Available for Command Line
;
       push    h       ;save ptr to line
       call    getenv  ;get environment
       mov     a,h
       ora     l
       jz      done0
;
; Get environment from descriptor
;
       call    getcl1  ;get command line data
       mov     b,a     ;save char count
       mov     a,h     ;check for no command line
       ora     l
       jz      done0
       mov     a,b     ;restore char count
       ora     a       ;check for no chars
       jnz     done1
;
; Get environment from MACRO File
;
done0:
       lxi     h,z3cl  ;pt to command line from macro expansion
       mvi     a,z3cls ;get size of command line
;
; Store Command Line
;
done1:
       pop     d       ;DE pts to line
       call    putcl   ;store in command line
       rnz             ;return to ZCPR3 for processing if OK
       call    eprint
       db      'Ovfl',0
       ret
;
;       PUTCL stores a command line in the ZCPR3 command line buffer.
; This command line is pted to by DE.  CL Buffer is pted to by HL.
; Size in A. On return, A=0 and Zero
; Flag Set if command line overflow is possible (no change to command line).
;
putcl:
       shld    clbfr   ;save ptr to command line buffer
       ora     a       ;any command line?
       jz      nocl
       mov     b,a     ;char count in B
       xchg            ;HL pts to new line
       push    h       ;save ptr to new line
pcl2:
       mov     a,m     ;go to end of line
       ora     a       ;at end?
       jz      pcl3
       inx     h       ;pt to next
       dcr     b       ;count down
       jnz     pcl2
       pop     h       ;clear stack
;
; Command Line Buffer Overflow
;
nocl:
       xra     a       ;error return
       ret
;
; At End of New Command Line (ptr on stack)
;       Ptr to first char of new command line on stack
;       HL pts to ending 0 of new command line
;       B = number of chars remaining before overflow of Z3 command line
;
pcl3:
       push    h       ;save ptr to last byte in case of error
       lhld    clbfr   ;pt to tail of command line
       mov     e,m
       inx     h
       mov     d,m
       xchg            ;HL pts to command line tail
       pop     d       ;restore ptr to last byte of command line
       push    d
       mov     a,m     ;get first char of tail
       cpi     ';'     ;continuation?
       jz      pcl4
       ora     a       ;done?
       jz      pcl4
       mvi     a,';'   ;set continuation char
       stax    d
       inx     d
       dcr     b       ;count down
       jz      pcl5    ;overflow
;
; Copy tail onto end of new command line
;
pcl4:
       mov     a,m     ;get next char
       stax    d       ;store it
       inx     h       ;pt to next
       inx     d
       ora     a       ;done?
       jz      pcl6
       dcr     b       ;count down
       jnz     pcl4
;
; Command Line too Long
;
pcl5:
       pop     h       ;get ptr to end of old line
       mvi     m,0     ;store ending 0
       pop     psw     ;clear stack
       jmp     nocl
;
; New Command Line OK
;
pcl6:
       pop     psw     ;clear stack
       lhld    clbfr   ;pt to command line buffer
       lxi     d,4     ;pt to first char in buffer
       xchg
       dad     d
       xchg
       mov     m,e     ;store address
       inx     h
       mov     m,d     ;DE pts to first char of buffer
       pop     h       ;HL pts to first char of new line
;
; Copy New Command Line into Buffer
;
pcl7:
       mov     a,m     ;copy
       stax    d
       inx     h
       inx     d
       ora     a       ;EOL?
       jnz     pcl7
;
; Exit with OK Code
;
       xra     a       ;set NZ
       dcr     a
       ret

;
; Buffers
;
clbfr:
       ds      2       ;ptr to command line

       end