HP67 GSB and RTN

With the HP67 we use LBL to name a subroutine, GSB to call one and RTN to return from one.

The question is, “how does the HP-67 know where to return to?” It needs to remember where it is up to. Where does it store that information?

Functional Analysis

The test program looks like this:

001: 31 25 11
002: 31 22 01
003: 35 22
004: 31 25 01
005: 31 22 02
006: 35 22
007: 31 25 02
008: 31 22 03
009: 35 22
010: 31 25 03
011: 31 22 04
012: 35 22
013: 31 25 04
014: 35 22

The instruction displayed in W/PRGM is:
014: 35 22

The user program counter says:
61: 0000000000002e

That is pointing at instruction 0 in register “e” (14) of ram bank 2. n=0, b=2, r=14 (“02e”).

Ram bank 2 contains:

45: 00000000000000
46: 0ef40eb4f30eb3
47: f20eb2f10eb1fa

Register 14 of bank 2 is (32+14=) ram[46]
Instruction 0 is the “0e” bit at the lhs of the register.

Per Eric Smith’s HP-67 table of internal codes “0e” is a RTN instruction (35 22) so all looks sensible for the starting point.

[GTO] [A]
(w/prgm= 001: 31 25 11)
(61: 0000000000062f = prog step 001)

[SST]
(display 001: 31 25 11 then flicker and "0.00") 
(w/prgm= 002: 21 22 01)
(61: 0000000000052f = prog step 002)

[SST]
(display 002: 31 22 01, flicker, 0.00)
(w/prgm= 012: 35 22)
(61: 0000022f62e22e)

I had thought it would SST into the subroutine but it looks like it has continued down to the first executable instruction – in this case the RTN.

The addresses in ram[61] are 22f, 62e, 22e.
These translate (=120-(r+1)*7-(n+1)) to 005, 008, 012.
012 is the current program step. It is stored in its usual spot in ram[61] (nibbles 2,1,0).
008 is the f GSB 3 instruction
005 is the f GSB 2 instruction

[SST]
(display 012: 35 22, not much flicker, 0.00)
(w/prgm= 009: 35 22)
(61: 0000000022f52e)

Mostly, it has shifted everything 3 “digits” to the right. Although it has also added 1 to the new rightmost item.
The addresses now are: 005, 009.

Of interest is that “000” is being shifted in from the left. I think the printed manual said something about RTN-ing from too deep a level of nesting takes you to “000” and stops. The manual (page 206) says “Subroutine branching is limited only by the number of returns that can be held pending by the HP-67. Three subroutine returns can be held pending at any one time in the HP-67.” It then goes on to show an example where main routine “A” calls subroutine “1” which calls subroutine “2” which calls subroutine “3”. So, my test case is one too deep anyway.

Page 207 goes on to say, “If you are executing a program one step at a time with the SST key and encounter a GSB or GSB f instruction, the calculator will execute the entire subroutine before continuing to the next step. However, only one RTN instruction may be executed as the result of a GSB or GSB f instruction during single-step execution; so if a program contains a subroutine within a subroutine, execution will not return to the main program during SST execution.” This matches what we’re seeing with this process.

The first SST executed the RTN at 014 and we saw instruction “012: 35 22” displayed.
The second one executed the RTN at 012 and we see instruction “009: 35 22” displayed.

[SST]
(display 009: 35 22, flicker, 0.00)
(w/prgm= 006: 35 22)
(61: 0000000000012f)

[SST]
(display 006: 35 22, flicker, 0.00)
(w/prgm= 007: 31 25 02)
(61: 0000000000002f)

RTN-ing when there isn’t a RTN address should stop the program or, if SST-ing, it positions you at the next program step.

[A]
(display flicker, 0.00)
(w/prgm= 007: 31 25 02)

Running the program executes the RTN at step 006, stops the program and positions you at the next step (007), as expected.

Conclusion

It looks like ram[61] contains: 00333222111ccc

where c is the current program step, 1 is the first return address, 2 is the next one and 3 is the one after that.

Return addresses are actually the address of the GSB (not the next instruction).

The process for a RTN is:
– get the RTN address (shift right 3 times)
– add one

Add one means:
A. decrement n, if no carry (n>=0) – you’re done
B. n=6, decrement r, if no carry – you’re done
C. r=15, decrement b, if carry – wrap to step 001 i.e. b=2

The calculator can tell when it has gotten to the end of the return stack because the next RTN address is “000”.

You can see how many RTNs are pending by looking at how many sets of 3 digits are in ram[61]. If there’s only one set (in position 2,1,0) that’s the user program counter and no returns are pending. If there are 3 sets then you are two levels deep (in a subroutine of a subroutine of the main program).

You will never see 4 sets during functional testing as SST is going to complete one whole subroutine as a step (so that level won’t be present when you look, after the SST.

Microcode

The microcode analysis summarizes to:

PROG
001: 31 25 11
002: 31 22 01
003: 35 22
004: 31 25 01
005: 31 22 02
006: 35 22
007: 31 25 02
008: 31 22 03
009: 35 22
010: 31 25 03
011: 35 22
012: 84

Action/Step ram[61] Notes
(start) 00000000000000
[A]
(GSB A) 0000000000062f found LBL A in step 001
001 f LBL A 0000000000052f
002 f GSB 1 0000000052f32f RTN=002, found LBL 1 in step 004
004 f LBL 1 0000000052f22f
005 f GSB 2 0000052f22f02f RTN=002,005 found LBL 2 in 007
007 f LBL 2 0000052f22f62e
008 f GSB 3 0052f22f62e42e RTN=002,005,008 found LBL 3 in 010
010 f LBL 3 0052f22f62e32e
011 h RTN 0000052f22f52e
009 h RTN 0000000052f12f
006 h RTN 0000000000042f
003 h RTN 0000000000032f

You can see the details in:
HP67 microcode for GSB and RTN

It's only fair to share...Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUponDigg thisPin on PinterestEmail this to someone

Leave a Reply

Your email address will not be published. Required fields are marked *