The RTN key does a return from a subroutine. It also stops a main program and, if nothing’s running at all, it will take you to the “top of memory marker” (“00 00” in w/prgm mode).
Here’s how it does all that:
00752 – 01365. Get a step and switch(prog_code)
01052 – 02351. switch again but with access to rom 4 now
02052 – 02223. Figure out it is a RTN and need to run it
02240 – 02247. Which case is it?
02334 – 02336. In a main program.
00752 pointer advance 00753 disptoggle 00754 c <-> m ; C= 10000000000221 M =00000000000000 00755 shiftl a[w] ; A= 00000009990000 00756 0 -> s11 ; S= ........8... 00757 0 -> f5 00760 if s11 = 0 00761 goto 00757 00757 0 -> f5 ; S= ........8..b 00760 if s11 = 0 00761 goto 00757 00762 0 -> f5 00763 rom 2 01364 buffer -> rom address 01365 goto 01000 01052 goto 01347 ; [RTN] 01347 rom 4 02350 buffer -> rom address 02351 goto 02000 02052 goto 02164 02164 p - 1 -> p ; P= 11 02165 p - 1 -> p ; P= 10 02166 p - 1 -> p ; P= 9 02167 if p # 8 02170 goto 02305 02305 if c[m] = 0 02306 goto 02220 02220 if p # 9 02221 goto 02120 02222 if s3 = 0 ; if not just keying into prgm mem 02223 goto 02240 ; go run it ; ; RTN0: ; Do a RTN step 02240 if s8 = 0 ; if not running 02241 goto 02332 ; go position to "00 00" instead 02242 if c[s] = 0 ; got a subroutine RTN 02243 goto 02210 02244 c - 1 -> c[s] ; C= 00000000000221 02245 if c[s] = 0 02246 goto 02334 ; RTN in main prog (tidy up and stop) ; else c[s] was > 1. go back to main prog (goto 02254) ; ; RTN3: ; RTN from main program 02334 0 -> c[ms] ; clear prefixes AND subroutine level 02335 c <-> m ; C= 00000000000000 M =00000000000221 02336 rom 1 ; tidy up INC clear the running flag ; tidy up 00737 1 -> f3 00740 clearstatus ; S= ............ 00741 goto 00620 00620 if s8 = 0 00621 goto 00531 ; display: 00531 ... 00777 goto 00726 ; wait loop
if s8 = 0 we’re not running and we should end up at “00 00”.
; RTN1: ; RTN when not running (from the keyboard) 02332 if s9 = 0 02333 goto 02250 ; else continues into RTN from main program 02250 search for label 02251 jsb 02127 (=MCIRC0 = wait until done) 02252 1 -> f7 02253 jsb 02047 02047 return 02254 search for label 02255 jsb 02127 (=MCIRC0 = wait until done) 02256 goto 02334 ; 02334 is RTN from main program
It looks like two searches take us to “00 00”.
The seeming NOP of “jsb 02047 : 02047 return” has a side effect if f7 is set. It copies the bottom 6 bits of the jsb address into “the buffer”. That means the second search looks for program code 047. That is a reserved instruction. It shouldn’t be present in memory.
s9 = 1 skips the go “00 00” process. It seems to get set when doing a subroutine but it needs to be explored further.
The other end of the RTN is the GSB. On a HP-65, GSB is inferred – you just use [A] or [B] etc in a program to mean GoSuB A or B etc. (Interestingly on a HP-67, if you press [A] or [B] etc in W/PRGM mode, the one key gets entered as “31 22 11” (f GSB A) or “31 22 12” (f GSB B) etc; so the principle carried forward.) You can see an [A] pressed from the keyboard and then a [B] run from within a program, in 65-rtn-rtn.txt
[A] from the keyboard gives:
01316 key -> rom 01036 goto 01351
[B] in the program gives:
01364 buffer -> rom address 01365 goto 01000 01034 goto 01351
Clearly the scan code for [A] is 036 and for [B], 034.
The common bit afterwards is:
01351 rom 4 02352 0 -> f5 ; S= ...........b 02353 if c[m] = 0 02354 goto 02371 02371 0 -> c[ms] 02372 if s8 = 0 ; if not running 02373 goto 02102
It checks that there aren’t any prefixes (f f-1 STO RCL LBL DSP g) in the “if c[m] = 0” step. Then it clears the sign “bit” in C and clears any prefixes (perhaps something branches here with some set).
The thing that determines what comes next isn’t “was it a key press?” nor “are we already in a subroutine?”. It is simply “are we running?” (if s8 = 0).
If we aren’t already running, it goes to:
02102 if s9 = 0 02103 goto 02302 02302 search for label 02303 goto 02106 02106 c + 1 -> c[s] ; C= 10000000000221 02107 clearstatus ; S= ............ 02110 1 -> s10 ; S= ..........a. 02111 jsb 02376
That causes a “search for label” and sets c[s] to 1 (as shown).
The alternate, if we were already running, is:
02374 mark and search 02375 clearstatus ; S= ............
That uses the other “search” microinstruction. This one leaves the current pointer in place and adds a secondary pointer. After this, it is the secondary pointer that moves – not the normal one. Note that c[s] remains zero if we are in a subroutine (one level down) instead of the main routine (top level).
The HP-65 only supports two levels of subroutine. The doco refers to the top level as the “main routine” and the lower level (called from inside the main routine) as the “subroutine”. You can’t call another level below that. The manual shows a call to another layer (eg LBL B, …, C, …, RTN) as equivalent to a “GTO C”. There isn’t a tertiary pointer to move around and c[s] is only ever 1 (in the main routine) or 0 (in the subroutine).
Regardless of whether it was [A] from the keyboard or [B] within a program, the process continues on from microinstruction 02376 which sets the “running” flag (s8 to 1). Don’t get confused by the “jsb 02376”. It never returns to the instruction after that as, like user program memory, the microcode only supports one return address. It is effectively a goto 02376 back into common code.