{"id":1857,"date":"2018-02-09T22:16:51","date_gmt":"2018-02-09T22:16:51","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=1857"},"modified":"2018-02-09T22:16:51","modified_gmt":"2018-02-09T22:16:51","slug":"continuous-memory-error","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/1857\/continuous-memory-error\/","title":{"rendered":"Continuous Memory Error"},"content":{"rendered":"<p>Hewlett-Packard produced calculators in the late 1970s which came with &#8220;Continuous Memory&#8221;. This retained programs and data in the calculator even when it was switched off. <!--more--><\/p>\n<p>The mechanism is the forerunner to modern BIOSes with CMOS settings so it was another very successful innovation.<\/p>\n<p>I have recently been developing a microcode emulator for one of HP&#8217;s Continuous Memory calculators, the HP-29C. Unlike its predecessor, the HP-29 only came with continuous memory &#8211; there was only the &#8220;C&#8221; model &#8211; and the microcode includes instructions specifically for continuous memory. I had actually been tinkering with my microcode emulator for the HP-67 and the idea crossed my mind, &#8220;if this is an accurate match to the original processor, how well does it run other programs for the processor?&#8221; It was at that was the point I plugged in the microcode for the HP-29C.<\/p>\n<p>There are some hardware aspects that changed between the two calculator models: different things wired up to different pins and a 12 digit display instead of a 15 digit one; but internally both calculators use the same processor chip. There isn&#8217;t a HP-67 variant of the Woodstock chip and a HP-29C variant. The idea seemed sound.<\/p>\n<p>After some tweaks for the hardware, I plugged in the HP-29C microcode and ran it. The calculator (emulation) came up with &#8220;Error&#8221; in the display.<\/p>\n<p>Now, whilst you might consider the outcome disappointing (and I definitely would have preferred to see &#8220;0.00&#8221;), it is impressive that it understood enough and functioned well enough to be able to create &#8220;Error&#8221; in the A and B registers and display it. It was actually a pretty good starting point for test 1.<\/p>\n<p>Why would it say, &#8220;Error&#8221; at power up?<\/p>\n<p>I did own a real HP-29C at one point a long time ago, and I did read the manual from cover to cover at the time. There was a vague recollection that there was something about a continuous memory failure. It was something I&#8217;d never seen; but I did think the manual mentioned it. I sure didn&#8217;t have continuous memory in the HP-67 emulator so perhaps it was something related to that.<\/p>\n<p>Guesses are all very good but what was more important was what was actually happening. It was one of my emulator so it had microcode logging. Here&#8217;s what the log said:<\/p>\n<p><code><\/p>\n<pre>\r\n>>> dr\r\nA=00000000000000 D=00000000000000 M1=00000000000000 P= 0\r\nB=00000000000000 E=00000000000000 M2=00000000000000\r\nC=00000000000000 F=00000000000000 S =................\r\n>>> dp\r\n00000: nop\r\n>>> ts1000\r\n00000: nop                                   ;\r\n00001: nop                                   ;\r\n00002: delayed rom 12                        ;\r\n00003: if n\/c goto 0303                      ;\r\n06303: cpu woodstock                         ;\r\n06304: 0 -> c[w]                             ;\r\n06305: m1 exch c                             ;\r\n06306: 0 -> c[w]                             ;\r\n06307: m2 exch c                             ;\r\n06310: clear s                               ;\r\n06311: binary                                ;\r\n06312: delayed rom 4                         ;\r\n06313: jsb 0235                              ;\r\n02235: p <- 1                                ; P= 1\r\n02236: load constant 2                       ; C=00000000000020 P= 0\r\n02237: c -> addr                             ;\r\n02240: data register -> c 14                 ; C=00000000000000\r\n02241: return                                ;\r\n06314: c -> a[w]                             ;\r\n06315: jsb 0360                              ;\r\n06360: p <- 12                               ; P=12\r\n06361: load constant 3                       ; C=03000000000000 P=11\r\n06362: load constant 4                       ; C=03400000000000 P=10\r\n06363: load constant 9                       ; C=03490000000000 P= 9\r\n06364: load constant 3                       ; C=03493000000000 P= 8\r\n06365: load constant 4                       ; C=03493400000000 P= 7\r\n06366: load constant 2                       ; C=03493420000000 P= 6\r\n06367: load constant 8                       ; C=03493428000000 P= 5\r\n06370: load constant 4                       ; C=03493428400000 P= 4\r\n06371: return                                ;\r\n06316: a - c -> a[m]                         ; A=0CB6CBD7C00000\r\n06317: if a[m] # 0 then goto 00334           ;\r\n06334: 0 -> c[w]                             ; C=00000000000000\r\n06335: p <- 1                                ; P= 1\r\n06336: load constant 3                       ; C=00000000000030 P= 0\r\n06337: p <- 1                                ; P= 1\r\n06340: delayed rom 2                         ;\r\n06341: jsb 0372                              ;\r\n01372: if n\/c goto 0141                      ;\r\n01141: a exchange c[w]                       ; A=00000000000030 C=0CB6CBD7C00000\r\n01142: binary                                ;\r\n01143: 0 -> c[w]                             ; C=00000000000000\r\n01144: a - 1 -> a[wp]                        ; A=0000000000002F\r\n\r\n01145: a exchange c[w]                       ; A=00000000000000 C=0000000000002F\r\n01146: c -> addr                             ;\r\n01147: a exchange c[w]                       ; A=0000000000002F C=00000000000000\r\n01150: c -> data                             ;\r\n01151: a - 1 -> a[wp]                        ; A=0000000000002E\r\n01152: if n\/c goto 0145                      ;\r\n\r\n01145: (2E -> addr, 0->mem[addr], 2E->2D)    ; C=00000000000000 A=0000000000002D\r\n...\r\n01152: if n\/c goto 0145                      ;\r\n\r\n01145: (0 -> mem[2D])\r\n01145: (0 -> mem[2C])\r\n...\r\n01145: (0 -> mem[1])                         ; C=00000000000000 A=00000000000001\r\n...\r\n01151: a - 1 -> a[wp]                        ; A=00000000000000\r\n01152: if n\/c goto 0145                      ;\r\n\r\n01145: a exchange c[w]                       ; (both 0 so neither change)\r\n01146: c -> addr                             ;\r\n01147: a exchange c[w]                       ; (ditto)\r\n01150: c -> data                             ;\r\n01151: a - 1 -> a[wp]                        ; A=000000000000FF\r\n01152: if n\/c goto 0145                      ;\r\n01153: return                                ;\r\n\r\n06342: 0 -> c[w]                             ;\r\n06343: jsb 0360                              ;\r\n06360: p <- 12                               ; P=12\r\n06361: load constant 3                       ; C=03000000000000 P=11\r\n06362: load constant 4                       ; C=03400000000000 P=10\r\n06363: load constant 9                       ; C=03490000000000 P= 9\r\n06364: load constant 3                       ; C=03493000000000 P= 8\r\n06365: load constant 4                       ; C=03493400000000 P= 7\r\n06366: load constant 2                       ; C=03493420000000 P= 6\r\n06367: load constant 8                       ; C=03493428000000 P= 5\r\n06370: load constant 4                       ; C=03493428400000 P= 4\r\n06371: return                                ;\r\n06344: p <- 2                                ; P= 2\r\n06345: load constant 2                       ; C=03493428400200 P= 1\r\n06346: jsb 0352                              ;\r\n06352: a exchange c[w]                       ; A=03493428400200 C=000000000000FF\r\n06353: p <- 1                                ;\r\n06354: load constant 2                       ; C=0000000000002F P= 0\r\n06355: c -> addr                             ;\r\n06356: a exchange c[w]                       ; A=0000000000002F C=03493428400200\r\n06357: return                                ;\r\n06347: c -> data register 14                 ; mem[46]=03493428400200\r\n06350: delayed rom 2                         ;\r\n06351: if n\/c goto 0374                      ;\r\n01374: if n\/c goto 0231                      ;\r\n01231: 0 -> a[w]                             ; A=00000000000000\r\n01232: 0 -> c[w]                             ; C=00000000000000\r\n01233: 0 -> s 1                              ; S=...3............\r\n01234: 0 -> s 2                              ;\r\n01235: p <- 13                               ; P=13\r\n; About to load \"Error\"\r\n01236: load constant 14                      ; C=E0000000000000 P=12\r\n01237: load constant 10                      ; C=EA000000000000 P=11\r\n01240: load constant 10                      ; C=EAA00000000000 P=10\r\n01241: load constant 12                      ; C=EAAC0000000000 P= 9\r\n01242: load constant 10                      ; C=EAACA000000000 P= 8\r\n01243: binary                                ;\r\n01244: c - 1 -> c[wp]                        ; C=EAACAFFFFFFFFF\r\n01245: a exchange c[w]                       ; A=EAACAFFFFFFFFF C=00000000000000\r\n01246: b exchange c[w]                       ;\r\n01247: display off                           ;\r\n01250: display toggle                        ; display ON\r\n01251: p <- 2                                ; P= 2\r\n01252: load constant 4                       ; C=00000000000400 P= 1\r\n01253: c - 1 -> c[x]                         ; C=000000000003FF\r\n01254: if n\/c goto 0253                      ;\r\n01253: ...\r\n>>>\r\n<\/pre>\n<p><\/code><br \/>\nYou can see &#8220;Error&#8221; being loaded into the A register and the B mask being set to display all digits from address 01236.<\/p>\n<p>There are a lot of instructions (shown as &#8220;&#8230;&#8221; above) zeroing memory (06334-01153) before &#8220;Error&#8221; is loaded.<\/p>\n<p>The key decision point before both of those is 06317. If mem[46] mantissa isn&#8217;t 3493428400, the microcode clears memory and displays &#8220;Error&#8221;.<\/p>\n<p>If I had continuous memory and I powered up the calculator then I might have a value in mem[46] and it might be the correct one. However, if my continuous memory failed and I have zeros in mem[46], or part of it failed and the content of mem[46] isn&#8217;t correct, then the calculator will clear the lot and warn you of the problem. It looks like my guess was correct.<\/p>\n<p>You can see, just after it zeros memory, the first thing it does is put 3493428400 in the mantissa of mem[46]. That starts happening right from address 06342.<\/p>\n<p>If mem[46] had the correct value at power up, the sequence would have been different. Given we&#8217;re in an emulator, we can see what would have happened. The steps are:<br \/>\n<code><\/p>\n<pre>\r\n>>> sd46 03493428400200\r\n>>> srpc 0\r\n>>> dp\r\n00000: nop\r\n>>> g\r\n>>> dr\r\nA=0000FFFFFFFF00 D=00000000000000 M1=00000000000000 P= 8\r\nB=29000000000000 E=00000000000000 M2=00000000000000\r\nC=00000000000000 F=00000000000000 S =...3.....9......\r\n>>> dp\r\n00347: if 1 = s 15 then goto 00175\r\n>>>\r\n<\/pre>\n<p><\/code><br \/>\nWe set data 46 to a value which included the required mantissa, set register pc back to 0, confirmed we were at the starting step, &#8220;go&#8221;ed (run) the program, &#8220;broke&#8221; back to the emulator (not shown above &#8211; it happens from the calculator window; not the monitor one), and then displayed the registers and current program step.<\/p>\n<p>The display is showing &#8220;0.00&#8221;. You can see that from the A and B register values (0\/2 shows as a blank sign digit, 0\/9 shows as &#8220;0.&#8221; then two 0\/0s show as &#8220;0&#8221; each). It is even easier to tell by looking at the calculator window.<\/p>\n<p>Obviously the monitor is a bit different to what you&#8217;ve seen in my earlier emulators as it clearly has some new features. You&#8217;ll see updated emulators with the new monitor shortly.<\/p>\n<p>I did manage to find a HP-29C manual online. At the bottom of page 183 it says, &#8220;If you drop or traumatize your calculator, or if power to the Continuous Memory is interrupted whether the calculator is off or on, the contents of program memory and the data storage registers may be lost. If this occurs, when the calculator is then turned on, the display will show Error. To restore the display , ensure that the battery is charged, or connect the ac adapter\/recharger, and press any key.&#8221;<\/p>\n<p>There is more information on the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/hp29-main\/\">HP-29 Topic<\/a> page.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hewlett-Packard produced calculators in the late 1970s which came with &#8220;Continuous Memory&#8221;. This retained programs and data in the calculator even when it was switched off.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,5,64],"tags":[65,32],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1857"}],"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=1857"}],"version-history":[{"count":4,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1857\/revisions"}],"predecessor-version":[{"id":1861,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1857\/revisions\/1861"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1857"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1857"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1857"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}