Some 30b Routines



#17

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


#18

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.

#19

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

  1. r = 0:       t = 0
  2. r + x = 0:   t = 180 (or Pi)
  3. 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.


#20

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

....


#21

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.


#22

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.


#23

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


#24

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

...


#25

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


#26

The programs work, but is that "poor programming practice"? :-)

However, I still need one more byte.


#27

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.


#28

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 :-)

...


#29

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.


#30

Agreed!

#31

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


#32

I knew you could do it!


Possibly Related Threads...
Thread Author Replies Views Last Post
  Flashing cable for HP 20 / 30B Stefan Koenig 3 769 09-19-2013, 05:53 AM
Last Post: Marcus von Cube, Germany
  Any 30b cables left? patryk 7 980 09-16-2013, 02:54 PM
Last Post: Marcus von Cube, Germany
  HP-30B (WP-34S) Technical Documentation Barry Mead 3 698 09-09-2013, 03:07 PM
Last Post: Harald
  HP's thinking behind the 20b/30b? John Ioannidis 3 640 09-07-2013, 10:21 AM
Last Post: Tim Wessman
  30b/34s interfacing? ross sponholtz 5 817 06-26-2013, 01:41 AM
Last Post: Walter B
  Inexpensive HP 30b Matthew Richards 23 2,376 05-22-2013, 10:10 AM
Last Post: Dave
  hp-30b with free shipping sjthomas 9 1,162 04-14-2013, 02:46 AM
Last Post: Gerson W. Barbosa
  Amazon offering 8$ for my HP-30B Siegfried (Austria) 7 928 04-13-2013, 04:38 PM
Last Post: Chris Smith
  That is how they should sell the HP 30B :) Harald 11 1,266 04-07-2013, 11:44 AM
Last Post: Juergen Keller
  20b, 30b not in HP's web store Eric Smith 3 639 02-08-2013, 11:52 AM
Last Post: Walter B

Forum Jump: