{"id":1244,"date":"2015-11-09T23:02:05","date_gmt":"2015-11-09T23:02:05","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=1244"},"modified":"2017-05-14T01:32:41","modified_gmt":"2017-05-14T01:32:41","slug":"hp67-gsb-and-rtn","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/1244\/hp67-gsb-and-rtn\/","title":{"rendered":"HP67 GSB and RTN"},"content":{"rendered":"<p>With the HP67 we use LBL to name a subroutine, GSB to call one and RTN to return from one.<\/p>\n<p>The question is, &#8220;how does the HP-67 know where to return to?&#8221; It needs to remember where it is up to. Where does it store that information?<br \/>\n<!--more--><\/p>\n<h2>Functional Analysis<\/h2>\n<p>The test program looks like this:<\/p>\n<pre>\r\n001: 31 25 11\r\n002: 31 22 01\r\n003: 35 22\r\n004: 31 25 01\r\n005: 31 22 02\r\n006: 35 22\r\n007: 31 25 02\r\n008: 31 22 03\r\n009: 35 22\r\n010: 31 25 03\r\n011: 31 22 04\r\n012: 35 22\r\n013: 31 25 04\r\n014: 35 22\r\n<\/pre>\n<p>The instruction displayed in W\/PRGM is:<br \/>\n014: 35 22<\/p>\n<p>The user program counter says:<br \/>\n61: 0000000000002e<\/p>\n<p>That is pointing at instruction 0 in register &#8220;e&#8221; (14) of ram bank 2. n=0, b=2, r=14 (&#8220;02e&#8221;).<\/p>\n<p>Ram bank 2 contains:<\/p>\n<pre>\r\n45: 00000000000000\r\n46: 0ef40eb4f30eb3\r\n47: f20eb2f10eb1fa\r\n<\/pre>\n<p>Register 14 of bank 2 is (32+14=) ram[46]<br \/>\nInstruction 0 is the &#8220;0e&#8221; bit at the lhs of the register.<\/p>\n<p>Per <a href=\"https:\/\/www.brouhaha.com\/~eric\/hpcalc\/hp67\/67_hex_table.html\">Eric Smith&#8217;s HP-67 table of internal codes<\/a> &#8220;0e&#8221; is a RTN instruction (35 22) so all looks sensible for the starting point.<\/p>\n<pre>\r\n[GTO] [A]\r\n(w\/prgm= 001: 31 25 11)\r\n(61: 0000000000062f = prog step 001)\r\n\r\n[SST]\r\n(display 001: 31 25 11 then flicker and \"0.00\") \r\n(w\/prgm= 002: 21 22 01)\r\n(61: 0000000000052f = prog step 002)\r\n\r\n[SST]\r\n(display 002: 31 22 01, flicker, 0.00)\r\n(w\/prgm= 012: 35 22)\r\n(61: 0000022f62e22e)\r\n<\/pre>\n<p>I had thought it would SST into the subroutine but it looks like it has continued down to the first executable instruction &#8211; in this case the RTN.<\/p>\n<p>The addresses in ram[61] are 22f, 62e, 22e.<br \/>\nThese translate (=120-(r+1)*7-(n+1)) to 005, 008, 012.<br \/>\n012 is the current program step. It is stored in its usual spot in ram[61] (nibbles 2,1,0).<br \/>\n008 is the f GSB 3 instruction<br \/>\n005 is the f GSB 2 instruction<\/p>\n<p>[SST]<br \/>\n(display 012: 35 22, not much flicker, 0.00)<br \/>\n(w\/prgm= 009: 35 22)<br \/>\n(61: 0000000022f52e)<\/p>\n<p>Mostly, it has shifted everything 3 &#8220;digits&#8221; to the right. Although it has also added 1 to the new rightmost item.<br \/>\nThe addresses now are: 005, 009.<\/p>\n<p>Of interest is that &#8220;000&#8221; 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 &#8220;000&#8221; and stops. The manual (page 206) says &#8220;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.&#8221; It then goes on to show an example where main routine &#8220;A&#8221; calls subroutine &#8220;1&#8221; which calls subroutine &#8220;2&#8221; which calls subroutine &#8220;3&#8221;. So, my test case is one too deep anyway.<\/p>\n<p>Page 207 goes on to say, &#8220;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.&#8221; This matches what we&#8217;re seeing with this process.<\/p>\n<p>The first SST executed the RTN at 014 and we saw instruction &#8220;012: 35 22&#8221; displayed.<br \/>\nThe second one executed the RTN at 012 and we see instruction &#8220;009: 35 22&#8221; displayed.<\/p>\n<pre>\r\n[SST]\r\n(display 009: 35 22, flicker, 0.00)\r\n(w\/prgm= 006: 35 22)\r\n(61: 0000000000012f)\r\n\r\n[SST]\r\n(display 006: 35 22, flicker, 0.00)\r\n(w\/prgm= 007: 31 25 02)\r\n(61: 0000000000002f)\r\n<\/pre>\n<p>RTN-ing when there isn&#8217;t a RTN address should stop the program or, if SST-ing, it positions you at the next program step.<\/p>\n<p>[A]<br \/>\n(display flicker, 0.00)<br \/>\n(w\/prgm= 007: 31 25 02)<\/p>\n<p>Running the program executes the RTN at step 006, stops the program and positions you at the next step (007), as expected.<\/p>\n<h2>Conclusion<\/h2>\n<p>It looks like ram[61] contains: 00333222111ccc<\/p>\n<p>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.<\/p>\n<p>Return addresses are actually the address of the GSB (not the next instruction).<\/p>\n<p>The process for a RTN is:<br \/>\n&#8211; get the RTN address (shift right 3 times)<br \/>\n&#8211; add one<\/p>\n<p>Add one means:<br \/>\nA. decrement n, if no carry (n>=0) &#8211; you&#8217;re done<br \/>\nB. n=6, decrement r, if no carry &#8211; you&#8217;re done<br \/>\nC. r=15, decrement b, if carry &#8211; wrap to step 001 i.e. b=2<\/p>\n<p>The calculator can tell when it has gotten to the end of the return stack because the next RTN address is &#8220;000&#8221;.<\/p>\n<p>You can see how many RTNs are pending by looking at how many sets of 3 digits are in ram[61]. If there&#8217;s only one set (in position 2,1,0) that&#8217;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).<\/p>\n<p>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&#8217;t be present when you look, after the SST.<\/p>\n<h2>Microcode<\/h2>\n<p>The microcode analysis summarizes to:<\/p>\n<pre>\r\nPROG\r\n001: 31 25 11\r\n002: 31 22 01\r\n003: 35 22\r\n004: 31 25 01\r\n005: 31 22 02\r\n006: 35 22\r\n007: 31 25 02\r\n008: 31 22 03\r\n009: 35 22\r\n010: 31 25 03\r\n011: 35 22\r\n012: 84\r\n\r\n<table>\r\n<tr><td>Action\/Step <\/td><td> ram[61]        <\/td><td> Notes <\/td><\/tr> \r\n<tr><td>(start)     <\/td><td> 00000000000000 <\/td><td> <\/td><\/tr>\r\n<tr><td>[A]         <\/td><td>                <\/td><td> <\/td><\/tr>\r\n<tr><td>(GSB A)     <\/td><td> 0000000000062f <\/td><td> found LBL A in step 001 <\/td><\/tr>\r\n<tr><td>001 f LBL A <\/td><td> 0000000000052f <\/td><td> <\/td><\/tr>\r\n<tr><td>002 f GSB 1 <\/td><td> 0000000052f32f <\/td><td> RTN=002, found LBL 1 in step 004 <\/td><\/tr>\r\n<tr><td>004 f LBL 1 <\/td><td> 0000000052f22f <\/td><td> <\/td><\/tr>\r\n<tr><td>005 f GSB 2 <\/td><td> 0000052f22f02f <\/td><td> RTN=002,005 found LBL 2 in 007 <\/td><\/tr>\r\n<tr><td>007 f LBL 2 <\/td><td> 0000052f22f62e <\/td><td> <\/td><\/tr>\r\n<tr><td>008 f GSB 3 <\/td><td> 0052f22f62e42e <\/td><td> RTN=002,005,008 found LBL 3 in 010 <\/td><\/tr>\r\n<tr><td>010 f LBL 3 <\/td><td> 0052f22f62e32e <\/td><td> <\/td><\/tr>\r\n<tr><td>011 h RTN   <\/td><td> 0000052f22f52e <\/td><td> <\/td><\/tr>\r\n<tr><td>009 h RTN   <\/td><td> 0000000052f12f <\/td><td> <\/td><\/tr>\r\n<tr><td>006 h RTN   <\/td><td> 0000000000042f <\/td><td> <\/td><\/tr>\r\n<tr><td>003 h RTN   <\/td><td> 0000000000032f <\/td><td> <\/td><\/tr>\r\n<\/table>\r\n<\/pre>\n<p>You can see the details in:<br \/>\n<a href=\"http:\/\/www.sydneysmith.com\/products\/gss-hp67u\/downloads\/67-gsb-rtn.txt\" target=\"_blank\">HP67 microcode for GSB and RTN<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the HP67 we use LBL to name a subroutine, GSB to call one and RTN to return from one. The question is, &#8220;how does the HP-67 know where to return to?&#8221; It needs to remember where it is up to. Where does it store that information?<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,5,3],"tags":[33],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1244"}],"collection":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1244"}],"version-history":[{"count":7,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1244\/revisions"}],"predecessor-version":[{"id":1347,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1244\/revisions\/1347"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}