This is the initial release of my HP-67 emulator. I got my HP-67 in
1983, secondhand. The calculator was manufactured in 1976, and still
runs perfectly. I'm used to it, I like it, and I haven't seen this
functionality in any UNIX tool I've come across, so I've now written
yet another HP-67 emulator (the first one I wrote in 1993 to run on my
Apple ][GS).

Here's what you'll find in this archive:

Changes        : a file of changes to the HP-67 program over time.

Differences    : a file of notable differences between this emulator
	and the actual HP-67. Potentially useful for anybody who wants
	to port over programs from the HP-67 program listing manual.

FAQL           : a list of anticipated questions, and my answers.

README         : that's what you're doing now.

TODO           : desirable improvements not yet done.

arguments.cc   : Parsing of the command line arguments and preload
	program name.

calcfloat.cc   : the C++ source code for the CalcFloat class 
	implementation.

calcfloat.h    : the CalcFloat class header.

config.h       : controls compiled-in features which do not govern the
	calculator's behaviour, such as which user-interface(s) to
	create.

datatypes.H    : pure method definition for calculator data types

flags.h        : the Flags class header and implementation.

hp67           : the binary executable, dynamically linked against
	libm.so.5.0.9, libc.so.5.4.44, libncurses.so.4.2,
	libg++.so.27.2.1, and libstdc++.so.27.2.1.

hp67.1         : The file docs.txt in groff format, as a man page.

hp67.h         : some configuration defines and enumerated types.

hp67.lsm       : The LSM entry for Linux archives.

hp67.static    : the binary executable, dynamically linked against
	libm.so.5.0.9, libc.so.5.4.44, libncurses.so.4.2,
	and statically linked against libg++.so.27.2.1 and
	libstdc++.so.27.2.1. This is for those people without a C++
	compiler on their system.

hp67funcs.cc   : the action functions associated with calculator
	commands.

hp_curses.h    : some ncurses configuration and definitions.

hp_prots.h     : prototypes.

hpglobals.h    : definitions of global variables.

hyperbolics.txt: a sample program of hyperbolic functions. Load with
	r/prog and execute with "run sinh" etc.

input.cc       : implementation of the input/output methods. Currently
	only ncurses input is defined.

input.h        : definition of pure method for I/O, and header for all
	implemented I/O methods.

integrator.txt : a sample program performing Simpson's rule
	integration. See below for details.

layout.h       : the layout of the ncurses screen is defined by macros
	in this file.

main.cc        : the toplevel program.

makefile       : the makefile

memory.h       : the template defining associative arrays.

parsers.cc     : parsers for arguments to commands.

progmem.cc     : the implementation of the program steps, program
	space, and calculator functions.

progmem.h      : the header for the program steps, program space, and
	calculator functions.

stack.h        : the template defining stack space.





=== About the integrator sample program:


   The integrator.txt sample program is based on the "CALCULUS AND
ROOTS OF f(x)" program card supplied with the HP-67. It can find the
integral, derivative, or root of a supplied function. The supplied
function must be invocable via a numbered label. If the function is
already coded, and doesn't use a numbered label, then simply create a
two-line sequence in the program space such as:

label 1
goto my_function_has_an_alphabetic_label

Then, a call to function 1 just calls the other function with the
long, alphabetic label.

   To use the sample integrator package:

run hp67
enter the following:   r/prog integrator.txt

next, create a sample function, let's say 2/sqrt(pi) * e^{-x^2}
Enter this sequence:
prog
label 1
square
chs
exp
2
*
pi
sqrt
/
rtn
immed

You are now back in immediate mode, with the function called "1". Note
that if you typed "prog" and the line below the one pointed to by the
arrow did not say "<<< END OF PROGRAM SPACE >>>" then you should move
the insertion point by pressing the up and down arrow keys until that
is the case.

   Next, enter the following:

1
run set_fn_number

This tells the integrator that we will be using the function referred
to by the label "1" for all of our calculations.

To integrate that function, using Simpson's rule, with 100 intervals,
on the interval from 0 to 1, enter the following:

0
1
100
run simpson_int

The X stack element now holds the integral of the function. The
Simpson's rule integrator evaluates the function 2*(N+1) times.

   Next, find the derivative of the function at x=1:

1
run deriv_int


To demonstrate the root finder, we need a function which has
roots. So, enter the following:

goto .000

This sets the insertion mark to the line number 0. Next, use "prog" to
enter program mode, and press the up-arrow key twice. This puts you at
the end of the program space. Enter the following sequence, still in
program mode:

label 2
gosub 1
0.5
-
rtn
immed
sci

This brings you back to immediate mode with a new function, number 2,
defined as function 1 less a half. We've also set the display mode to
scientific, it's more useful for root finding because the displayed
numbers are used as an exit condition, to decide when an answer is
close enough.

   To find a root of function 2:

2
run set_fn_number

Next, you have to make a guess. Let's say that the root is somewhere
around 1.1:

1.1
run root_int


It has now computed the root of the function.  You should see the
value:
9.02  -001
That means 9.02 * 10 ^ (-1), or 9.02E-1.

However, the root is only accurate to the precision displayed on your
screen. In other words, if you wanted the root known to three digits,
you would enter "sci" mode and then set the display digits with "dsp
2". If you wanted the root to ten digits, you would have to set "dsp
9". You can do that now, and feed the result of the previous root
finding attempt in to refine your guess.

dsp 9
run root_int

It should now display:
9.021803690  -001

The analytic solution gives the following:

9.0218036899236  -001


   There is one other entry point to the package, obtained with

run deltasize_int


This takes the current X value and uses it to assign the differential
x which will be used to compute derivatives, "new_delta_int". The root
finder also takes derivatives, and it is possible for some functions
to behave badly in the root finder for the default value of
"new_delta_int". The meaning of this variable is that, when a
derivative of 'x' is being computed, its value is obtained as follows:

f'(x) =
   ( f(x * (1 + delta_x / 2)) - f(x * (1 - delta_x / 2)) ) / (x * delta_x)

The default value is 0.00005, so the derivative at x=1000 is computed
by taking (f(1000.025) - f(999.975)) / 0.05

   If you are having trouble with roots or derivatives with the
default value of new_delta_int, just enter a new value and run the
deltasize_int function.



==================================================

Tips on using preload files:

As of version 1.3, the HP-67 emulator has the ability to pre-load
program files when invoked. If given a command line argument in the
form "--program=NAME" or "-p NAME", then the program file NAME is
loaded at startup. If this switch is not given, and the environment
variable HP67PROGRAM is defined and holds the name of a file readable
by the user, then that file is loaded as the startup. Finally, if the
HP67PROGRAM environment variable doesn't exist, or does not hold the
name of a user-readable file, then the file $HOME/.hp67rc is loaded,
if it exists.

This structure is fairly flexible. If the HP67PROGRAM environment
variable holds a relative pathname, then the emulator can be made to
load different files depending on the current working directory. For
instance, if "HP67PROGRAM" is set to "localhp67prog", then whenever
the calculator is invoked from within a directory containing that
file, the file is loaded, otherwise the $HOME/.hp67rc file is
loaded. This behaviour can be overridden with the "-p NAME" switch, or
all preloading disabled with the "-i" switch.

The most common use for these preload files will probably be to define
your own shortcuts. For instance, there is no quick way to enter
negative numbers in the calculator. You have to enter the number, then
click on the "chs" button, or enter "chs" at the keyboard then press
ENTER. If your $HOME/.hp67rc file contains the lines:

label c
chs
rtn

then pressing ALT-c (or ESC-c) will change the sign of the current
number. Similar shortcuts can be used, say, for sines and cosines,
logarithms, square roots, or any other sequences which the user finds
convenient. Of course, a shortcut key can do more than just invoke a
single keypad function, there is a rich programming language available
which includes flow control, breakpoints, and step-through debugging.

==================================================


If anybody finds this emulator useful, let me know. I'm partial to
text interfaces, but if enough people say they're interested in an X
interface, I'll write one.


Christopher Neufeld
Nov 25, 1997

