HP-67
      
    NAME
    hp67 - a scientific calculator in Reverse Polish
    Notation 
     
    SYNOPSIS
    hp67 [-n|--noexit] [--program=program|-p program]
    [--ignorercfile|-i] [--help|-h] 
     
    DESCRIPTION
    This program emulates an HP-67 calculator with a few minor
    variations. This calculator uses the 'Reverse Polish Notation'
    favoured by Hewlett-Packard.
    Reverse Polish Notation is somewhat different from the
    "forward" notation available on many, probably most, handheld
    calculators. It is the notation used by the Forth system of
    languages. Here are some examples of how the notation
    works:
    To evaluate: (3 + 4*7) / (2 + 8^3)
    You hit the following sequence of keys:
    
      - 
3  <ENTER>
4  <ENTER>
7  *
   +
2  <ENTER>
8  <ENTER>
3  y^x
   +
   /
 
The <ENTER> key is used to separate different numbers
    entered consecutively. As numbers are entered they are pushed
    onto a LIFO stack. The most recently entered number, at the top
    of the stack, is called the 'X' value, the next most recently
    entered number is the 'Y' value. On the screen the 'X' appears
    nearest the bottom, with 'Y' immediately above it. Unary
    operations such as 'sin' pop a single number (X) off the stack,
    act on that number, and push the result onto the stack. Binary
    operations such as '/' pop two numbers off the stack, and
    divide the first number popped (X) into the second (Y), then
    push the result onto the stack. This has the effect of reducing
    by one the total number of elements on the stack. Look over the
    above example until it's clear. Another register, 'LSTX', is
    not displayed on the stack. This holds the value which 'X' held
    before the last operation was made. Not all operations will
    update this number. LSTX is most commonly used in error
    correction, such as if you typed '*' instead of '/', and in the
    implementation of automatic constants.
     
    OPTIONS
    
      - -n, --noexit
- Disable the CTRL-D exit key. This behaviour is desirable
      if the program is run from within a dedicated xterm, such as
      via the following shell script:
- 
        #! /bin/sh # 
        /usr/X11R6/bin/color_xterm $@ -ls -tn xterm-color \ -e
        hp67 --noexit & 
- This script can then be invoked, for instance, as
      follows:
- hp67.sh -iconic -geometry +700+400
- to produce a dedicated xterm window which cannot be
      aborted, short of sending the program a killing signal.
- -p program, --program=program
- Load the program space with the named program during.
      Equivalent to issuing the command r/prog program from
      the keyboard immediately when the program begins.
- -i, --ignorercfile
- Don't preload any programs.
- -h, --help
- Issue a usage message and exit.
SPECIFICS OF THE HP-67 EMULATOR
     
    Command entry format
    Numbers must be entered alone on the line. They may be
    expressed in fixed or scientific notation. Examples of valid
    entries on the command line are:
    
      - 12.493 12.4e-5 .008E4 1.2E+4
Note that it is not normally possible to enter negative
    numbers directly at the command line prompt (but see the entry
    for '{' in the section on "magic" keys in curses mode.)
    Commands and operations may be entered alone on the command
    line, or immediately after a valid number, with argument if
    allowed. The argument must be separated from the command by one
    or more blanks or tab characters. Examples of valid commands
    and operations are:
    
      - 
+
sto speedoflight
dsp 9
fix
 
See the list of operations for details of which commands
    require operands.
    If an operation pops a non-existent stack element, it is not
    an error, a zero is obtained. Similarly, an attempt to read an
    uninitialized memory element returns a zero.
     
    Display layout
    The calculator requires at least an 80x22 screen to work,
    and the layout of buttons is most logical when the number of
    columns is exactly 80. The upper portion of the screen consists
    of buttons showing the currently valid commands to the
    calculator. The right side has a numeric keypad, while the
    lower-left portion is responsible for interaction with the
    user. The lower-middle portion shows the most recently accessed
    memory elements, up to 15 if the number of screen rows is large
    enough, and the first 8 characters of the element's label
    (assuming an 80 column screen).
    In immediate (interactive) mode, a number of stack elements
    are displayed in this region, with X at the bottom, Y above it,
    and higher elements above those.
    In program mode, the current insertion and run point is
    shown with an arrow to its left. Above and below it are
    neighbouring program elements. New elements are inserted after
    the position of the arrow, and when the calculator runs, the
    arrow always shows the next step which will be executed.
    A stepping mode also exists. If a program is interrupted
    with a keypress, or if "step" is entered in immediate mode,
    then the display shows part of the stack, and part of the
    program. The program window shows the next step which will be
    performed, the earlier step in the program memory (not
    necessarily the last step performed, if that was a branch), and
    the step after the next one to be performed. Every time "step"
    is entered, one program step is executed and the insertion/run
    pointer is updated.
     
    Curses magic behaviour
    When operating in curses mode, hp67 performs some extra
    actions for certain input sequences.
    The '#' is a comment character for almost all functions. The
    disk I/O functions ignore it, and so can load file names
    containing the character, but all other operations consider
    that the argument ends with the last non-whitespace before the
    '#' character appears. A comment may not be the only content of
    the input line.
    If a line of input begins with a character which identifies
    it as a number, such as a digit or decimal point, then it
    continues to accept characters until such time as one shows up
    which is not part of a valid float. The valid float is passed
    to the interpreter, while the remaining text waits on the input
    line. So, if the sequence "102s" is typed, it is as if the
    number "102", then <ENTER>, then "s" were typed. If the
    sequence "45e+l" is entered, it is interpreted as "45",
    <ENTER>, "e+l". Note that there is at present no command
    which begins "e+l", so this is likely not to appear in normal
    use. If the sequence "1e4e" is typed, it is interpreted as
    "1e4" (10000), <ENTER>, "e". This number watching allows
    one to avoid an extra keypress, it is legal to type "30 ENTER
    40 +", the result is seventy.
    Note that the following sequence on the command line: "3+4"
    <ENTER> may not do what you expect. This has the effect
    of pushing 3 onto the stack, adding it to whatever was on the
    stack before, then pusing 4 onto the stack.
    Now, the input line supports a few special command
    sequences.
    In the following, the notation "M-a" means "meta (lowercase)
    a". This sequence can be produced by holding down the ALT key
    on terminals which support this, or prefixing the 'a' keypress
    with ESC.
    The following are 'hot keys'. If they are entered in the
    first position on a blank input line their functions will be
    invoked:
    
      - <DELETE>
- In immediate mode, invokes the "clx" function to delete
      the top element of the stack. In program mode, deletes the
      current program line.
- M-<SPACE>
- In immediate mode, invokes the "step" function.
- M-<key>
- If <key> is a printable key, in immediate mode this
      invokes the command "run <key>", running a subroutine
      identified by the single letter label <key>. In program
      mode, this invokes the command "label <key>", creating
      an entry point identified by the single letter label
      <key>.
- <CTRL>-D
- In immediate mode, exits the calculator. In program mode,
      returns to immediate mode.
- UP-ARROW
- In program mode, moves the program insertion/execution
      pointer back one space.
- DOWN-ARROW
- In program mode, moves the program insertion/execution
      pointer forward one space (without executing the step).
- {
- As the first element on the line, the '{' character
      disables (for the current input line) the magic
      floating-point number parsing described above. This is
      intended for future expansion, when input types such as
      complex numbers may use different characters to mark input.
      It can be used to enter negative numbers at the command
      line.
- CTRL-L
- forces curses to redraw the entire window from scratch.
      Useful if the window is resized, or if some other output to
      the screen intrudes.
All control keys not listed above are filtered at the
    keyboard read stage and can never be embedded into labels or
    commands. The TAB key is immediately translated into a blank at
    read time.
    On terminals which support ncurses mouse events, the
    function list at the top of the screen, and the keypad on the
    right side, are both clickable to invoke the corresponding
    action. Commands which take no arguments are sent with an
    implied <ENTER> following them, so simply pressing the
    text of "sin" calculates the sine of the current X value.
    Commands which take arguments are sent with an implied BLANK
    following them, allowing the user to enter the argument.
    Numbers on the keypad, of course, are sent without
    modification.
     
    LIST OF COMMANDS
    The following commands are available either in programming
    or in user mode:
    
      - + --'Addition operator X <- Y + X LSTX
- This operator takes no arguments. It pops the top two
      elements of the stack and adds them together, pushing the
      result on the stack.
- - --'Subtraction operator X <- Y - X LSTX
- As above, but it subtracts.
- * --'Multiplication operator X <- Y * X LSTX
- As above, but it multiplies.
- / --'Division operator X <- Y / X LSTX
- ! --'Factorial operator X <- !X LSTX
- This operator takes no arguments. It replaces the value
      in the X register with the factorial of the number. The
      factorial is the product of all natural numbers less than or
      equal to the number. If the value in X is not an integer, it
      returns the real-number generalization of the factorial, the
      gamma function of 'X+1'. An error occurs if X is a negative
      integer, or if an overflow occurs.
- recip --'Reciprocal operator X <- 1 / X LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its reciprocal.
- chs --'Change sign operator X <- -X LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its negative value.
- sin --'Sine operator X <- sin(X) LSTX
- This operator takes no arguments. It repalces the value
      in the X register with its sine, where X is interpreted as an
      angle in the units of the 'THETA' flag. See below for
      information on changing this flag.
- cos --'Cosine operator X <- cos(X) LSTX
- As above, but for cosine.
- tan --'Tangent operator X <- tan(X) LSTX
- As above, but for tangent.
- asin --'Inverse sine operator X <- asin(X) LSTX
- As above, but for inverse sine.
- acos --'Inverse cosine operator X <- acos(X) LSTX
- As above, but for inverse cosine.
- atan --'Inverse tangent operator X <- atan(X)
      LSTX
- As above, but for inverse tangent.
- sqrt --'Square root operator X <- sqrt(X) LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its square root. This won't work for
      negative numbers.
- square --'Square operator X <- X ^ 2 LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its square.
- ln --'Natural logarithm operator X <- ln(X) LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its natural logarithm.
- exp --'Exponential operator X <- exp(X) LSTX
- This operator takes no arguments. It replaces the value
      in the X register with e^X.
- log10 --'Base 10 logarithm X <- log(X) LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its base 10 logarithm.
- exp10 --'Power on 10 operator X <- 10^X LSTX
- This operator takes no arguments. It replaces the value
      in the X register with 10^X.
- y^x --'Power operator X <- Y ^ X LSTX
- This operator takes no arguments. It replaces the value
      in the X register with the value Y^X. This returns errors if
      X is negative and Y is not an integer, or if X is zero and Y
      is less than or equal to zero.
- abs --'Absolute value operator X <- abs(X) LSTX
- This operator takes no arguments. It replaces the value
      in the X register with its absolute value.
- dsp --'Set display precision
- This operator takes one argument, an integer between 0
      and 14 inclusive. In 'fix' and 'sci' modes this sets the
      number of digits to appear to the right of the decimal point.
      In 'eng' mode this sets the total number of digits to appear
      on the screen to 'n+1'. In other words, changing from 'sci'
      to 'eng' mode does not change the precision of the display.
      This operator is available with indirection. If the argument
      is "(i)" it will set the number of digits to the greatest
      integer value of the I register, if that value lies in the
      correct range.
- fix --'Set fixed display mode
- This operator takes no arguments. It sets the display of
      stack elements to fixed point notation. Numbers which cannot
      be displayed in this notation in the precision specified by
      'dsp' will be displayed instead in scientific notation.
- sci --'Set scientific notation display mode
- This operator takes no arguments. It sets the display of
      stack elements to scientific notation. In this form all
      numbers are written with a single digit preceding the decimal
      point, and a four digit exponent on the right of the
      display.
- eng --'Set engineering notation display mode
- As above, but between one and three digits precede the
      decimal point, and the exponent is always a multiple of
      three.
- hex --'Set hexadecimal display mode
- In hexadecimal mode, all numbers are displayed in
      hexadecimal format, as the next integer closer to zero (i.e.
      rounding down for positive values, and up for negative
      values). In hexadecimal mode the magic input completion is
      disabled, and numbers can be entered as either octal,
      decimal, or hexadecimal integers. A number beginning with
      '0x' is interpreted as hexadecimal, otherwise a number
      beginning with '0' is octal. In all other cases the number is
      treated as a decimal value.
- deg --'Set degrees mode THETA = degrees
- This operator takes no arguments. It sets the internal
      'THETA' flag to degrees. All subsequent angles are
      interpreted in units of degrees, and functions which return
      angles return them in degrees.
- rad --'Set radians mode THETA = radians
- As above, but it sets angles to radians.
- grd --'Set gradians mode THETA = gradians
- As above, but it sets angles to gradians. There are 400
      gradians in a circle, and if you use this mode even once I'll
      be surprised.
- sto --'Store to memory register <label> <-
      X
- This operator takes a single argument. That argument can
      be any string which does not contain a '#' and does not begin
      with a '.'. The current X value will be written into the
      memory identified by this label. If no such memory register
      exists, it is created. This operator can also use indirect
      addressing. If the label is "(i)", the current value of the I
      register is extracted, converted to an integer, then to a
      character string, and passed as if it were the argument typed
      on the command line. So, if I holds the value 214.1, the X
      register is stored to the memory element labelled "214".
- rcl --'Recall from memory reg. X <- <label>
- As above, but it recalls from memory and pushes the
      number obtained onto the stack. The current X value is not
      lost, it is merely pushed up with the rest of the stack.
- sto+ --'Add to memory register <label> <-
      <label>+X
- This operator takes one argument, the memory label. It
      acts like the register, it adds the current X value to it.
      This operation is available with indirection.
- sto- --'Subtract from memory reg. <label> <-
      <label>-X
- As above, but it subtracts X from the memory
      register.
- sto* --'Multiply into memory reg. <label> <-
      <label>*X
- As above, but it multiplies X into the memory
      register.
- sto/ --'Divide into memory reg. <label> <-
      <label>/X
- As above, but it divides X into the memory register.
- x<>y --'Swap X and Y X <--> Y
- This operator takes no arguments. It exchanges the X and
      Y elements on the stack. This is useful, for instance, if you
      want to evaluate X^Y. You can first swap X and Y, then use
      the 'pow' operator.
- r>p --'Rectangular to polar conversion LSTX
- 
        This operator takes no arguments. It converts the pair
        (X,Y) into polar form. 
        
          - 
               X <- sqrt(X^2 + Y^2)
               Y <- atan2(Y,X)
 
- p>r --'Polar to rectangular conversion LSTX
- 
        This operator takes no arguments. It reads the X register
        as a distance and the Y register as an angle, and converts
        to cartesian form. This has the effect: 
        
          - 
                X <- X * cos(Y)
                Y <- X * sin(Y)   
 
- The former Y value is lost.
- d>r --'Degrees to radians conv. X <- X * 180/pi
      LSTX
- This operator takes no arguments. It converts the value
      in the X register from degrees to radians. Note that it does
      not change the value of the 'angmode' internal flag.
- r>d --'Radians to degrees X <- X * 180/pi LSTX
- This operator takes no arguments. It converts the value
      in the X register from an angle in radians to one in degrees.
      Note that it does not change the value of the internal
      'THETA' flag.
- pi --'Numerical value of pi X <- pi
- This operator takes no arguments. It is shorthand for
      entering the first 19 decimal places of 'pi'. It pushes 'pi'
      onto the stack. The X register is not lost, it moves into the
      Y register, and so on down the stack.
- h>hms --'Hours to hours/minutes/seconds conversion
      LSTX
- This operator takes no arguments. It reads the X register
      as a number of hours, and converts it to hh.mm.ssss form. See
      the 'hms+' and 'hms>h' operators description for more
      information.
- hms>h --'Convert hours/minutes/seconds to hour
      LSTX
- This operator takes no arguments. It reads the X register
      as a number in hh.mm.ssss form and converts the result to a
      fraction of an hour. So, 1.30 would become 1.5, since one
      hour and thirty minutes is equal to an hour and a half.
- hms+ --'Add in hours/min/sec fmt. X <- X + Y hms
      LSTX
- 
        This operator takes no arguments. It adds X and Y as if
        they were in the form: hh.mmssss. That is, the integer part
        of the number is taken as hours, the first two digits after
        the decimal point are taken as minutes, and all digits
        after that are interpreted as seconds. For instance,
        3.182014 would become 3 hours, 18 minutes, 20.14 seconds.
        After the addition, the result is adjusted so that the
        seconds and minutes fields do not equal or exceed sixty.
        For example: 
        
          - 
        1.4020   <ENTER>
        1.3052
        hms+
 
- yields: 3.1112
- int --'Integer roundoff X <- (int)X LSTX
- This operator takes no arguments. It rounds the number in
      the X register to the next integer closer to zero.
- frac --'Fractional part X <- frac(X) LSTX
- 
        This operator takes no arguments. It discards the integer
        portion of X. If X is negative, it still discards the whole
        part, so that 
        
          
 frac(-1.2) = -0.2
 
- round --'Round off to displayed value
- This operator takes no arguments. It rounds off the value
      in the X register to the actual value displayed on the
      screen. If the X register holds 1.2284, and the display mode
      is 'fixed' and 'dsp 2', then the screen will display the
      value '+1.23'. The 'rnd' function rounds off the internal
      representation to match.
- rci --'Recall from I register
- This operator takes no arguments. It pushes the current I
      value onto the stack, pushing the rest of the stack down to
      accomodate it.
- sti --'Store in I register I <- X
- This operator takes no arguments. It stores the current X
      value in I. The former value of I is lost, nothing else is
      changed. Note that this function cannot be replaced by "sto
      (i)" as that would invoke the indirection behaviour of the
      "sto" function.
- dsz --'Decrement; skip if zero I <- I - 1
- This operator takes no arguments. It decrements the I
      register. If a program is executing, and the I register is
      zero after the decrement, then the next program step is
      skipped.
- dsz(i) --'Decrement indirect; skip if zero
- This operator takes no arguments. It decrements the
      memory register whose label matches I. If the register is
      zero after the decrement and a program is executing, the next
      program step is skipped.
- isz --'Increment; skip if zero I <- I + 1
- As 'dsz', but it increments the register.
- isz(i) --'Increment indirect, skip if zero
- As 'dsz(i)', but it decrements the register.
- x<>i --'Exchange X and I X <--> I
- This operator takes no arguments. It exchanges the
      current X and I values.
- stat+ --'Add statistical data pair LSTX
- This operator takes no arguments. It takes the current X
      and Y values and updates internal registers containing the
      sum of: X, X^2, Y, Y^2, and X*Y. The X value is replaced by
      the total number of data pairs collected. This function can
      also be used if you are only processing X values, rather than
      X,Y pairs. Just ignore the results from the 'Y' values. This
      operator updates memory elements accessible to any running
      program. These are, "_stats_sumx", "_stats_sumx2",
      "_stats_sumy", "_stats_sumy2", "_stats_sumxy", "_stats_n",
      and contain the sum of values of X, X squared, Y, Y squared,
      X * Y, and the number of points, respectively.
- stat- --'Subtract statistical data pair LSTX
- As above, but it subtracts out the values from the
      internal registers. This is usually used to remove erroneous
      data pairs entered with 'sum+'.
- avg --'Obtain average X and Y values LSTX
- This operator takes no arguments. It replaces the current
      X and Y values with the average values of X and of Y entered
      with 'sum+'.
- sdev --'Obtain standard deviation of X and Y values
      LSTX
- This operator takes no arguments. It replaces the current
      X and Y values with the standard deviations of X and of Y
      entered with 'sum+'.
- % --'Percentage operator X <- Y * X/100 LSTX
- This operator takes no arguments. It multiplies the top
      two elements on the stack, and then divides by 100.
- %chg --'Percent change operator X <- (X-Y)*100/Y
      LSTX
- This operator takes no arguments. It changes the value in
      the X register to the percentage of Y by which X differs from
      Y.
- clx --'Clear X value X <- Y
- This operator takes no arguments. It pops the stack,
      discarding the X value and promoting the former Y value to
      the new X value. Note that this is subtly different from the
      clear operator on the HP-67, repeated invocations of which do
      not clear the entire stack.
- rdown --'Roll stack down
- This operator takes no arguments. It rolls the stack so
      that the X value goes to the bottom of the stack, and all
      other registers move up one position, making the former Y
      value into the new X value. This differs from the HP-67 roll
      down operator in that it rolls only active stack elements.
      The HP-67 has a stack size of four, and the X register is
      always moved into the fourth position, even if fewer than
      four stack elements were in use.
- rup --'Roll stack up
- This operator takes no arguments. It rolls the stack so
      that the bottom stack element moves into the X position, and
      all other stack elements move one level deeper. This differs
      from the HP-67 operator in the same way as 'rdown'
      above.
- lastx --'Retrieve LastX register
- This operator takes no arguments. It pushes the current
      contents of LSTX onto the stack.
- clstk --'Clear stack space
- This operator takes no arguments. It deletes all stack
      elements.
- clreg --'Clear memory registers
- This operator takes no arguments. It deletes all memory
      registers, freeing the memory and returning it to the
      machine.
- goto --'Move the program counter to a position
- This operator takes one argument. It moves the program
      counter to the label or line number represented by the
      argument. Line numbers are in the form of a decimal point
      followed immediately by a numeric string. Valid labels cannot
      begin with a decimal point, so there is no ambiguity. It can
      be invoked with indirection, in which case it searches for
      the label which matches the integer value of the I register,
      for positive I, or steps back exactly N steps for negative I,
      where N is the value of int(I).
- R/S --'Run/stop
- This operator takes no arguments. It halts program
      execution immediately and returns to user mode. The current
      return stack is not lost, so the program can be stepped
      through from this point without losing subroutine
      information. The program will continue after this instruction
      if 'run' is entered without arguments. Note that a running
      program hitting a R/S statement is, technically, an error, so
      the calculator will sound or flash an alert if the terminal
      supports that.
- sf --'Set flag
- This operator takes one or two arguments, the first one a
      label or the indirection operator, and sets a binary flag
      with that label identifier. If the argument list ends in the
      string " clr", then this is stripped from the label and the
      resulting flag is a clear-on-test flag. The clear-on-test
      status is updated every time that the 'sf' operator is
      called, so a given flag can be clear-on-test in one part of
      the program, and explicit-clear-only in another. The program
      keeps a list of all set flags. This is used to pass
      information (usually on flow) between different parts of a
      program. If the flag is already set it has no effect.
- cf --'Clear flag
- Unsets the flag named by the argument. If the flag was
      not already set it is not an error.
The following commands are available only in immediate
    mode:
    
      - run --'Run a program
- This operator can take one argument, or no arguments. If
      invoked with no arguments it runs from the current program
      counter location. If invoked with an argument it runs from
      that label. If the target label is a single character it can
      be invoked with the M-<key> hot key.
- While a program is running it can be stopped by pressing
      any key.
- prog --'Enter programming mode
- This operator takes no arguments. It allows the user to
      key in programs. hp67 re-enters user mode when 'immed' is
      entered.
- step --'Step through a program
- Executes the command under the current insertion pointer,
      and advances the pointer to the next element.
- r/prog --'Load a program from a disk file
- This operator takes one argument, the pathname of the
      text file which contains the program to load. The program
      loaded is inserted after the current program counter
      location. Care should be taken that this doesn't insert it
      into the middle of another program segment, or that one will
      be trashed efficiently. This function cannot be used inside a
      program, and one loaded file cannot call another file to
      load.
Variables and memories can be loaded this way also. When
    loading the program starts out in programming mode, but if the
    token 'immed' appears in the file then subsequent lines are
    interpreted as if they had been issued in immediate mode. They
    can put numbers on the stack, act on them with operators, store
    them to memory labels, exactly as if the commands had been
    typed at the keyboard. A later 'prog' token can switch back to
    programming mode. The file is parsed until an error or the end
    of file is encountered. Be careful not to leave a blank line at
    the end of the file, since a blank line is interpreted as the
    <<~ENTER~>> command.
    
      - w/prog --'Save program elements
- This operator takes one argument, the pathname of the
      text file which should be written with the program
      instructions. The text is written out, including
      comments.
- w/data --'Save memory elements
- This operator takes one argument, the pathname of the
      text file which will be used to store non-zero memory
      elements. The format is compatible with the input required
      'r/prog' operator, so loading the file with that command
      restores the memory as it appeared when the present when the
      file is re-loaded, unless those elements have the same label
      as the ones being loaded. Note that there is a possibility
      for unexpected behaviour here, if a program element existed
      and was exactly zero, then was saved, and re-loaded after the
      element was assigned a non-zero value, then the new value is
      not reset to zero. To ensure that the program memory is
      exactly the same as that which was saved, it is recommended
      that you invoke 'clreg' before loading the memory.
The following commands are available only in programming
    mode:
    
      - label --'Create a label
- This operator takes one argument, a printable ASCII
      string which does not begin with a period. It is used as the
      target of branches and M-<key>.
- gosub --'Go to a subroutine
- This operator takes one argument, a valid label or the
      indirection notation. It pushes the return address onto an
      internal stack and continues execution from the label. The
      'rtn' statement returns from the subroutine. As with other
      features of this program, subroutine nesting is limited only
      by the total memory available.
- rtn --'Return from a subroutine
- This operator takes no arguments. It pops a return
      address and continues execution from there. If there are no
      more entries on the stack it returns to the user mode.
- f? --'Check flag
- This operator takes one argument. If the flag pointed to
      by the label is not set then the next program step is
      skipped. If the flag is a clear-on-test flag, then it is
      cleared.
- x==0 --'Check X=0?
- This operator takes no arguments. If the value contained
      in the X register is not zero then the next program step is
      skipped.
- x==y --'Check X=Y?
- As above, but the condition for executing the next
      program step is that X must equal Y.
- x!=0 --'Check X not equal to zero?
- See above, you figure it out.
- x!=y --'Check X not equal to Y?
- See above, you figure it out.
- x<0 --'Check X is negative?
- See above.
- x<=y --'Check X is not greater than Y?
- See above.
- x>0 --'Check X is positive and non-zero?
- See above.
- x>y --'Check X is greater than Y?
- See above.
- clprg --'Clear program space
- This operator takes no arguments. It can only be executed
      from programming mode. It erases all program elements.
- immed --'Exit programming mode
- This operator takes no arguments. It exits programming
      mode and enters user mode. <CTRL>-D is a shorthand hot
      key for this.
MORE NOTES ON PROGRAMMING HP67 CALCULATOR
    This program maintains the concept of a program counter. The
    program counter marks the place where the next program step
    will be inserted if you're writing a new program, and marks the
    place where the next instruction will be executed in user or
    stepping mode. It is incremented immediately before the current
    command is executed. If the program hits an 'rtn' statement,
    then, the program counter is pointing to the statement after
    the calling 'gosub' when it returns. Typing 'run' without
    arguments at this point will send the program on from
    there.
    When the user or program issues a 'goto label' command the
    label is searched forward from the statement after the current
    program counter, if necessary cycling round at the end and
    coming back from the first program location, until it either
    finds the label or returns to its starting point. The latter
    results in an error. Notice that labels need not be
    unique, and the 'goto', 'gosub', and 'run' statements will
    all branch to the first label after the current program counter
    which matches the search string. A 'goto .linenum' command has
    no such ambiguity, as all line numbers are necessarily
    unique.
    The return address stack is flushed out when any one of the
    following occurs:
    
      - 1)
- the user enters 'prog' mode and deletes or adds a
      step.
- 2)
- the user issues a 'load' command which changes program
      memory.
- 3)
- the user isses a 'run' or 'step' command with a label. If
      no label is given the stack is NOT cleared.
If the return stack is cleared a subroutine or two deep into
    your program you will not be able to resume it and expect it to
    run to completion. The next 'rtn' statement, instead of
    returning to the calling gosub, will return to user mode
    instead.
    When writing functions which might be used as subroutines
    later, take care to choose variable names which are unlikely to
    collide with those of the caller, for instance by appending to
    all names a string identifying the function of the module. If I
    implement name scoping at some future time this won't be so
    critical. If the function modifies the I register, that value
    should be saved on entry and restored just prior to exit, so
    that the calling function's behaviour is not affected.
    The R/S command can be used as a breakpoint. Insert it in
    the program, and execution will halt when it hits that line,
    then you can step through with the "step" function, or press
    "run" and the program will continue from the point following
    the breakpoint. Also, by putting R/S immediately after a
    decision command like "x>y", "f?", or "x==0" you can make
    conditional breakpoints.
     
    MAGIC TO KEEP IN MIND
    The memory label "(i)" (without the quotation marks) is
    special. Any attempt to assign to it or read from it results,
    instead, in access to the memory element whose label is the
    string representation of the integer value of the I register.
    To change or retrieve the value of the I register, the sti or
    rci functions must be used.
    Similarly, the goto label "(i)" and flag "(i)" are special,
    see above.
    The statistical functions update special named memory
    elements, see the description of "stat+".
    Labels cannot begin with a '.'
    The '#' character begins a comment.
    Flags can be made to clear on test.
     
    FILES
    
      - $HOME/.hp67rc
- This file, if it exists, is read in as a preloaded
      program file, unless overridden by command line arguments or
      the HP67PROGRAM environment variable.
ENVIRONMENT
    
      - HP67PROGRAM
- This variable, if set, contains the name of the program
      file to read when the emulator starts up, unless overridden
      by command line arguments. If this variable is set, and the
      $HOME/.hp67rc file exists, then the latter will be
      read only if the former does not resolve to a readable
      file.
ABOUT THE PROGRAM
    Version 1.0 completed Feb 11, 1997 
    Copyleft GPL 1997 by Christopher Neufeld
    Distribute freely so long as this file is included.
    This program is essentially a re-write of the RPN classic
    desk accessory for the Apple ][GS which I released in 1993. If
    anybody out there has actually used the CDA version, please let
    me know.
     
    AUTHOR
    Christopher Neufeld 
     
    
    
      
    Index
    
      - NAME
- SYNOPSIS
- DESCRIPTION
- 
        
          - OPTIONS
 
- SPECIFICS OF THE HP-67 EMULATOR
- Command entry format
- Display layout
- Curses magic behaviour
- LIST OF COMMANDS
- MORE NOTES ON PROGRAMMING HP67
      CALCULATOR
- MAGIC TO KEEP IN MIND
- FILES
- ENVIRONMENT
- ABOUT THE PROGRAM
- AUTHOR