EQStk 9.1+
modified version of EQStk 9.1. Adds a 7 level interactive stack, see at 
the end of the document for further details.



				EQSTK v9.1

		Equation Writer Stack Display for the HP48

	(c) 1995 by Mika Heiskanen & Claude-Nicolas Fiechter

0.0 DISCLAIMER
==============

EQSTK is distributed in the hope that it will be useful, but the
copyright holders provide the program "as is" without warranty of any
kind, either expressed or implied, including, but not limited to, the
implied warranties of merchantability and fitness for a particular
purpose. In no event will the copyright holders be liable to you for
damages, including any general, special, incidental or consequential
damages arising out of the use or inability to use the program. So there.


1.0 OVERVIEW
============

EQSTK provides an alternative to the built-in stack displayer, with the
main advantages of being capable of displaying equations in similar form
as the built-in Equation Writer. The display also can handle symbolic arrays
in the form they are defined in most symbolic math packages, such as ALG48.


2.0 INSTALLATION
================

EQSTK library works in any port of a HP48G(X) or S(X), with no speed loss
when being run from a covered GX port.

To install EQSTK on your HP48 download the file 'eqstk.lib' to your
calculator and store in it a port of your choice. For example to store
the library to port 0, type in (or press suitable keys)

	'eqstk.lib' DUP RCL SWAP PURGE 0 STO

and power-cycle the calculator. The library will autoattach itself to
the HOME directory.

Installing a universal font library containing a small font is recommended as
it makes displays using lower case characters much better. EQSTK uses the
library only if it is stored in a visible port though.

	**********************************************
	* EQSTK requires the universal font library  *
	* with small and medium fonts to be present. *
	**********************************************

The package also includes a smaller version of the library named
'eqstkb.lib', which does not have the following functionality:

    o All features documented in section "User Functions"
    o Special symbols for identifiers Phi, phi etc listed in "Global name"
    o Dot indicates subscript as explained in "Global name"

Enabling any single feature again from above is possible by editing and
recompiling the source code distributed with the package.


3.0 COMMANDS
============

3.1 AGROB
---------

Stack:	( ob maxsize --> grob )

AGROB takes an object from stack, along with the desired maximum font size,
and converts the object into a grob. If the object is an algebraic expression
or of some other suitable type, equation writer form output is produced.

The size argument should be a real number in the range 1 to 3, where 3
specifies the maximum possible starting font size.


3.2 ASTK
--------

Stack:	( --> )

ASTK command starts an alternative loop to provide the full functionality of
the HP48, with the exception of changed display.

ASTK displays the menu as usual, but the stack no longer has any size limit.
Most importantly, the status area is not shown at all unless the area is
flagged as frozen, for example when a keypress generates an error. How many
stack levels are shown depends only on the size of the objects being
displayed in their AGROB form.

When ASTK is started for the first time, it will use the medium font as the
maximum font size to use when calling the agrob subroutines. Any further
executions will only toggle an internal flag in the already running ASTK
to toggle the maximum font between the smallest and the medium fonts.

To exit ASTK simply press the CONT key (left-shift ON).

Note that ASTK does not modify any other keys than CONT, thus for example
the interactive stack still uses the regular display loop.


4.0 IMPLEMENTATION DETAILS
==========================

4.1 AGROB Parser
----------------

AGROB uses the internal ->STR subroutines to decompile objects, with the
following exceptions:

Tagged Objects
--------------

The tag is ignored, and thus the test defaults to testing for the following
list of exceptions.

Grobs
-----

Grobs already are in the required form, so nothing is done.

Global name
-----------

Global names are displayed without the '' delimiters. Also subscripts
can be generated as follows:

	-  By having an embedded dot character in the identifier.
	   The first part of the name forms the actual displayed name.
	   The second part of the name forms the subscript which is
	   displayed in a smaller font. The second part can also have
	   further dots to generate a subscript for the subscript itself.
	-  By having trailing decimal digits in the name. The digits
	   will form the subscript in a smaller font.

In the following examples the decreasing font size is left to the
imagination of the reader:

	X.Y.Z	==>	X		X1	==>	X
		         Y				 1
		          Z

Due to the restricted internal font, and for easy access to some symbols the
following names create special grobs:

	Psi, Phi, phi, Gamma, GAMMA, Planck, Nabla, Blank, Cont

In addition the infinity and small omega symbols default to built-in grobs
due to the bad representation they have in the UFL small font. The user
should try typing above names when ASTK is active to see what the results
are.


Local variable names
--------------------

Local variable names are displayed without the '' delimiters.

Units
-----

Units are shown as in the built-in Equation Writer. For example:

			  m
	1_m/s	==>	1_--
			  s
Arrays
------	

Arrays having more than two dimensions are shown using the internal ->STR.
For one or two dimensions the objects in the array are decompiled using
the general rules for AGROB, the results are then arranged in a grid and
are surrounded with brackets. One dimensional arrays are shown as column
vectors.

Lists
-----

An empty list is displayed using the internal ->STR.

If the list contains no lists the list is shown as a column vector
with surrounding parenthesis.

A list of lists all of equal lenght is considered a two dimensional
array, and execution is similar as for arrays with the exception of
using surrounding parenthesis instead of brackets.

Otherwise the list is displayed using the internal ->STR.

Algebraics
----------

All objects inside the algebraic are displayed using the regular rules. The
functions in the algebraic then cause the grobs to be merged as is proper for
the function. By default all functions simply display the name of the
function followed by the arguments in parenthesis, with the following
exceptions:

	+	Arguments displayed with + in the middle
	-	Arguments displayed with - in the middle
	NEG	Argument  displayed with - in the front
	*	Arguments displayed with a dot in the middle
	/	Arguments displayed on top of each other w/ a line in between
	^	Second argument displayed as exponent
	INV	Argument displayed with "-1" exponent
	SQ	Argument displayed with "2" exponent
	EXP	Argument displayed as exponent for "e"
	ALOG	Argument displayed as exponent for "10"
	CONJ	Argument displayed with "*" exponent
	ABS	Argument displayed with surrounding ||
	SQRT	Argument displayed with surrounding square root
	XROOT	Arguments displayed as written on paper
	!	Argument displayed with following "!"
	MOD	Arguments displayed with " MOD " in the middle
	NOT	Argument displayed with a special NOT symbol in front
	AND	Arguments displayed with a special AND symbol in the middle
	OR	Arguments displayed with a special OR symbol in the middle
	XOR	Arguments displayed with a special XOR symbol in the middle
	=	Arguments displayed with "=" in the middle
	==	Arguments displayed with "==" in the middle
	<>	Arguments displayed with "<>" in the middle
	<	Arguments displayed with "<" in the middle
	>	Arguments displayed with ">" in the middle
	<=	Arguments displayed with "<=" in the middle
	>=	Arguments displayed with ">=" in the middle

The following cases are a bit more complex:

	Derivative
	----------

	A series of derivatives with respect to X is causes the argument
	to be shown with the proper number of ticks (') as the 'exponent'.

	A series of derivatives with respect to mixed variables is shown
	as taking partial derivatives of the argument.

	Examples: (d denotes the derivative function)

				      ''   '
	'dX(dX(Y))+a*dX(Y)+b=0'	==>  Y  +aY +b=0

				      d
	'dY(dX(F(X,Y)))=0'	==>  ----(F(X,Y))=0
				     dYdX

	Integral
	--------

	Integral function is displayed as written on paper. As a special
	feature '?' as an integration limit is not displayed.

	Examples: (S denotes the integral function, 00 infinity)


	'S(0,00,EXP(-SQ(X)/2),X))=SQRT(PI/2)'

		 00
		  /  2
		 | -x
		 | --       ---
		 |  2	   |PI
	==>	 |e  dX =  |--
		/	  \|2
		0

	'S(?,?,S(?,?,S(?,?,1/(X^2+Y^2+Z^2),X),Y),Z)'


		  ///
	         |||   1
	==>	 |||--------dXdYdZ
		 ||| 2  2  2
		 |||X +Y +Z
		///

	Summation
	---------

	Summation function is displayed as written on paper.

	Example: (Z denotes the summation function)

	'Z(I=1,n,SQ(I))=1/3*n^3+1/2*n^2+1/6*n)'

		 n
		--   2    1 3   1 2   1
		>  (I ) = -n  + -n  + -n
		--        3     2     6
		I=1

	| function
	----------

	| is displayed as in the built-in Equation Writer.


User Functions
--------------

The user can create own functions for example by typing 'F(X,Y)' directly
or executing { X Y } 'F' APPLY. The AGROB parser utilizes this feature for
executing various functions on the arguments as follows:

	'Mul(expr1,expr2)'	==>  Multiplication with no mult. mark
	'Der(expr,n)'		==>  nth derivative of expr (tick form)
	'DER(expr,n)'		==>  nth derivative of expr (d/dx form)
	'der(expr,n1,n2..)'	==>  nth partial derivatives of expr
	'Grad(expr)'		==>  Gradient
	'Div(expr)'		==>  Divergence 
	'Curl(expr)'		==>  Curl
	'Lap(expr)'		==>  Laplacian
	'LapT(expr)'		==>  Laplace transform
	'FouT(expr)'		==>  Fourier transform
	'ILapT(expr)'		==>  Inverse Laplace transform
	'IFouT(expr)'		==>  Inverse Fourier transfrom
	'Cross(expr1,expr2)'	==>  expr1 x expr2
	'If(expr1,expr2)'	==>  expr2 ,expr1
	'So(expr1,expr2)'	==>  expr1 ==> expr2
	'Equ(expr1,expr2)'	==>  expr1 <==> expr2
	'PM(expr1,expr2)'	==>  expr1 plus/minus expr2
	'MP(expr1,expr2)'	==>  expr1 minus/plus expr2
	'pm(expr)'		==>  plus/minus expr
	'mp(expr)'		==>  minus/plus expr

The following are more about formatting than actually providing some
mathematical functions:

	'Par(expr)'		==>  Parenthesis are drawn around the argument
	'Vector(expr)'		==>  An arrow is drawn above the argument
	'Top(expr1..exprN)'	==>  The arguments are shown on top of each
				     other, aligned to left border.
	'Lt(expr1..exprN)'	==>  The argument is given a left brace "{"
				     For multiple arguments Top is called 1st
	'Rt(expr1..exprN)'	==>  The argument is given a right brace "}"
				     For multiple arguments Top is called 1st
	'fm(expr)'		==>  Decrement font size for expr
	'fp(expr)'		==>  Increment font size for expt

The user should note that all of above are just pseudo-functions, the only
thing they do is to arrange the arguments in a convenient way. Thus for
example true functions do not 'see' the pseudo-functions to have any special
priorities, and thus parenthesis may not be shown when needed. The 'Par'
pseudo-function is provided for use in such cases.

To support the common notation for special functions the following patterns
at the end of the function name are recognized:

	'.n'	==> First argument is shown as subindex.
		    Remaining arguments, if any, are shown in parenthesis.
	'.nm'	==> First argument is shown as subindex, second as topindex.
		    Remaining arguments, if any, are shown in parenthesis.

Examples:
				
	'J.n(n,x)'	==> J (x)	(Bessel function)
			     n

			     m
	'P.nm(n-1,m,x)'	==> P   (x)	(Associated Legendre function)
			     n-1

For more examples please see the samples directory provided with the
package.	


4.2 ASTK Parser
---------------

Calling AGROB blindly for all objects could be unbearably slow. Thus ASTK
calls AGROB subroutines to decompile an object only when:

	- The object is one of the following:
		Albebraic, global name, local name, unit, array, grob
	- The object is a list containing less than 20 objects


5.0 COVERED PORTS
=================

The internal Agrob subroutine is unsafe if evaluated from a covered port.
Thus both AGROB and ASTK copy it to a variable named 'agrob' in the hidden
directory for evaluation if needed, both also purge it when they exit.

Should you happen to exit either program by ON-C though, the variable would
remain in the hidden directory and would take 10Kb of user memory. To make
sure it doesn't remain there simply start and exit ASTK.


6.0 SAMPLES
===========

The package provides a BZ-compressed sample directory of objects. To have a
look at them, simply download the file to your HP48, uncompress it with BZ,
store it to a variable and enter the directory. Then start ASTK and press
any variable name to see the object in it.

Note that some of the objects are invalid in regular HP48 operation, and
have been built with hacking tools just to see what AGROB can do. None of
the objects will cause an error in the normal HP48 display, but you should
not try to operate with them.


7.0 SOURCE CODE
===============

The source code is included in the package in GNU Tools format (new opcodes
and label generation are used).

Programmers of various alternative stack displays may wish to extract
XLIB 740 2 (AGrob in the source code) to be used in their own stack
display programs. Permission to use it is hereby granted, provided the
program is not commercial. For convenience some conditional flags are
provided in the source code to enable easy removal of some of the 'fancier'
features.


9.0 HISTORY
===========

EQSTK library is largely based on the AWV48 library
by Claude-Nicolas Fiechter.

v1.0
----
- Faster.
- Added integral, summation, derivative
- Implemented ASTK

v2.0
----
- Subscripts
- A couple bug fixes.

v3.0
----
- Faster.
- Implemented most of the missing internal functions.
- Implemented array decompilation
- Implemented unit decompilation
- Implemented dotted subscripts
- Allowed arrays and lists in ASTK display
- Fixed a bug in ASTK display loop
- Works from covered ports too (6.5K memory requirement)

v4.0
-----

- Fixed MOD, XOR
- Implemented XROOT
- Implemented special grobs for AND, OR, NOT, XOR
- Implemented special identifier names (Phi, Psi..)
- Improved derivative output to be more compact when possible
- Fixed the EXPLODE substitute
- Fixed minus (-) to use proper priority setting for the rightmost argument
- Allowed special identifiers in user function names
- Allowed special identifiers in derivative variable names
- Implemented special user functions
- Modified samples to use new features, added more samples.

v5.0
----
- Speeded up in several places
- Implemented tagged objects
- Added more special identifiers

v5.21
-----
- Fixed size 3 representation for NEG
- Validated DA1 always so that ON-key aborts editline properly.
- Fixed grob! substitute to work properly when called to bang
  a grob of width 57 at the last pixel of a nibble.

v5.3
----
- Use "1; " or similar for displaying equations that do not fit on the line.
- Fixed matrix dimension tests to be absolutely valid

v5.4
----
- Implemented special grob for 'GAMMA'
- Allowed romptr function names to be special user functions (GAMMA etc)
- Implemented .n and .nm type function name formatting
- Implemented pm and mp user functions to complement PM and MP
- Implemented DER, Der and der user functions
- Allowed multiple arguments for Lt and Rt user functions, in which case
  the Top user function is called first.
- Implemented user functions fm and fp for font size control

v5.5
----
- Fixed NOT priority (relative to AND and XOR)

v5.6
----
- Implemented array size checks to reduce hopeless tasks (out of memory)
- Added new samples, removed ALG48 tests as too trivial examples
- Compiled 2 versions:
	eqstk.lib	- Full version
	eqstkb.lib	- Small version (all compiler flags cleared)
v5.7
----
- Added parenthesis if left argument of * is a unit object

v5.8
----
- Fixed WHERE function for multiple equates

v6.0
----
- Fixed { {} { A B } } not to crash AGROB

v6.1
----
- Fixed problem with the priority of negative real numbers
- Made the configuration object to automatically purge 'agrob' from hidden dir

v6.2
----
- Uses UFL small font instead of Jazz small font

v7.0
----
- Requires UFL with FNT1 and FNT2 to be present

v8.0
----
- Fixed integration variable to be parsed as a general identifier to
  allow for example intergration with respect to phi
- Added stack decompile speedups. Whenever stack decompile is
  requested and the topmost function is one of + - * = <= >= etc
  the left hand side is decompiled first. If the result is wider
  than the display the right hand side is ignored.

v9.0
----
- Cache implemented for ASTK to provide great speedup for stack
  display when the stack doesn't change much.

v9.1
----
- Implemented checks on changes in system flags affecting display
  modes to force a cache clear and thus a redraw.
- Fixed exit from EQSTK to be as valid as possible for all
  possible stack save modes.



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


EQStk7+ is a hacked version of EQStk 9.1, which adds a 7 level interactive 
stack.
Matias Mutchinick <mmb@quetzal.innsz.mx> has added the 7 level interactive 
stack. Mika Heiskanen gave his permission to modify his source, as long as 
the different versions are clearly named.
Matias didn't find the time to update the documentation to release EQStk7+, 
so I asked Matias, if he would let me do this and he agreed:

"sure, no problem, just put a little note, saying that
the interactive stack was hacked directly in the calculator
and because of the time, no fancy source other than the obtained
when dissasembleing the code with Jazz is available at the 
moment."

When you install EQStk7p.lib (that's how the file of the library is called) 
and activate EQStk like normal (ASTK command) you'll have a 7 level 
interactive stack by pressing the Up-Arrow-key. 

Note: Don't type IS7 (the hook to invoke the 7 level interactive stack, see 
the explanation under *Options* at the end of this documentation). This 
would result in a warmstart.


Here are some tips for the use with EQStk/EQStk7+:

Status area
~~~~~~~~~~~

While running EQStk/EQStk7+ you can't see the status area. Here are some
optional suggestions to circumvent this.

When you're using EQStk you can see the status area by just pressing the
UP-Arrow-key to invoke the standard interactive stack.

With EQStk7+ you don't have this chance and you can follow the ideas here:
(All ideas are usefull for EQStk and EQStk7+)


To see the change of RAD/DEG you can assign a tiny program to a user key. 
This will give you a short message which mode you use, when changing 
between RAD/DEG.
(Sure user keys have to be active then. I suggest to set flag -61 and flag 
-62 by typing -61 SF and pressing LeftShift USER [ENTER-key]. For further 
explanation of USER keys and CST (custom) menus see chapter 30 in the 
manual).

Type that program:
<< IF -17 FC? THEN RAD "RADIANT" ELSE DEG "DEGREE" END 1 DISP >>
Type:
21.2
ASN


It's not neccessary to show the POLAR mode, because you see in the 
representation of the stack, if POLAR mode is on.
For example:
POLAR mode active:       (5, <53.1301023542)
POLAR mode not active:   (3, 4)


To show that you are turning off USER mode you can assign that program to 
the (leftshifted) USER key:
<< -62 CF "USER OFF" 1 DISP >>
61.2
ASN

If you see the message "USER OFF" when pressing LeftShift USER [alpha-key] 
you're just quitting USER mode. If you don't see a message you're just 
entering USER mode.


Another usefull idea would be to assign ASTK (to start EQStk /to switch 
between small and large font) to a user key. Or to add ASTK to your CST 
(custom) menu. This way one could fast start EQStk/toggle_the_font_size. 
And remember CONT will quit EQStk and return to the built in stack display.

Also it might be helpful to use a FlagCommander to have a fast look/
option_to_change the used flags (settings!). I personally love to use the
Flag Catalog 4.1 from Raymond Hellstern.

Scrolling large objects
~~~~~~~~~~~~~~~~~~~~~~~
If an object doesn't fit on the stack you will see

 ; 

instead of

 :

 after the number of the line, like

1; "This is a large ob...

instead of

1:                  34545

If you want to take a look on large objects like equations/matrices and so 
on I want to suggest to use another splendid library from Mika Heiskanen - 
TED.

TED is an editor and includes a viewer for all objects. This viewer is 
called VV. With the use of VV you can also scroll large objects very fast 
and easy. VV starts much faster then the built in viewer. To view a really 
large equation it took about 1 minute with the built in viewer, but only 2 
seconds with VV! You may want to include VV in a CST menu or assign VV to 
a user key.

For example you could assign VV to the Down-Arrow key. 
To do this you would have to follow these steps:
Type VV in a list:
{ VV }
extract VV by the following key sequence with the command OBJ-> (I just 
write down the characters of the keys):
H C A
then DROP 1
and finally type 35.1 ASN

That's it. The trick with the list is necessary, because you can't enter a 
command (like VV) on the stack direct. This way you can assign every built 
in command or library command to a key.
Notice that the built in VIEW command can still be reached via the 
LeftShifted Down-Arrow-key.


Option: Assign the 7 level interactive stack (IS7) to a key
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To have the chance to assign the 7 level interactive stack to a key I have 
added a hook called IS7 to the library.

For example: I have assigned the UP command from Joe Horn's program to my 
Up-arrow-key and therefore needed the chance to activate the 7 level 
interactive stack with another key combination.

To assign the 7 level interactive stack to a UserKey follow this steps:

I personally have deceided to assign IS7 to the RightShifted Up-Arrow-key. 
(Further info on assigning UserKeys are found in chapter 30 of the manual).

Make a list containing IS7
{IS7}

Do Obj-> (press keys H C D)

DROP the number 1

Type the key-combination for the assignment.

In this example this would be:

25.3

and type/press ASN

That's it. Now (when USR keys are active) you can invoke the 7 level 
interactive stack with the RightShifted Up-Arrow-key.

Note! You can't type IS7 into the command line to start the 7 level 
interactive stack! This will result in a warmstart. Mika Heiskanen has 
explained the reason in the following post:

"Re: Problem whit EQSTK & TED" 1997/04/26 by Mika Heiskanen
  <http://www.dejanews.com/getdoc.xp?AN=237474895&fmt=raw>



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All mentioned libraries/programs can be found at the superb HP48 Software
Archive http://www.hpcalc.org

Many thanks to Mika for his many great libraries without them the HP48 
wouldn't be what it is and also many thanks to Matias for adding the long 
awaited 7 level interactive stack :-)

19.03.99
Peter Karp <karpfenteich@gmx.de>
