F.o version 1.85
by Jason Hann

F.b version 1.83.b
by Jason Hann

Disp (no version)
also by Jason Hann

Written in 2002
Released to the public 2/20/03

Jason Hann is reachable at  hann@tmbg.org

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

F.o is a right triangle solver for the HP48g series calculator.  This program has been used on P series GX and on R series G+ and GX.  This program was not tested on any S series HP48s, so you are warned!  F.b is an alternate version of the program as requested by my boss who previously used a TI-85 until it ran out of battery power and he lost his memory (calculator memory, that is).

The triangle solver consists of two programs which are completely stand alone programs and can be used independently.  However, they were each designed with the other in mind, so I would suggest using the Disp program.  The Disp program can be used separately from the F.o program to display decimal feet in the
status line in usual feet-inch sixteenths format.  If you would like to use the Disp program apart from the F.o program, then feel free.  If you are going to distribute the Disp program with other software then please drop me a line at  hann@tmbg.org  so I will know about it.  Also please give credit where credit is due.

F.o (and F.b) were written to solve for the unknown side or pitch of a right triangle.  It was intended to be used for structural engineering type jobs where the lengths are given in feet, inches, and sixteenths of an inch.  These numbers are entered in the following format:  Feet.In16  where anything left of the decimal point is whole feet, the first two decimal places are whole inches, and the second two decimal places are sixteenths of an inch.  The results are given in decimal feet, which is where the Disp program comes in handy.  For example, to enter 5'-4 3/4" (five feet four and three quarters of an inch) you would type 5.0412.  This is converted by the program into 5.39583333333.  The pitch of these triangles is represented in the rise per unit of base, for example 2 inches up for every 12 inches over.  So you would enter a pitch of 2.  If you need to convert to or from degrees, use the ATAN and TAN functions of the calculator.

F.o (and F.b) is 100% sysRPL and uses (I believe) all supported entry points.  Disp is about 95% ASM and 5% sysRPL.  It was optimized as much as I could for lightning fast speed, so it is really bigger than it needs to be to do the job, but it is fast.  The 5% of sysRPL is for a garbage collection, some GROB and string handling, and most (but not all!) of the floating point math; yes, I did some of it in ASM.

F.o (and F.b) and Disp were completely programmed on my HP48GX-P using Jazz on the Hacker ROM card I bought so many years ago (1995 according to the 'about' button in the library).  This is the older version (unfortunately) but I do not know the number, sorry.


Now then, on to the instructions.
=================================

F.o (and F.b) and Disp are contained in a directory and need to be stored somewhere on your 48.  I don't care where and neither do the programs.  The name I gave to the directory is 'F2K' so I will be refering to that name in the instructions.  If this is not where you stored your copy, substitute your directory name for 'F2K' when it appears in the instructions.  The directory name 'F2K' is sort of a joke to all of the programs in the recent past which have had a "2000" version.  F.o is so named because it is the Original version (sort of) and F.b is so named because it is the Boss version of the program.  I am including F.b only for those people who might prefer it over F.o.  It is smaller but it is also (to me at least) harder to use.  Disp should be self explanatory.

Once you have stored the directory in your calc, enter the directory.  You should see a couple of things there.  These are (in order):

F.o    the triangle solver program
F.b    the alternate triangle solver
Disp   the number displayer
bENTER ('Beta'ENTER) your handy custom ENTER program
last   stores number indicating last values entered
Pitch  stores pitch of angle (inches of rise per foot of base)
Base   stores base value
Rise   stores rise value
Diag   stores diagonal (hypotenuse) value
Saved  stores a complete triangle

The only ones you need to be concerned with are F.o (or F.b) and bENTER.


How to use F.o
==============

When you press the F.o button, a new menu (TMENU) will appear.  There are two pages, but everything you really need is on page one.  So lets start with page two.

Press the NXT button to access page two.

On page two you should see only one button: Ver.  This displays the version of the program you are running.  If you also had the program CPR installed in this directory, you would see a button labled CPR which would launch the CPR program.  I am not releasing the CPR program, however, so the only way you will see this button on page two is to create your own variable or program in the F2K directory and call it CPR.  Go ahead and try it just for fun.  You will have to exit the F.o menu (by pressing VAR) and then re-run F.o in order for the button to appear.

Now then, back to the first menu page.  You should see the following:

FIS>     converts a Feet.In16 number on the stack to decimal feet
P:?      stores/recalls the pitch value, where ? = the pitch in inches
Base     stores/recalls the base value
Rise     stores/recalls the rise value
Diag     stores/recalls the diag value
Solve    solves for the unknown value

To begin with, in order to enter numbers into the program, you typically type them in using the Feet.In16 format (kind of like HH.mmss).  The program does all of the calculations using decimal feet, however, so the first button, FIS>, converts Feet.In16 into decimal feet.  To try it, type 2.06 and press the FIS> button.  You should see  ft: 2.5  appear on the stack.  That is because 6 inches (the .06 part) is 1/2 of a foot, so you get 2.5 feet.  You will notice that the program automatically tags the output with 'ft' to let you know that it is in decimal feet.  If you modify the number in any way, the tag will disappear, so remember what is in decimal feet and what is not.  Now try 3.0412 which is 3 feet, 4 and 3/4 inches (that's 12/16 which reduces to 3/4).  It should give you 3.39583333333 on the stack.  This number is hard to understand in decimal feet, which is why the Disp program was created.  So at this point lets cover the Disp program.


An Interlude: The Disp program
==============================

The Disp program takes an argument from stack level one.  If that argument is a real number or an integer, it will display the number in the status line as feet, inches and fractions of an inch (down to 1/16 of an inch resolution).  It assumes that the number on the stack is in decimal feet, so if you have a number that is not in decimal feet, just ignore what the Disp program is showing you.  It will take no action if the argument is anything other than an integer or real number or if the stack is empty.  Also, it can display tagged numbers correctly no matter how many tags are on it (for example: a tagged tagged tagged number like Hello: :World: :ft: 3.39583333333 ).  The program does this by searching into the tag structure to find what the tag points to, and if it points to another tag, it does the search again until it finds a non-tag object.  It then determines what action to take (whether it is a number or not).  Disp can also display numbers that have units attached to them in much the same way as tagged objects.

So with the number 3.39583333333 on stack level one, return to the VAR menu and press the Disp button.  In the status area you should see

FIF:            3'-4 3/4"

It actually looks a little better than plain text, but you get the idea.  The Disp program takes the number from stack level one and recomposes it into a Feet.In16 number and then displays it.  It was written to be fast since this program runs frequently when entering numbers and doing math on the stack.  Because it is fast, you can put it into the custom ENTER variable so that it runs every time you press the ENTER key on the calculator which will eliminate the tedium of returning to the VAR menu and pressing Disp every time you want to know what a number is.

In order to do this, I have provided the bENTER (betaENTER) program.  If you recall the contents of bENTER to the stack you should see

<< DROP Disp >>

This drops a value provided by the custom ENTER feature and then runs the Disp program to display the contents of stack level 1.  If you are one of those people who like to use fixed notation or scientific notation, then you would have to modify bENTER to something such as

<< DROP STD Disp 4 FIX >>

in order to change back to standard mode (which Disp requires to display correctly, it might just crash otherwise!  It hasn't on me, but just to be sure...) and then change back to a fixed decimal with four digits.  You will have to custom tailor the bENTER program for your own needs.

In order to get the calculator to use the custom ENTER feature, you have to have USER keys turned on (and I would suggest locked on, i.e. LSHIFT-USER twice) and you have to have the custom ENTER flag on.  That is system flag 63 (or -63 if you are typing it in).  Once both of those flags are set, the bENTER (and thusly the Disp program) should run every time you enter a number or do a calculation.  Try it.  Enter a few numbers on the stack and note that they appear in Feet.In16 in the status line.  Add a few numbers and the same thing happens.

One particular 'feature' of the Disp program needs to be noted.  Any negative number on stack level one will automatically be turned into a positive number when the Disp program runs.  This was actually a requested 'feature' by one of my coworkers and everyone is used to it, since there really is no such thing as a negative length; it's just a length in the opposite direction.  This also made programming the Disp program a little easier.  If you absolutely have to have a negative number, change to a different directory on your calculator where the Disp program does not exist, or turn off your User keys while working with the negative number.  Alternately, you could modify your bENTER program further by placing a DUP before the Disp and a DROP after.  This would look like:

<< DROP DUP Disp DROP >>

If this still isn't satisfactory, I may can be persuaded to make another version that doesn't do this.


Meanwhile, back at the ranch...
===============================

Now that the Disp program is running when it should, you can do something useful with F.o.  First, enter in 2 inches and press the FIS> button to convert it to decimal feet (that would be:

.02
FIS>

and would result in ft: .166666666667 on the stack).  You should see 0'-2" in the status line if you are using the Disp program.  This number is going to be used as our pitch, which means for every foot horizontally we travel, we go up 2 inches.  So press the P: button which is next to the FIS> button.  The appearance of the P: button changes when you enter a pitch, and now (after entering 2" for the pitch) should appear as P:2.  If you would like to see this, enter a pitch of three inches  ( .03  FIS>  P: ) and it should appear as P:3.  Repeat the process again to get back to a 2" pitch.

Now lets give it a horizontal distance.  Type in 3.1008 and press the FIS> button.  You should see 3'-10 1/2" in the status line.  Press the Base button to store that length as the base.  If you would like to recall the base length (or the Pitch, Rise, or Diag) simply right-shift the button by pressing RIGHT-SHIFT and then Base.  Base: 3.875  should appear in stack level one, the tag Base letting you know that it is the base value.

At this point you can solve for the rise by pressing the Solve button.  This uses the pitch and the base to solve for the rise.  If you press  RIGHT-SHIFT Rise  the stored rise value will be recalled.  Notice that the calculated rise is the same as the stored rise, this is because the program automatically stores any solved value in the appropriate location.

If what you really wanted to solve for was the diagonal (hypotenuse), then just press Solve again and the program will solve for the diagonal.  Be aware, however, that the program uses the last entered value to solve for the next value.  In this case the last entered value was the rise which was entered by the program itself when the Solve button was pressed the first time.  So to get the diagonal, the program uses the pitch and the rise.  Also be aware that the program will DROP the last value solved for if it is still in stack level one.  The program does this by checking to make sure the tag of the object in level one is for the last value solved, and checks the value of the number to make sure that it matches that of the one stored in the program.  This helps keep the stack clear of unwanted numbers, but if (for example) you entered a base and wanted BOTH the rise and diagonal, you would need to press ENTER after the first Solve in order to make a copy of the rise before pressing the Solve button again.

If you press Solve again (a third time), you should get your original base value (plus or minus some very small floating point math rounding; I got 3.87499999999).

Those are the basics of the program.  If you have a rise and want the diagonal, enter the rise value and press solve.  If you wanted the base value, you would press solve twice.  If you have a diagonal and want the base value, enter the diagonal and press solve once, or press solve twice to get the rise value.

If you have two sides and need the pitch and/or the third side, then you have to enter both of the values.  For example, if I know that my base is 2'-4 3/16" and my rise is 4", I would enter

2.0403
FIS>
Base
.04
FIS>
Rise

At this point I would press the Solve button.  Since the program knows that I entered two new side lengths in succession, it will first solve for the pitch appropriate for those sides.  This pitch ( 1 11/16" ) appears in decimal feet on stack level one and in the status line (if you are using the Disp program) and is also automatically stored in the Pitch variable.  If I wanted to continue and solve for the diagonal, I would simply press the Solve button again (since the last side length entered was the rise) and get 2'-4 1/2".  If you are entering two sides and are looking for the third, be sure to enter them so that the second one entered is immediately to the left (except when solving for base) of the one you are looking for.  This is not a restriction in the program, it just eliminates and unnecessary Solve.  So if you are looking for the diagonal, enter the base then rise.  If you are looking for the base, enter rise then diagonal.  If you are looking for the rise, enter the diagonal then the base.  If you enter them in the wrong order, don't worry, just keep pressing the Solve button until the number with the correct tag appears.

One warning is that in order to get the program to work in the manner which it does, it is impossible to enter two sides that are the same length and then solve for the pitch and the third side.  The program makes a few assumptions that do not allow this, so entering a 1' base and 1' rise will cause the program to solve for the diagonal using the current pitch and the rise of 1'.  This is easy to overcome, however, by the simple fact that if your base and rise are equal, then the pitch is always 12" (12 inch rise for every 12 inch of base).  Alternately, if your diagonal is equal to either the base or the rise, then the other side has to be zero. 

This restriction does have a nice side effect; if you have entered a pitch and are entering a rise (in order to solve for the diagonal) but accidentally hit the Base button, you can retype (or recall by RIGHT-SHIFT Base) the value and store it in the rise.  Since both the base and rise are equal, the program will solve using the pitch and the last entered length (the rise) and give you the next side (the diagonal).

One last feature; it is possible to save an entire triangle in the variable named Saved.  If you press the RIGHT-SHIFT Solve button, the program will recall the values of the Pitch, Base, Rise, and Diag and store them in the Saved variable in the F2K directory.  Pressing LEFT-SHIFT Solve will store the values saved in the Saved variable into the program.  This is useful for saving work on one problem so that you can work on another one and then return to the original problem.


F.b: a different take on triangle solving
=========================================

My boss, who used to use a TI-85, had a triangle solving program that was lost when his batteries died.  When he attempted to use what is now the F.o program, he found it confusing.  His description of how his TI did it was very confusing for me and it took me a while to figure it out.  F.b is the result of the work and confusion and my boss likes it very much.  So without further ado;


How to get F.b to do what F.o does
==================================

The easiest way is to stop using F.b and erase it from your calculator.  If you insist on at least trying it, then this is how it works.

After pressing the F.b button, you will see a menu very similar to that of F.o.  In fact, the second menu page is identical to that of F.o, so I won't bother explaining it again.  The FIS> button works in the same manner as well, and the program also really needs the Disp program running in the custom ENTER variable.  If you skipped the explaination of F.o, I would suggest returning and reading it so that you know about these two things.  Also, the triangle saving and recalling feature that is found in F.o by RIGHT and LEFT-SHIFTING the Solve button was relocated by necessity to the FIS> button.  Sorry about the confusion, but if you pick one version of the program and stick with it, it shouldn't matter.

Looking at F.b menu page one you will see:

FIS>     converts a Feet.In16 number on the stack to decimal feet
P:?      stores/recalls the pitch value, where ? = the pitch in inches
Base     stores/recalls the base value and solves for Rise
Rise     stores/recalls the rise value and solves for Diag
Diag     stores/recalls the diag value and solves for Base
D>-<P    solves for diagonal, or diagonal and pitch, or pitch

As I said, the FIS> button works as described above, so we'll skip it.  The P: button also works as described above by storing the new pitch when pressed, or recalling the pitch when RIGHT-SHIFTED.  The other buttons are considerably different.

The Base button, when pressed, stores the value in stack level one into the Base variable, it then IMMEDIATELY solves for the Rise value which will appear on stack level one.  If you wanted to continue on to find the diagonal, pressing the Rise button would store that value (the rise that was just solved for) in the Rise variable and then IMMEDIATELY solve for the Diag value which will appear on stack level one.  If you wanted to go back to the Base, press the Diag button.  Yes, I know it's wierd, but that's what he wanted.

Because of the fact that the program immediately solves for the next value, you have to keep moving your finger to the next button if you want to continue.  You also cannot enter two values and then solve for the pitch or the third side.  In order to take care of the first problem, practice.  For the second problem, I created the D>-<P button.

In order to solve for a pitch and/or diagonal using two sides, those two sides MUST be the base and the rise, the diagonal cannot be used.  If this is a problem, use the F.o program instead.  Place both of the values on the stack, it doesn't matter in what order.  Understand that, for simplicity's sake, the program assumes that the longer of the two values is the base length, the other is used for the rise.  Pressing the D>-<P button will then result in both the diagonal (in stack level one) and the pitch (in stack level two) to be calculated.  If you only wanted to find the diagonal, then LEFT-SHIFT the D>-<P button (notice that the D is on the left side).  If you only wanted the pitch, then RIGHT-SHIFT.


In the end...
=============

I reserve all rights to this program that I feel like reserving at any time in the future.  I take no responsibility for any problems, lost data, lost time, lost hair you may experience when using this program.  You have been warned already about potential problems.  If you have been using this calculator long, you already know what can go wrong.  Feel free to copy this program and give it to others, but please give them this document as well.  This program is freeware, and you may de-compile/dissassemble it for learning purposes.  You may NOT sell this program or have it appear on a disk or for download for sale, with or without other software without first contacting me for approval.  That goes for ALL programs contained within this zip (F.o, F.b, and Disp).  You may also use the Disp program by itself for your own purposes on your calculator, and may use it in software written by yourself on your calculator.  If you distribute this software (written by yourself which uses DISP), please give credit to me for the Disp program and let me know about it (hann@tmbg.org).  If you are selling your software that utilizes the Disp program, please contact me first for permission.  'Nuf said about that.