{"id":1365,"date":"2019-08-11T00:52:50","date_gmt":"2019-08-10T22:52:50","guid":{"rendered":"https:\/\/www.pagetable.com\/?p=1365"},"modified":"2019-08-11T00:52:50","modified_gmt":"2019-08-10T22:52:50","slug":"nes-and-snes-controllers-on-a-6502-like-the-c64","status":"publish","type":"post","link":"https:\/\/www.pagetable.com\/?p=1365","title":{"rendered":"NES and SNES Controllers on a 6502 (like the C64)"},"content":{"rendered":"<p>NES and SNES controllers support 8 to 12 buttons with only three data pins (plus VCC\/GND). Let&rsquo;s attach them to a C64 \u2013 or any 6502-based system!<\/p>\n<p><a href=\"docs\/nes_snes_controller_6502\/nes_snes_controller_6502.jpg\"><img decoding=\"async\" src=\"docs\/nes_snes_controller_6502\/nes_snes_controller_6502_small.jpg\" alt=\"\" \/><\/a><\/p>\n<h2 id=\"NES-Connector\">NES Connector<\/h2>\n<p>The NES controller needs to be connected to +5V, GND and three GPIOs.<\/p>\n<pre><code> ----------\n| 5  6  7   \\\n| 4  3  2  1 |\n ------------\n<\/code><\/pre>\n<table>\n<thead>\n<tr>\n<th> Pin <\/th>\n<th> Description <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td> 1   <\/td>\n<td> GND         <\/td>\n<\/tr>\n<tr>\n<td> 2   <\/td>\n<td> CLK         <\/td>\n<\/tr>\n<tr>\n<td> 3   <\/td>\n<td> LATCH       <\/td>\n<\/tr>\n<tr>\n<td> 4   <\/td>\n<td> DATA        <\/td>\n<\/tr>\n<tr>\n<td> 5   <\/td>\n<td> &#8211;           <\/td>\n<\/tr>\n<tr>\n<td> 6   <\/td>\n<td> &#8211;           <\/td>\n<\/tr>\n<tr>\n<td> 7   <\/td>\n<td> +5V         <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"SNES-Connector\">SNES Connector<\/h2>\n<p>The SNES controller&rsquo;s pins are just like the NES controller&rsquo;s, but with a different connector.<\/p>\n<pre><code> \/---------------------\n| 7  6  5 | 4  3  2  1 |\n \\---------------------\n<\/code><\/pre>\n<table>\n<thead>\n<tr>\n<th> Pin <\/th>\n<th> Description <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td> 1   <\/td>\n<td> +5V         <\/td>\n<\/tr>\n<tr>\n<td> 2   <\/td>\n<td> CLK         <\/td>\n<\/tr>\n<tr>\n<td> 3   <\/td>\n<td> LATCH       <\/td>\n<\/tr>\n<tr>\n<td> 4   <\/td>\n<td> DATA        <\/td>\n<\/tr>\n<tr>\n<td> 5   <\/td>\n<td> &#8211;           <\/td>\n<\/tr>\n<tr>\n<td> 6   <\/td>\n<td> &#8211;           <\/td>\n<\/tr>\n<tr>\n<td> 7   <\/td>\n<td> GND         <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"User-Port\">User Port<\/h2>\n<p>The C64 User Port exposes, among other lines, +5V, GND and 8 GPIOs (CIA#2 Port B):<\/p>\n<pre><code> 1 | 2  3  4  5  6  7  8  9  10 | 11 12\n--- ---------------------------- -------\n A | B  C  D  E  F  H  J  K  L  | M  N\n<\/code><\/pre>\n<p>(viewed towards the C64 edge connector)<\/p>\n<table>\n<thead>\n<tr>\n<th> Pin <\/th>\n<th> Description <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td> 1   <\/td>\n<td> GND         <\/td>\n<\/tr>\n<tr>\n<td> 2   <\/td>\n<td> +5V         <\/td>\n<\/tr>\n<tr>\n<td> C   <\/td>\n<td> PB0         <\/td>\n<\/tr>\n<tr>\n<td> D   <\/td>\n<td> PB1         <\/td>\n<\/tr>\n<tr>\n<td> E   <\/td>\n<td> PB2         <\/td>\n<\/tr>\n<tr>\n<td> F   <\/td>\n<td> PB3         <\/td>\n<\/tr>\n<tr>\n<td> H   <\/td>\n<td> PB4         <\/td>\n<\/tr>\n<tr>\n<td> J   <\/td>\n<td> PB5         <\/td>\n<\/tr>\n<tr>\n<td> K   <\/td>\n<td> PB6         <\/td>\n<\/tr>\n<tr>\n<td> L   <\/td>\n<td> PB7         <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"Connection\">Connection<\/h2>\n<p>Let&rsquo;s semi-arbitrarily map the signals like this:<\/p>\n<table>\n<thead>\n<tr>\n<th> GPIO <\/th>\n<th> Description                  <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td> PB3  <\/td>\n<td> LATCH (for both controllers) <\/td>\n<\/tr>\n<tr>\n<td> PB4  <\/td>\n<td> DATA (controller 1)          <\/td>\n<\/tr>\n<tr>\n<td> PB5  <\/td>\n<td> CLK (for both controllers)   <\/td>\n<\/tr>\n<tr>\n<td> PB6  <\/td>\n<td> DATA (controller 2)          <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The latch and clock outputs go to both controllers. There is a data line for each controller.<\/p>\n<p>So the connection diagram for two NES controllers looks like this:<\/p>\n<table>\n<thead>\n<tr>\n<th> Description <\/th>\n<th> User Port Pin <\/th>\n<th> NES #1 Pin <\/th>\n<th> NES #2 Pin <\/th>\n<th> Color  <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td> GND         <\/td>\n<td> 1             <\/td>\n<td> 1          <\/td>\n<td> 1          <\/td>\n<td> black  <\/td>\n<\/tr>\n<tr>\n<td> +5V         <\/td>\n<td> 2             <\/td>\n<td> 7          <\/td>\n<td> 7          <\/td>\n<td> red    <\/td>\n<\/tr>\n<tr>\n<td> LATCH       <\/td>\n<td> F             <\/td>\n<td> 3          <\/td>\n<td> 3          <\/td>\n<td> blue   <\/td>\n<\/tr>\n<tr>\n<td> DATA#1      <\/td>\n<td> H             <\/td>\n<td> 4          <\/td>\n<td> &#8211;          <\/td>\n<td> green  <\/td>\n<\/tr>\n<tr>\n<td> CLK         <\/td>\n<td> J             <\/td>\n<td> 2          <\/td>\n<td> 2          <\/td>\n<td> white  <\/td>\n<\/tr>\n<tr>\n<td> DATA#2      <\/td>\n<td> K             <\/td>\n<td> &#8211;          <\/td>\n<td> 4          <\/td>\n<td> yellow <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>And this is the same diagram for two SNES controllers:<\/p>\n<table>\n<thead>\n<tr>\n<th> Description <\/th>\n<th> User Port Pin <\/th>\n<th> NES #1 Pin <\/th>\n<th> NES #2 Pin <\/th>\n<th> Color  <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td> GND         <\/td>\n<td> 1             <\/td>\n<td> 7          <\/td>\n<td> 7          <\/td>\n<td> black  <\/td>\n<\/tr>\n<tr>\n<td> +5V         <\/td>\n<td> 2             <\/td>\n<td> 1          <\/td>\n<td> 1          <\/td>\n<td> red    <\/td>\n<\/tr>\n<tr>\n<td> LATCH       <\/td>\n<td> F             <\/td>\n<td> 3          <\/td>\n<td> 3          <\/td>\n<td> blue   <\/td>\n<\/tr>\n<tr>\n<td> DATA#1      <\/td>\n<td> H             <\/td>\n<td> 4          <\/td>\n<td> &#8211;          <\/td>\n<td> green  <\/td>\n<\/tr>\n<tr>\n<td> CLK         <\/td>\n<td> J             <\/td>\n<td> 2          <\/td>\n<td> 2          <\/td>\n<td> white  <\/td>\n<\/tr>\n<tr>\n<td> DATA#2      <\/td>\n<td> K             <\/td>\n<td> &#8211;          <\/td>\n<td> 4          <\/td>\n<td> yellow <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In fact, you can attach an NES and an SNES controller in parallel for each of the two slots, as long as you ever only connect one controller per slot.<\/p>\n<p>This is the user port connector with wires attached for two controllers, using the color scheme above:<\/p>\n<p><a href=\"docs\/nes_snes_controller_6502\/userport_connector.jpg\"><img decoding=\"async\" src=\"docs\/nes_snes_controller_6502\/userport_connector_small.jpg\" alt=\"\" \/><\/a><\/p>\n<p>This is an NES connector attached as the first controller (green data line):<\/p>\n<p><a href=\"docs\/nes_snes_controller_6502\/nes_connector.jpg\"><img decoding=\"async\" src=\"docs\/nes_snes_controller_6502\/nes_connector_small.jpg\" alt=\"\" \/><\/a><\/p>\n<p>And this is an SNES connector attached as the second controller (yellow data line):<\/p>\n<p><a href=\"docs\/nes_snes_controller_6502\/snes_connector.jpg\"><img decoding=\"async\" src=\"docs\/nes_snes_controller_6502\/snes_connector_small.jpg\" alt=\"\" \/><\/a><\/p>\n<h2 id=\"The-Code\">The Code<\/h2>\n<p>The code to read both controllers at a time is pretty simple:<\/p>\n<pre><code>; C64 CIA#2 PB\nnes_data = $dd01\nnes_ddr  = $dd03\n;\nbit_latch = $08 ; PB3 (user port pin F): LATCH (both controllers)\nbit_data1 = $10 ; PB4 (user port pin H): DATA  (controller #1)\nbit_clk   = $20 ; PB5 (user port pin J): CLK   (both controllers)\nbit_data2 = $40 ; PB6 (user port pin K): DATA  (controller #2)\n\n; zero page\ncontroller1 = $e0 ; 3 bytes\ncontroller2 = $f0 ; 3 bytes\n\nquery_controllers:\n    lda #$ff-bit_data1-bit_data2\n    sta nes_ddr\n    lda #$00\n    sta nes_data\n\n    ; pulse latch\n    lda #bit_latch\n    sta nes_data\n    lda #0\n    sta nes_data\n\n    ; read 3x 8 bits\n    ldx #0\nl2: ldy #8\nl1: lda nes_data\n    cmp #bit_data2\n    rol controller2,x\n    and #bit_data1\n    cmp #bit_data1\n    rol controller1,x\n    lda #bit_clk\n    sta nes_data\n    lda #0\n    sta nes_data\n    dey\n    bne l1\n    inx\n    cpx #3\n    bne l2\n    rts\n<\/code><\/pre>\n<p>After calling <code>query_controllers<\/code>, three bytes each at <code>controller1<\/code> and <code>controller2<\/code> will contain the state:<\/p>\n<pre><code>; byte 0:      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |\n;         NES  | A | B |SEL|STA|UP |DN |LT |RT |\n;         SNES | B | Y |SEL|STA|UP |DN |LT |RT |\n;\n; byte 1:      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |\n;         NES  | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |\n;         SNES | A | X | L | R | 1 | 1 | 1 | 1 |\n; byte 2:\n;         $00 = controller present\n;         $FF = controller not present\n<\/code><\/pre>\n<p>A 0 bit means the button is pressed, 1 means it is released.<\/p>\n<p>The code pulses LATCH once, which makes the controllers sample their button states and transmit the first bit through their respective DATA lines. Pulsing CLK 15 more times will make the controllers send the remaining bits. Since SNES controllers send 16 bits of data, but NES controllers only send 8 bits, the type of controller can be detected through the lowermost nybble of byte 1. Similarly, the presense of a controller is detected by continuing to read bits: If a controller is attached, it will send 0 bits.<\/p>\n<h2 id=\"Repository\">Repository<\/h2>\n<p>The driver code, together with demo code for the C64 can be found at <a href=\"https:\/\/github.com\/mist64\/nes_snes_controller_6502\">https:\/\/github.com\/mist64\/nes_snes_controller_6502<\/a>.<\/p>\n<p><a href=\"docs\/nes_snes_controller_6502\/demo.png\"><img decoding=\"async\" src=\"docs\/nes_snes_controller_6502\/demo.png\" alt=\"\" \/><\/a><\/p>\n<h2 id=\"More?\">More?<\/h2>\n<p>For each additional controller, only a single extra GPIO is needed. This way, six controllers would be possible on a single 8 bit I\/O port, with only slightly modified code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>NES and SNES controllers support 8 to 12 buttons with only three data pins (plus VCC\/GND). Let&rsquo;s attach them to a C64 \u2013 or any 6502-based system! NES Connector The NES controller needs to be connected to +5V, GND and three GPIOs. &#8212;&#8212;&#8212;- | 5 6 7 \\ | 4 3 2 1 | &#8212;&#8212;&#8212;&#8212; &#8230; <a title=\"NES and SNES Controllers on a 6502 (like the C64)\" class=\"read-more\" href=\"https:\/\/www.pagetable.com\/?p=1365\" aria-label=\"Read more about NES and SNES Controllers on a 6502 (like the C64)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,41,8,16],"tags":[],"class_list":["post-1365","post","type-post","status-publish","format-standard","hentry","category-2","category-c64","category-commodore","category-github"],"_links":{"self":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/1365","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1365"}],"version-history":[{"count":0,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/1365\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1365"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1365"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1365"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}