Page 1 of 6

External stack

Posted: Thu Mar 14, 2019 7:30 am
by hsilop
Greetings fellow DM42 owners. I received mine only 2 days ago and have been feverishly porting my library of astrophysics programs from my HP41CV.

I soon discovered that programs do ugly things to the stack, and having such a lovely custom menu arrangement I though I'd like to make programs that operate like function *only* change the X register and programs that act like procedures push their result onto the stack. So I built an external stack. These programs will work even one program calls another ( as a lot of mine do ) since the external stack can hold many previous incarnations of the stack contents.

BTW - I am *very* new to HP42 style programming so be gentle with me. I am just trying to find ways to leverage the most out of this truly incredible machine

Read on ..

Stack is initialiased ( once ) like so:

Code: Select all

SIZE 100
99
STO "SP"

The stack starts at register 99 and grows downwards. SP is the stack pointer.

There are two top level progams "STKPSH" which pushes the X,Y,Z and T registers onto the stack, leaving the current stack undisturbed. And "STKPOP" which pops the previously pushed values for X,Y,Z and T.

Code: Select all

LBL "STKPSH"
XEQ "STKSAV"
XEQ "PUSH"
XEQ "PUSH"
XEQ "PUSH"
XEQ "PUSH"
XEQ "STKRES"
END

LBL "STKPOP"
XEQ "POP"
STO "STK_T"
XEQ "POP"
STO "STK_Z"
XEQ "POP"
STO "STK_Y"
XEQ "POP"
STO "STK_X"
XEQ "STKRES"
END

LBL "STKRES"
RCL "STK_T"
RCL "STK_Z"
RCL "STK_Y"
RCL "STK_X"
END

LBL "STKSAV"
STO "STK_X"
R↓
STO "STK_Y"
R↓
STO "STK_Z"
R↓
STO "STK_T"
R↓
END

LBL "PUSH"
STO IND "SP"
R↓
1
STO- "SP"
R↓
END

LBL "POP"
1
STO+ "SP"
RCL IND "SP"
END
In my functions I call STKPSH to the very start, perform whatever actions to calculate the return value then save X call STKPOP, ROLL and restore X just before returning.

Code: Select all

 XEQ "STKPSH"
 ... does something to X
STO "SAV_X"
XEQ "STKPOP"
R↓
RCL "SAV_X"
END
 
Procedures do a similar thing with the exception of the old X value not being rolled.

Code: Select all

 XEQ "STKPSH"
 ... computes a new X
STO "SAV_X"
XEQ "STKPOP"
RCL "SAV_X"
END
 
Here is a complete example. This function shows X light-years in metres. Register C holds the speed of light in a vacuum in metres per second.

Code: Select all

LBL "LYtoM"
XEQ "STKPSH"
RCL "C"
3600
×
24
×
365.25
×
×
STO "SAV_X"
XEQ "STKPOP"
R↓
RCL "SAV_X"
END

Re: External stack

Posted: Thu Mar 14, 2019 10:38 am
by Walter
Looks like a very nice idea. I think that others being more competent in SW shall investigate for possible side effects though.

Re: External stack

Posted: Thu Mar 14, 2019 11:42 am
by hsilop
It was the side effects I was trying to eliminate. This scheme makes one-number functions operate the same as built-in function like SQRT and one value procedures work like PI or RCL. The X,Y,Z,T stack behaves as you would expect.

Re: External stack

Posted: Thu Mar 14, 2019 1:52 pm
by Walter
Those are not the side effects I meant. Using your external stack, you eat memory - how do you care for (e.g. statistical) data competing for this memory?

Re: External stack

Posted: Thu Mar 14, 2019 9:58 pm
by hsilop
What registers are used by statistical functions? Would it help If I declared the external stack as a matrix perhaps? I haven't read much about those yet.

But, seriously, we have SO MUCH free memory on the DM42 surely I can find a quiet patch for my stack.

Re: External stack

Posted: Fri Mar 15, 2019 12:20 am
by dlachieze
You can also see the PUSH/POP stack routines published earlier in this sub-forum.

Re: External stack

Posted: Fri Mar 15, 2019 12:39 am
by Thomas Okken
hsilop wrote:
Thu Mar 14, 2019 9:58 pm
What registers are used by statistical functions?
The statistical functions use numbered registers (which in turn are stored in the matrix variable REGS). By default it uses registers 11 through 23, as follows:

11: ΣX
12: ΣX↑2
13: ΣY
14: ΣY↑2
15: ΣXY
16: N
17: ΣLN(X)
18: ΣLN(X)↑2
19: ΣLN(Y)
20: ΣLN(Y)↑2
21: ΣLN(X)LN(Y)
22: ΣXLN(Y)
23: ΣYLN(X)

This applies to ALLΣ mode. In LINΣ mode, the sums involving logarithms are not accumulated, so from the list above, only registers 11 through 16 are used in that case. The default is ALLΣ.

Finally, this block of registers can be moved to a different address using the ΣREG function. The default setting, as shown above, is ΣREG 11.

ΣREG 11 plus LINΣ modes corresponds with the behavior of the HP-41 series.

Re: External stack

Posted: Fri Apr 05, 2019 9:46 am
by hsilop
Forget this shit approach, the PUSH/POP stack thread by whuyse is a MUCH more elegant solution.

I'm just a noob ... matrices rock!

Re: External stack

Posted: Fri Apr 05, 2019 9:51 am
by Thomas Okken
The next release of Free42 will have local variables, which will make it possible to preserve the stack with no side effects at all. Stay tuned...

Re: External stack

Posted: Fri Apr 05, 2019 1:08 pm
by akaTB
Thomas Okken wrote:
Fri Apr 05, 2019 9:51 am
The next release of Free42 will have local variables, which will make it possible to preserve the stack with no side effects at all. Stay tuned...
:shock: