{"id":2095,"date":"2018-04-01T23:54:34","date_gmt":"2018-04-01T23:54:34","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=2095"},"modified":"2018-04-02T00:09:06","modified_gmt":"2018-04-02T00:09:06","slug":"hp-55-startup","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/2095\/hp-55-startup\/","title":{"rendered":"HP-55 Startup"},"content":{"rendered":"<p>Francois Roulet recently sent me a listing showing the startup sequence for the HP-55. It has a certain elegance to it and, as I believe Francois supports the sharing of knowledge, I&#8217;m including and discussing it here. <!--more--><\/p>\n<p>Here&#8217;s a copy of <a href=\"http:\/\/www.sydneysmith.com\/products\/hp55u\/downloads\/55-start-fr.txt\" rel=\"noopener\" target=\"_blank\">Francois&#8217; HP-55 startup listing<\/a>.<\/p>\n<p>The listing is from his <a href=\"http:\/\/home.citycable.ch\/pierrefleur\/HP55\/default.htm\" rel=\"noopener\" target=\"_blank\">classic series HP-55 emulator<\/a> and that uses decimal values consistently throughout, so don&#8217;t get confused if you see addresses with digits outside 0-7. I&#8217;ve chosen to use octal in most of my articles because it is easier to see goto destinations when delayed \/ rom \/ group select instructions are involved. That said, there are certain Woodstock instructions where hexadecimal would have been a better choice so, as with most things, there are trade-offs involved. Decimal has its own set of pluses and minus and is a better choice in some circumstances. <\/p>\n<p>I was going to (did) go through each of the steps in the listing and explain what&#8217;s happening. However, summarizing the loops only served to make them less obvious than the original repetitions. You&#8217;ll probably find it easier to follow the original listing.<\/p>\n<p>Some hints though:<\/p>\n<p>1. The process is: clear status, clear regs (A-F,M), clear ram[0..9], clear ram[10..19], clear ram[20..29], create seven &#8220;GTO 00&#8221; instructions in a register, store those in ram[23..29], then setup FIX 2 and display &#8220;0.00&#8221;.<\/p>\n<p>2. Setting C[0]=1 (steps 152\/153) sets up 2-digit ram addresses, so it can access anything from 00 to 29.<\/p>\n<p>3. Steps 159-167 are a loop that repeats for 0..9 (eg ram[00..09], ram[10..19], etc) and exits when the 9 overflows to 0 again.<\/p>\n<p>4. &#8220;clear regs&#8221; already zeroed the stack (X,Y,Z,T are &#8220;CPU&#8221; registers C,D,E,F) so step 162 isn&#8217;t really needed.<\/p>\n<p>5. Steps 10-16 could have been better done by setting P=13 at the start, exiting with P#0 instead of P#14, and not needing the &#8220;shiftl&#8221;. The loop with P=15 and P=14 does nothing.<\/p>\n<p>6. s6 is used during startup to increment the tens digit of the ram address.<\/p>\n<p>7. Steps 2150-2152 are just a delay loop prior to turning on the display (step 2153, 2167). You can tune out during those. (&#8220;2152 goto 102&#8221; is a &#8220;goto 2150&#8221; as 2152=2048+104 so 102 is two steps earlier).<\/p>\n<p>8. Francois has flagged ram[20] as LastX, which it is. During startup just think of it as ram[20] during the standard loop through 10 ram registers, like all the others. Good to have it flagged though. You&#8217;ll need to know that one for later.<\/p>\n<p>HP later chose to use hex code &#8220;00&#8221; for &#8220;GTO 00&#8221; or &#8220;R\/S&#8221;. That makes the startup process a little shorter and leaves more ROM space for more features.<br \/>\n<!--\n\n\n\n<h2>Analysis<\/h2>\n\n\n<code>\n\n<pre>\r\n0   : jsb 95\r\n95  : jsb 150\r\n150 : clearstatus\r\n151 : clearregs\r\n<\/pre>\n\n<\/code>\nA fairly simple start so far. It's really \"clear everything, just in case\". It's probably redundant as hardware is usually built to power up in a known state (typically zeroed) anyway, but it would have been a good practice at the time. As you'll have seen, it only became a problem after CMOS started to be used for memories (after the HP-55).\n\nWe'll see 152 again later. Here's what happens this time:\n<code>\n\n<pre>\r\n152 : 0 -> c[w]\r\n153 : c + 1 -> c[x] ; C=00000000000001\r\n154 : 12 -> p\r\n155 : if s6 = 0\r\n156 : goto 158\r\n158 : 11 -> p\r\n159 : c -> data address\r\n160 : b <-> c[w] ; B=00000000000001 C=00000000000000\t\r\n161 : c -> data  ; 0 -> ram[0]\r\n162 : c -> stack ; push 0 onto the stack (loop will clear stack)\r\n163 : b <-> c[w] ; 0 back to B, ram addr back to C (undo 160)\r\n164 : c + 1 -> c[p] ; P is 11 so C=00100000000001\r\n165 : goto 159\r\n\r\n159 : ... ; 0 -> ram[1], ..., -> ram[8] (and 0s to stack)\r\n\r\n; C=00900000000001\r\n159 : c -> data address\r\n160 : b <-> c[w]\r\n161 : c -> data; 0 -> ram[9]\r\n162 : c -> stack\r\n163 : b <-> c[w]\r\n164 : c + 1 -> c[p]; CY=1 C=00000000000001\r\n165 : goto 159 ; no. CY is set.\r\n166 : b -> c[w] ; B=00000000000000 so C=00000000000000\r\n167 : return\r\n<\/pre>\n\n<\/code>\nSteps 152 and 153 setup 2-digit addressing for the \"c -> data address\" instructions.\n154-158 we'll revisit later (when we see s6 set).\n159-165 is a loop like \"for i=0 to 9; ram[i]=0; next\".\nIt also pushes 0 on the stack ten times, thus clearing the stack (X,Y,Z,T).\nWhen the counter (C[11]) overflows from 9->0 (after ram[9] has been set to 0), the loop exits.\n\nIt returns to step 96 which sets s6 and goes back into 152:\n<code>\n\n<pre>\r\n96  : 1 -> s6\r\n97  : jsb 152\r\n152 : 0 -> c[w]\r\n153 : c + 1 -> c[x] ; C=00000000000001\r\n154 : 12 -> p\r\n155 : if s6 = 0 ; no, not this time.\r\n156 : goto 158  ; no.\r\n157 : c + 1 -> c[p] ; C=01000000000001\r\n158 : 11 -> p\r\n<\/pre>\n\n<\/code>\n152-153 do what they did last time, set C[0]=1 for 2-digit ram addresses.\n154-158 has s6 set this time. It adds 1 to the tens digit of the ram address (C[12]), then points to the ones digit (11 -> p).\n159-165 should be familiar. It goes like this now:\n<code>\n\n<pre>\r\n; C=01000000000001 (C[0]==0 so 2 digit address, C[12-11]=10 so ram[10]\r\n159 : c -> data address\r\n160 : b <-> c[w]\r\n161 : c -> data ; 0 -> ram[10]\r\n162 : c -> stack; more 0s to the stack\r\n163 : b <-> c[w]; undo 160 again\r\n164 : c + 1 -> c[p] ; 10->11 etc\r\n165 : goto 159\r\n159 : ... ; 0 -> ram[11], ..., ram[19]\r\n164 : c + 1 -> c[p] ; CY=1 C=01000000000001\r\n165 : goto 159 ; no. cy=1\r\n166 : b -> c[w]; C=00000000000000 again\r\n167 : return\r\n<\/pre>\n\n<\/code>\nIt's the same as last time but C[12] was 1 so we've zeroed ram[10-19].\n\nThe return goes to 98 which looks like:\n<code>\n\n<pre>\r\n98  : 12 -> p\r\n99  : goto 8\r\n8   : c + 1 -> c[p] ; C=01000000000000\r\n9   : jsb 153\r\n153 : c + 1 -> c[x] ; C=01000000000001\r\n154 : 12 -> p\r\n155 : if s6 = 0 ; still set so\r\n156 : goto 158  ; no\r\n157 : c + 1 -> c[p]; C=02000000000001, 10s to 2\r\n158 : 11 -> p; point to 1s\r\n<\/pre>\n\n<\/code>\nAnd back into the 159-167 loop:\n<code>\n\n<pre>\r\n159 : ...; 0 -> ram[20],...,ram[29]\r\n164 : c + 1 -> c[p] ; CY=1 C=02000000000001\r\n165 : goto 159; no. cy=1\r\n166 : b -> c[w]\r\n167 : return\r\n<\/pre>\n\n<\/code>\n\nThe return goes to 10. Steps 10-16 load seven \"hexcode\" 50 instructions into the A register. As Francois points out \"50\" is the code for \"GTO-00\". The loop starts with P=12 and decrements through P=15 and 14 (which don't do anything). It also does a \"shiftl\" (step 16) to adjust the result. It works but, in retrospect, starting with P=13, stopping after P=0, and not needing the \"shiftl\" would have been neater. There may be more to it than what I'm seeing, but it looks like one of those things intended for a later revisit:\n<code>\n\n<pre>\r\n10  : 12 -> p\r\n11  : load 5 ; C=05000000000000 P=11\r\n12  : load 0 ; C=05000000000000 P=10\r\n13  : if p # 14\r\n14  : goto 11\r\n\r\n11  : ...    ; C=05050505050505 P=9,...,0,15\r\n11  : ...    ; no change for P=15, 14\r\n13  : if p # 14\r\n14  : goto 11; no, p==14\r\n\r\n15   \t14\t00000000000000\t00000000000000\t05050505050505\ta <-> c[w]\r\n16   \t14\t05050505050505\t00000000000000\t00000000000000\tshiftl a[w]\r\n17   \t14\t50505050505050\t00000000000000\t00000000000000\t12 -> p\r\n18   \t12\t50505050505050\t00000000000000\t00000000000000\tload 2\r\n19   \t11\t50505050505050\t00000000000000\t02000000000000\tload 3\r\n20   \t10\t50505050505050\t00000000000000\t02300000000000\t11 -> p\r\n21   \t11\t50505050505050\t00000000000000\t02300000000000\tgoto 35\r\n35   \t11\t50505050505050\t00000000000000\t02300000000000\tc + 1 -> c[x]\r\n36   \t11\t50505050505050\t00000000000000\t02300000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02300000000001\ta <-> c[w]\r\n38   \t11\t02300000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02300000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 23\r\n221   \t11\t02300000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02300000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02400000000001\tgoto 36\r\n36   \t11\t50505050505050\t00000000000000\t02400000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02400000000001\ta <-> c[w]\r\n38   \t11\t02400000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02400000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 24\r\n221   \t11\t02400000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02400000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02500000000001\tgoto 36\r\n36   \t11\t50505050505050\t00000000000000\t02500000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02500000000001\ta <-> c[w]\r\n38   \t11\t02500000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02500000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 25\r\n221   \t11\t02500000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02500000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02600000000001\tgoto 36\r\n36   \t11\t50505050505050\t00000000000000\t02600000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02600000000001\ta <-> c[w]\r\n38   \t11\t02600000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02600000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 26\r\n221   \t11\t02600000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02600000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02700000000001\tgoto 36\r\n36   \t11\t50505050505050\t00000000000000\t02700000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02700000000001\ta <-> c[w]\r\n38   \t11\t02700000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02700000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 27\r\n221   \t11\t02700000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02700000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02800000000001\tgoto 36\r\n36   \t11\t50505050505050\t00000000000000\t02800000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02800000000001\ta <-> c[w]\r\n38   \t11\t02800000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02800000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 28\r\n221   \t11\t02800000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02800000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02900000000001\tgoto 36\r\n36   \t11\t50505050505050\t00000000000000\t02900000000001\tc -> data address\r\n37   \t11\t50505050505050\t00000000000000\t02900000000001\ta <-> c[w]\r\n38   \t11\t02900000000001\t00000000000000\t50505050505050\tgoto 220\r\n220   \t11\t02900000000001\t00000000000000\t50505050505050\tc -> data\t\t\"GTO-00\" -> 29\r\n221   \t11\t02900000000001\t00000000000000\t50505050505050\ta <-> c[w]\r\n222   \t11\t50505050505050\t00000000000000\t02900000000001\tc + 1 -> c[p]\r\n223   \t11\t50505050505050\t00000000000000\t02000000000001\tgoto 36\r\n\r\n224   \t11\t50505050505050\t00000000000000\t02000000000001\tclearregs\r\n225   \t11\t00000000000000\t00000000000000\t00000000000000\tgoto 248\r\n248   \t11\t00000000000000\t00000000000000\t00000000000000\t10 -> p\r\n249   \t10\t00000000000000\t00000000000000\t00000000000000\tload 1\t\t\t(FIX)\r\n250   \t9\t00000000000000\t0000\r\n<\/pre>\n\n<\/code>\n\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Francois Roulet recently sent me a listing showing the startup sequence for the HP-55. It has a certain elegance to it and, as I believe Francois supports the sharing of knowledge, I&#8217;m including and discussing it here.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,5,71],"tags":[32],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2095"}],"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=2095"}],"version-history":[{"count":4,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2095\/revisions"}],"predecessor-version":[{"id":2099,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2095\/revisions\/2099"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2095"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2095"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2095"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}