Post Reply 
hp41cx named variables in extended memory
02-03-2020, 10:43 PM
Post: #1
hp41cx named variables in extended memory
Was there a utility routine in PPC or other that let you create named variables in extended memory? I thought there was?

I know the performance would suffer but it might suite my application. I am picturing something that let you store a name in Alpha and it would provide CRUD functions to manage a value stored under that name in EM.

Thanks!
Todd
Find all posts by this user
Quote this message in a reply
02-04-2020, 05:28 AM (This post was last modified: 02-04-2020 05:28 AM by dayd.)
Post: #2
RE: hp41cx named variables in extended memory
Hi Todd,
I use this sub that I wrote to retrieve currency values (devise is French for currency) from a text file, no other module than XF or CX is needed. At start the currency code name is in alpha. And the value ends in x of course.

Code:
LBL "DEVISE"
ASTO L
"DBD"
ENTER^
CLX
SEEKPTA
CLA
ARCL L
CLX
POSFL
GETREC
CLX
ANUM
END

The "DBD" text file come regularly from a script on my phone (I don't have the internet in my CX, yet...) and looks like this;

Code:
UPD 03,022020
USD 1,1059
JPY 120,24
DKK 7,4724
GBP 0,8512
SEK 10,667
CHF 1,0687
CZK 25,208
AUD 1,6532
CAD 1,4704
BRL 4,6964
FRF 6,55957

I have a similar system for GPS coordinates with 2 values per record and the ANUMDEL function from the XIO module come handy in that case.
I think that the Paname rom have interesting related functions, too.

André
Find all posts by this user
Quote this message in a reply
02-27-2020, 02:54 AM (This post was last modified: 02-29-2020 04:39 PM by Artur - Brasil.)
Post: #3
RE: hp41cx named variables in extended memory
Hi,
I'm writing two programs for 41C with X-Functions and X-Memory.

One creates a data file in X-Memory for replacing registers from 00 to 10 (it can replace any register, actually, if you get memory to hold the programm (or a NovRAM - HEPAX module).
So, operations like RCL 05 will be written as XEQ "R5"; STO 05 as XEQ "S5"
One subroutine creates the file: ALPHA: name of file; X: number of registers - XEQ "XREG"
One subroutine for each "Rn" and one for each "Sn".
It's quite a byte consumming, but works. You can get private data registers for every program.
The routine CU, in synthetic programming books is not very usefull - only for called programs: after you called it, the n registers (in main memory) will desappear to the called program. My got another way, but eats bytes...

It's already finished.

The second program is for creating a file in X-Memory for named variables (name up to six charaters) , for numeric or alpha contents. I'm writting it.
One subroutine creates the file: ALPHA: name of file XEQ "XVAR".
Two subroutines for recovering values: in ALPHA, put the name of variable. So, if numeric, XEQ "XRCL": the content will be recovered to X; if alpha, XARCL will recover content to ALPHA.
For storing data, ALPHA: name:value XEQ "XSTO", either for alpha or numeric variable.

What do you think about this idea?
Best wishes from Brazil
Artur

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-27-2020, 01:15 PM
Post: #4
RE: hp41cx named variables in extended memory
(02-27-2020 02:54 AM)Artur - Brasil Wrote:  What do you think about this idea?
Best wishes from Brazil
Artur

Greetings Artur, very interesting. I have an unusual pattern when I program the '41cx. I associate a six character mnemonic with each important register variable and i create a table in extended memory that links a strict type with the name and register number. I have a simple routine to display them. I also use a six character label for each function (but I always wind up scavaging those back to simple numeric labels to recover registers as the program grows).

Its the only way I can write "literate" code in the 41 that lets me set the project down and stand a chance when I come back to it.

Your function(s) might provide a better way to actually drive the register values to EM. Especially since, once I had the program debugged, I could move them "back" into registers to recover performance.

please share as you develop your utilities.
Regards
Todd
Find all posts by this user
Quote this message in a reply
02-27-2020, 03:03 PM
Post: #5
RE: hp41cx named variables in extended memory
Yesterday at night, I realized another way to make the STO function for numeric x-registers from 10 to 19.
It is using flag 10. If you want to store in x-register 10 or above, just set flag before calling S0, S1, S2 ... S9 (I'll add 10, giving S10, S11 .. S19). This solution will save many bytes for routines from S10 ... S19.
I did not analyze the impact on RCL function yet. Let's see if it will also be possible to use flag 10 too for RCL.
I believe the majority of programs use less than 10 registers - so, this solution would work well. Putting the SF 10 instruction before restoring from 10 to 19 will be tedious. It's something to analyze...

I'll provide both solutions and wait for community improvements. HP-41 is really a great computer system!

Best wishes!
Artur

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-27-2020, 03:50 PM
Post: #6
RE: hp41cx named variables in extended memory
Quote:Its the only way I can write "literate" code in the 41 that lets me set the project down and stand a chance when I come back to it.
If your goal is more readable code then I know there's a 41C compiler that runs on a PC and lets you use names instead of register numbers (numbered labels too?) So you can do things like:
Code:
define COUNTER 01
; Count the numbers from 1 to X
STO COUNTER
0.
LBL 00
RCL COUNTER
+
DSE COUNTER
GTO 00
I don't recall the name offhand.
Find all posts by this user
Quote this message in a reply
02-27-2020, 04:44 PM
Post: #7
RE: hp41cx named variables in extended memory
Quote: I have an unusual pattern when I program the '41cx. I associate a six character mnemonic with each important register variable and i create a table in extended memory that links a strict type with the name and register number.

If I understood well, you create a reference table, like a help for remembering what REG 10, by example, means in your programm.

RAM X-MEMORY FILE
REG 10 ---> 10 Prices average (example)

It's a great idea too!
But my work is in another way! Store values in X-memory like you do in RAM.
STO 05 ---> S5
RCL 05 ---> R5

Best wishes!
Artur

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-27-2020, 08:21 PM (This post was last modified: 02-28-2020 02:41 PM by Artur - Brasil.)
Post: #8
RE: hp41cx named variables in extended memory
(02-27-2020 03:50 PM)David Hayden Wrote:  
Quote:Its the only way I can write "literate" code in the 41 that lets me set the project down and stand a chance when I come back to it.
If your goal is more readable code then I know there's a 41C compiler that runs on a PC and lets you use names instead of register numbers (numbered labels too?) So you can do things like:
Code:
define COUNTER 01
; Count the numbers from 1 to X
STO COUNTER
0.
LBL 00
RCL COUNTER
+
DSE COUNTER
GTO 00
I don't recall the name offhand.
Great, David, but as you told, this compiler runs on a PC, so, it's not portable as my 41CX. I'm making one for 41 with X-funtions and X-Memory on 41CX. Even if it does not add too much in importance, it is beeing a great adventure make it!
Artur

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-28-2020, 02:27 PM (This post was last modified: 02-28-2020 02:59 PM by Artur - Brasil.)
Post: #9
RE: hp41cx named variables in extended memory
Hi, guys!

Here is the code for creating numeric registers in X-Memory, version 1. No use of flag 10.

Version 1 - stores from 00 to nnnnnn, limited only to program memory and X-Memory available.

Main program: creates the X-file to hold numeric registers, given ALPHA: file name X:number of registers (ex: 15 - will be available 00 to 14)
LBL "XREG"
SF 25
CRFLD
FC?C 25
RSZFL if file already exists, resize it, in case you have changed to a bigger os smaller file
CLX
SEEKPTA
RTN

LBL "R0" global labels for Restoring (RCL) - just call them in your program or from keyboard
0
GTO 00
LBL "R1"
1
GTO 00
LBL "R2"
2
GTO 00
... repeat LBL "Rnnnn" as many times your biggest neccessity of storage registers
... but be aware we are calling a local label, so, distance from fist GTO 00 must be
... less than 112 Byte
... my experience showed that you can create up to R10 and this limitation will be
... preserved. After routine LbL 00, you can resume LBL "R11" up to "R19" and distance
... will be less than 112Byte

LBL "R2"
10 the last routine just befor LBL 00 doesn't need the GTO 00 instruction!
LBL 00 local subroutine to make the restoring work - preserves Y,Z,T stack registers, as STO
SEEKPT
CLX
GETX
RTN
... as told before, you can continue with "R11" up to "R19" here, if desired. Let's put two ex.
LBL "R11"
11
GTO 00
...
LBL "R19"
19
GTO 00 well, if you need more registers, for each group of nine (R20-R28, R29-37, ...) you
must replicate the LBL 00 subroutine as LBL 02, LBL 03, for example, and change the GTO 00 to GTO 02, GTO 03 too. The distance limitation will be preserved.

LBL "S0" here we star the restoring global labels. As "Snn", just call them from programs or k.
X<> L Storing is more complicated and consumes more bytes, but preserves stack, as STO
CLX
0
GTO 01
LBL "S1"
X<> L
CLX
1
GTO 01
... again, insert as many "Snn" routines as you have created "Rnn". The distance limitation for GTO 01 exists too. You can put up to "S9" before the subroutine LBL 01
LBL "S9"
X<> L
CLX
9 the last routine just before LBL 01 doesn't need the GTO 01 instruction!
LBL 01 here the routine which saves the X contents.
SEEKPT
X<> L
SAVEX
RTN
... as told before, you can continue with "S10" up to "S17" here, if desired. Let's put one ex.
...
LBL "S17"
X<> L
CLX
17
GTO 01
well, if you need more, for each group of seven (S18..S24, S25..31...) you
must replicate the LBL 01 subroutine as LBL 05, LBL 06 and change GTO 01 to GTO 05, GTO 06... The distance limitation will be preserved.

END

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-28-2020, 02:37 PM (This post was last modified: 02-28-2020 05:35 PM by Artur - Brasil.)
Post: #10
RE: hp41cx named variables in extended memory
As seen above, the code gets bigger as number of registers to store/restore increases.
For 19 registers, the program gets 180 lines, 499 bytes.
Another infortune was routines for storing beeing bigger than for recalling, leading to the number of recalling storing around LBL 01 being different of recalling.

So, I put my head to work: using FLAG 10 could prevent creating routines for working with registers from 10 to 19. But... you will need to set flag 10 before storing or restoring from 10 .. 19. Example:

SF 10
XEQ "R4" will restore the value of register 14 instead of 4.

This solution will save a lot of bytes, but is limited to register 19 (9 + 10) and requires user remembers of including SF 10 instruction before XEQ "Rnn"

Best wishes
Artur

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-28-2020, 07:52 PM (This post was last modified: 02-29-2020 02:36 AM by Artur - Brasil.)
Post: #11
RE: hp41cx named variables in extended memory
Here the full version 2.1 - using FLAG 10 for sto/rcl 10-19 (remember, size of file must be 1+ the higher register number you're going to use - up to 19 in this version).
323 bytes against 499 of version 1 !!!

1 LBL "XREG2" creates the file for X-Regs given ALPHA: file_name X: number of regs (you will have 0...n-1)
2 SF 25
3 CRFLD
4 FC?C 25
5 RESZFL if file already exists, just resize it.
6 CLX
7 SEEKPTA
8 RTN
9 LBL "R0" to recover regs from 00 to 09, just call XEQ "R0" .. XEQ "R9".
10 0 For registers from 10..19: SF 10 XEQ "R0" .. XEQ "R9"
11 GTO 00 each time you call Sn or Rn routines, FLAG 10 is cleared automatically.
12 LBL "R1"
13 1
14 GTO 00
15 LBL "R2"
16 2
17 GTO 00
18 LBL "R3"
19 3
20 GTO 00
21 LBL "R4"
22 4
23 GTO 00
24 LBL "R5"
25 5
26 GTO 00
27 LBL "R6"
28 6
29 GTO 00
30 LBL "R7"
31 7
32 GTO 00
33 LBL "R8"
34 8
35 GTO 00
36 LBL "R9"
37 9
38 LBL 00 the local label that process STO work
39 FS?C 10
40 XEQ 02
41 SEEKPT
42 CLX
43 GETX
44 RTN
45 LBL 02 auxiliary routine for regs 10 ... 19
46 RUP
47 STO L
48 RDN
49 10
50 STO+ Y
51 X<> L
52 RDN
53 RTN
54 LBL "S0" to store regs from 00 to 09, just call XEQ "S0" .. XEQ "S9".
55 X<> L For registers from 10..19: SF 10 XEQ "S0" .. XEQ "S9"
56 RDN
57 FC? 10
58 0
59 FS?C 10
60 10
61 GTO 01
62 LBL "S1"
63 X<> L
64 RDN
65 FC? 10
66 1
67 FS?C 10
68 11
69 GTO 01
70 LBL "S2"
71 X<> L
72 RDN
73 FC? 10
74 2
75 FS?C 10
76 12
77 GTO 01
78 LBL "S3"
79 X<> L
80 RDN
81 FC? 10
82 3
83 FS?C 10
84 13
85 GTO 01
86 LBL "S4"
87 X<> L
88 RDN
89 FC? 10
90 4
91 FS?C 10
92 14
93 GTO 01
94 LBL "S5"
95 X<> L
96 RDN
98 FC? 10
99 5
100 FS?C 10
101 15
102 LBL 01
103 SEEKPT
104 X<> L
105 SAVEX
106 RTN
107 LBL "S6"
108 X<> L
109 RDN
110 FC? 10
111 6
112 FS?C 10
113 16
114 GTO 01
115 LBL "S7"
116 X<> L
117 RDN
118 FC? 10
119 7
120 FS?C 10
121 17
122 GTO 01
123 LBL "S8"
124 X<> L
125 RDN
126 FC? 10
127 8
128 FS?C 10
129 18
130 GTO 01
131 LBL "S9"
132 X<> L
133 RDN
134 FC? 10
135 9
136 FS?C 10
137 19
138 GTO 01
139 END

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
02-29-2020, 12:17 PM
Post: #12
RE: hp41cx named variables in extended memory
[quote='Artur - Brasil' pid='128543' dateline='1582919576']
Here the full version 3.0 - using FLAG 10 for sto/rcl 10-19, BUT, with just 263 bytes, against 323 bytes of version 2.1 and 499 of version 1.0!

How it was possible? I modified the registers mapping from what user sees and how to store them.
Version 2.1:
WANTED X-REG
00 ----> 00
01 ----> 01
...
19 (FLAG 10) --> 19

Version 3.0:
00 --> 00
01 --> 02
02 --> 04
03 --> 06
...
09 --> 18
10 --> 01
11 --> 03
12 --> 05
...
18 --> 17
19 --> 19

And instead of add 10, I removed 1, using DSE, which does not disturb stack! Great!

1 LBL "XREG2"
2 SF 25
3 CRFLD
4 FC?C 25
5 RESZFL
6 CLX
7 SEEKPTA
8 RTN
9 LBL "R0"
10 1
11 GTO 00
12 LBL "R1"
13 3
14 GTO 00
15 LBL "R2"
16 5
17 GTO 00
18 LBL "R3"
19 7
20 GTO 00
21 LBL "R4"
22 9
23 GTO 00
24 LBL "R5"
25 11
26 GTO 00
27 LBL "R6"
28 13
29 GTO 00
30 LBL "R7"
31 15
32 GTO 00
33 LBL "R8"
34 17
35 GTO 00
36 LBL "R9"
37 19
38 LBL 00
39 FC?C 10
40 DSE X
41 SEEKPT
42 CLX
43 GETX
44 RTN
45 LBL "S0"
46 X<> L
47 RDN
48 1
49 GTO 01
50 LBL "S1"
51 X<> L
52 RDN
53 3
54 GTO 01
55 LBL "S2"
56 X<> L
57 RDN
58 5
59 GTO 01
60 LBL "S3"
61 X<> L
62 RDN
63 7
64 GTO 01
65 LBL "S4"
66 X<> L
67 RDN
68 9
69 GTO 01
70 LBL "S5"
71 X<> L
72 RDN
73 11
74 LBL 01
75 FC?C 10
76 DSE X
77 SEEKPT
78 X<> L
79 SAVEX
80 RTN
81 LBL "S6"
82 X<> L
83 RDN
84 13
85 GTO 01
86 LBL "S7"
87 X<> L
88 RDN
89 15
90 GTO 01
91 LBL "S8"
92 X<> L
93 RDN
94 17
95 GTO 01
96 LBL "S9"
97 X<> L
98 RDN
99 19
100 GTO 01
101 END

One further improvement: replace all:
X<> L 2 byte
RDN 1 byte = 3byte*9 = 27byte

For:
XEQ 03 2byte * 9 = 18
...
LBL 03 2
X<> L 2
RDN 1
RTN 1 = 6byte + 18 = 24byte,
only 3 bytes of gain. But one more XEQ and subroutine level.

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
03-01-2020, 01:26 AM (This post was last modified: 03-01-2020 10:26 AM by Artur - Brasil.)
Post: #13
RE: hp41cx named variables in extended memory
Making a simple arithmetic:

20 regs in HP-41 memory = 7bytes * 20 = 140 bytes

My routines use, for the same 20 regs : 499 bytes or 263 bytes (and more X-Memory to hold the registers).

If you see just the bytes, no way to win this war. But the main idea is to have private numbered registers for those programs that serve as basis for others.

Both routines make the x-file the current one only at initialization. So, if your programs make use of others X-files, you will need to make the X-Reg file the current one again.

Best wishes!
Artur - Brasil

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
03-17-2020, 09:32 PM (This post was last modified: 03-18-2020 02:48 PM by Artur - Brasil.)
Post: #14
RE: hp41cx named variables in extended memory
Revison A (mars, 18th)

As promised, although nobody indeed made even any comment about it, here the routine to create named variables in X-memory, complementing the X-Memory numbered registers routine published before.

The vars must have a name up to 5 chars. Example: WIDTH. Please, do not use : in variable name.

All variables will be saved in a X-files which names you give. Each X-File has no limit for number of variables, only limited to memory available.

The use is very simple: put the name of file (to be created or already existing) in ALPHA, by example: BOX. If file does not exist yet, it will be created; if already exists, the program just open it.

IMPORTANT: both routines (STA and RCA) make the x-file the current one only at initialization (XVARN). So, if your programs make use of others X-files, you will need to make the X-Reg file the current one again.

Call XVARN (X-Variables Named) routine:

ALPHA BOX ALPHA
XEQ ALPHA XVARN ALPHA

Now, you must have one text X-File named BOX. (See cathalog 4 in CX)

For creating and saving the variable LEN with value 10, just type:
ALPHA LEN ALPHA 10 XEQ ALPHA STA ALPHA. (Store Alpha named variable)

Create as many variables your X-Memory modules can hold.
Not allowed two variables in the same file with same name.

For recovering the contents of any named variable, put its name in ALPHA register and call RCA routine.

ALPHA LEN ALPHA XEQ ALPHA RCA ALPHA --> X: 10

I saved variables in X-file as: nameConfusedn.nnnnnnnnEsnn (s - signal)
Numeric values are stored in American and Scientiic format, up to 9 digits of precision.
This may lead to something like: LEN:1,200000000E1 which is a waste of precious bytes on 00000000 sequence.
So, I created a routine to clean these unneccessary zeroes and compress the file to minimal registers needed.
Eventually, call CLNVAR (clear nominal var file), with the current x-file as the one you want to clean or insert a call to it in the XVARN routine. So, it will run when you start the process (remove the VIEW commands in routine CLNVAR.

Here is the full code (REV A)

1 LBL "XVARN"
2 X<> L
3 RDN
4 1
5 SF 25
6 CRFLAS
7 CF 25
8 X<> L
9 RTN

10 LBL "STA"
11 X<> L
12 RDN
13 58
14 XTOA
15 RDN
16 POSFL
17 X<0?
18 GTO 02
19 DELREC
20 X<> L
21 LBL 03
22 RCLFLAG
23 RDN
24 SF 28
25 SCI 9
26 ARCL X
27 APPREC
28 RUP
29 STOFLAG
30 CLX
31 SEEKPT
32 RDN
33 RTN

34 LBL 02
35 X<> L
36 ASTO L
37 CLA
38 FLSIZE
39 ARCL L
40 x<> L
41 RDN
42 4
43 ST+ L
44 X<> L
45 RESZFL
46 RDN
47 GTO 03

48 LBL "RCA"
49 STO L
50 CLX
51 SEEKPT
52 RDN
53 58
54 XTOA
55 RDN
56 POSFL
57 X<0?
58 GTO 01
59 GETREC
60 CLX
61 SEEKPT
62 RDN
63 RCLFLAG
64 X<> L
65 SF 28
66 SCI 9
67 ANUM
68 X<> L
69 STOFLAG
70 X<> L
71 RTN

72 LBL 01
73 X<> L
74 "^NOT FOUND"
75 AVIEW
76 BEEP
77 RTN

78 LBL "CLNVAR" compress named vars x-file to minimal neccessary of bytes
79 CLA
80 X<> L
81 RDN
82 FLSIZE
83 VIEW X
84 LBL 06
85 CLX
86 SEEKPT
87 "0E"
88 RDN
89 POSFL
90 X<0?
91 GTO 07
92 VIEW X
93 ST/ X
94 DELCHR
95 GTO 06
96 LBL 07
97 RDN
98 CLA
99 FLSIZE
100 SF 25
101 LBL 08
102 VIEW X
103 DSE X
104 RESZFL
105 FS? 25
106 GTO 08
107 CLX
108 SEEKPT
109 x<> L
110 BEEP
111 END

Hope it can help someone!

Best wishes from Brazil
Artur


Attached File(s)
.pdf  NamedVar.PDF (Size: 10.38 KB / Downloads: 2)

ARTUR MARIO JUNIOR
BRAZIL
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 4 Guest(s)