HP Forums

Full Version: HP 41 - branching to local label and return stack - FINAL RESULTS AND PROGRAMS
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
I'm trying to use my 41 in a routine to make soft menus (like on 48 or 50 series, where the data is input to variables listed in a bottom line of display assigned to first keyboard row).
Well, the 41 has not a dedicated bottom line in display, but we can display a space or : separeted "variables" in display and it's up to the user key in the corrrespondent key of two top rows in keyboard.
Well, the problem with my new version is that I pass from one caller program to the SFTMEN the string to display and this program prompt it to user, but, when him presses the A...E and the program branches to local label A ... E it looses the return to caller program!
I read a lot and seems to me that I saw something that could be done for not loosing the return stack.

Does anyone could help me? Or has a routine that could be used for soft menus in 41CX?

Here the first steps of both programs:

MAIN:
01 - LBL "AUTO"
02 - "BA:POT:IMP:CUR:"
03 - XEQ "SFTMEN"
04 - X=0?

SFTMEN program:
01 - LBL "SFTMEN"
02 - PROMPT
03 - LBL A
04 - 1
05 - STO 42
06 - RTN ' DOESN'T WORK!
07 - LBL B
...
I believe 'prompt' is looking for the user to enter a number.

This works (i.e. returns) where the user enters a number from 1-4 corresponding to the menu item.

SFTMEN program:
01 - LBL "SFTMEN"
02 - PROMPT
03 - STO 42
06 - RTN

Also in USER mode the top two rows of keys will directly execute routines if they have the LBL A-J in the current program.

That would look like:

MAIN:
01 - LBL "AUTO"
02 - "BA:POT:IMP:CUR:"
03 - AVIEW
04 - STOP
05 - LBL A
.......
The typical way I've seen it done (such as in the TVM program on the Advantage module) is to have the appropriate A-E local labels for input/output variables, and another local label (usually J) that displays the soft-menu. To enter values in the variables, just type a value into X and press the corresponding key.

The rough structure of the program would be like this:

LBL "TVM"
...various program-specific setup steps (clear key assignments, turn on USER, etc.)...
XEQ J //Display the soft-menu and stop
RTN
LBL A
FC?C 22 //Check for user input
XEQ "N" //No user input, call the solve/computation routine for this variable
STO 01 //Store X into 01 (n, in the case of TVM), whether user input or the newly computed value
RTN
...similar labels for B-E, and a-e if you want shifted functions...
LBL J
"N I% PV PMT FV"
AVIEW
RTN

This is a pretty user-friendly way to do it that doesn't require a lot of extra program steps, and the UX is very similar to the TVM and soft-menu solvers on other models.
(05-20-2019 03:00 PM)Craig Bladow Wrote: [ -> ]I believe 'prompt' is looking for the user to enter a number.

This works (i.e. returns) where the user enters a number from 1-4 corresponding to the menu item.

SFTMEN program:
01 - LBL "SFTMEN"
02 - PROMPT
03 - STO 42
06 - RTN

Actually, this prompt expects:
A number (data) and corresponding key - will get the register number to store this data; next will store data in it; so, will turn on a control flag and will return to menu;
Just the corresponding Key pressed - will get the register number that holds the data and will display (PSE) it; so, will turn on a control flag and will return to menu;
R/S - if the user informed data or get the data diplayed before, the control flag will be ON and this last variable input/viewed saved. So, pressing R/S will solve for this last variable.
R/S without previous data input or data viewing - an error (BEEP) and returns to menu.

It mimics the HP-12C for solvind financial data, but with some increments...

Quote:Also in USER mode the top two rows of keys will directly execute routines if they have the LBL A-J in the current program.
That would look like:
MAIN:
01 - LBL "AUTO"
02 - "BA:POT:IMP:CUR:"
03 - AVIEW
04 - STOP
05 - LBL A
.......
This is what I was expecting to happen and 41 actually does it, but with a big mistake: it kills the return stack, so, I can't go back to the main program!
I was reading about Synthetic Programming and return stack is kept in registers a and b. If I could save these registers before the PROMPT and restore them back in the labels A, B, C ... this would be one (uggly) solution for this problem. But such routine in Synthetic Program is for big guys...
(05-20-2019 03:41 PM)Dave Britten Wrote: [ -> ]The typical way I've seen it done (such as in the TVM program on the Advantage module) is to have the appropriate A-E local labels for input/output variables, and another local label (usually J) that displays the soft-menu. To enter values in the variables, just type a value into X and press the corresponding key.
The rough structure of the program would be like this:

LBL "TVM"
...various program-specific setup steps (clear key assignments, turn on USER, etc.)...
XEQ J //Display the soft-menu and stop
RTN
LBL A
FC?C 22 //Check for user input
XEQ "N" //No user input, call the solve/computation routine for this variable
STO 01 //Store X into 01 (n, in the case of TVM), whether user input or the newly computed value
RTN
...similar labels for B-E, and a-e if you want shifted functions...
LBL J
"N I% PV PMT FV"
AVIEW
RTN

This is a pretty user-friendly way to do it that doesn't require a lot of extra program steps, and the UX is very similar to the TVM and soft-menu solvers on other models.

Yes, Dave, this is what I'm trying to do, but I have many equations/formulas (electrical machines and their formulas) to programm. The registers that will keep the variables are previously mapped, so, I was trying to put the menu routines in a separated programm and call it (and a few inner subroutines) as need. The it would be better to put the PROMPT command in that programm, not in the main programm.
Hello Artur,
I did a small investigation of the return stack content with ZENROM RAMED.
After some experiments it became clear that the return stack is cleared when you interactively press one alpha local label (A..J & a..e).
This is why it never returns when you press A in user mode but in your example it will if you press R/S (simulating pressing A but not actually pressing it).
You need to reorganize your solution to put the local alpha labels in your main program.
Sylvain
Hi Sylvain,

This code was - I was thinking this - an evolution of what you told: "put the A...E treatment inside your code (main program). What a disgusting discovery ...

I was reading the book Advanced Programming Tips for HP41, where they mention ZenRom a lot , to see if it could show some solution. Nothing ...

Well, saving a and b control registers and recovering them after 41 has cleaned the return stack could work?
I would like to try, but I don't know how to inser such RCL b RCL a and respective STO in a FOCAL programm.
PPC has something on page 264 (PDF file) or 254 (printed page).
Also important explanition on 267 (PDF) or 257 (printed page).
Hello Artur,

You could use the LR (Lengthen Return stack) and SR (Shorten Return stack) FOCAL programs from the PPC ROM.
I modified your program with something that should work like you want it.

Sylvain

MAIN:
Code:
01 LBL "AUTO"
02 "BA:POT:IMP:CUR:"
03 XEQ "SFTMEN"
04 X=0?
...
SFTMEN program:
Code:
01 LBL "SFTMEN"
02 AVIEW
03 5                           // destination register for LR
04 XROM "LR"                   // saving 5 return addresses into register 5 & 6
05 CLA
06 STOP
Code:
07 LBL A    
08 1    
09 STO 42
10 GTO 10
11 LBL B    
...
XX GTO 10
...
Code:
XX LBL 10
XX 5                           // source register for SR
XX XROM "SR"                   // restoring 5 return addresses from register 5 & 6
XX END
(05-20-2019 05:50 PM)Artur - Brasil Wrote: [ -> ]PPC has something on page 264 (PDF file) or 254 (printed page).
Also important explanition on 267 (PDF) or 257 (printed page).
I see that we had the same thinking path Wink
Here the full routine of softmenu.
The caller programm, or main program, exists for some topic - in my case, there will be a programm for transformers, one for ac motors, one for dc motors, one for auto-transformers, and so on.
Each topic has many functions (equations) for solving: B = u.A; A = N1/N2, etc...
So, each main programa has one menu for these equations "B:A:FMM:..."
Each equation or function has many variables: "B: u: A" for example. As registers for holding them are fixed in softmenu and I would try do not overwrite ones by anothers, I give the user the chance to use from A...E or a...e in first menu and same in a second menu.

It may seems difficult to use, but actually it is very easy.
Main program:
"equations menu"
call SFTMEN
LBL 01
first equation implementation:
"equation name" --> X
"1st variables menu"
call SFT1
"2nd variables menu" //or CLA if there is no 2nd menu
call "SFT2"
tests on variables before the use o SOLVE
everything ok? calls SFT3 (it will call SOLVE)
lbl "Equation"
your equation for SOLVE (Advantage module)
RTN -- end of first equation
second equation ...
third equation ...



1 LBL "SFTMEN" //expects in ALPHA: "menu of functions"
2 CF 01 //clear solution for variable
3 PROMPT // shows functions menu
4 0 //R/S or J return to main program
5 RTN
6 LBL A //BIG PROBLEM - kills return stack
7 1
8 STO 42 //indirect register for numeric label of function
9 RTN
10 LBL B
11 2
12 STO 42
13 RTN
14 LBL C
15 3
16 STO 42
17 RTN
18 LBL D
19 4
20 STO 42
21 RTN
22 LBL E //up to 5 functions by main programm
23 5
24 STO 42
25 RTN
26 LBL "SFT1" //expects in X: name of selected function; ALPHA: variables menu of it
27 CF 05 //no 2nd menu at now
28 STO 43 //name of function (will be used by SOLVE)
29 ASTO 47 // registers 47 and 48 will keep the functions menu
30 ASHF
31 ASTO 48
32 RTN
33 LBL "SFT2" // 2nd variables of menu (receives ALPHA: nothing - if none)
34 ALENG
35 X=0?
36 GTO 15 //no 2nd variables menu
37 SF 05 //there is 2nd variables menu
38 ASTO 49 //Registers 49 and 50 will keep the vars menu (up 12 chars)
39 ASHF
40 ASTO 50
41 LBL 15 //shows the 1st variables menu
42 CLA
43 ARCL 47 first 6 chars
44 ARCL 48 adds the 6 left most chars
45 FS? 05 //is there a second variable menu?
46 XEQ 05 //will add a > character to menu
47 CF 22 //for testing numeric data input
48 PROMPT //shows 1st variables menu
49 FS?C 01 //R/S: if activated solution ...
50 RTN // returns to main programm: will test variables for problems
51 GTO 04 // else, calls 2ns variable menu
52 LBL 05 //just add the > char to menu, indicating there is a second menu (R/S goes to it)
53 41
54 XTOA
55 RTN
56 LBL A //first menu of variables
57 1 //number of register that will hold data (variable)
58 GTO 01
59 LBL B
60 2
61 GTO 01
62 LBL C
63 3
64 GTO 01
65 LBL D
66 4
67 GTO 01
68 LBL E
69 5
70 GTO 01
71 LBL a first shift menu
72 11 //number of register that will hold data (variable)
73 GTO 01
74 LBL b
75 12
76 GTO 01
77 LBL c
78 13
79 GTO 01
80 LBL d
81 14
82 GTO 01
83 LBL e
84 15
85 GTO 01
86 LBL 01 //Receives the register that will hold data
87 STO 44 //stores indirect register that will hold data
88 FS? 22 // was something keyed in?
89 GTO 03 // stores data
90 RCL IND 44 //else, recovers already stored data
91 PSE
92 SF 01 // turns on variable solution
93 RCL 43 //get the function's name to X
94 GTO 15 //returns to 1st variables menu
95 LBL 04 // shows 2ns variables menu
96 FC? 05
97 GTO 15 // has no 2nd variables menu, returns to first one
98 CLA
99 40 // ads a < char indicating there is a previous var menu
100 XTOA
101 ARCL 49
102 ARCL 50
103 CF 22 //will test numeric data input
104 PROMPT //Shows 2nd variables menu
105 FS?C 01 //f R/S and if solution activated ...
106 RTN // returns to main programm with data in registers
107 GTO 15 // goes to begin
108 LBL J //Return to main programm with 0
109 0
110 RTN Volta programa chamador
111 LBL A //second menu for variables: A-E, a-e
112 6
113 GTO 01
114 LBL B
115 7
116 GTO 01
117 LBL C
118 8
119 GTO 01
120 LBL D
121 9
122 GTO 01
123 LBL E
124 10
125 GTO 01
126 LBL a
127 16
128 GTO 01
129 LBL b
130 17
131 GTO 01
132 LBL c
133 18
134 GTO 01
135 LBL d
136 19
137 GTO 01
138 LBL e
139 20
140 GTO 01
141 LBL 03 //stores the input data
142 X<>Y //gets the input data
143 STO IND 44 // indirect register to variable register
144 SF 01 // turns on solution for variable in reg 44
145 RCL 43 // recall the function name to X
146 GTO 15 // returns to 1st menu of variables
147 LBL "SFT3" // will execute SOLVE
148 CLA
149 ARCL 43 // recover the function name to solve
150 SOLVE //runs next step if result found
151 GTO 02
152 "NO SOL."
153 AVIEW
154 RTN
155 LBL "SFT4" //ALPHA: message of error found in variables
156 AVIEW
157 BEEP
158 RTN
159 LBL 02 //shows result found
160 RCL IND 44
161 ABS //I need all solve results positive
162 STO IND 44
163 BEEP
164 PSE
165 END
(05-20-2019 06:37 PM)Sylvain Cote Wrote: [ -> ]
(05-20-2019 05:50 PM)Artur - Brasil Wrote: [ -> ]PPC has something on page 264 (PDF file) or 254 (printed page).
Also important explanition on 267 (PDF) or 257 (printed page).
I see that we had the same thinking path Wink

Yes!!! But my knowledge stops here ... I really don't know how to work with Synthetic instructions.
I need to study them, but I have to study for faculty. I have already spent hundred of hours with my 41 ... Sad
Artur,
Before going deeper into this, what hardware do you have ?
You seem to have a HP-41CX and the Advantage module, am I correct ?
What other modules/peripherals do you have ?
Sylvain
Sylvain,

I have an HP-41CX, the Advantage, a double X-Memory and a NovRAM installed. This last has HEPAX on it. Also one Wand, a cassete and the card reader (but these last two are not in good working condition).
Well, I believe this will be not an easy task. Just reading the ZenRom notes, the a and b registers also keep the memory pointer. So, if it would be possible to put shynthetic instructions directly in my program (and not counting one back in RTN stack) we still would have to work with memory pointer - how to not rewrite this portion of registers?

Any way, manyy thanks for your kind assistance!!
(05-20-2019 07:42 PM)Artur - Brasil Wrote: [ -> ]Any way, manyy thanks for your kind assistance!!
My pleasure, I do have some free time today, I will be in and out, so expect some latency in my questions & responses.

(05-20-2019 07:42 PM)Artur - Brasil Wrote: [ -> ]I have an HP-41CX, the Advantage, a double X-Memory and a NovRAM installed. This last has HEPAX on it.
What kind of NovRAM module do you have (NoVRAM, NoV-32 or NoV-64) ?
Do you have the PIC Programmer for the NoVRAM module ?
Quote:What kind of NovRAM module do you have (NoVRAM, NoV-32 or NoV-64) ?
Do you have the PIC Programmer for the NoVRAM module ?
My one has written just NovRAM.

The HEPAX 002, removing the Advantage Module, gave me:
3: Ext Fcn 2D
4: NO ROM
5: TIME 2C
6: HEPAX 1D
7: NO ROM
8: HEPAX RAM
9: HEPAX RAM
A: HEPAX RAM
B: HEPAX RAM
C: NO ROM
D: NO ROM
E: NO ROM
F: NO ROM
I don't have the programmer, but I can try buid one, just inform the link, please.
I read a little more and get more information on page 119 (printed 114) of Synthetic Programming Made Easy.
Ok, forget about NoVRAM, I just saw that you also have a Wand, I can work that. Smile
Give me some time, I will extract the two routines (LR & SR) and their dependencies from the PPC ROM,
create barcode pages in PDF, send them to you so that you can print it and then read it with your wand.
I've been using GETKEY. This is a portion from a program I've been using for decades:

Code:
LBL 43  "GET F,X,L,C ESC"   AVIEW    \ "OK" in entry menu comes here.  Calc: key numbers here are 21, 64, 33, 13, and 15.
LBL 10   GETKEY   10 +
         SF 25   GTO IND X   GTO 43  \ If no key is pressed, GETKEY gives 0, you add 10, and loop again.  Invalid key will
                                     \ flash display once and repeat.  GTO 43, not 10 because of LCD rotate bug.

GETKEY does not stop the program, so you shouldn't lose your return stack contents (although I don't remember if I've tried it). The "add 10" part was to keep key numbers from conflicting with local-label keys, IIRC. The SF 25 is there so GTO IND X won't stop if there's no label that corresponds to the number of the key that was pressed.

Here's a slightly strange thing about it. If you don't press a key within ten seconds, it moves on (with 0 in X). If there was no key pressed whose key number matches a numerical label, I have it go around again to keep waiting. If you press a key in the short time it takes to make its way back around to re-start GETKEY, it won't see it, and you'll have to press it again.
(05-20-2019 10:03 PM)Garth Wilson Wrote: [ -> ]I've been using GETKEY. This is a portion from a program I've been using for decades:

Code:
LBL 43  "GET F,X,L,C ESC"   AVIEW    \ "OK" in entry menu comes here.  Calc: key numbers here are 21, 64, 33, 13, and 15.
LBL 10   GETKEY   10 +
         SF 25   GTO IND X   GTO 43  \ If no key is pressed, GETKEY gives 0, you add 10, and loop again.  Invalid key will
                                     \ flash display once and repeat.  GTO 43, not 10 because of LCD rotate bug.

GETKEY does not stop the program, so you shouldn't lose your return stack contents (although I don't remember if I've tried it). The "add 10" part was to keep key numbers from conflicting with local-label keys, IIRC. The SF 25 is there so GTO IND X won't stop if there's no label that corresponds to the number of the key that was pressed.

Here's a slightly strange thing about it. If you don't press a key within ten seconds, it moves on (with 0 in X). If there was no key pressed whose key number matches a numerical label, I have it go around again to keep waiting. If you press a key in the short time it takes to make its way back around to re-start GETKEY, it won't see it, and you'll have to press it again.

Hey, man, we really had the same thinking path!!
I tried this after posting my question here. Even the 10+ I did, but, for simple menu of functions it would work fine, but, going down on program, you will see others short alpha labels. Those expect three kinds of typing as I explained before: number and letter key, just letter key and R/S. This would be impossible to treat with GETKEY.
By the way, GETKEY waits for about 10s and resume if no key is pressed with code 0. I just put it in a loop: while code is 0, repeat.

Hard to find a solution, isn't it?
First I gave a chance to my 41 changing its battery system. ok
So, I get more confidence in programming it, but memory was short... so I started using X-memory and GETP.
But such programms with so many labes become large and again the memory problem.
Diego Dias come to help with this beautiful NovRAM. No more memory trouble.
Now, this almost impossible trouble with a simple RTN...
Or I study engineering or HP41, I'm exausting my forces...
But hope is the last to loose: I reset the machine and keyed the ByteGrabber routine for starting with synthetics ...

Best wishes!
Artur
Artur,
I have extracted LR and SR from the PPC ROM.
Using HP-IL module, plotter module, PILBox and pyILPER plotter simulation, I was able to plot the barcode of the program and save it to a PDF file.
I could have done with the real hardware but it was faster that way. (thank you so much Jean-Fran├žois, Christoph & Joachim for your fantastic tools)
You can find the file HERE.
I have print and loaded it into another HP-41 using the bar code reader and it works.
If you have problem reading it, try printing it with a scale of 110%, it may help the bar code reader.
Sylvain
Pages: 1 2 3
Reference URL's