{"id":2106,"date":"2018-04-14T12:58:57","date_gmt":"2018-04-14T12:58:57","guid":{"rendered":"http:\/\/www.sydneysmith.com\/wordpress\/?p=2106"},"modified":"2018-04-14T12:58:57","modified_gmt":"2018-04-14T12:58:57","slug":"hp-29c-keypress-routine","status":"publish","type":"post","link":"https:\/\/www.sydneysmith.com\/wordpress\/2106\/hp-29c-keypress-routine\/","title":{"rendered":"HP-29C Keypress Routine"},"content":{"rendered":"<p>So, you bought an old calculator; or a new one a very long time ago. You press a button and an answer pops out. How does it get from the first thing, to the second? This&#8217;ll answer the &#8220;getting from&#8221; part. I&#8217;ll leave the &#8220;getting to&#8221; part to later (get the <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/hp65-book1\/\">HP-65 book<\/a> if you&#8217;re not good at waiting). Here&#8217;s what happens &#8230;<!--more--><\/p>\n<p>Pressing a key results in the s15 flag inside the calculator getting set and a scancode being passed to its processor. (See <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/1926\/hp-29c-wait-loop\/\">HP-29C Wait Loop<\/a> and <a href=\"http:\/\/www.sydneysmith.com\/wordpress\/1850\/hp29-scan-codes\/\">HP-29 Scan Codes<\/a>).<\/p>\n<p>The Wait Loop is waiting for something to happen, such as s15 getting set. This article covers what the microcode inside the calculator does as a result.<\/p>\n<p>Here&#8217;s part of the Wait Loop:<br \/>\n<code><\/p>\n<pre>\r\n00173: if 0 = s 15 then goto 00152\r\n00152: ...\r\n00166: ... then goto 00173\r\n<\/pre>\n<p><\/code><br \/>\nIt checks that there isn&#8217;t a key press, goes to 00152, checks some other things, and then ends up back at 00173 again.<\/p>\n<p>Here&#8217;s what happens is s15 isn&#8217;t 0:<br \/>\n<code><\/p>\n<pre>\r\n(press the \"x&lt;->y\" key, scan code 0x43)\r\n(s 15 gets set, shown here as \"S= ..F\")\r\n00156: if 0 = s 11 then goto 00165         ; S=...3.5...9.....F\r\n00165: 0 -> s 5                            ;\r\n00166: if 1 = s 5 then goto 00173          ;\r\n00173: if 0 = s 15 then goto 00152         ; it's not, so we're not going\r\n00175: ...                                 ;\r\n<\/pre>\n<p><\/code><br \/>\nWe&#8217;re no longer in the loop &#8211; we didn&#8217;t go to 00152. The &#8220;if (something) then goto (somewhere)&#8221; instruction is a  two-word instruction. We went instead, to the next instruction after 00173 &#8211; to 00175. That makes 00175 the &#8220;keypressed&#8221; address. It looks like:<br \/>\n<code><\/p>\n<pre>\r\n00175: display off                         ;\r\n00176: b exchange c[w]                     ; B=00000000000000 C=29000000000000\r\n00177: keys to a                           ; A=0000FFFFFFF430\r\n00200: 0 -> s 13                           ;\r\n<\/pre>\n<p><\/code><br \/>\nIt turns the display off and we see that as a blink when we press a key. It saves anything in the C register, by putting it in B for now, because it is about to use A and C to work some things out. The keys to a&#8221; instruction puts the current scan code in A[2] and A[1]. You can see 43 there. Remember that we pressed the &#8220;x<->y&#8221; key which has a scan code of 0x43. It also clears s13. I don&#8217;t know why as yet.<\/p>\n<p>The next thing it does is multiply the scan code row (the 4) by 5 and add the scan code column. This is a simple way of reducing the range down to something smaller. If you look at the HP-29 scan code article, you&#8217;ll see that column numbers are all within 0-4 so multiplying row by 5 and adding column makes sense. In theory, you could reduce a range of (potentially) 00-FF down to 35 keys. Scan codes are easier for hardware. A short list of possible keys is easier for software. In practice, the row numbers range from 4-D(=13) so it isn&#8217;t quite as neat as it could be; but it does reduce the span of the jump table.<\/p>\n<p>The row*5+col code looks like this:<br \/>\n<code><\/p>\n<pre>\r\n00201: binary                              ;\r\n00202: 0 -> c[x]                           ;\r\n00203: c + 1 -> c[x]                       ; C=29000000000001\r\n00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF330\r\n00205: if n\/c goto 0203                    ;\r\n00203: c + 1 -> c[x]                       ; C=29000000000002\r\n00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF230\r\n00205: if n\/c goto 0203                    ;\r\n00203: c + 1 -> c[x]                       ; C=29000000000003\r\n00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF130\r\n00205: if n\/c goto 0203                    ;\r\n00203: c + 1 -> c[x]                       ; C=29000000000004\r\n00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF030\r\n00205: if n\/c goto 0203                    ;\r\n00203: c + 1 -> c[x]                       ; C=29000000000005\r\n00204: a - 1 -> a[xs]                      ; A=0000FFFFFFFF30\r\n00205: if n\/c goto 0203                    ;\r\n00206: c - 1 -> c[x]                       ; C=29000000000004 c[0]= was a[2]\r\n00207: 0 -> a[xs]                          ; A=0000FFFFFFF030\r\n00210: shift right a[x]                    ; A=0000FFFFFFF003 a[0]= was a[1]\r\n00211: a + c -> a[x]                       ; A=0000FFFFFFF007 a[x]= was a[2]+a[1]\r\n00212: c + c -> c[x]                       ; C=29000000000008 c[0]= 2x was a[2]\r\n00213: c + c -> c[x]                       ; C=29000000000010 c[0]= 4x was a[2]\r\n00214: a + c -> a[x]                       ; A=0000FFFFFFF017 a[x]= 5x was a[2] + was a[1]\r\n<\/pre>\n<p><\/code><br \/>\n00203-00205 is a loop reducing the row number by 1 each time and adding 1 to C[0]. It is like doing &#8220;a -&gt; c [xs]&#8221; then &#8220;shift right a[x]&#8221; twice (A[2]-&gt;C[2]; C[2]-&gt;C[1]-&gt;C[0]). We end up with the 4 from 0x43 in C[0].<\/p>\n<p>We still have the 3 from 0x43 in A[1] so 00210 moves it into A[0].<\/p>\n<p>As shown, the sequence 00211-00214: adds row+col (4+3=7), sets C[x] to 4*row (4*4=0x10), and adds that too. We get (row+col + 4*row = 5*row+col). For 0x43, row=4, col=3, 5*4+3= 23= 1*16+7=) 0x17 in A[x].<\/p>\n<p>The next bit looks a little confusing; but it is really just a jump to 00400 + 5*row+col<br \/>\n<code><\/p>\n<pre>\r\n00215: shift left a[x]                     ; A=0000FFFFFFF170\r\n00216: p <- 1                              ; P= 1\r\n00217: m1 -> c                             ; C=00000000000000\r\n00220: 0 -> c[x]                           ;\r\n00221: delayed rom 1                       ; to 00400-00777\r\n00222: a -> rom address                    ; 0x17 = 10111 = 027\r\n; scancode 043 -> row4,col3 -> 5*4+3 = 23\r\n; 23= 1*16+7 so hex  = 0x17\r\n; 23= 2* 8+7 so octal= 027 \r\n00427: if n\/c goto 0151                    ; 00400 + 5*row + col\r\n<\/pre>\n<p><\/code><br \/>\nYou end up with:<\/p>\n<table>\n<tr>\n<td>Keycode<\/td>\n<td>Key<\/td>\n<td>Scan Code<\/td>\n<td>Goto<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>SST<\/td>\n<td>0xb3<\/td>\n<td>00472<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td>GSB<\/td>\n<td>0xb2<\/td>\n<td>00471<\/td>\n<\/tr>\n<tr>\n<td>13<\/td>\n<td>GTO<\/td>\n<td>0xb1<\/td>\n<td>00470<\/td>\n<\/tr>\n<tr>\n<td>14<\/td>\n<td>f  <\/td>\n<td>0xb0<\/td>\n<td>00467<\/td>\n<\/tr>\n<tr>\n<td>15<\/td>\n<td>g  <\/td>\n<td>0xb4<\/td>\n<td>00473<\/td>\n<\/tr>\n<tr>\n<td>21<\/td>\n<td>x<->y<\/td>\n<td>0x43<\/td>\n<td>00427<\/td>\n<\/tr>\n<tr>\n<td>22<\/td>\n<td>Rv <\/td>\n<td>0x42<\/td>\n<td>00426<\/td>\n<\/tr>\n<tr>\n<td>23<\/td>\n<td>STO<\/td>\n<td>0x41<\/td>\n<td>00425<\/td>\n<\/tr>\n<tr>\n<td>24<\/td>\n<td>RCL<\/td>\n<td>0x40<\/td>\n<td>00424<\/td>\n<\/tr>\n<tr>\n<td>25<\/td>\n<td>SUM<\/td>\n<td>0x44<\/td>\n<td>00430<\/td>\n<\/tr>\n<tr>\n<td>31<\/td>\n<td>ENTER<\/td>\n<td>0xd3<\/td>\n<td>00504<\/td>\n<\/tr>\n<tr>\n<td>33<\/td>\n<td>CHS<\/td>\n<td>0xd1<\/td>\n<td>00502<\/td>\n<\/tr>\n<tr>\n<td>34<\/td>\n<td>EEX<\/td>\n<td>0xd0<\/td>\n<td>00501<\/td>\n<\/tr>\n<tr>\n<td>35<\/td>\n<td>CLx<\/td>\n<td>0xd4<\/td>\n<td>00505<\/td>\n<\/tr>\n<tr>\n<td>41<\/td>\n<td>&#8211;<\/td>\n<td>0x63<\/td>\n<td>00441<\/td>\n<\/tr>\n<tr>\n<td>42<\/td>\n<td>7<\/td>\n<td>0x62<\/td>\n<td>00440<\/td>\n<\/tr>\n<tr>\n<td>43<\/td>\n<td>8<\/td>\n<td>0x61<\/td>\n<td>00437<\/td>\n<\/tr>\n<tr>\n<td>44<\/td>\n<td>9<\/td>\n<td>0x60<\/td>\n<td>00436<\/td>\n<\/tr>\n<tr>\n<td>51<\/td>\n<td>+<\/td>\n<td>0xa3<\/td>\n<td>00465<\/td>\n<\/tr>\n<tr>\n<td>52<\/td>\n<td>4<\/td>\n<td>0xa2<\/td>\n<td>00464<\/td>\n<\/tr>\n<tr>\n<td>53<\/td>\n<td>5<\/td>\n<td>0xa1<\/td>\n<td>00463<\/td>\n<\/tr>\n<tr>\n<td>54<\/td>\n<td>6<\/td>\n<td>0xa0<\/td>\n<td>00462<\/td>\n<\/tr>\n<tr>\n<td>61<\/td>\n<td>x<\/td>\n<td>0x73<\/td>\n<td>00446<\/td>\n<\/tr>\n<tr>\n<td>62<\/td>\n<td>1<\/td>\n<td>0x72<\/td>\n<td>00445<\/td>\n<\/tr>\n<tr>\n<td>63<\/td>\n<td>2<\/td>\n<td>0x71<\/td>\n<td>00444<\/td>\n<\/tr>\n<tr>\n<td>64<\/td>\n<td>3<\/td>\n<td>0x70<\/td>\n<td>00443<\/td>\n<\/tr>\n<tr>\n<td>71<\/td>\n<td>\/<\/td>\n<td>0x93<\/td>\n<td>00460<\/td>\n<\/tr>\n<tr>\n<td>72<\/td>\n<td>0<\/td>\n<td>0x92<\/td>\n<td>00457<\/td>\n<\/tr>\n<tr>\n<td>73<\/td>\n<td>.<\/td>\n<td>0x91<\/td>\n<td>00456<\/td>\n<\/tr>\n<tr>\n<td>74<\/td>\n<td>R\/S<\/td>\n<td>0x90<\/td>\n<td>00455<\/td>\n<\/tr>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>So, you bought an old calculator; or a new one a very long time ago. You press a button and an answer pops out. How does it get from the first thing, to the second? This&#8217;ll answer the &#8220;getting from&#8221; part. I&#8217;ll leave the &#8220;getting to&#8221; part to later (get the HP-65 book if you&#8217;re &hellip; <a href=\"https:\/\/www.sydneysmith.com\/wordpress\/2106\/hp-29c-keypress-routine\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">HP-29C Keypress Routine<\/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,66],"tags":[],"_links":{"self":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2106"}],"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=2106"}],"version-history":[{"count":2,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2106\/revisions"}],"predecessor-version":[{"id":2108,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/posts\/2106\/revisions\/2108"}],"wp:attachment":[{"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sydneysmith.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}