Last X



#7

Bought an HP-21 recently and was amazed to find out that it has no Last X function! I never realized that. In fact, I'm ashamed to say I never realized that any of the old HP's didn't have Last X. Until recently, I've only ever owned the 25, 41 and 32SII.

Looking at the pictures in the museum, I think I only see the 21, 22, and 35 that don't appear to have Last X.

Interesting. You learn something every day.


#8

Hi;

add the HP70, HP80 and the HP81 (desktop).

Anyone else?

(to be also very honest, I knew about the fact, but I was not aware of the fact the HP21 and the HP22 did not have LastX feature. And I deal with HP calculators since 1982; infact, I've been dealing mostly with the LCD types, I have only three LED-display models)

Thank you! Good point!

Vieira, Luiz C. (Brazil)


#9

Some time ago, I posted a 48 series / 49G replacement program for the
"Classic RPN" LSTx command. But in that program, if the
last arguments buffer is empty, then, unlike the classic RPN
LSTx command, it returns nothing to the stack and puts
the real number 0 in the last arguments buffer.

As (I hope) everyone here knows, on a classic RPN calculator (well, at
least those that have a LSTx key), the LAST X register
always exists and always contains one object. Even after a reset of
continuous memory, it contains the number 0 (perhaps arguably 0h in the
case of my 16C). The LSTx command always returns one
object to the stack.

On an RPL calculator, the situation is rather different. It doesn't have
a LAST X register or LSTx command; instead, it has a
last arguments buffer, which contains from 0 through 5 objects, and a
LASTARG (LAST on a 28 series) command which returns from 0 through 5
objects to the stack. Also, it's possible to disable last arguments save
and recovery entirely, for example, by setting system flag -55 on a 48
series or 49G, or by clearing system flag 31 on a 28 series; in this
case the LASTARG (LAST on a 28 series) command errors out.

The following programs should work on any 48 series or 49G calculator,
but for a 28 series, the LASTARG command would have to be changed to
LAST, and, in the second and third programs, the sequence "-55. SF CF"
changed to "31 CF SF".

*Not tested* on a 28 series or with "ROM" revisions other than 1.19-6 on
a 49G. Tested on 48SX ROM version E, 48GX ROM version R, and 49G "ROM"
revision 1.19-6.

Now that I think of it, on a 48 series or 49G, LAST is a synonym for
LASTARG; it compiles to the same thing as LASTARG, but that always
decompiles to LASTARG.

The following programs differ in how they handle the case that the last
arguments buffer is empty. The last arguments buffer will be empty
immediately after a warmstart, and immediately after last arguments is
enabled (-55 CF on a 48 series or 49G, or 31 SF on a 28 series) after
being disabled (-55 SF on a 48 series or 49G, or 31 CF on a 28 series).

All of these programs require that last arguments be enabled (the
default). If last arguments is disabled, then they error out, leaving
the stack and flags unchanged.

The following programs retrieve the level 1 argument of the last command
that took any arguments from the last arguments buffer and return it to
the stack, unless the last arguments buffer is empty. Note that some
commands (CLEAR, DEPTH, STD, MEM, and so on) don't take any arguments,
and leave the last arguments buffer unchanged. Also note that for
commands that evaluate an expression or program, the last arguments are
saved from the evaluated expression or program, not from the original
command. In the case that more than one object is in the last argument
buffer, only the one returned by the program will be in the last
argument buffer when the program finishes.

You can copy the programs (include the "%%HP: T(3)A(R)F(.);" ASCII
header), paste them to a text file, and use the Kermit protocol to
transfer that to your 48 series or 49G.

In the case that you type these in, note that \<< and \>> represent the
opening and closing program delimiters, and \-> represents the right
arrow.

I consider these programs to be simple enough that they don't really
need comments. If you want to see the details of how they work, you can
single-step through them.

I expect that most users, especially those accustomed to classic RPN
calculators, would prefer this first program. If the last arguments
buffer is empty, then the real number 0 is returned to the stack and
also stored in the last arguments buffer.

Checksum on 48 series: # ECA9h

Checksum on 49G: # A414h

Bytes: 69

%%HP: T(3)A(R)F(.);
\<<
DEPTH \-> d
\<<
LASTARG DEPTH d -
IF
DUP
THEN
DUP2 2. + ROLLD DROPN
END
DUP DROP
\>>
\>>
Some RPL users might prefer this second program, although it takes more
memory and I suppose that it might be a bit slower. If the last
arguments buffer is empty, then the real number 0 is returned to the
stack and the last arguments buffer is left empty. Note that there is a
very remote possibility that if the user does a warmstart or CANCEL
(ATTN on the 48S series) while the program is running, then the
calculator will be left with last arguments disabled.

Checksum on 48 series: # F5Dh

Checksum on 49G: # D44Fh

Bytes: 94.5

%%HP: T(3)A(R)F(.);
\<<
DEPTH \-> d
\<< LASTARG DEPTH d -
IF
DUP
THEN
DUP2 2. + ROLLD DROPN DUP DROP
ELSE
-55. DUP SF CF
END
\>>
\>>
Some RPL users might even prefer this last program. If the last
arguments buffer is empty, then (unlike the classic RPN
LSTx command) it doesn't return anything to the stack.
This one also leaves the last arguments buffer empty. Like the previous
program, there is a very remote possibility that if the user does a
warmstart or CANCEL (ATTN on the 48S series) while the program is
running, then the calculator will be left with last arguments disabled.

Checksum on 48 series: # D527h

Checksum on 49G: # CD47h

Bytes: 97

%%HP: T(3)A(R)F(.);
\<<
DEPTH \-> d
\<< LASTARG DEPTH d -
IF
DUP
THEN
DUP2 2. + ROLLD DROPN DUP DROP
ELSE
DROP -55. DUP SF CF
END
\>>
\>>
Regards,
James

#10

Oops! I wrote:

The following programs should work on any 48 series or 49G calculator, but for a 28 series, the LASTARG command would have to be changed to LAST, and, in the second and third programs, the sequence "-55. SF CF" changed to "31 CF SF".

Make that:

...the sequence "-55. DUP SF CF" changed to "31 DUP CF SF".

#11

I (obviously) don't know much about programming the 48, so please excuse the simple question. I use the following for Last X. I don't remember exactly where I got it. How do yours compare with this one?

\<<
DEPTH \-> n
\<< LASTARG DEPTH n -
DUP \-> s
\<< ROLLD s 1 - DROPN
\>>
\>>
\>>

#12

I expect that you got it from Joe Horn's Goodies Disk #3. Credit for
writing it should go to Darryl Okahata.

It's smaller than any of mine (an advantage).

I'd guess that it would be slightly slower than mine because of the
nested procedures, but any of these should be fast enough that this
shouldn't be an issue.

It doesn't change any flags, so there's no possibility that it could
leave last arguments disabled in the event that the user terminated the
running program (a tiny advantage over two of my programs).

The biggest problem that I have with it is that it leaves the argument
for DROPN in the last arguments buffer so that (unlike the classic RPN
LSTx command and my programs), if you run it twice
without running anything else that should change the last arguments
buffer (or LAST X register on a classic RPN), then you'll probably get
something different the second time. Perhaps, in most "real-world"
usage, this won't matter very much, but I consider this to be a
disadvantage (or maybe even a bug).

If the last arguments buffer is empty, then (unlike the classic RPN
LSTx command and two of my programs), it returns
nothing to the stack. I expect that those accustomed to classic RPN
would consider this to be a bug.

Regards,
James


Forum Jump: