The Museum of HP Calculators

HP Forum Archive 19

 Some 30b RoutinesMessage #1 Posted by Jeff O. on 20 Aug 2010, 1:02 p.m. In the absence of a complete repurposing of the 30b, I decided to come up with a set of key reassignments and/or programs to make the 30b more easily useable (to me, at least) as a scientific calculator. I decided to implement the following functions in the 10 available program slots: SIN-1 COS-1 TAN-1 Complex add Complex subtract Complex multiply Complex divide Complex Invert Polar to Rectangular Conversion Rectangular to Polar Conversion Complex numbers and Rectangular to Polar functions are based on the (old) paradigm of representing a complex number in rectangular form with the real in stack-x and the imaginary in stack-y. Stack-z and stack-t hold the second complex value for add, subtract, multiply and divide, with the 4-level real stack considered a 2-level complex stack. Complex invert preserves the stack-z and stack-t values. The polar to rectangular routine also preserves the stack so you can enter a complex rectangular value, then enter a complex polar value, convert it to rectangular form and then add, subtract, multiply or divide with the first value. R->P and P->R work in both radians and degrees mode. All programs display a message when complete to announce the function just executed. I also put the same message as step 1 to act as a program label for several of the routines, but did not have enough room to do so for all. I did not really attempt to optimize the programs - once I got them working with all routines fitting in memory, I stopped. I'm sure there is room for improvement. I'd like to have enough room to add the program labels to all programs, but I'll leave that as an exercise for the reader. I wish the 30b had 10 more program slots and maybe double the memory so I could move a few more functions to the keyboard and create some additional routines. ```Prgm 0 Program Description: Arc Sine bytes and checksum: 18.057 Step function comments 0 SH7 assign to shift-hold 7 1 message SIN-1 Program label 2 Math execute SIN-1 function 3 Input execute SIN-1 function 4 Down execute SIN-1 function 5 Input execute SIN-1 function 6 message SIN-1 displays SIN-1 upon completion 7 Stop Prgm 1 Program Description: Arc Cosine bytes and checksum: 13.253 Step function comments 0 SH8 assign to shift-hold 8 1 Math execute COS-1 function 2 Input execute COS-1 function 3 Up execute COS-1 function 4 Up execute COS-1 function 5 Input execute COS-1 function 6 message COS-1 displays COS-1 upon completion 7 Stop Prgm 2 Program Description: Arc Tangent bytes and checksum: 12.009 Step function comments 0 SH9 assign to shift-hold 8 1 Math execute TAN-1 function 2 Input execute TAN-1 function 3 Up execute TAN-1 function 4 Input execute TAN-1 function 5 message TAN-1 displays TAN-1 upon completion 6 Stop Prgm 3 Program Description: Add two rectangular form complex numbers bytes and checksum: 24.218 Step function comments 0 SH+ assign to shift-hold + 1 message CPLX+ Program label 2 ) Swap 3 ( Rv Roll down 4 + 5 ( Rv Roll down 6 + 7 ( Rv Roll down 8 ( Rv Roll down 9 ( Rv Roll down 10 message CPLX+ displays CPLX+ upon completion 11 Stop Prgm 4 Program Description: Subtract two rectangular form complex numbers bytes and checksum: 25.053 Step function comments 0 SH- assign to shift-hold - 1 message CPLX- Program label 2 ) Swap 3 ( Rv Roll down 4 - 5 ( Rv Roll down 6 ) Swap 7 - 8 ( Rv Roll down 9 ( Rv Roll down 10 ( Rv Roll down 11 message CPLX- displays CPLX- upon completion 12 Stop Prgm 5 Program Description: Multiply two rectangular form complex numbers bytes and checksum: 49.254 Step function comments 0 SH* assign to shift-hold x 1 message CPLX* Program label 2 Lbl 04 Program label for call from divide routine 3 STO 1 4 STO 3 5 (Rv Roll down 6 STO 2 7 STO 4 8 ( Rv Roll down 9 STO * 1 10 STO * 4 11 ( Rv Roll down 12 STO * 2 13 STO * 3 14 RCL 4 15 + 16 RCL 1 17 RCL - 2 18 message CPLX* displays CPLX* upon completion 19 RTN Return for Call Prgm 6 Program Description: Divide two rectangular form complex numbers bytes and checksum: 20.047 Step function comments 0 SH/ assign to shift-hold / 1 message CPLX/ Program label 2 Call03 execute complex invert routine 3 Call04 execute complex multiply routine 4 message CPLX/ displays CPLX/ upon completion 5 Stop Prgm 7 Program Description: Invert a rectangular form complex number bytes and checksum: 47.060 Step function comments 0 NPV assign to the NPV key 1 message CPLX x-1 Program label 2 Lbl 03 Program label for call from divide routine 3 STO 1 4 ( Rv Roll down 5 ( Rv Roll down 6 ( Rv Roll down 7 STO 2 Store value that was at top of stack 8 ( Rv Roll down 9 STO * 1 10 ) Swap 11 +/- 12 Input 13 x^2 14 RCL + 1 15 / 16 ) Swap 17 Ans 18 / 19 RCL 2 20 ( Rv Roll down 21 message CPLX x-1 displays CPLX x-1 upon completion 22 RTN Return for Call Prgm 8 Program Description: Rectangular to Polar Conversion (by Thomas Klemm) Bytes and checksum: 55.134 Step function comments 0 IRR assign to the IRR key 1 message R->P Program label 2 STO 1 store real component 3 x^2 square real component 4 ) Swap swap squared real component and imaginary component 5 STO 2 store imaginary component 6 x^2 square imaginary component 7 + add squared imaginary component 8 square root take square root to calculate magnitude 9 STO 3 store magnitude 10 Input duplicate magnitude to stack y since GF consumes stack x value 11 GF 02 branch to end if magnitude = 0 12 RCL + 1 add real component: r + x 13 Input duplicate r + x to stack y since GF consumes stack x value 14 GF 01 branch if magnitude + real component = 0 15 RCL 2 imaginary component: y 16 ) Swap swap y and r + x 17 / divide to calculate tangent of half-angle: y / (r + x) 18 Math execute TAN-1 function 19 Input execute TAN-1 function 20 Up execute TAN-1 function 21 Input execute TAN-1 function 22 Gto 02 branch to end 23 Lbl 01 Routine to handle magnitude + real component = 0 part 24 Math execute COS-1 function to obtain 180 (or Pi) 25 Input execute COS-1 function to obtain 180 (or Pi) 26 Up execute COS-1 function to obtain 180 (or Pi) 27 Up execute COS-1 function to obtain 180 (or Pi) 28 Input execute COS-1 function to obtain 180 (or Pi) 29 Lbl 02 Label for branch in steps 11 and 22 30 2 enter two 31 * multiply half-angle by 2 to get angle 32 RCL 3 recall magnitude 33 message R->P displays R->P upon completion 34 Stop Prgm 9 Program Description: Polar to Rectangular Conversion bytes and checksum: 25.058 Step function comments 0 CashFl assign to the CashFl key 1 message P->R Program label 2 STO 1 store magnitude 3 ( Rv Roll down to preserve stack 4 Cos take cosine of angle 5 Ans recall the angle 6 Sin take sine of angle 7 RCL * 1 calculate imaginary component 8 ) Swap 9 RCL * 1 calculate real component 10 message P->R displays P->R upon completion 11 Stop ``` edited to use much better R->P routine by Thomas Klemm and add more program labels. Edited: 24 Aug 2010, 8:23 p.m. after one or more responses were posted

 Re: Some 30b RoutinesMessage #2 Posted by gene wright on 20 Aug 2010, 1:44 p.m.,in response to message #1 by Jeff O. Good job! The assignment programs for the inverse trig functions are in one of the learning modules for the 30b. If you haven't seen those, they are available at the link that Tim Wessman set up. Not sure WHY they aren't available on HP's website somewhere.

 Re: Some 30b RoutinesMessage #3 Posted by Thomas Klemm on 20 Aug 2010, 4:09 p.m.,in response to message #1 by Jeff O. Quote: ```Prgm 8 Program Description: Rectangular to Polar Conversion ``` You might consider the following formula: ``` sin(t) r sin(t) y tan(t/2) = ---------- = ------------ = ----- 1 + cos(t) r + r cos(t) r + x ``` `r = 0: t = 0` `r + x = 0: t = 180 (or Pi)` `else: t = 2 atan(y/(r+x))` It makes the program somewhat shorter: ```Prgm 8 Program Description: Rectangular to Polar Conversion Step function comments 0 IRR assign to the IRR key 1 message R->P Program label 2 STO 1 store real component 3 x^2 square real component 4 ) Swap swap squared real component and imaginary component 5 STO 2 store imaginary component 6 x^2 square imaginary component 7 + add squared imaginary component 8 square root take square root to calculate magnitude 9 STO 3 store magnitude 10 GF 02 branch to end if magnitude = 0 11 RCL + 1 add real component: r + x 12 GF 01 branch if magnitude + real component = 0 13 RCL 2 imaginary component: y 14 ) Swap swap y and r + x 15 / divide to calculate tangent of half-angle: y / (r + x) 16 Math execute TAN-1 function 17 Input execute TAN-1 function 18 Up execute TAN-1 function 19 Input execute TAN-1 function 20 2 enter two 21 * multiply half-angle by 2 to get angle 22 Gto 02 branch to end 23 Lbl 01 Routine to handle magnitude + real component = 0 part 24 1 enter 1 25 - subtract 1 from 0 leading to -1 26 Math execute COS-1 function to obtain 180 (or Pi) 27 Input execute COS-1 function to obtain 180 (or Pi) 28 Up execute COS-1 function to obtain 180 (or Pi) 29 Up execute COS-1 function to obtain 180 (or Pi) 30 Input execute COS-1 function to obtain 180 (or Pi) 31 Lbl 02 Label for branch in steps 10 and 22 32 RCL 3 recall magnitude 33 message R->P displays R->P upon completion 34 Stop ``` As I don't have a 30b I can't test the program nor can I show the amount of bytes and the checksum. However I like your style of commenting each line very much and tried to preserve it. Kind regards Thomas Edited: 21 Aug 2010, 11:34 a.m.

 Re: Some 30b RoutinesMessage #4 Posted by Jeff O. on 23 Aug 2010, 12:36 p.m.,in response to message #3 by Thomas Klemm Thomas, Thanks, that is a much more elegant method and a major improvement in program length. When I entered your program as listed above, it did not function properly. Since you do not have a 30b, did you realize that the "GF" statements in step 10 and step 12 consume the value in stack-x? I added a couple of steps (Input function in steps 10 and 13) which I believe will fix this issue and ran some tests. All seems well now, the program seems to handle all cases. I like the way it normalizes angles over 180 to be negative, and handles an input of 0, 0 (which my version did not handle). But I may have missed something, so please feel free to review to make sure it will still work as you intended. The revised listing is below. Quote: ... I like your style of commenting each line very much and tried to preserve it. Thanks, I'm glad you like it, although I don't think I can take credit for inventing it. :-) Best regards, Jeff ```Prgm 8 Program Description: Rectangular to Polar Conversion Bytes and checksum: 57.255 Step function comments 0 IRR assign to the IRR key 1 message R->P Program label 2 STO 1 store real component 3 x^2 square real component 4 ) Swap swap squared real component and imaginary component 5 STO 2 store imaginary component 6 x^2 square imaginary component 7 + add squared imaginary component 8 square root take square root to calculate magnitude 9 STO 3 store magnitude 10 Input duplicate magnitude to stack y since GF consumes stack x value 11 GF 02 branch to end if magnitude = 0 12 RCL + 1 add real component: r + x 13 Input duplicate r + x to stack y since GF consumes stack x value 14 GF 01 branch if magnitude + real component = 0 15 RCL 2 imaginary component: y 16 ) Swap swap y and r + x 17 / divide to calculate tangent of half-angle: y / (r + x) 18 Math execute TAN-1 function 19 Input execute TAN-1 function 20 Up execute TAN-1 function 21 Input execute TAN-1 function 22 2 enter two 23 * multiply half-angle by 2 to get angle 24 Gto 02 branch to end 25 Lbl 01 Routine to handle magnitude + real component = 0 part 26 1 enter 1 27 - subtract 1 from 0 leading to -1 28 Math execute COS-1 function to obtain 180 (or Pi) 29 Input execute COS-1 function to obtain 180 (or Pi) 30 Up execute COS-1 function to obtain 180 (or Pi) 31 Up execute COS-1 function to obtain 180 (or Pi) 32 Input execute COS-1 function to obtain 180 (or Pi) 33 Lbl 02 Label for branch in steps 11 and 24 34 RCL 3 recall magnitude 35 message R->P displays R->P upon completion 36 Stop ``` ....

 Re: Some 30b RoutinesMessage #5 Posted by Thomas Klemm on 23 Aug 2010, 6:21 p.m.,in response to message #4 by Jeff O. Quote: Since you do not have a 30b, did you realize that the "GF" statements in step 10 and step 12 consume the value in stack-x? Oops, I forgot that in this aspect the 30b behaves more like RPL. So it's necessary to DUP the top of the stack using "Input" before executing "GF". This makes two additional lines. Mmh, let me see how we could get rid of them: Remove the following two lines: ```26 1 enter 1 27 - subtract 1 from 0 leading to -1 ``` Shift lines 22-23 down to LBL 02: ```33 Lbl 02 Label for branch in steps 11 and 24 22 2 enter two 23 * multiply by 2 34 RCL 3 recall magnitude 35 message R->P displays R->P upon completion 36 Stop ``` Of corse the line numbering has to be adjusted. However now the program might lack some clarity. Why do I have to multiply 0 by 2, you may ask. Well, it just doesn't hurt. Best regards Thomas Edited: 23 Aug 2010, 7:03 p.m.

 Re: Some 30b RoutinesMessage #6 Posted by Jeff O. on 24 Aug 2010, 7:41 a.m.,in response to message #5 by Thomas Klemm Very nice. Feel free to keep making it shorter! ```Prgm 8 Program Description: Rectangular to Polar Conversion Bytes and checksum: 55.134 Step function comments 0 IRR assign to the IRR key 1 message R->P Program label 2 STO 1 store real component 3 x^2 square real component 4 ) Swap swap squared real component and imaginary component 5 STO 2 store imaginary component 6 x^2 square imaginary component 7 + add squared imaginary component 8 square root take square root to calculate magnitude 9 STO 3 store magnitude 10 Input duplicate magnitude to stack y since GF consumes stack x value 11 GF 02 branch to end if magnitude = 0 12 RCL + 1 add real component: r + x 13 Input duplicate r + x to stack y since GF consumes stack x value 14 GF 01 branch if magnitude + real component = 0 15 RCL 2 imaginary component: y 16 ) Swap swap y and r + x 17 / divide to calculate tangent of half-angle: y / (r + x) 18 Math execute TAN-1 function 19 Input execute TAN-1 function 20 Up execute TAN-1 function 21 Input execute TAN-1 function 22 Gto 02 branch to end 23 Lbl 01 Routine to handle magnitude + real component = 0 part 24 Math execute COS-1 function to obtain 180 (or Pi) 25 Input execute COS-1 function to obtain 180 (or Pi) 26 Up execute COS-1 function to obtain 180 (or Pi) 27 Up execute COS-1 function to obtain 180 (or Pi) 28 Input execute COS-1 function to obtain 180 (or Pi) 29 Lbl 02 Label for branch in steps 11 and 22 30 2 enter two 31 * multiply half-angle by 2 to get angle 32 RCL 3 recall magnitude 33 message R->P displays R->P upon completion 34 Stop ``` ... Edited: 24 Aug 2010, 8:37 a.m.

 Re: Some 30b RoutinesMessage #7 Posted by Thomas Klemm on 24 Aug 2010, 1:01 p.m.,in response to message #6 by Jeff O. Quote: Feel free to keep making it shorter! I'm afraid I've come to an end. All I can offer is a sketch that hopefully makes the formula plausible: ``` y tan(t) = --- x y tan(t/2) = ----- r + x ``` Cheers Thomas

 Re: Some 30b RoutinesMessage #8 Posted by Jeff O. on 24 Aug 2010, 8:07 p.m.,in response to message #7 by Thomas Klemm I looked up half-angle formulas to verify your method (for my own information, I did not doubt that you were correct.) The diagram shows nicely why it is true. Quote: I'm afraid I've come to an end. Feel free to tackle the others. The improvements to R->P allowed me to label all but two routines, but I need a few more bytes to label COS-1 and TAN-1 ...

 Re: Some 30b RoutinesMessage #9 Posted by Don Shepherd on 24 Aug 2010, 8:27 p.m.,in response to message #8 by Jeff O. Quote:but I need a few more bytes to label COS-1 and TAN-1 Jeff, I think STOP's at the end of programs are optional. Get rid of them and see if it still works, I suspect it will. Might give you a few bytes. Don

 Re: Some 30b RoutinesMessage #10 Posted by Jeff O. on 24 Aug 2010, 8:52 p.m.,in response to message #9 by Don Shepherd The programs work, but is that "poor programming practice"? :-) However, I still need one more byte.

 Re: Some 30b RoutinesMessage #11 Posted by Katie Wasserman on 24 Aug 2010, 9:26 p.m.,in response to message #10 by Jeff O. You really don't need the first message step in each program since they only serve to remind you which function is in which memory slot when you are in program mode. Your keystroke assignment in step 0 is probably a good enough reminder.

 Re: Some 30b RoutinesMessage #12 Posted by Jeff O. on 25 Aug 2010, 10:23 a.m.,in response to message #11 by Katie Wasserman Quote: You really don't need the first message step in each program.. I agree that I don't need them, but I do want them. It's nice to be able to scroll through the program list and see the labels instead of "Prgm 0", Prgm 1", etc. Besides, now it's personal - the classic challenge to fit what you want in the available memory. (Strange that we have this challenge with a new machine in 2010...) Quote: Your keystroke assignment in step 0 is probably a good enough reminder The message I put as the last step to be displayed after the program runs is an even better reminder :-) ...

 Re: Some 30b RoutinesMessage #13 Posted by Katie Wasserman on 25 Aug 2010, 11:45 a.m.,in response to message #12 by Jeff O. Quote: (Strange that we have this challenge with a new machine in 2010...) Although I like these kinds of challenges there should be little need for them these days considering how cheap memory is. I understand HP's requirement to stick to a single processor capable of running the LCD directly, that has a low quiescent current draw, enough ROM, etc.. This Atmel processor fits the bill on that account, it's a good choice for a non-programmable calculator. But a programmable calculator needs more memory and this chip should be supplemented by some external RAM at least.

 Re: Some 30b RoutinesMessage #14 Posted by Jeff O. on 25 Aug 2010, 1:02 p.m.,in response to message #13 by Katie Wasserman Agreed!

 Re: Some 30b RoutinesMessage #15 Posted by Thomas Klemm on 25 Aug 2010, 3:44 a.m.,in response to message #8 by Jeff O. Jeff, you could try the following: ```Prgm 5 Program Description: Multiply two rectangular form complex numbers Step function comments 0 SH* assign to shift-hold x 1 message CPLX* Program label 2 Lbl 04 Program label for call from divide routine 3 STO 1 4 ( Rv Roll down 5 STO 2 6 ) Swap 7 STO * 1 8 * 9 ( Rv Roll down 10 STO * 2 11 ) Swap 12 ( Rv Roll down 13 * 14 + 15 RCL 1 17 RCL - 2 18 message CPLX* displays CPLX* upon completion 19 RTN Return for Call ``` If I counted correctly this saves 6 bytes. Not much, but maybe just enough. Cheers Thomas

 Re: Some 30b RoutinesMessage #16 Posted by Jeff O. on 25 Aug 2010, 9:48 a.m.,in response to message #15 by Thomas Klemm I knew you could do it!

Go back to the main exhibit hall