Program PREPIC
                            11 September 2009

prepic [options]

Preprocess a Microchip PIC assembler source file to produce a file that
can be passed directly to the assembler.  The input file name suffix
determines the default output file name suffix and can enable or disable
particular features.  The valid input file name formats are:

  <name>.aspic

       MPASM source file (for PIC 10, 12, 16, 17, and 18).  Default output
       file name is <name>.asm.

  <name>.ins.aspic

       MPASM include file.  Default output filename is <name>.inc.

  <name>.dspic

       ASM30 source file (for dsPIC, also known as PIC 30F).  Default
       output file name is <name>.S.

  <name>.ins.dspic

       ASM30 include file.  Default output file name is <name>.inc.

The input file is just copied to the output file except when a
preprocessor command or inline function is encountered.

The command line options are:

  <input file name>

       The first command line option that does not start with a dash (-)
       will be taken as the input file name if no input file name was
       previously set.  A input file name is mandatory.

       The file name suffixes may be omitted on the command line.  In that
       case file names with each of the valid suffixes ".ins.aspic",
       ".aspic", ".ins.dspic", and ".dspic" will be tried in that order.
       The first file found will be used.

  -IN <input file name>

      Explicitly set the input file name.  This is the only way to
      indicate an input file name that starts with a dash (-).

  <output file name>

       The first command line argument that does not start with a dash
       after the input file name is specified, but no output file name has
       yet been specified, will be taken as the output file name.  The
       default output file name for each input file type is listed above.

  -OUT <output file name>

       Explicitly set the output file name.  This is the only way to
       indicate an output file name that starts with a dash (-).

  -SET name

       Create a BOOL variable of name NAME and set it to TRUE before the
       input file is processed.

  -NOT name

       Create a BOOL variable of name NAME and set it to FALSE before the
       input file is processed.

  -I name val

       Create a INTEGER variable of name NAME and set it to VAL before the
       input file is processed.

  -F name val

       Create a REAL (floating point) variable of name NAME and set it to
       VAL before the input file is processed.

  -S name val

       Create a STRING variable of name NAME and set it to VAL before the
       input file is processed.  VAL must be enclosed in quotes ("") or
       apostrophies ('') if it contains any spaces.


                               Data Types

Each preprocessor explicit constant, symbolic constant, variable, and
expression has a data type.  These data types are referred to by name,
and are listed below together with their descriptions.  The data type
names are keywords, and are therefore case-insensitive.  The data types
are:

  BOOL

    A value of this type is always either TRUE or FALSE.  TRUE and FALSE
    are built in keywords, and are case-insensitive.

  INTEGER

    An integer value.  Its string representation is:

      [-][radix#]number

    Where RADIX is the radix represented in decimal.  RADIX must be from 2
    to 36, with the default being 10 (ten).  NUMBER is the integer number
    in the specified radix.  The letters A-Z or a-z are used for digit
    values from 10-35.  Each digit value must be less than the radix.

    Integer values are written in decimal by PREPIC unless this is
    overridden by specific formatting.

  REAL

    This data type is also sometimes called floating point in descriptive
    text.  The string representation is a consecutive string of decimal
    digits containing exactly one decimal point before, within, or after
    it.  This string may be optionally followed by "E" and an exponent
    value.  This is all interpreted as you would expect if you've used a
    computer since the late 1950s.

    Floating point values are written with 7 significant digits by PREPIC
    unless this is overridden by specific formatting.

  STRING

    A string constant is a sequence of characters enclosed in quotes ("")
    or apostrophies ('').  The value is the characters between but not
    including the quotes.

    The dictionary collating sequence is used for string comparisons of
    letters and decimal digits.  A string is "less than" another string if
    it would be listed earlier in a dictionary according to these rules.
    Upper case letters are immediately less than their lower case
    counterparts.  The digits 0-9 are less than all letters.  If two
    strings of different length are compared that are equal up to the
    length of the shorter string, then the shorter string is less than the
    longer string.  The space character is less than all other printable
    characters.

    The collating sequence is not defined for characters other than space,
    the digits 0-9, and the upper and lower case letters A-Z.  The results
    for the remaining characters will be consistent on any one
    implementation, but are not guaranteed to be consistent accross
    implementations.

    As a example, the following strings are listed in less than to greater
    than order: "aB", "ab", "cd", "cde", "cde f", "cdef", "def22", "defaa"

  TIME

    Values of this data type specify an absolute time.  The time is stored
    internally in 60.30 bit fixed point universal coordinated time seconds
    with zero at the start of year 2000.  This data type therefore has a
    resolution of about 931 picoseconds, and a range of about +-15 billion
    years.

    The text representation of this data type is:

      YYYY/MM/DD.hh:mm:ss.ssssss

    This is the text representation produced by PREPIC when a time value
    is implicitly converted to text.  Hours are always written in 24 hour
    format, so there is no AM/PM indicator.  When converting to a TIME
    data type from the text representation, trailing fields may be omitted
    after the first slash.  Omitted fields will be assumed to have the
    value 0. For example, all the following text time representations
    indicate 2:00pm on Monday 23 October 2006:

      2006/10/23.14
      2006/10/23.14:00
      2006/10/23.14:00:00

    When TIME values are compared, eariler times are considered less than
    later times.


                         Preprocessor Commands

Lines containing preprocessor commands must have the first non-blank
character be a slash (/), followed directly by a preprocessor command
name, which may be followed by command parameters.  The command name and
parameters are separated from each other by one or more spaces.
Preprocessor command names are not case sensitive.  Command parameters are
also case-insensitive to the extent possible.

The preprocessor commands are:

  //<comment>

    Any line that starts with "//" after leading spaces are stripped is a
    preprocessor comment.  The entire line is ignored.  No in-line
    functions on the line are expanded.

    This type of comment differs from a native assembler comment in that a
    preprocessor comment is not copied to the output file.  This can be
    useful, for example, in documenting preprocessor code that is not
    appropriate to be visible in the output file.

  /INCLUDE pathname

    Switch the input file to the indicated file.  When the end of that
    file is encountered, reading of the original file is resumed on the
    line following the /INCLUDE command.

    The pathname argument is a string expression.  It must therefore be
    enclosed in quotes or apostrophies if it is a constant.  See the
    STRING data type description for details.  The pathname is relative to
    the directory containing the current source file.

  /INBIT name port bit [PUP]

       Declares an I/O pin as an input.

       NAME is the private name being defined for the I/O pin, and will be
         used to generate unique assembler symbols associated with this
         pin, shown below.

       PORT is the name of the I/O port containing the I/O bit.  It must
         be of the form "PORT" followed by a single letter indicating the
         particular port.  The PORT argument is case-insensitive. Examples
         are "PORTA", "PortB", or "portc".  Some processors have a single
         I/O port called GPIO.  The GPIO port must be referred to as
         "PORTA".

       BIT is the bit number within the port register.  It must be a 0-7
         value on 8 bit PICs (PIC 12, 16, 17, 18) and a 0-15 value on 16
         bit PICs (PIC 30).

       PUP is an optional keyword indicating that the internal passive
         pullup should be initially enabled for this I/O pin.  An error
         will be generated when the standard PORT module is assembled if
         the requested combination of passive pullups requested by all
         /INBIT commands is not attainable on this specific processor.

       This preprocessor command only creates or modifies assembler state.
       It generates no executable code.  It is assumed that the assembler
       state has been properly initialized prior to this /INBIT command,
       as is done if the standard include files STD_DEF.INS.ASPIC and
       STD.INS.ASPIC (or STD_DEF.INS.DSPIC and STD.INS.DSPIC on PIC 30)
       are used as directed.  The actual runtime initialization code that
       uses the assembler state is in the PORT_INIT subroutine in the
       standard PORT module.

       The following assembler symbols will be defined or modified:

       <name>_reg  -  Assembler constant equal to the address of the PORTx
         register containing the direct I/O pin value.

       <name>_tris  -  Assembler constant equal to the address of TRISx
         register controlling the I/O pin in/out direction.

       <name>_lat  -  Assembler constant equal to the address of LATx
         register containing the output latch bit for this I/O pin. This
         constant is only defined if the machine has a port latch
         register. For example, 16 family PICs do not have these, although
         18 and 30 family PICs do.

       <name>_bit  -  Assembler constant equal to the bit number for this
         I/O pin within the PORTx, TRISx, and other possible port-related
         registers.

       <name>_pin  -  String substitution macro that expands to the port
         register followed by the bit number within that register for this
         I/O pin.  The string substitution macro is defined:

       #define <name>_pin <port register>,<bit>

         This string substitution macro can be used to supply both
         arguments to bit manipulation instructions as shown in the
         example below.

         NOTE: This string substitution macro is not implemented for dsPIC
         processors.

       <name>_pinlat  -  String substitution macro that expands to the
         latch register followed by the bit number within that register
         for this I/O pin.  This is like the <name>_pin macro (above),
         except that it refers to the bit in the latch instead of the port
         register.  This macro is only defined when the latch register
         exists.

         NOTE: This string substitution macro is not implemented for dsPIC
         processors.

       VAL_TRISx  -  Assembler variable containing the initial value for
         the TRISx register (where X is the port name, like "A")
         controlling the direction of this I/O bit.  The bit for this I/O
         pin will be set, which will cause the pin to be initialized as an
         input by the standard PORT_INIT subroutine.

       VAL_PULLUPx  -  Assembler variable indicating the desired initial
         state of the passive pullups for the port containing the I/O bit.
         The "x" in the variable name is the port name, like "B" or "C"
         for example.  A bit in this variable is set to indicate the
         associated passive pullup is to be initially enabled.  Illegal
         requests for passive pullups will generate an error message when
         the standard PORT module is assembled.

       For example,

         /inbit button portb 3 pup  ;low when user button is pressed

       declares bit 3 of port B (RB3 pin) to be an input with its passive
       pullup enabled.  The equivalent of the following assembler
       statements will be generated:

         button_reg  equ  portb
         button_tris equ  trisb
         button_lat  equ  latb          (only on machines that have LATB)
         button_bit  equ  3
         #define button_pin portb,3
         #define button_pinlat latb,3   (only on machines that have LATB)
         val_trisb   set  val_trisb | b'00001000'
         val_pullupb set  val_pullupb | b'00001000'

       Example MPASM code using the directive above is:

              dbankif button_reg  ;set banks for access to BUTTON pin
              btfsc   button_pin  ;is the button pressed ?
              goto    done_button ;no, done handling user button
              ;
              ;   The user button is pressed.
              ;
              ...
         done_button unbank       ;done handling the user button

       Example ASM30 code using the directive above is:

              btsc    button_reg, #button_bit ;is the button pressed ?
              bra     done_button ;no, done handling user button
              ;
              ;   The user button is pressed.
              ;
              ...
         done_button:             ;done handling the user button

       Undefined I/O pins default to outputs driven low.

  /OUTBIT name port bit [polarity] [init]

       Like /INBIT except that it declares the I/O bit to be an
       output instead of an input.  This means the VAL_TRISx assembler
       variable will be updated to indicate this bit is an output.

       In addition to the symbols and string substitution macros created
       by /INBIT, /OUTBIT also creates the macros SET_name_ON and
       SET_name_OFF.  These set the bank for access to the appropriate
       register, then use a BSF or BCF instruction to turn the output pin
       on or off.  On PICs with LATx registers, the BCF/BSF instruction
       operate on them.  Otherwise the BCF/BSF instructions operate on the
       PORTx register.

       The optional polarity parameter defines the polarity of the "on"
       and "off" states of the pin.  The polarity parameter must be either
       "P" for positive or "N" for negative.  Positive polarity means that
       high is on and low is off, and negative polarity the opposite.
       For example, this may be useful if a LED is connected in series
       with a resistor between the I/O pin and the positive supply.
       Setting the pin low turns the LED on and setting it high turns the
       LED off.  In this case the polarity should be indicated as N
       instead of P:

         /outbit led portb 5 n

       The polarity is taken into account by the SET_name_ON and
       SET_name_OFF macros.  For the example above, SET_LED_ON would cause
       the RB5 pin to be driven low, and SET_LED_OFF would cause RB5 to be
       driven high.

       The optional INIT parameter indicates how the I/O pin should be set
       when the I/O ports are initialized.  The INIT parameter may be
       either 0 or 1 to explicitly set the pin low or high, respectively,
       or it may be "ON" or "OFF" which will set it high or low depending
       on how the pin polarity is defined.  The default is OFF.

       Undefined I/O pins default to outputs driven low.

  /FLAG name

       Create a new global flag with the indicated name.  The assembler
       variable NFLAGB is updated if a new byte is required to hold the
       new flag.  The flags will be in bytes named GFLn, where N starts at
       0 and increases by one as each new flag byte is required. The
       following assembler constants will be defined:

         flag_<name>_regn -  Number of the GFLn register containing the
           flag bit.  In other words, this constant will be 0 if the flag
           is in GFL0, 1 if it is in GFL1, etc.

         flag_<name>_reg  -  Address of the GFLn byte containing the flag
           bit.

         flag_<name>_bit  -  Number of the flag bit within the GFL0
           register.  The least significant bit is numbered 0, and the
           most significant is 7 on 8 bit PICs and 15 on 16 bit PICs.

       A string substitution macro is created called flag_<name> which
       expands into the byte containing the flag and the bit number within
       the byte.  The string substitution macro is written:

         #define flag_<name> gfl<n>,<bit>

       NOTE: This string substitution macro is not implemented for dsPIC
       processors.

       All flag bits defined with /FLAG are initialized to 0 in the
       standard STRT module before code in any other module is executed.

       Example MPASM code:

         /flag    t100                ;set every 100mS
                  .
                  .
                  .
                  dbankif gbankadr
                  btfss   flag_t100   ;time to do 100mS processing ?
                  goto    done_100ms  ;no, skip this section
                  bcf     flag_t100   ;reset to 100mS proc not pending

                  ;perform 100mS processing here

         done_100ms unbank            ;done with the 100mS processing

       Example ASM30 code:

         /flag    t100                ;set every 100mS
                  .
                  .
                  .
                  btss.b  flag_t100_reg, #flag_t100_bit ;100mS tick ?
                  bra     done_100ms  ;no, skip this section
                  bclr.b  flag_t100_reg, #flag_t100_bit ;reset the flag

                  ;perform 100mS processing here

         done_100ms:                  ;done with the 100mS processing

  /VAR NEW name [dtype] [= value]

       Create a new variable of name NAME.  The preprocessor symbol NAME
       will now refer to the new variable regardless of its previous
       meaning, if any.  NAME will revert to its previous meaning when
       this symbol is deleted.

       The optional DTYPE parameter specifies the data type of the
       variable.  The default data type is STRING.

       The variable will be set to the optional VALUE, if supplied.
       Otherwsie the variable's value will be the default for its data
       type.

  /VAR EXIST name [dtype] [= value]

       Like VAR NEW, except that no new variable is created if NAME is
       already a variable of the indicated type.  The default for DTYPE is
       STRING.

       If a new variable is created, then it will be initialized to the
       optional VALUE, if supplied, else it will be initialized to the
       default for its data type.  If the variable previously existed,
       then its existing value is preserved, whether VALUE is supplied or
       not.

  /VAR LOCAL name [dtype] [= value]

       Like VAR NEW except that the new variable will be automatically
       deleted at the end of the current execution block.  Examples of
       executions blocks are subroutines and explicit blocks defined with
       the BLOCK command.

  /SET name value

       Set the variable NAME to the value VALUE.  It is an error if VALUE
       can not be converted to the data type of NAME, or if NAME is not
       the name of a variable.

  /CONST name [dtype] = value

       Create a new constant of name NAME.  The preprocessor symbol NAME
       will now refer to the new constant regardless of its previous
       meaning, if any.  NAME will revert to its previous meaning when
       this symbol is deleted.

       The optional DTYPE parameter specifies the data type of the
       constant.  The default data type is STRING.

  /DEL name

       Delete the current version of the preprocessor symbol NAME.  If no
       previous version exists, then the symbol NAME becomes unused and
       references to it are errors.

  /SYLIST

       Write the list of all currently defined preprocessor symbols and
       their values to the output file as comments.

  /WRITE str ... str

       Write the concatenation of all argument strings as one line to the
       output file.  If no arguments are supplied, then a blank line is
       written.  Individual arguments must be enclosed in quotes ("") or
       apostrophies ('') if they contain spaces or special characters that
       are to be written literally.

  /SHOW str ... str

       Write the concatenation of all argument strings as one line to
       standard output.  If no arguments are supplied, then a blank line
       is written.  Individual arguments must be enclosed in quotes ("")
       or apostrophies ('') if they contain spaces or special characters
       that are to be written literally.

  /IF condition [then]
  /THEN
  /ELSE
  /ENDIF

       These commands form a IF construct, which is used to conditionally
       execute sections of code.  The CONDITION parameter must be of data
       type BOOL.  There are two forms of the IF construct, depending on
       whether the optional THEN keyword is given on the IF command line.
       The general form without the THEN keyword is:

         /IF condition
             <code that is always executed>
           /THEN
             <code executed when condition is true>
           /ELSE
             <code executed when condition is false>
           /ENDIF

       The THEN and ELSE commands are optional.

       The general form with the THEN keyword on the IF command line is:

         /IF condition THEN
             <code executed when condition is true>
           /ELSE
             <code executed when condition is false>
           /ENDIF

       the ELSE command is optional.

  /SUBROUTINE name

       Declare the entry point of a subroutine and define symbol NAME to
       refer to that subroutine.  The preprocessor symbol NAME will now
       refer to the new subroutine regardless of its previous meaning, if
       any.  NAME will revert to its previous meaning when this symbol is
       deleted.

       Following code is considered part of the subroutine until a ENDSUB
       command is encountered.  The code from SUBROUTINE thru ENDSUB will
       not be executed when the subroutine is being defined.  Subroutines
       are executed by using a CALL command, described below.

       The code from SUBROUTINE thru ENDSUB is a execution block.  This
       type of execution block can take arguments, which can be set with
       the CALL command.  Argument 0 is always the subroutine name as it
       appeared in the CALL command.  The arguments passed from the CALL
       command are numbered sequentially starting at 1.

  /ENDSUB

       Ends a subroutine definition started with the last SUBROUTINE
       command.  Code following this command is no longer considered part
       of the subroutine, and will be executed if code execution was
       enabled when the SUBROUTINE command was encountered.  If ENDSUB is
       encountered while executing a subroutine, it functions just like
       RETURN (below).

  /CALL name [arg ... arg]

       Executes the most recently defined subroutine of name NAME.
       Execution returns to after the CALL command when the subroutine
       completes.

       There may be zero or more ARG parameters separated by spaces. These
       become the execution block arguments inside the subroutine. They
       are available to the subroutine via the ARG inline function.
       Arguments are numbered sequentially starting at 1.  The special
       argument 0 is always the subroutine name as given in NAME.

       The arguments are interpreted as raw collection of characters.  One
       or more blanks separate arguments.  Characters enclosed in quotes
       ("...") or apostrophies ('...') are treated as one entity and are
       not broken into individual arguments even if they contain blanks.
       However, the whole string, including the enclosing quote
       characters, becomes the argument value.

       Note that, as with all commands, any inline functions are first
       evaluated before the command is interpreted.

       Some examples of calls to subroutine XYZ and the resulting value of
       the arguments inside the subroutine are:

         /call xyz
           Arg 0: xyz

         /call xyz a b "a b" "don't"
           Arg 0: xyz
           Arg 1: a
           Arg 2: b
           Arg 3: "a b"
           Arg 4: "don't"

         /call xyz 1 2 [+ 3 4]
           Arg 0: xyz
           Arg 1: 1
           Arg 2: 2
           Arg 3: 7

  /RETURN

       Ends the execution of the latest subroutine called.  Execution
       resumes after the last CALL command.

  /MACRO name

       Defines a preprocessor macro.  These are defined just like
       preprocessor subroutines except that the definition starts with
       MACRO and ends with ENDMAC.

       Macros differ from subroutines in how they are called.  A
       preprocessor macro is called just like a native assembler macro.  If
       the macro name appears syntactically as a opcode, then the macro is
       run and its output replaces the macro invocation line.

       Arguments can be passed to the macro by placing them following the
       macro name on the macro invocation line.  Argument handling inside
       the macro is identical to that of preprocessor subroutine
       arguments.  See the CALL command description for more details on
       arguments.  Note that the call argument syntax in the macro
       invocation differs from the CALL command.  Macro arguments are
       separated by commas with any number of spaces before and after each
       comma.

       If a label preceeds the macro invocation on the same line, then the
       special argument -1 is created that will be the label name.  The
       special argument 0 is the macro name as given in the macro
       invocation.

       The macro invocation syntax is deliberately compatible with the
       MPASM macro invocation and instruction syntax.  This allows, for
       example, existing MPASM directives or instructions to be "hooked"
       to execute preprocessor code.

       Following code is considered part of the macro until a ENDMAC
       command is encountered.  The code from MACRO thru ENDMAC will not
       be executed when the macro is being defined.

       A macro definition is a execution block that can take arguments.

  /QUITMAC

       Stops execution of a macro.  Preprocessor execution is returned to
       the line following the macro invocation.

  /ENDMAC

       Ends a macro definition started with the last MACRO command.  Code
       following this command is no longer part of the macro, and will be
       executed if code execution was enabled when the MACRO command was
       encountered.  If ENDMAC is encountered while executing a macro,
       execution returns to immediately after the macro invocation
       (just like QUITMAC in this case).

  /BLOCK

       Starts a new executable block.  The block is ended with the
       ENDBLOCK command.  This type of execution block can not take
       arguments.  Inside the block, the ARG inline function will resolve
       arguments for the next innermost block that can take arguments,
       such as a SUBROUTINE/ENDSUB block for example.

  /QUIT

       Exits the current execution block.  Execution resumes with
       parameters in effect before the block was entered.

  /REPEAT

       Go back to the start of the current execution block.

  /ENDBLOCK

       Ends the current execution block, which must have been started with
       a BLOCK command.

  /WRITETO name

       Any output that would normally go to the preprocessed output file
       will now go to the file indicated by NAME.  The file is created if
       it does not previously exist, and is overwritten if it does.

  /WRITEEND

       Ends writing to the file started with the most recently executed
       /WRITETO command.  The output file is restored to what it was when
       /WRITETO was executed.  It is not possible to stop writing to the
       original preprocessor output file.

  /STOP

       Completely ends this run of the preprocessor.  No more input file
       is read, and no more output file written.  Any open output files
       are closed and the program exits.


                            Inline Functions

The preprocessor replaces each inline function with the expansion of that
function.  These inline functions can appear anywhere except within quoted
strings surrounded by quotes ("") or apostrophies (''), or within
comments.  The format of an inline function is:

  [name arg ... arg]

Note that the brackets ([]) are literal in this case.  NAME is the name of
the function, and is always case-insensitive.  Functions can have zero or
more arguments, depending on the function.  The function name and the
arguments are separated by one or more spaces.  Any number of spaces are
allowed immediately after the "[" and immediately before the "]".  String
constants must be enclosed in quotes ("") or apostrophies ('').  The
source characters starting with the "[" and ending with the "]" are
replaced by the function value in the output file.

Inline functions can be nested to any depth.  The functions are evaluated
and replaced with their expansions from the innermost to the outermost.

The inline functions are:

  V value

       Writes the value in input language format.  The exact format
       depends on the input language and the value's data type.

  ARG n

       Returns the value of argument N to the innermost execution block
       that can take arguments.  For example, a SUBROUTINE/ENDSUB
       execution block can take arguments whereas a BLOCK/ENDBLOCK
       execution block can not.

       Arguments are numbered.  Arguments explicitly passed into the block
       are numbered sequentially starting with 1.  Special arguments 0 or
       less may exist, depending on the block type.

       If no argument of number N is defined, the function value is
       nothing (expands to no characters).  N must be integer.

       This function returns the argument characters exactly, not as a
       string or any particular data type.  The function is replaced by
       the argument value, or nothing at all if the argument does not
       exist.  Note that the existance of a argument can be tested with
       the EXIST function using the name type ARG.

  EXIST name [nametype]

       Indicates whether NAME exists.  This function always returns a BOOL
       value, with TRUE indicating NAME exists and FALSE that it does not
       exist.

       The optional NAMETYPE parameter specifies the type of object NAME
       is.  NAME must exist and be of the specified type for the function
       to return TRUE.  The default name type is any PREPIC symbol, such
       as a variable or constant name.  The choices for NAMETYPE are:

       PSYM

         Any PREPIC symbol.  This is the default if no NAMETYPE argument
         is given.

       EVAR

         System environment variable.

       FNAM

         File system name.  NAME can be a file, directory, or any other
         object implemented by the file system this program is running on.
         Symbolic links will be followed, and the function return value
         reflects the existance of the final translated pathname.

       FNAMNL

         File system name.  Symbolic links are not followed.

       ARG

         Execution block argument.  NAME must be a integer value, and
         represents the execution block argument number.  Arguments are
         numbered sequentially starting at 1.  See the CALL command
         description for more information on arguments.

  STR arg ... arg

       Returns the concatenation of the string representations of all
       arguments.  For example:

         [str "abc" 13 'def' 27.1] --> "abc13def27.10000"

  CHARS arg ... arg

       Returns the concatenation of the string representations of all
       arguments as a raw sequence of characters, not a string.  For
       example:

         [chars "abc" 13 'def' 27.1] --> abc13def27.10000

       This function can be used to "unquote" a string.

  QSTR characters

       Returns a quoted string.  NOTE: This function does not follow the
       normal rules for arguments.  The characters starting 2 columns
       after QSTR up to the "]" is enterpreted as one text string whether
       it contains blanks or not.  For example:

         [qstr This is a simple test.] --> "This is a simple test."

  CHAR arg

       Converts the integer argument to a single character of character
       code ARG, and returns the string containing only that character.

  UCASE arg

       Returns the string representation of ARG with all alphabetic
       characters upper case.

  LCASE arg

       Returns the string representation of ARG with all alphabetic
       characters lower case.

  SLEN arg

       Returns the number of characters in the string representation of
       ARG.

  SUBSTR st ln str

       Returns the substring of string STR that starts at character index
       ST and extends for LN characters.  The first character of a string
       has index 1.  The start and end of the substring is automatically
       clipped to be within the input string STR.  The empty string is
       returned if STR is empty.  Example:

         [substr 2 5 "This is a test"] --> "his i"

  SINDX ind str

       Returns the string containing only the character at index IND of
       string STR.  The first character of a string is at index 1.  The
       empty string is returned if the requested character is outside the
       input string.

  TNAM fnam

       Returns the full absolute treename of the file name FNAM.  Embed
       Inc portable pathname rules are used to interpret FNAM.

  LNAM fnam suff ... suff

       Returns the generic leafname of the file name FNAM.  The FNAM
       argument is required.  The SUFF arguments are optional, and are
       suffixes removed from the file name if present.  The first SUFF
       argument found in the file name is used.  For example:

         [lnam "c:\mystuff\virus.exe" ".bat" ".exe"] --> "virus"
         [lnam "c:\mystuff\virus.exe" ".bat" ".gif"] --> "virus.exe"

  EVAR name

       Returns the expansion of the environment variable NAME.  If the
       indicated environment variable does not exist, then the empty
       string is returned.  The returned data type is always STRING.

  PI

       Returns the value of Pi in floating point, 3.141592653589...

  + arg ... arg

       Computes the sum of all the arguments.  The result is integer 0 if
       no arguments are supplied.  The result data type is integer if all
       arguments are integers, and REAL if the arguments are a mix of
       INTEGER and REAL.  There may be a single TIME argument with the
       rest numeric.  In that case the result data type is TIME, and the
       value is the TIME argument plus the seconds represented by the sum
       of the remaining arguments.

  - arg1 arg2

       Computes the subtraction of ARG1 minus ARG2.  The result data type
       depends on the data type of the arguments:  If both data types are
       numeric, then the result is INTEGER if both are INTEGER, and REAL
       if at least one is REAL.  Some subtractions with TIME are allowed.
       When TIME and numeric data types are mixed, the numeric value
       represents a relative time in seconds.  Only certain operations on
       TIME values are allowed:

         TIME - numeric --> TIME, arg1 earlier by arg2 seconds
         TIME - TIME --> REAL, seconds from arg2 until arg1

  * arg ... arg

       Computes the product of all the arguments.  The result is integer 1
       if no arguments are supplied.  The result data type is integer if
       all arguments are integers, and floating point if one or more
       arguments are floating point.

  / arg1 arg2

       Computes ARG1 divided by ARG2.  The arguments may be either integer
       or floating point.  The result data type is floating point.

  DIV arg1 arg2

       Performs an integer divide of ARG1/ARG2.  Both arguments must be
       integer.  The result data type is integer.

  ABS arg

       Returns the absolute value of ARG.  ARG must be numeric, and the
       result will be the same data type as ARG.

  SIN ang

       Returns the floating point sine of the angle ANG in radians.

  COS ang

       Returns the floating point cosine of the angle ANG in radians.

  TAN ang

       Returns the floating point tangent of the angle ANG in radians.

  SQRT arg

       Returns the square root of ARG.  ARG must be numeric and >= 0. The
       result is always floating point.

  EXP arg1 arg2

       Computes ARG1 to the power of ARG2.  Both ARG1 and ARG2 must be
       numeric.  The result is integer if both arguments are integer, and
       floating point otherwise.  ARG1 must not be negative when ARG2 is
       floating point.

  LOG2 arg

       Returns the logarithm base 2 of ARG.  ARG must be numeric and
       greater than zero.  The result is always floating point.

  RDEG ang

       Converts the angle ANG from radians to degrees.  The result data
       type is REAL.

  DEGR ang

       Converts the angle ANG from degrees to radians.  The result data
       type is REAL.

  FFTC2 tcfilt sfreq

       Computes the filter fraction of a single pole low pass filter.
       TCFILT is the 1/2 decay time of the filter, and SFREQ is the sample
       frequency.  The filter fraction is the weighting fraction of the
       incoming signal each filter iteration.  The result data type is
       floating point.

  FFFREQ ffreq sfreq

       Computes the filter fraction of a single pole low pass filter.
       FFREQ is the desired -3dB rolloff frequency of the filter, and
       SFREQ is the sample frequency.

  FP24I val

       Converts the numeric value VAL to Embed Inc PIC 24 bit floating
       point and returns the result as a 6 character hex integer in native
       assembler format.  For example:

         [FP24I 3.14159] --> h'419220'

  FP val fmt ... fmt

       Converts the floating point value VAL to its string representation
       using specific formatting rules.  The remaining function parameters
       after VAL are converted to their string representations and
       concatenated to form the formatting string.  The formatting string
       contains commands that control the formatting of the output number.

       Formatting commands start with a command name keyword and are
       possibly followed by additional parameters depending on the
       command.  In general, later commands override earlier ones, which
       override the defaults. The formatting commands are:

       FW n

         Field width.  For N >= 1, the output string will be N characters
         wide.  N = 0 indicates free format, meaning the minimum number or
         necessary output characters will be used.

       FWE n

         Field width of the exponent part of the number if exponential
         notation is used.  0 = free form.

       SIG n

         Minimum significant digits required.  Default = 3.

       MXL

         Maximum digits allowed left of decimal point.  Default = SIG + 1.

       RIT n

         Fixed number of digits right of decimal point.

       MNR n

         Minimum required digits right of decimal point.

       MXR n

         Maximum allowed digits right of point.  May force use of
         exponential notation.

       EXP

         Force use of exponential notation.

       NEXP

         Prohibit use of exponential notation.

       ENG

         Use engineering format when exponential notation is used.  Causes
         the exponent to be a multiple of 3.  Default.

       SCI

         Do no use engineering format when exponential notation is used.
         The exponent is not restricted to a particular multiple.

       PNT

         Force decimal point to always be written, even if no digits to
         its right.

       NPTN

         Don't write the decimal point where there are no digits to its
         right.  Default.

       ZB

         Write zero before decimal if there would otherwise not be a digit
         there.  Default.

       NZB

         Don't write zero as only digit before decimal point.

       TZ

         Trailing zeros are allowed.  Default.

       NTZ

         Truncate trailing zeros.

       PLE

         Write plus sign before exponent if it is positive.

       NPLE

         Do not write plus sign before positive exponent.  Default.

       GRP

         Write digits in groups (commas every three digits for English).

       NGRP

         Do not write digits in groups.  Default.

       PL

         Write leading plus if number is positive.

       NPL

         Do not write leading plus if number is positive (default).

       LZ

         Fill fixed size field with leading zeros on left.

       NLZ

         Do not add leading zeros.  Blanks will fill fixed size field.
         (default).

  INT val fmt ... fmt

       Converts the integer value VAL to its string representation
       using specific formatting rules.  The remaining function parameters
       after VAL are converted to their string representations and
       concatenated to form the formatting string.  The formatting string
       contains commands that control the formatting of the output number.

       Formatting commands start with a command name keyword and are
       possibly followed by additional parameters depending on the
       command.  In general, later commands override earlier ones, which
       override the defaults. The formatting commands are:

       FW n

         Field width.  For N >= 1, the output string will be N characters
         wide.  N = 0 indicates free format, meaning the minimum number or
         necessary output characters will be used.

       PL

         Write leading plus if number is positive.

       NPL

         Do not write leading plus if number is positive.  Default.

       LZ

         Fill fixed size field with leading zeros on left.

       NLZ

         Do not add leading zeros.  Leading blanks will fill fixed size
         field.  Default.

       BASE n

         N is number conversion base (radix).  Must be 2 - 36.  Default is
         10 (decimal).

       USIN

         The input integer will be interpreted as unsigned.

       SIN

         The input integer will be interpreted as signed.  Default.

  RND arg

       Returns ARG rounded to the nearest integer.

  TRUNC arg

       Returns ARG rounded to the nearest integer towards zero.  This has
       the effect of "truncating" the fraction part of the value.

  SHIFTR val n

       Right shift VAL by N bits.  Both arguments must be integer.

  SHIFTL val n

       Left shift VAL by N bits.  Both arguments must be integer.

  < arg1 arg2

       Returns boolean true iff arg1 is less than arg2.  If either
       argument is of type STRING, then the string representation of both
       arguments is used for the comparison.  Otherwise both arguments
       must be numeric, or both must be of type TIME.

  <= arg1 arg2

       Returns boolean true iff arg1 is less than or equal to arg2.  If
       either argument is of type STRING, then the string representation
       of both arguments is used for the comparison.  Otherwise both
       arguments must be numeric, or both must be of type TIME.

  = arg1 arg2

       Returns boolean true iff arg1 is equal to arg2.  If either argument
       is of type STRING, then the string representation of both arguments
       is used for the comparison.  Otherwise both arguments must be
       numeric, both BOOL, or both TIME.

  >= arg1 arg2

       Returns boolean true iff arg1 is greater than or equal to arg2.  If
       either argument is of type STRING, then the string representation
       of both arguments is used for the comparison.  Otherwise both
       arguments must be numeric, or both must be of type TIME.

  > arg1 arg2

       Returns boolean true iff arg1 is greater than arg2.  If either
       argument is of type STRING, then the string representation of both
       arguments is used for the comparison.  Otherwise both arguments
       must be numeric, or both must be of type TIME.

  <> arg1 arg2

       Returns boolean true iff arg1 is not equal to arg2.  If either
       argument is of type STRING, then the string representation of both
       arguments is used for the comparison.  Otherwise both arguments
       numeric, both BOOL, or both TIME.

  NOT arg

       Returns the opposite of the boolean argument.  The result is always
       boolean.

  AND arg ... arg

       If all arguments are boolean, then this function returns the
       logical AND of the argument values.

       If all arguments are integer, then this function returns the
       bitwise AND of all values.

       The arguments must be either all integer or all boolean.  At least
       two arguments are required.

  OR arg ... arg

       If all arguments are boolean, then this function returns the
       logical OR of the argument values.

       If all arguments are integer, then this function returns the
       bitwise OR of all values.

       The arguments must be either all integer or all boolean.  At least
       two arguments are required.

  XOR arg ... arg

       If all arguments are boolean, then this function returns the
       logical exclusive OR of the argument values.

       If all arguments are integer, then this function returns the
       bitwise exclusive OR of all values.

       The arguments must be either all integer or all boolean.  At least
       two arguments are required.

  ~ arg

       Bitwise inversion, also known as the one's complement.  The
       argument must be integer and the result is integer.

  IF cond val1 val2

       Returns VAL1 when COND is TRUE, and VAL2 when COND is FALSE.  COND
       must be boolean.  VAL1 and VAL2 can be any data type.  The returned
       value is VAL1 or VAL2 with its data type unaltered.

  SEQ fnam [AFT] incr first

       Get the value of a sequence number file and update it accordingly.
       Sequence number files are described in detail in the SEQUENCE
       documentation file.  The returned data type is always INTEGER.

       FNAM is the name of the sequential number file.  The ".seq" suffix
       is implied and may be omitted.

       The AFT keyword is optional.  It indicates to return the sequence
       number after the increment is applied (value written back to
       sequence number file).  The default is to return the sequence
       number before the increment (value originally in file).

       INCR is the amount to increment the value in the sequential number
       file by.  It is optional and defaults to 1.

       FIRST is the original sequence number to use if the sequence number
       file does not exist or is empty.  FIRST is optional and defaults to
       1.

       The sequential number file is read and updated as one atomic
       operation.  Other concurrent attempts to access the file will
       result in operations wholly before or wholly after this one.  This
       inline function is intended for creating unique serial numbers,
       sequential build numbers, or the like.

  NOW

       Returns the current time.  The returned data type is TIME.

  DATE time [LOCAL] field arg ... arg

       Returns a string representing a particular part of a date/time.
       TIME is the time to convert.  The optional keyword LOCAL indicates
       that the result should be expressed in local time, not universal
       coordinated time.  FIELD is a keyword that identifies the
       particular string field of the date/time to return.  ARG are
       arguments specific to FIELD.  Different FIELD values require
       different arguments with different meanings.

       The FIELD keywords and their arguments are:

       YEAR

         The full year, like "2006".

       MNUM

         Two digit month number, like "07" for July.

       MONTH

         Full month name, like "July".

       MON

         Month name 3 letter abbreviation, like "Jul" for July.

       DAY

         Two digit day number within month, like "08".

       DAYWK

         Full day of week name, like "Tuesday".

       DWK

         Day of week 3 letter abbreviation, like "Tue" for Tuesday.

       HOUR

         Hour within day in 24 hour format, always two digits, like "18"
         for 6:00pm.

       MIN

         Minutes within hour, always two digits.

       SEC

         Seconds within minute, always two digits.

       SECF n

         Seconds with N fractional digits.