{"id":2002,"date":"2018-03-03T23:02:31","date_gmt":"2018-03-03T23:02:31","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=2002"},"modified":"2018-03-03T23:02:31","modified_gmt":"2018-03-03T23:02:31","slug":"hp-21-dsp","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/2002\/hp-21-dsp\/","title":{"rendered":"HP-21 DSP"},"content":{"rendered":"<p>This one should be remarkably straight forward; but it isn&#8217;t. There are standard ways of doing standard things. This is a standard thing. It just doesn&#8217;t follow any of the standard ways. Here&#8217;s what happens<!--more-->:<br \/>\n<code><\/p>\n<pre>\r\n>>> dr\r\nA=0000FFFFFFFFFF D=00000000000000 M1=00000000000000 P= 0\r\nB=21000000000000 E=00000000000000 M2=00000000000000\r\nC=00000000000000 F=00000000000000 S =..23.5..........\r\n>>> g,403\r\nBreakpoint 1 at 00403\r\n>>> ts200\r\n00403: keys -> rom address                 ;\r\n\r\n00621: select rom 0                        ;\r\n00222: 0 -> s 9                            ;\r\n00223: jsb 0363                            ;\r\n00363: 0 -> s 13                           ;\r\n00364: c -> a[s]                           ;\r\n00365: display toggle                      ;\r\n; do {\r\n00366: 0 -> s 15                           ;\r\n;   for (p=7; p>0; p--)\r\n00367: p <- 7                              ; P= 7\r\n00370: p - 1 -> p                          ; P= 6, 5, 4, ..., 0\r\n00371: if p # 0 then goto 00370            ;\r\n;   next\r\n; } while (s 15 == 1)\r\n00373: if 1 = s 15 then goto 00366         ;\r\n; \/\/ S=..23.5..........\r\n00375: cpu woodstock                       ;\r\n00376: if 0 = s 15 then goto 00376         ;\r\n...\r\n>>>\r\n<\/pre>\n<p><\/code><br \/>\nAll it does is clear s9 (the dot_pressed flag), wait for the DSP key to be released (until not &#8220;1 = s 15&#8221;) and then wait for a keypress.<\/p>\n<p>What is doesn&#8217;t do is set any flag anywhere to note that DSP was pressed. It doesn&#8217;t store anything in any internal CPU register. It has no way of knowing, in future, that DSP was pressed previously. Yet it does, because it does work.<\/p>\n<p>It is only when you press a digit afterwards that the trick becomes clearer. Here&#8217;s what happens when I pressed &#8220;3&#8221;:<br \/>\n<code><\/p>\n<pre>\r\n>>> g,403\r\n(((press 3)))\r\nBreakpoint 1 at 00403\r\n>>> ts200\r\n00403: keys -> rom address                 ;\r\n00561: a + 1 -> a[p]                       ; A=0000FFFFFFFFF1\r\n00562: a + 1 -> a[p]                       ; A=0000FFFFFFFFF2\r\n00563: if n\/c goto 0330                    ;\r\n00730: a + 1 -> a[p]                       ; A=0000FFFFFFFFF3\r\n00731: return                              ;\r\n<\/pre>\n<p><\/code><br \/>\nPerfectly normal and as we&#8217;d expect so far (see <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/1987\/hp-21-scan-codes\/\">HP-21 scan codes<\/a>). A[0] now = 3.<\/p>\n<p>What happens next is very different compared to earlier calculators:<br \/>\n<code><\/p>\n<pre>\r\n00224: if p = 2 then goto 00223            ;\r\n00226: 0 -> s 1                            ;\r\n00227: if 1 = s 9 then goto 00232          ;\r\n00231: 1 -> s 1                            ; S=.123.5.........F\r\n00232: f exch a                            ; A=0000FFFFFFFFF2\r\n00233: if n\/c goto 0006                    ;\r\n00006: clear s                             ;\r\n<\/pre>\n<p><\/code><br \/>\nIt&#8217;s not what it says that&#8217;s different. It&#8217;s where it is that&#8217;s different.<\/p>\n<p>Ordinarily, we&#8217;d press a prefix key and expect a flag to get set. On a HP-67, HP-65 or pretty much any other calculator, that&#8217;s how it works. The prefix key might be a colored f, g, h or f-1 key. It might also be (on calculators with more than one memory register) a STO or RCL key, or a GTO, GSB or LBL key. Press the key, set a prefix flag. <\/p>\n<p>Next you press another key and check prefix flag(s). Using &#8220;0&#8221; for an example, the concept looks like this:<br \/>\n<code><\/p>\n<pre>\r\nkey0: if f_prefix goto keyf0 ; eg calc percent\r\n      if g_prefix goto keyg0 ; eg calc percent change\r\n      if h_prefix goto keyh0 ; eg get Last X\r\n      if sto_prefix goto sto0\r\n      ...\r\n      ; no prefixes\r\n      add 0 digit to display and X\r\n<\/pre>\n<p><\/code><br \/>\nSo how does this know to do &#8220;DSP 3&#8221; instead of it just being a &#8220;3&#8221;? It is because we are at address 00224. We &#8220;return&#8221;ed to 00224 because, a long time back at 00223 in the DSP microcode, we did a &#8220;jsb 0363&#8221;.<\/p>\n<p>We are <strong>still in the DSP microcode<\/strong>! I was not expecting that.<\/p>\n<p>It is a clever approach; it&#8217;s kind of &#8220;if (key==DSP) { n=getkey(); &#8230; }&#8221;.<\/p>\n<p>If you look at the internal state from before we did the return, you can see that we have in fact set a &#8220;prefix flag&#8221;. It is just that the &#8220;flag&#8221; set is the return stack. That&#8217;s how it knows a DSP key was pressed previously:<br \/>\n<code><\/p>\n<pre>\r\n>>> di\r\nDisplay          : on (12 digits)\r\nArithmetic base  : 10\r\nRam address      : 0\r\nf                : 2\r\ncarry            : false\r\nbank\/dlyrom      : 0\/-1\r\nsp, stack        : 0 [00141,00224]\r\nlastkey          : 91\r\nvoltage          : 2.5\r\n>>> \r\n<\/pre>\n<p><\/code><br \/>\nSo, what does &#8220;DSP n&#8221; do (the point of this article)? If you look above at the code from 00226 to 00006 you&#8217;ll see that it sets s1 and puts the number of digits (&#8220;n&#8221;) into internal register f.<\/p>\n<p>s1 affects the display routine. It causes exponent digits to be displayed so s1 is the SCIentific mode flag.<\/p>\n<p>The more astute will raise concerns that there is a &#8220;clear s&#8221; afterwards and that is going to result in the calculator forgetting it should be in SCI mode. One of the peculiarities in the Woodstock CPU is that &#8220;clear s&#8221; doesn&#8217;t affect all of s. This makes sense with hardware flags such as s15 (a key is down), s3 (the switch is set to RADians) and s5 (power is good). It doesn&#8217;t make any sense at all for s1 and s2 but they are preserved despite a &#8220;clear s&#8221;.<\/p>\n<p>My working guess, is that Woodstock evolved from the earlier classic processor and they just lifted the existing solution for &#8220;clear s&#8221; from that to Woodstock. The classic had a 12 bit s register, not 16, so perhaps all of s0-s3 are unaffected by &#8220;clear s&#8221; in Woodstock. This wouldn&#8217;t show with s3 as it&#8217;s connected to hardware. It might affect s0 for some Woodstock calculators but no one seems to have observed that, so I could be wrong.<\/p>\n<p>Note that &#8220;0 -> s n&#8221; and &#8220;1 -> s n&#8221; work as expected for s1 and s2. The idiosyncrasy is only in &#8220;clear s&#8221;. <\/p>\n<h2>DSP . n<\/h2>\n<p>Here&#8217;s DSP . 2:<br \/>\n<code><\/p>\n<pre>\r\n>>> g,403\r\n(((press DSP)))\r\nBreakpoint 1 at 00403\r\n>>> ts 200\r\n00403: keys -> rom address                 ;\r\n00621: select rom 0                        ; DSP, scancode 0221\r\n00222: 0 -> s 9                            ;\r\n00223: jsb 0363                            ; n=getkey()\r\n00363: 0 -> s 13                           ;\r\n00364: c -> a[s]                           ;\r\n00365: display toggle                      ;\r\n; while (s 15 == 1 ) ;\r\n00366: ...                                 ; S=.123.5..........\r\n00375: cpu woodstock                       ;\r\n00376: if 0 = s 15 then goto 00376         ;\r\n...\r\n>>> g,403\r\n(((press .)))\r\nBreakpoint 1 at 00403\r\n>>> ts200\r\n00403: keys -> rom address                 ;\r\n00622: if n\/c goto 0023                    ; \".\", scancode 0222\r\n00423: 1 -> s 9                            ; S=.123.5...9.....F\r\n00424: p <- 2                              ; P= 2\r\n00425: return                              ;\r\n\r\n; back in DSP routine\r\n00224: if p = 2 then goto 00223            ;\r\n00223: jsb 0363                            ; n=getkey()\r\n00363: 0 -> s 13                           ;\r\n00364: c -> a[s]                           ;\r\n00365: display toggle                      ;\r\n; while (s 15 == 1 ) ;\r\n00366: ...                                 ; S=.123.5...9......\r\n00375: cpu woodstock                       ;\r\n00376: if 0 = s 15 then goto 00376         ;\r\n...\r\n\r\n>>> g,403\r\n(((press 2)))\r\nBreakpoint 1 at 00403\r\n>>> ts200\r\n00403: keys -> rom address                 ;\r\n00562: a + 1 -> a[p]                       ; A=00000FFFF00001\r\n00563: if n\/c goto 0330                    ;\r\n00730: a + 1 -> a[p]                       ; A=00000FFFF00002\r\n00731: return                              ;\r\n\r\n; back in DSP routine\r\n00224: if p = 2 then goto 00223            ; note: p=0\r\n00226: 0 -> s 1                            ; S=..23.5...9.....F\r\n00227: if 1 = s 9 then goto 00232          ;\r\n00232: f exch a                            ; A=00000FFFF00003\r\n00233: if n\/c goto 0006                    ;\r\n00006: clear s                             ; S=..23.5.........F\r\n\r\ndisplay:\r\n00007: ...                                 ; \" 0.00\"\r\n00376: if 0 = s 15 then goto 00376         ;\r\n00376: ...\r\n<\/pre>\n<p><\/code><br \/>\ns1 is the SCI flag.<br \/>\ns9 is a dot_pressed flag.<\/p>\n<p>You could do DSP . . . 6 and still get DSP . 6<\/p>\n<p>There are a lot of other combinations that you could do after DSP that are neither a &#8220;.&#8221; nor a digit. Each of those would have to be designed and checked to behave well with the DSP prefix. DSP DSP probably works as DSP. If we were already in a microcode subroutine, DSP DSP is likely to lose the parent address.<\/p>\n<p>This is part of the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/hp21-main\/\">HP-21 topic<\/a>.<\/p>\n<p>The examples shown are using the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/hp21w\/\">hp21w<\/a> simulator for Windows.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This one should be remarkably straight forward; but it isn&#8217;t. There are standard ways of doing standard things. This is a standard thing. It just doesn&#8217;t follow any of the standard ways. Here&#8217;s what happens<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,5,68],"tags":[32],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2002"}],"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=2002"}],"version-history":[{"count":2,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2002\/revisions"}],"predecessor-version":[{"id":2004,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2002\/revisions\/2004"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2002"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}