;
                                  ALIAS.COM                                   

             Size (recs) CRC   Version    Author/Latest Issue      Disk
               3k (24)   CFA8  1.5        Joe Wright 9/90          Z3COM1

   1- Syntax  2- ALIAS0  3- ALIAS1  4- Recursion  5- Help File  6-ALIAS.HLP   


   The ALIAS facility is the script expansion utility of ZCPR3.  An 'alias' is 
a COM file,  created by the ALIAS program, which contains one or more commands 
(separated  by semicolons) to be placed in the command line buffer.   When the 
alias  is  invoked,  parameters from the command line are implanted  into  the 
script  contained  within the alias,  and the resulting new  command  line  is 
placed into the command line buffer and executed.  

   See ALIAS.HLP for details on use of ALIAS.COM
:1
    Syntax   ALIAS            <-- define new command

         or  ALIAS dir:ufn    <-- redefine old command
:2
 ALIAS0 - 1/8 
 
   Version 1.5 is  significantly  different from  Conn's 1.1 in  that  the two
modules are reversed in order.   That is the real alias  module is  now ALIAS0
and the and the editor is ALIAS1.  Further, they are assembled to standard REL
files and linked in the normal way to a COM file.

            SLRNKP ALIAS/N,/A:100/J,ALIAS0,ALIAS1,/E
                               or
                     ZML ALIAS=ALIAS0,ALIAS1
                               or
                  LINK ALIAS=ALIAS0,ALIAS1[NR]

   ALIAS0 is now the actual alias  module  written to  disk.   It  is entirely
self-contained and does not  call the  Libraries.   ALIAS1 is the editor which
prompts the user for the ALIAS0 command line.

   ALIAS0 has been enhanced somewhat to allow all five  system filenames to be
addressed, $F0 being the prototype SH.VAR shell variable file.   The 'T' file-
type operator was put back in such  that  $T0  will  point  to  VAR.
 ALIAS0 - 2/8 

   As before,  ALIAS has one 'escape' character,  '$' dollar.   The characters 
following '$' are interpreted to mean..

     $n   Where n varies 0 through 9.
          $0   returns the NAME of this alias (from EXTFCB)
          $1   returns the first token on the command line
          $9   returns the ninth token on the command line

Any $n which does not have a corresponding token returns a NULL string.

     $*   The entire command line without further translation
     $D   The current drive letter
     $U   The current user number

For F, N & T, n=0 is the SH.VAR filename; n=1..4 are the System File names.

     $Fn  System File n Name and Type as NAME.TYP    (n is 0..4)
     $Nn  System File n Name as simply NAME          (n is 0..4)
     $Tn  System File n Type as simply TYP           (n is 0..4)
     $$   Simply return one '$' to the command line
 ALIAS0 - 3/8 

   ALIAS15 implements a  new Pointer parameter which will expand to a hexadec-
imal address.  The Pointer will allow access to dynamic memory values within a
known data structure  (the base  page or the  environment  descriptor,  a jump 
table, etc.).  

                Syntax:  $.ADDR[[[.OFF].OFF]+OFF]

   The alias parameter is formed with  a '$' followed by  a '.' point followed
by an address.   On expansion,  it will return the  Word at the address.   For
example,  '$.6' will return the value in locations 6 & 7 of the base page, the
'protected memory' address, something like C706 or whatever the BDOS entry is.

   We can also find the Z3 Environment.   The alias itself is  a  ZCPR3 Type 1
file with a standard Z3 header.   The address of  Z3ENV is  always at  109h in
such a file.   The form '$.109' will expand to the hex address of the Environ-
ment (E780 in my case).
 ALIAS0 - 4/8 

   To find an address in the  Environment  Descriptor,  Z3CL for  example,  we
append its offset.   '$.109.18' will get the  environment address at 109h, add
18h to it and return the  value contained there,  the address of Z3CL (E900 in
my case).  The value at Z3CL is the NXTCHR pointer.  Return this with one more
level of indirection as '$.109.18.0'.  

$.1            (0001H)        BIOS+3    D503      (my system)
$.6            (0006H)        BDOS      C706

$.109          (0109H)        Z3ENV     E780
$.109.18       (Z3ENV+18)     Z3CL      E900
$.109.18.0     (Z3CL)         NXTCHR    E9nn

Let's consider the Z3MSG buffer.

$.109.22       (Z3ENV+22)     Z3MSG     E880

The Error Address at Z3MSG+4 is returned with..

$.109.22.4     (Z3MSG+4)
 ALIAS0 - 5/8 

   The pointers can have  as  many  levels  of  indirection  as  necessary but
it's easy to get lost after two or three.

   We can also add an offset to a pointer.  For example..

$.109.22+6 will point to the  Program  Error  flag  at Z3MSG+6.   Or  point to
System File 1 in the environment with '$.109+52'.   We can  use the '+' or '-'
operators to provide an offset from the memory variable.  For example, '$.1+3'
will return BIOS+6, the CONST entry  while '$.1-3' returns BIOS+0,  the begin-
ning of the bios.   We can also use this as the  basis of the  next element in
the Pointer parameter.  Another example..
 ALIAS0 - 6/8 

   The Ampro bios is structured such that the  Disk  Parameter  Headers of all
sixteen possible drives reside,  starting  with the  first  floppy  drive,  at
BIOS+80H.   We can extract any of the pointers in any of the headers with some
simple math.   Let's get the address of the Sector Translate Table for drive E
(4).  XLATE is the first pointer in any DPH.

   Assuming NZCOM,  it is the  CBIOS we are interested in.   Let's  go through
this step by step and simplify things at the end..

$.109.1                  (Z3ENV+1)      CBIOS+6        EA06
$.109.1-6                CBIOS+6-6      CBIOS          EA00 
$.109.1-6+80             CBIOS+80       CBIOS+80       EA80
$.109.1-6+80+40          CBIOS+C0H      CBIOS+C0H      EAC0
$.109.1-6+80+40.0        (CBIOS+C0H)    EXLATE         EC22

We simplify the math with..

$.109.1+BA.0 and we have it.   This may or may not be useful,  but  it's there
if we ever need it.
 ALIAS0 - 7/8 

   The alias created by  ALIAS15 is  seven  records long.   The standard alias
was eight records and no alias may be longer.   Alias  editors in general will
reject a file of nine or more  records and  declare it  'Not an Alias'.   This
eight-record length is arbitrary but historical.  

   Note also that the various  Alias  editors read the input alias only to get
the command line from it.   They tend to  write the  New  alias with their own
Alias code, not with the original.  And so it is with ALIAS15.  

   In light of this, a ^W 'Write' command has been implemented so that you can
read an alias made by  SALIAS or whatever and save it with the new ALIAS0 code
allowing $., $F0 or $Tn extensions.  

   The alias will build a CCP command in a local buffer according to its argu-
ments and the tail passed to it as it was called.  Any pending commands in the
MCL will be appended to this local buffer and then the entire buffer copied to
the beginning of the MCL.   The alias then  'returns' to the  CCP  (ZCPR3) for
execution.
 ALIAS0 - 8/8 

   VALIAS and SALIAS implemented a  Mode  control in the  alias  as  Normal or
Recursive.   In  Recursive  Mode the  alias will clear the rest of the MCL and
copy only its expansion to the beginning of the MCL.   Both  VALIAS and SALIAS
maintain this flag at 10Ch in the  alias as  00h if Normal and 0FFh if recurs-
ive, and a 46h 'F' character at 10Bh.  

   The command tail of a given  alias  entry may be no longer than 126 charac-
ters because of the constraints of the TBUFF size.   If  the  expansion  of  a
particular alias line is  longer than  126  bytes we flag an Ovfl error and do
NOT move the alias into the MCL.

   SALIAS allows placing control characters in  the  alias  script.   Although
cute, is this necessary or even desirable?  The alias creates commands for the
CCP and the CCP expects no controls.  Why allow them in an alias?
:3
 ALIAS1 - 1/2 

   In order to handle  a  'Recursive Mode'  ALIAS0,  ALIAS1  has been modified
quite heavily.   Other changes have also been made to the effect that it works
a little differently now.

Syntax:
     ALIAS
Displays a Null alias and prompts for input.

     ALIAS NAME
Loads alias NAME.COM (if it exists) and displays it.  Prompts for new alias.

   The display includes  Mode status,  Normal or Recursive.  At this point you
have three main options, enter a new alias,  toggle the Mode flag or Write the
alias to disk without  change  (in case you have  read  a 'foreign'  alias and
would recreate it with  ALIAS0).  All of these will write a new alias.  If you
RETURN at this point we simply quit.  
 ALIAS1 - 2/2 

   Any change to an alias or creating a new alias will redisplay the new alias
for inspection.  RETURN at this point will Write the new alias.   If the alias
is not already named,  you will be  prompted for a name.   All alias files are
type COM.  

   Because ALIAS1 is only a  line  editor  (BDOS Function 10),  Rob Friefeld's
SALIAS should be considered for  writing and editing complex aliases.   SALIAS
vs 1.5 now supports $., $F0 and $Tn forms in its own alias.  

   ALIAS1 will accept a  new  name  on  the  command  line for the alias to be
created.  No more 'File Not Found' messages.   Also  added  ^N  New command to
allow loading an alias from the users prompt.  The prompt now looks like..

   (RETURN to Quit, ^W to Write, ^N New alias, ^T toggle Mode)
                               or
   (RETURN to Write, ^C to Quit, ^N New alias, ^T toggle Mode)
:4
 Recursion - 1/6 

   Recursion occurs when an alias calls itself.   This might  be  useful in an
EDIT, ASSEMBLE, LINK session where an error flagged by the assembler or linker
would automatically put you back in your  editor to  try again and the absence
of errors would link and exit.  The following will concentrate on how to write
aliaes which are properly recursive.

   At first blush, it would seem that we could do something like this..

FOO: PROGRAM        Some program which sets the Error flag
     IF ER          Now check for Error
     FOO            Re-run FOO on error
     FI             Close the IF

And we can,  almost.   If there is  an  error,  FOO is rerun.   This leaves an
unresolved IF on the Flow stack and appends the last  FI to the 'new' alias in
the MCL.   Each iteration  pushes  another  IF  onto  the  Flow stack and adds
another FI to the MCL.   Everything is fine until  either the Flow stack over-
flows (eight IF's max) or the MCL fills up with all the FI's.  Not really cool
because we never know how many times we rerun FOO nor how much room we have in
the MCL.  
 Recursion - 2/6 

   The solution is  simple but  requires  a  little explanation.   Rewrite the
alias so that its 'recursion' neither overflows the Flow stack nor the MCL.  
Consider..

FOO: FI        Close IF ER
     PROGRAM
     IF ER
     FOO       Rerun this alias

   This one has no pending FI to overflow the MCL and will keep the Flow stack
straight while it is 'recurring'.   The  first  FI is  balanced  by calling it
correctly with another alias, like this..

RUN: IF T      Impress True on the Flow stack
     FOO       Execute FOO
     FI        Close the IF

Watch how nicely this expands..
 Recursion - 3/6 

RUN: IF T      Set Flow True
FOO: FI        Close IF T from RUN or IF ER from FOO
     PROGRAM   Clears (and maybe sets) Error flag
     IF ER
     FOO       Run FOO again if ER
     FI        From RUN, Close IF ER from FOO when no Error

Perfectly balanced.  Written this way, recursive aliases do not corrupt either
the Flow stack or the MCL.   You  can  enter  commands  following  RUN  on the
command line and they will remain  pending  until RUN is  finished and then be
executed automatically.

There is no  apparent  need for  a 'Recursive Mode' alias which clears pending
commands from the MCL as it runs.  'Normal Mode' works quite nicely.

An example of nesting...
 Recursion - 4/6 

RUN:
     IF T           Push True onto the Flow stack
     MAIN           Run MAIN
     FI             Pop the Flow stack and resume MCL commands

MAIN:
     FI             Pop the Flow stack
     PROG1          Do something.  Set ER if we need FOO.
     IF ER
     FOO            Run FOO if any error
     FI
     IF ER          FOO returns ER to force one more PROG1
     MAIN

FOO:
     FI
     PROG2          Do something.  Clear ER to do PROG2 again.
     IF ~ER         Check the ER flag
     FOO            Rerun PROG2
 Recursion - 5/6 

   In this scenario,  PROG1 will be run and on error, PROG2 is run.   If PROG2
is run,  it will  repeat  until it  sets  ER and then PROG1 will be run again.
This keeps up until PROG1 does not set the error flag.

   It is left to the reader to discern a use for  this,  but the  form  of the
aliases is correct and allows you to append  commands to  RUN to the extent of
the MCL length.  It expands like this..

RUN:
     IF T           Push True onto the Flow stack
MAIN:
     FI             Pop the Flow stack
     PROG1          Do something.  Set ER if we need FOO.
     IF ER          Run FOO if any error
FOO:
     FI
     PROG2          Do something.  Clear ER to do PROG2 again.
     IF ~ER         Check the ER flag
     FOO            Rerun FOO if no error
 Recursion - 6/6 

     FI
     IF ER          FOO returns ER to force one more PROG1
     MAIN           Run MAIN

     FI             Pop the Flow stack and resume MCL commands
:5

                                   ALIAS.HLP 

             Size (recs) CRC   Version    Author/Latest Issue      Disk
               6k (41)   C045  1.5        Joe Wright 9/90          Z3HLP1
==============================================================================

   Z-System HELP file on ALIAS vs 1.5.
:6 :ALIAS
