{"id":795,"date":"2019-10-08T10:55:22","date_gmt":"2019-10-08T09:55:22","guid":{"rendered":"http:\/\/bergatrollet.se\/blog\/?p=795"},"modified":"2019-10-23T13:37:17","modified_gmt":"2019-10-23T12:37:17","slug":"the-c64-keyboard","status":"publish","type":"post","link":"http:\/\/bergatrollet.se\/blog\/2019\/10\/the-c64-keyboard\/","title":{"rendered":"The c64 keyboard"},"content":{"rendered":"\n<p>I have been involved in a few project where a PC keyboard was to be used for the c64. VICE emulator and Ultimate64 reimplementation on the c64.<\/p>\n\n\n\n<p>Let&#8217;s have a look at how the keyboard on a c64 works..<\/p>\n\n\n\n<p>The CIA#1 chip has two registers that are associated with the  physically  keyboard. In order to scan the keyboard you poke a value in $DC00 and  you put 0 on the line in the matrix you want to test. Then you read $DC01 to detect which of the eight keys in that column of the matrix you got a hit at. A zero in a line means that this key in the matrix was pressed. <\/p>\n\n\n\n<p>Please mind that we are talking the physical button of the keyboard, and this is where it gets complex. The keys on national keyboards aren&#8217;t meant to produce the same output. National keyboard variants have other prints (or stickers) that is associated with a DC00\/DC01 combination.<\/p>\n\n\n\n<p> The support for DC00\/DC01 -> which key is implemented using tables in Kernal, and they are then different in the different national variants.<\/p>\n\n\n\n<p>$EB81 is ths unshifted table,  Shifted is at $EBC2, Commodore &#8220;shifted&#8221; at $EC03 and control &#8220;shifted&#8221; at $EC78. <\/p>\n\n\n\n<p>In the English edition of Kernal, the first table looks like this and my scribbly notes from my Commodore64 Whole Memory Guide shows the delta vs the Swedish Kernal.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"3035\" height=\"3622\" data-attachment-id=\"800\" data-permalink=\"http:\/\/bergatrollet.se\/blog\/2019\/10\/the-c64-keyboard\/2019-10-08-0003\/\" data-orig-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?fit=3035%2C3622\" data-orig-size=\"3035,3622\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;DCP-9020CDW&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1570531133&quot;,&quot;copyright&quot;:&quot;Bergatrollet AB&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"2019-10-08-0003\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?fit=251%2C300\" data-large-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?fit=605%2C722\" src=\"https:\/\/i1.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?fit=520%2C621\" alt=\"\" class=\"wp-image-800\" srcset=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?w=3035 3035w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?resize=251%2C300 251w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?resize=768%2C917 768w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?resize=858%2C1024 858w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?w=1210 1210w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/2019-10-08-0003.jpg?w=1815 1815w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>Adding to this, national variants of the c64 also had updated character ROMs. That means that some international characters defined were hijacked and replaced with others. In the Swedish one, the characters [, libra\/pound and ] are replaced with the Swedish chars \u00e4, \u00f6 and \u00e5. The below shows the representation in upper\/gfx mode, but naturally the Swedish chars exist in both upper and also lower case.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1038\" height=\"274\" data-attachment-id=\"801\" data-permalink=\"http:\/\/bergatrollet.se\/blog\/2019\/10\/the-c64-keyboard\/image-9\/\" data-orig-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?fit=1038%2C274\" data-orig-size=\"1038,274\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?fit=300%2C79\" data-large-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?fit=605%2C160\" src=\"https:\/\/i1.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?fit=520%2C137\" alt=\"\" class=\"wp-image-801\" srcset=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?w=1038 1038w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?resize=300%2C79 300w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?resize=768%2C203 768w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image.png?resize=1024%2C270 1024w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1032\" height=\"266\" data-attachment-id=\"802\" data-permalink=\"http:\/\/bergatrollet.se\/blog\/2019\/10\/the-c64-keyboard\/image-1-3\/\" data-orig-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?fit=1032%2C266\" data-orig-size=\"1032,266\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?fit=300%2C77\" data-large-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?fit=605%2C156\" src=\"https:\/\/i1.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?fit=520%2C134\" alt=\"\" class=\"wp-image-802\" srcset=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?w=1032 1032w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?resize=300%2C77 300w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?resize=768%2C198 768w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-1.png?resize=1024%2C264 1024w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p> To summarise the process on the c64, this is it:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"605\" height=\"67\" data-attachment-id=\"805\" data-permalink=\"http:\/\/bergatrollet.se\/blog\/2019\/10\/the-c64-keyboard\/image-2-3\/\" data-orig-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?fit=971%2C108\" data-orig-size=\"971,108\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image-2\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?fit=300%2C33\" data-large-file=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?fit=605%2C67\" src=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?resize=605%2C67\" alt=\"\" class=\"wp-image-805\" srcset=\"https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?w=971 971w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?resize=300%2C33 300w, https:\/\/i0.wp.com\/bergatrollet.se\/blog\/wp-content\/uploads\/2019\/10\/image-2.png?resize=768%2C85 768w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<p>So if you make an interface that takes the position of a PC keyboards and generate a DC00\/DC01 combination, then there are a lot of aspects you need to address.<\/p>\n\n\n\n<p>I haven&#8217;t read up on what the physical keyboard sends on the cable, if it&#8217;s as complex as on the c64 but an opening link for this interested could be <a href=\"https:\/\/stackoverflow.com\/questions\/43830339\/how-to-convert-usb-keyboard-packet-or-usage-id-code-to-ascii-or-other-convenient\">THIS ONE<\/a>.<\/p>\n\n\n\n<p>Under OSes, there tends to be drivers for the keyboards and emulators that return something to you which is a proper representation of the graphics printed on the keyboard (See <a href=\"ps:\/\/www.x.org\/releases\/X11R7.7\/doc\/libX11\/i18n\/compose\/iso8859-15.html\">HERE<\/a>) . In Windows you can select language, which is the equivalent of changing Kernal keymap on the c64, but please mind that taking that value and poke something in the DC00\/DC01 means that you are making assumptions on the Kernal matrix and char ROM.<\/p>\n\n\n\n<p>If I run VICE, and I press &#8220;=&#8221; on my Swedish PC keyboard with Swedish keyboard set in my Windows keyboard setting, this feeds the &#8220;=&#8221; to VICE. VICE will then place #$DF in $DC01 when $BF is written to $DC00 to achieve char code $3D. Using an English\/International Kernal, you will then get a &#8220;=&#8221; on the screen. All good. But if you have a Swedish Kernal, the same position on the key matrix yields $3B (&#8220;+&#8221;). If you want a &#8220;=&#8221;, then you need to return $F7 on $DC01 when you poke $DF to $DC00.<\/p>\n\n\n\n<p>So in practice, emulators (VICE is the case I I know of &#8211; not sure about the others) only supports English\/international Kernals.<\/p>\n\n\n\n<p>There are two ways to mitigate this;<br>&#8211; Allow any Kernal to be loaded, but exchange the keymap portion with the one from the international Kernals.<br>&#8211; Get the key from the keyboard and look at what char that would be on the c64. Then lookup that key in the Kernal keymaps to tell what DC00\/DC01 values it would need to return that keycode.<\/p>\n\n\n\n<p>The first option would make alterations to the emulated environment, which isn&#8217;t really neat. The second option means producing new logics around the keyboard handling, and I guess that it &#8220;sort of works&#8221; now (even if it doesn&#8217;t &#8211; it&#8217;s just that it doesn&#8217;t show as long as you stay on international keymap kernals).<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have been involved in a few project where a PC keyboard was to be used for the c64. VICE emulator and Ultimate64 reimplementation on the c64. Let&#8217;s have a look at how the keyboard on a c64 works.. The &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"more-link\" href=\"http:\/\/bergatrollet.se\/blog\/2019\/10\/the-c64-keyboard\/\"> <span class=\"screen-reader-text\">The c64 keyboard<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[88,105],"tags":[],"class_list":["post-795","post","type-post","status-publish","format-standard","hentry","category-88","category-c64"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pkM6p-cP","jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/posts\/795","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/comments?post=795"}],"version-history":[{"count":13,"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/posts\/795\/revisions"}],"predecessor-version":[{"id":820,"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/posts\/795\/revisions\/820"}],"wp:attachment":[{"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/media?parent=795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/categories?post=795"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/bergatrollet.se\/blog\/wp-json\/wp\/v2\/tags?post=795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}