{"id":1952,"date":"2018-02-25T02:25:38","date_gmt":"2018-02-25T02:25:38","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=1952"},"modified":"2018-02-25T02:38:30","modified_gmt":"2018-02-25T02:38:30","slug":"hp-29c-flashing-dot","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/1952\/hp-29c-flashing-dot\/","title":{"rendered":"HP-29C Flashing Dot"},"content":{"rendered":"<p>When I first built a microcode emulator for the HP-29C, it came up with a flashing decimal point. I didn&#8217;t remember this being the case with the real thing; but that was a long time ago and I might have forgotten.<\/p>\n<p>I had a vague feeling there was something about low power and a flashing dot. Perhaps it normally flashes but doesn&#8217;t if power is low. All of the earlier (&#8220;classic&#8221;) calculators had hardware driven low power indicators, and I didn&#8217;t have any hardware in the emulator for that, so the normal behaviour must be a flashing decimal point.<\/p>\n<p>My daughter said, &#8220;it makes more sense for the dot to flash during low power as the consumption would be slightly less&#8221;. That&#8217;s where all of my thinking started unraveling. <!--more--><\/p>\n<p>The manual for the calculator does exist online. On page 42 it says, &#8220;When you are operating from battery power in RUN mode, the decimal point blinks on and off to warn you that you have a minimum of one minute of operating time left.&#8221;<\/p>\n<p>My logic was blown out of the water. She was right.<\/p>\n<p>Why was the calculator blinking the decimal point? Why did it think the power was low? It must know or think that &#8211; because it was the thing doing the blinking. It was under software control; not hardware.<\/p>\n<p>After a bit of looking, it turns out that the s 5 flag gets set (1) if there is sufficient power for normal operation and it is clear (0) if low power is detected. The calculator checks the s 5 flag and changes its behaviour accordingly.<\/p>\n<p>The following retraces how I got to that point, and explores how the calculator flashes the dot. (I added the ability to &#8220;Set Internal&#8221; &#8220;voltage&#8221; in HP29w Ver 0.02)<\/p>\n<p><code><\/p>\n<pre>\r\nC:\\Test\\hp29w>hp29w -d\r\n\r\nHP29w Ver 0.02\r\nCopyright 2018 Greg Sydney-Smith\r\n\r\nCPU speed is 200 kHz\r\n\r\n>>> si voltage 1.9\r\n>>> g\r\n\r\n(You see 0.00 with a flashing decimal point)\r\n(Switch to OFF to return to the debugger ...)\r\n\r\n>>> ts200\r\n00345: p - 1 -> p                          ; P=13\r\n00346: 0 -> s 15                           ;\r\n00347: if 1 = s 15 then goto 00175         ;\r\n00351: if p # 4 then goto 00345            ;\r\n00345: ...                                 ; P=12,11,10,..., 4\r\n00351: if p # 4 then goto 00345            ;\r\n\r\n00353: p <- 0                              ; P= 0\r\n00354: a + 1 -> a[p]                       ; A=0000FFFFFFFF05\r\n00355: if n\/c goto 0345                    ;\r\n00345: ...                                 ; P=13,12,11,..., 4\r\n00351: if p # 4 then goto 00345            ;\r\n\r\n; 00345-00351 is a delay loop: for (p=13; p>4; p--)\r\n; There are 10 loops, over 6 words. It takes 60 T-states.\r\n\r\n00353: p <- 0                              ; P= 0\r\n00354: a + 1 -> a[p]                       ; A=0000FFFFFFFF06\r\n00355: if n\/c goto 0345                    ;\r\n...\r\n00354: a + 1 -> a[p]                       ; A=0000FFFFFFFF07\r\n00355: if n\/c goto 0345                    ;\r\n...\r\n00354: a + 1 -> a[p]                       ; A=0000FFFFFFFF08\r\n00355: if n\/c goto 0345                    ;\r\n...\r\n...\r\n00354: a + 1 -> a[p]                       ; A=0000FFFFFFFF0F\r\n00355: if n\/c goto 0345                    ;\r\n00354: a + 1 -> a[p]                       ; A=0000FFFFFFFF00\r\n00355: if n\/c goto 0345                    ;\r\n\r\n; 00353-00355 is a loop around the delay loop:\r\n; for (A[0]=0; A[0]<0x10; A[0]++)\r\n; It runs 16 times. The extra overhead is 3 words.\r\n; Total time is 16*(3+60)= 1008 T-states.\r\n\r\n; it ends by putting what was in A[0] back, and returning\r\n00356: p <- 0                              ;\r\n00357: a exchange b[p]                     ;\r\n00360: return                              ;\r\n<\/pre>\n<p><\/code><\/p>\n<p>A subroutine suggests \"part of a bigger picture\" so, after a little looking around, here's the bigger picture:<\/p>\n<p><code><\/p>\n<pre>\r\n>>> l152\r\n00152: 0 -> s 1\r\n00153: 0 -> s 3\r\n00154: if 0 = s 3 then goto 00163\r\n00156: if 0 = s 11 then goto 00165\r\n00160: 0 -> s 11\r\n00161: ...\r\n00163: if 0 = s 11 then goto 00232\r\n00165: 0 -> s 5\r\n00166: if 1 = s 5 then goto 00173\r\n00170: jsb 0331\r\n00171: jsb 0331\r\n00172: nop\r\n00173: if 0 = s 15 then goto 00152\r\n<\/pre>\n<p><\/code><\/p>\n<p>This should look familiar because we've seen some of it before. Address 00152 is the start of the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/1926\/hp-29c-wait-loop\/\">HP-29C wait loop<\/a>.<\/p>\n<p>We're mainly interested in the lines from 00165 which check the s 5 flag. If power is fine, it skips over to 00173 and checks for a keypress or loops back to 00152 to see if anything has happened since last time.<\/p>\n<p>If power isn't fine, it does two \"jsb 0331\" instructions then continues as for the \"power is fine\" situation.<\/p>\n<p>We've seen some of the 00331 process above. Here's what it looks like in a listing:<br \/>\n<code><\/p>\n<pre>\r\n>>> l331\r\n00331: p <- 0\r\n00332: if a[p] # 0 then goto 00361\r\n00334: a - 1 -> a[p]\r\n00335: jsb 0365\r\n00336: c - 1 -> c[p]\r\n00337: b exchange c[w]\r\n00340: p <- 1\r\n00341: load constant 2\r\n00342: c -> addr\r\n00343: data register -> c 15\r\n00344: a exchange b[p]\r\n00345: p - 1 -> p\r\n00346: 0 -> s 15\r\n00347: if 1 = s 15 then goto 00175\r\n00351: if p # 4 then goto 00345\r\n00353: p <- 0\r\n00354: a + 1 -> a[p]\r\n00355: if n\/c goto 0345\r\n00356: p <- 0\r\n00357: a exchange b[p]\r\n00360: return\r\n...\r\n00365: p <- 13\r\n00366: p - 1 -> p\r\n00367: if b[p] = 0 then goto 00366\r\n00371: b -> c[w]\r\n00372: return\r\n>>>\r\n<\/pre>\n<p><\/code><\/p>\n<p>00345-00355 is a very tight way of doing the two nested loops discussed above.<\/p>\n<p>s 15 is the key pressed flag so it is being checked in the loop to keep the keyboard responsive. We'll probably see 00175 when we explore what happens when a key gets pressed. We're going to note but ignore it for now.<\/p>\n<p>00356-00360 is the exit from the loop that we already saw.<\/p>\n<p>That leaves 00331-00344.<\/p>\n<p>00334 only gets run if A[0] is 0 (because of 00331 and 00332\/3). It sets A[0]=0xF<\/p>\n<p>00335 calls 00365.<br \/>\n00365 starts just right of the mantissa sign and goes looking through B until it finds a non-zero digit. In the display formatting used in B:<\/p>\n<ul>\n<li>a '2' indicates a sign should be shown (0 in A shows as blank, 9 in A shows as '-')<\/li>\n<li>a '9' indicates a decimal point should be added ('5' shows as '5.')<\/li>\n<li>a '0' indicates a normal digit ('3' shows as '3')<\/li>\n<\/ul>\n<p>The subroutine basically sets P to where the decimal point is.<\/p>\n<p>I've set talk to 7, ENTERed 2.34 and rerun the loop. Here's what we get:<br \/>\n<code><\/p>\n<pre>\r\n00170: jsb 0331                            ;\r\n00331: p <- 0                              ;\r\n00332: if a[p] # 0 then goto 00361         ;\r\n00334: a - 1 -> a[p]                       ; A=0234FFFFFFFF0F\r\n00335: jsb 0365                            ;\r\n00365: p <- 13                             ; P=13\r\n00366: p - 1 -> p                          ; P=12\r\n00367: if b[p] = 0 then goto 00366         ;\r\n00371: b -> c[w]                           ; C=29000000000000\r\n00372: return                              ;\r\n00336: c - 1 -> c[p]                       ; C=28000000000000\r\n00337: b exchange c[w]                     ; B=28000000000000 C=29000000000000\r\n00340: p <- 1                              ; P= 1\r\n00341: load constant 2                     ; C=29000000000020 P= 0\r\n; ram_addr=32\r\n00342: c -> addr                           ;\r\n; data[47] -> C=02340000000000\r\n00343: data register -> c 15               ; C=02340000000000\r\n00344: a exchange b[p]                     ; A=0234FFFFFFFF00 B=2800000000000F\r\n00345: p - 1 -> p                          ; P=13\r\n00346: 0 -> s 15                           ;\r\n00347: if 1 = s 15 then goto 00175         ;\r\n>>>\r\n<\/pre>\n<p><\/code><br \/>\nYou can see 2.34 in the A register (and F after that to blank out later digits).<br \/>\nYou can see the '9' that indicates the decimal point changing to an '8' which doesn't.<br \/>\nYou can also see it getting the X value out of ram[47] (bank 2, register 15).<\/p>\n<p>We are also in the delay loop (00345...).<\/p>\n<p>The display is on, so the A\/B combination is displayed and we see \" 234        \".<\/p>\n<p>The next high level step is 00171 jsb 0331. This time we get:<br \/>\n<code><\/p>\n<pre>\r\n>>> g,360\r\nBreakpoint 1 at 00360\r\n>>> ts\r\n00360: return                              ;\r\n00171: jsb 0331                            ;\r\n00331: p <- 0                              ;\r\n00332: if a[p] # 0 then goto 00361         ;\r\n00361: 0 -> a[p]                           ; A=0234FFFFFFFF00\r\n00362: jsb 0365                            ;\r\n00365: p <- 13                             ; P=13\r\n00366: p - 1 -> p                          ; P=12\r\n00367: if b[p] = 0 then goto 00366         ;\r\n00371: b -> c[w]                           ; C=28000000000000\r\n00372: return                              ;\r\n00363: c + 1 -> c[p]                       ; C=29000000000000\r\n00364: if n\/c goto 0337                    ;\r\n00337: b exchange c[w]                     ; B=29000000000000 C=28000000000000\r\n00340: p <- 1                              ; P= 1\r\n00341: load constant 2                     ; C=28000000000020 P= 0\r\n00342: c -> addr                           ; ram_addr=32\r\n00343: data register -> c 15               ; data[47] -> C=02340000000000\r\n00344: a exchange b[p]                     ;\r\n00345: p - 1 -> p                          ; P=13\r\n00346: 0 -> s 15                           ;\r\n00347: if 1 = s 15 then goto 00175         ;\r\n00351: if p # 4 then goto 00345            ;\r\n00345: p - 1 -> p                          ; P=12\r\n>>>\r\n<\/pre>\n<p><\/code><br \/>\nThis time, a[p] does equal 0 so we goto 00361 and that includes add 1 to c[p] at 00363; instead of the subtract 1 we did last time at 00336.<\/p>\n<p>We end up with B=2900... instead of 2800... and the decimal point gets displayed. We see \" 2.34        \".<\/p>\n<p>At the highest level, we see:<br \/>\n<code><\/p>\n<pre>\r\n>>> g,00170\r\nBreakpoint 1 at 00170\r\n>>> dr\r\nA=0234FFFFFFFF00 D=02340000000000 M1=02340000000000 P= 0\r\nB=29000000000000 E=00000000000000 M2=00000000000000\r\nC=02340000000000 F=00000000000000 S =...3............\r\n>>> g,00171\r\n; ram_addr=32\r\n; data[47] -> C=02340000000000\r\nBreakpoint 1 at 00171\r\n>>> dr\r\nA=0234FFFFFFFF0F D=02340000000000 M1=02340000000000 P= 0\r\nB=28000000000000 E=00000000000000 M2=00000000000000\r\nC=02340000000000 F=00000000000000 S =...3............\r\n>>>\r\n<\/pre>\n<p><\/code><br \/>\nNote the B values and the A[0] values.<\/p>\n<h2>In Summary<\/h2>\n<p>If s 5 = 0 then we run the low power code.<\/p>\n<p>This is really just two lines, at 00170 and 00171. Both of these are \"jsb 0331\".<\/p>\n<p>The first time through 0331 has A[0]=0. It changes the '9' in B for the decimal point to an '8'. That turns off the decimal point.<\/p>\n<p>The second time through 0331 has A[0]=F. It changes the '8' back to a '9'. The decimal point gets displayed again.<\/p>\n<h2>Timing<\/h2>\n<p>1008 T-states with a 200 kHz clock and 56 bits per opcode word is about 1\/3 of a second. The display blinks on for 1\/3s, off for 1\/3s, and so on.<\/p>\n<p>200 kHz \/ 56 = 3571 op words per sec.<br \/>\n1008 \/ 3571 = 282 mS, a little faster than 1\/3s, but not much. <\/p>\n<p>This is part of the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/hp29-main\/\">HP-29 topic<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I first built a microcode emulator for the HP-29C, it came up with a flashing decimal point. I didn&#8217;t remember this being the case with the real thing; but that was a long time ago and I might have forgotten. I had a vague feeling there was something about low power and a flashing &hellip; <a href=\"https:\/\/www.sydneysmith.com\/wordpress\/1952\/hp-29c-flashing-dot\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">HP-29C Flashing Dot<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/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,66],"tags":[32],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1952"}],"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=1952"}],"version-history":[{"count":7,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1952\/revisions"}],"predecessor-version":[{"id":1959,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/1952\/revisions\/1959"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1952"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1952"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}