Up Up Down Down Left Right Left Right B A Start
Up Up Down Down Left Right Left Right B A Start. Dan’s MEGA65 Digest for October 2024.
Everyone who owned a Commodore 64 had at least one joystick, a game controller consisting of a lever that could be pushed in eight directions and a single action button. Games based on this controller typically involved the player using the stick to move an avatar—a spaceship, a person, a creature—as well as pushing the action button to activate a weapon against some enemies. The button on this kind of joystick was almost universally referred to as the “fire” button for how often it was used to launch missiles or shoot bullets.
Then came the Nintendo Entertainment System with its gamepad controller, a plastic rectangle with a directional thumb pad, two action buttons, and two more business-like buttons intended for pausing the game and accessing menus. NES games, especially Super Mario Bros. and The Legend of Zelda, popularized a new game design language based on the two action buttons. While Mario-like platform games were made for the C64 and its one-button joystick, expecting the player to shove the joystick forward (“up”) to jump, every generation of gamers that followed the NES expected to be able to jump in a platform game by pressing one of the two action buttons.
The vast majority of C64 games used the one-button joystick protocol. But there have been several attempts, both vintage and modern, to bring multi-button gaming to the C64, and to other computers with 9-pin joystick ports. This is of particular interest to modern retro game developers who want to use multi-button game design conventions while coding for the C64 and MEGA65.
In this Digest, we’ll explore a bit of the history of 9-pin game controllers, and investigate several methods used to implement multi-button schemes. We’ll look at the fundamentals of game controller electronics, and game controller programming. We’ll also take a closer look at several modern game controllers and controller adapters you can buy today for your MEGA65.
But first news!
More MEGA65 parts available separately
Last month, we noticed that Trenz Electronic is now making the MEGA65 mainboard available for preorder as a standalone part. Trenz has since added more MEGA65 parts to their store: the MEGA65 keyboard, the plastic case, the floppy drive, and the power supply. The keyboard is a sophisticated part, including the mechanical key switches, keycaps, cable, metal frame, and LEDs. The case includes other plastic bits such as the ALPS floppy drive eject button and reset button cap. You could, in theory, assemble a full MEGA65 from the spare parts available.
Math wizards may notice that the cost of the parts all together add up to more than the cost of a complete MEGA65. I can’t speak for Trenz, but this jibes with my limited understanding of the microeconomics of short-run niche electronics. Without economies of scale, Trenz has to account for labor, logistics, and potential lossage to support the individual items, even when pulling from the same stock they use to assemble full units. As deft puts it, “Imagine buying a car one piece at a time.”
I’m grateful that they’re making these available, so we have potential replacement parts, as well as options for other projects.
“Should I upgrade my mainboard?”
Did you receive your MEGA65 in 2022, or buy it second-hand from someone who did? Then your computer has the revision 3 (R3) mainboard. Starting in 2024, Trenz Electronic began shipping MEGA65s with the revision 6 (R6) mainboard, which has several changes from R3. If you’re unsure which MEGA65 mainboard you have, you can double-check which one you have in the MegaInfo panel: open the Freezer (hold Restore for one second, then release), then press Help. It’ll say which one you have next to “MEGA65 Model.”
Should owners of the R3 board upgrade to the R6? Probably not. It is unlikely that a difference between the R3 and R6 mainboards would be worth the cost of a new mainboard to most R3 owners. The differences may not even be noticeable.
There are a few notable categories of changes between the R3 and R6 boards: bidirectional cartridge and joystick I/O lines, an added SDRAM chip, and electrical fixes.
Bidirectional cartridge lines. The original R3 mainboard supports the vast majority of cartridges made for the Commodore 64, which provide program data as input to the computer. It will also support cartridges made for the MEGA65 in the future. The cartridge port changes in the R6 board apply to a few electronically fancy cartridges that communicate with the computer using both input and output. For example, the MSSIAH MIDI interface cartridge works with the C64 core, and requires the R6 mainboard. EasyFlash 3 is also known to require the R6. Notably, an EasyFlash 1 cartridge can be both read from and written to by an R3 MEGA65. That’s how we’ve been testing the MEGA65 cartridge protocol.
Bidirectional joystick port lines. The original R3 mainboard also supports the vast majority of game controller peripherals for the C64, which provide input to the computer about how the user is manipulating the controller. A few unusual peripheral designs use the data lines for both input and output, to implement more buttons or other features with proprietary protocols. The R6 mainboard adds support for such protocols. See this month’s feature article for more on game controller protocols.
SDRAM chip. The R6 adds an SDRAM chip that is intended to broaden the possibilities for alternate FPGA cores. It is possible that someday there could exist an alternate core that requires the R6 and doesn’t run on the R3. Personally, I think it’s worth tempering these expectations. I’ve discussed this with a bunch of people familiar with MiSTer-style core development, and they have all estimated that the most compelling alternate cores for the MEGA65—including an Amiga core—should fit the original R3 board. There may never be an alternate core that requires the SDRAM, even though it was added for this purpose. No core exists today that requires an R6, and I’m not aware of anyone working on one.
Most importantly, the MEGA65 core does not use the new SDRAM component. All software written for the MEGA65 will run on both R3 and R6 mainboards, now and in the foreseeable future. There are no plans to treat the SDRAM chip as a memory expansion for the MEGA65.
Minor fixes. Lastly, the R6 board implements some minor fixes for known issues. If you are noticing these issues on an R3 board, you may be able to use inexpensive workarounds, such as an HDMI repeater or a replacement Real-Time Clock. If you’re not noticing these issues, you won’t notice the fixes with an upgrade. This category also includes a few changes to accommodate the availability of components; these changes don’t affect the functionality of the computer.
I know I’ve spent a lot of money over the years indulging my FOMO by buying hobby computers “just in case” I want them later, and it’d be hypocritical of me to say an R6 is not a worthy upgrade to an R3 when I own one of each. But given that a new mainboard is more than half the cost of a new MEGA65, it’s worth resisting the temptation to think other people have all of those things and you have none of them. Really, R3 and R6 are mostly identical.
Portland Retro Gaming Expo 2024
I took the MEGA65 to the Portland Retro Gaming Expo in Portland, Oregon, mere weeks after getting back from Chicago. PRGE is another massive show, but with a different vibe from VCF Midwest. As the name implies, the show is dominated by vintage gaming, with free-to-play arcade and gaming console exhibits, gaming tournaments, several concurrent tracks of talks and panels, meet-and-greet booths with voice acting and YouTube celebrities, and a massive vendor floor with multiple eras of console games and related merchandise.
PRGE has always featured vintage home computing in its line-up, but representation of the home 8-bits on the vendor floor has waned as our vintage hardware has become more collectible. This year, PRGE established a “home computing” exhibit to keep some of our favorite computers in the show. My MEGA65 booth joined several large displays of Texas Instruments, Commodore, Atari, and Apple vintage equipment, as well as more obscure Z80-based computers. I sat closest to the tournament area, where competitors tore through Street Fighter and Rivals of Aether as commentators hyped up the crowd. I was also across from the big surprise of the show, a large display by The Last Blockbuster, with Blockbuster video iconography, merch, and racks of VHS tapes.
My MEGA65 table was much larger and more welcoming to visitors than it was at VCF Midwest. I’m grateful to Hans, the show runner, for gifting me two tables, and for lending me a big screen TV. And I got to hang up the banner! Even in this back corner of the show floor, the MEGA65 drew a lot of attention, and I spent nearly all of the first day on my feet, answering questions, shaking hands, and handing out cards and mousepads. Several people from press outlets wanted interviews. If the fire alarm hadn’t gone off in the middle of the day, I may never have had a break for lunch. The second day was quieter, but I still had quite a few kids stop by for a round of Unicone or First Shot.
It was especially gratifying to see young people take an interest in the MEGA65. Some of them already knew what it was and were excited to see it in person, some dragged their parents over to the table for a look, and several sat down at the computer for long stretches of time to peruse the demo disks and write short programs. I talked to MEGA65 owners and wannabe owners, and plenty of people simply intrigued by an 8-bit style computer that seemed familiar but unlike anything they’d seen before. I got to introduce many people to the stories of both the Commodore 65 and the MEGA65.
New TI-99/4A core
My very first computer was a Texas Instruments TI-99/4A, and now thanks to zeldin, I can recreate those childhood memories! Mega99 is a TI-99/4A core, written from scratch exclusively for the MEGA65. The core needs the ROM files from the MAME project (ti99_4a.zip
, ti99_fdc.zip
, and ti99_speech.zip
) as well as the provided mega99sp.bin
file in the root of the SD card. Flash the core to a spare slot in the core selection menu.
As of this writing, the core is only available for the R6 boards. This is not a matter of hardware capacity, and hopefully zeldin can produce a build for R3 owners in the future.
Be sure to read the README.md
file for installation and usage instructions. The core matches the 99/4A CPU timing by default, and can also run in a turbo mode. And get yourself the TI-99/4A User’s Guide to remind yourself how this thing works! Hint: the Mega key is the FUNC key, and many text entry features use it.
Thank you zeldin for this excellent and nostalgic core!
Featured Files
Here are some recent demos uploaded to Filehost worth checking out:
- Shodan, by Drex.
- 3D functions and Patterns, by adorigatti.
- HyperBallad, by MirageBD.
Joytest65
This month’s Digest is all about joystick and paddle programming, so I made a joystick and paddle tester app to go with it. It includes documentation and assembly language source code.
The 9-pin connector
The C64 was one of several early computers that adopted the Atari joystick port standard from the Atari 2600 (1977), and supported the use of Atari game controllers to play C64 games. I’m most familiar with the classic Atari CX40 joystick, but there were many others, and everyone has a favorite. Commodore used the Atari-style controller connector on everything from the VIC-20 to the Amiga, and they intended the C65 to have two 9-pin peripheral ports, just like the C64. The MEGA65 has two 9-pin peripheral ports on the left-hand side.
Nintendo released the NES in the USA with a proprietary controller connector and more buttons, and the game console arms race that followed produced more custom connectors, more buttons, and more evolutions in game design language. Commodore made two attempts to follow suit in their final years, both using new protocols over the original Atari-style connector: the C64GS and the Amiga CD32. These protocols were backwards compatible with older Commodore computers, and the new consoles also supported the one-button controllers and ran compatible games.
Commodore also made several types of computer mice that used the 9-pin connector, especially the 1351 mouse for the 8-bit computers, and the Amiga mouse. As you probably know by now, your MEGA65 supports both types of mice, using built-in adapter logic to make the Amiga mouse appear to software as a 1351. See the User’s Guide, 2nd edition, for information on how to configure the mouse emulation mode. We won’t cover the mice protocols in this issue of the Digest.
What follows is a description of how Atari and Commodore computers use the 9-pin connector for game controllers. Other 8-bit computers and early game consoles used the connector, but not necessarily the same wiring or protocols.
Joystick fundamentals
A standard 9-pin one-button joystick tells the computer that the action button is being pressed by connecting pin #6 to pin #8 (the ground pin, labeled “GND”). This doesn’t require any fancy electronics, it’s typically just a button connected to these two pins. When the player presses down on the button, two pieces of metal in the button make contact, completing an electronic circuit. When the player releases the button, a mechanical spring-like action separates the two pieces of metal, breaking the circuit and signaling to the computer that the button was released. This kind of button is also known as a momentary switch.
Pins #1, #2, #3, and #4 work similarly, representing the joystick directions up, down, left, and right, respectively, when connected to pin #8. The joystick indicates a diagonal direction by completing two circuits simultaneously, such as up and left. Typically, there are no fancy electronics involved here either. The joystick is built such that when the user pushes on the stick, it closes one or two momentary switches wired to those pins.
Within the MEGA65, these pins are connected to the Complex Interface Adapter (CIA) chip, which translates these electronic signals into register values that can be read by a program. Try this: connect a joystick to port 2, and run the following simple program:
10 PRINT PEEK($DC00)
20 GOTO 10
The program prints the number 127 repeatedly. Move the joystick and press the fire button. The number changes depending on which buttons are pressed.
This register value is a bit field, where each button is assigned to a bit. If the button is not pressed, the bit is 1 (“high”). If the button is pressed, the bit is 0 (“low”). This is why the register value is 127 when no buttons are pressed: all of the bits associated with the buttons are “held high” until they are “pulled low” by the button presses. (The register has additional bits not connected to the joystick pins.)
The one-button 8-direction joystick protocol can be summarized as follows:
- Buttons connect pin to GND; CIA bit = 0 when pressed
- Pin #1: Up, CIA bit 0
- Pin #2: Down, CIA bit 1
- Pin #3: Left, CIA bit 2
- Pin #4: Right, CIA bit 3
- Pin #6: Fire, CIA bit 4
- Pin #8: Ground (GND)
%01111111 = 127
%01111110 = 126: up
%01111010 = 122: up and left
%01101010 = 106: up, left, and fire
It is the program’s responsibility to read these register values, do the math, then change the game state appropriately, such as to move the player sprite around the screen.
Like the C64, the MEGA65 has two CIA chips. Only the first CIA is used to read the joystick ports. And yes, these are the same CIA chips that provide timers and other features.
The CIA and port 1
Register $DC00 represents joystick port 2. To read the status of joystick port 1, you read register $DC01.
C64 owners remember this one: with a joystick connected to port 1 and the cursor at the READY
prompt, you can get junk to show up on the screen just by jiggling the stick around. This is no longer true with the MEGA65 in MEGA65 mode (as of release v0.96), but you can still reproduce this in GO64
mode or the C64 core. Try it!
The C64 uses the CIA chip connected to the joystick ports for multiple purposes. This includes reading the keyboard. When you type on the keyboard, it pulls down the CIA bits in certain patterns, just like a joystick on port 1 does. This is why, when the C64 is expecting keyboard input, a joystick in port 1 moving around can seem like typing. Even though you can prevent this effect in code for a game, many C64 games simply assumed that most people would keep their joystick connected to port 2.
The MEGA65 is better behaved because its keyboard handling uses a different mechanism that is not as reliant on the CIA chip. A couple of specific functions still test the CIA for specific key presses, but in general, port 1 joystick events are much less likely to interfere with the keyboard.
Reading the joystick from BASIC 65
BASIC 65 provides a handy function for reading the state of the joysticks. The JOY(port)
function returns a value that represents joystick activity on the requested port (1 or 2). Instead of a bit field, the JOY()
function returns a number from 0 to 8, where 0 means the joystick is in the center, and 1 through 8 are the eight directions counting clockwise from “up.” When the button is pressed, it adds 128 to this value. See the User’s Guide for a table and example program.
10 PRINT JOY(2)
20 GOTO 10
As of ROM beta version 920397, the JOY()
function can also read both joystick ports simultaneously, and report a merged result. To request this, use a port number of “3”: JOY(3)
. This is intended solely to allow a game to work with a single joystick in either port, so the player doesn’t have to change their joystick connections to play. It does not return a useful result when two joysticks are connected and moved simultaneously. If your game uses two joysticks, use JOY(1)
and JOY(2)
separately. This feature will be in the next MEGA65 stable release.
Reading the joystick from machine code
A machine code program can read the state of the joystick by accessing the CIA registers and interpreting the bits directly. For best results, such a program must take interrupts into account if it leaves the KERNAL interrupt handler active.
The KERNAL interrupt handler messes with the CIA registers many times per second to process certain keyboard events. A program wanting a clean read of the CIA register must disable interrupts to prevent the handler from messing up the result.
The program has to tell the CIA chip to ignore the state of the keyboard when reading the joystick. I won’t cover how this works in detail, just know that the way to do this is to write the value $FF to the data register ($DC00 or $DC01) before reading it.
Here’s the complete sequence for a clean read of port 2 in assembly language:
sei ; Disable interrupts
ldx #$ff
stx $dc00 ; Lock out the keyboard lines on port 2
lda $dc00 ; A = port 2 pin state
ldx #$7f
stx $dc00 ; Restore the keyboard lines on port 2
cli ; Re-enable interrupts
Paddle pairs and potentiometers
In addition to joysticks, the Atari controller standard also supports a paddle controller. A paddle uses a dial-like wheel instead of a joystick. A game can detect how far the wheel is turned by reading more registers. This controller is called a “paddle” after the seminal home computer game Pong, which used such a controller to manipulate a paddle in a virtual game of ping pong.
Each joystick port supports two paddles, each with its own dial and fire button. The MEGA65, Commodore 64, and Atari 2600 all have two joystick ports, for up to four paddle players. The two dial-like controls are also used together by peripherals such as light pens or mice, where the two inputs represent movement along X and Y axes.
The paddle protocol is different from the joystick protocol. Electronically, the fire buttons are wired to joystick port pin #3 for the first paddle and pin #4 for the second paddle, connecting them to pin #8 (GND) when pressed. A program can read these pins using the CIA data registers, just like reading the joystick. The register bits read 0 when the button is pressed.
The paddle dial itself is a potentiometer, also known as a variable resistor or “pot.” Instead of simply connecting or disconnecting the path between two pins like the fire button, the potentiometer forms an electrical connection between two pins through an amount of electrical resistance that the computer can measure. When the player turns the knob, the amount of resistance changes, indicating the position of the dial. The first paddle on a port connects signal pin #5 (“POTX”) to pin #7, where the computer provides a voltage of +5V. The second paddle on the port uses signal pin #9 (“POTY”) and pin #7.
The paddle protocol:
- Potentiometers connect pin to +5V
- Buttons connect pin to GND; CIA bit = 0 when pressed
- Pin #3: Paddle A button, CIA bit 2
- Pin #4: Paddle B button, CIA bit 3
- Pin #5: Paddle A analog (POTX)
- Pin #7: +5V
- Pin #8: Ground (GND)
- Pin #9: Paddle B analog (POTY)
Resistor values and register values
Strangely, Commodore used a different potentiometer in their own paddles compared to the ones by Atari, and the two paddle types produce different numbers when accessed from a Commodore program. It is generally understood, and some have measured, that Commodore paddles use a potentiometer rated at 470 kΩ (kilo-ohms), and Atari paddles are rated at 1 MΩ (mega-ohms), with the measured resistance range a bit less but on that order of magnitude. This means that when an Atari paddle is connected to a Commodore, turning the knob goes from the minimum value to the maximum value in half the rotational distance (half the “throw”) than an official Commodore paddle. In practice, this can be both good and bad: shorter throw can result in faster play, but with less accuracy and a large “dead zone” where the resistance is above the maximum recognized by the computer.
I wanted to know the actual resistance value range recognized by the MEGA65, so I started by measuring the resistance of my Commodore and Atari paddles with an ohmmeter. What I discovered was a bit of a surprise.
I took some ohmmeter measurements of my Commodore and Atari paddles, and also tested the values returned by the BASIC 65 POT()
function, which returns a value from 0 to 255 based on the dial setting. Both paddles had a minimum resistance in the fully clockwise position, then increased counter-clockwise to their maximum. The Commodore paddles measured a minimum of 44 Ω to a maximum of 166 kΩ. The POT()
function returned a value of 220 at the maximum, not the full 255. Atari paddles had a higher resistance of 124 Ω at minimum to 782 kΩ at maximum. Here, the POT()
function returned the full 255 after only a third of a turn, with a whopping dead zone of two thirds of a rotation, returning 255 for that portion.
So I opened the cases of both sets of paddles, and discovered that my Commodore paddles have a potentiometer rated at 200 kΩ, far less than the 470 kΩ that others have reported. My Commodore paddles also have a capacitor in parallel with the signal lines, which smoothes out the signal and shouldn’t affect the DC resistance, but is notable because it is absent from other paddles. I asked some friends to open theirs and they all reported 470 kΩ pots, so I must have some weird ones.
While it’s reasonable in the abstract that a Commodore program should be able to detect the full range of motion of the Commodore paddle knob, it may have turned out to be unreasonable in practice. A game expecting the full value range to represent a full turn of the knob might be unplayable with Atari paddles, and vice versa. Perhaps Commodore decided to split the difference at some point and changed to a 470 kΩ potentiometer, and I just happen to have an earlier model of the paddles.
Of course, it’s possible that a previous owner of my paddles replaced the pots with the unusual values and these didn’t come from Commodore.
Reading paddles from BASIC 65
As with joysticks, BASIC 65 has a function for reading paddles: POT(paddle)
returns a paddle position as a number between 0 and 255, and adds 256 if the paddle’s button is pressed. The paddles on joystick port 1 are #1 and #2, and the paddles on joystick port 2 are #3 and #4.
10 PRINT POT(1), POT(2), POT(3), POT(4)
20 GOTO 10
The MEGA65 paddle registers
The MEGA65 has dedicated circuitry and registers for reporting the four paddle values. A MEGA65 machine code program can read these values directly from registers.
- $D620: Port 1, paddle X
- $D621: Port 1, paddle Y
- $D622: Port 2, paddle X
- $D623: Port 2, paddle Y
The fire buttons on the two paddles work just like joystick buttons, and can be read directly from the CIA data register for the appropriate port.
That’s all a MEGA65 programmer needs to know. On the C64, the process is a little more elaborate, and it’s interesting to know why.
Reading paddles the old-fashioned way
The CIA chip only knows how to handle digital signals (1’s and 0’s), and can’t read a resistance value (an analog value in a range). Instead, it gets the help of another chip in the chipset more familiar with converting between analog and digital signals: the SID sound chip.
To read a paddle value, a program first tells the CIA to connect the SID to one of the joystick ports. The program must then wait briefly before reading the value from a SID register. The SID needs a small amount of time to read the resistance value and update the register. During this time, the SID charges an internal capacitor that is connected to the signal and voltage lines of the controller. Once it is charged, the SID flips to a different circuit that discharges it. The SID determines the resistance of the paddle controller from the amount of time it takes to perform this charge-discharge process. To convert this to a value between 0 and 255, the SID needs 512 CPU cycles. At the end of this time, the SID updates its register value.
512 machine cycles at a rate of 1 MHz takes about 1/1950th of a second. That doesn’t sound like a lot, but it can be a long wait for an action game, over 10% of the time it takes to draw a frame of graphics. Of course, the program is welcome to do other things during this time. A game loop could set the CIA select bits at the beginning of the frame, then read the paddle values near the end of the game logic, adding a busy-wait at the end as needed.
The SID can only be connected to one joystick port at a time. To read paddles from both ports, a program must connect to the first port, wait the 512 cycles, read the SID registers, then connect to the second port, wait another 512 cycles, and read the SID registers again. A game that reads all four paddles may or may not need to be clever to use the waiting time wisely, depending on how much time the game needs per frame.
If the program leaves the SID connected to a single port and takes over the hardware interrupt vectors (such that the KERNAL interrupt handler isn’t messing with the CIA connections), it can skip the wait and just read the SID register at its convenience. The register will contain the last stable value.
The C64 Wiki page on paddles has a diagram of the resistor-capacitor circuit that the SID is using to measure the resistance value in the controller. I was confused at first because the diagram makes it look like the capacitor is provided by the paddle controller, outside of the joystick port. This is not the case: the SID provides the capacitor part of the RC circuit. The capacitor present in my Commodore paddles bridges the +5V and signal lines, and is there for smoothing purposes and is not part of the RC timing circuit. Other paddles don’t have the smoothing capacitor.
The C64 way to read paddles from machine code
A C64 machine code program must perform the full procedure to read an analog value from the SID chip: select the port to connect the SID chip, wait briefly, then read the result from a SID register.
To select the port, set bits 6 and 7 of register $DC00: for joystick port 1, set bit 6 = 1 and bit 7 = 0; for joystick port 2, set bit 6 = 0, bit 7 = 1. This is the same address as the CIA data register for reading joystick pins on port 2, but you use this address even when connecting the SID to joystick port 1. That’s just how the CIA chip is wired.
The program then waits briefly for the SID to get the value. On a C64, this relatively easy: perform a busy-wait loop for some number of iterations. Based on a reference table of cycle counts per instruction, you probably only need 103 or so repetitions of a loop, but it doesn’t hurt to wait longer. The C64 CPU runs at 1 MHz, so 512 CPU cycles is sufficient.
(The MEGA65 normally runs its CPU at 40 MHz. To reproduce the SID reading procedure, you have two options: temporarily down-clock the CPU to 1 MHz for the busy-wait, or perform the busy-wait loop 40 times. Note that instruction cycle counts differ on the 45GS02 CPU than on the 6502.)
After the delay, the values of the two paddles can be read from SID registers $D419 and $D41A. The ROM code that implements the BASIC POT()
function takes an additional step to debounce the register value, which just means to wait until two consecutive reads of the register return the same value.
Here is code for the complete procedure, reading the state of both paddles on port 2:
; Disable interrupts
sei
; Down-clock MEGA65 CPU to 1 MHz
; FAST $D031.6 -> 0
lda #$40
trb $d031
; Connect SID to port 2 analog inputs
lda #%10000000
sta $dc00
; Wait for SID to read, ~512 1 MHz cycles
ldx #$00
- inx
bne -
; Read port 2 paddles, with debounce
- lda $d419
cmp $d419
bne -
sta paddle2a
- lda $d41a
cmp $d41a
bne -
sta paddle2b
; Reset MEGA65 CPU to 40 MHz
; FAST $D031.6 -> 1
lda #$40
tsb $d031
; Re-enable interrupts
cli
; ...
paddle2a: !byte $00
paddle2b: !byte $00
Two buttons—and why not a third
The Commodore 64 Games System (1990), aka the C64GS, repackaged the C64 into a keyboard-less console box. To enhance the console’s gaming potential, the Cheetah Annihilator joystick had two buttons: a trigger button in the joystick grip, and a second button that could be detected separately in the base. This two-button protocol worked over the 9-pin connector and could be supported by any C64 game that knew about it. Only a few games were written to support it.
Math wizards may notice that all nine of the joystick port pins have been assigned: up, down, left (or paddle A button), right (or paddle B button), paddle B (“POTY”), fire, +5V, GND, and paddle A (“POTX”). That’s nine. So how is the second button connected?
In the two-button protocol, the second button uses paddle A’s analog line (pin #9, “POTX”). Unlike the other joystick buttons that connect their respective pins to pin #8 (GND, “pulled low”), this button connects pin #9 to pin #7 (+5V, “pulled high”), with a current-limiting resistor to protect the sensitive CIA and SID chips. (One recommended resistance value I’ve seen is 270-330 ohms.) To a program, a button press looks like a paddle dial flipping between its minimum and maximum positions.
The Cheetah Annihilator only had two action buttons, but if someone were to add a third button to such a controller, it would have an easy way to connect: just use the other paddle line (pin #5, “POTY”). This three-button protocol was uncommon in vintage joysticks, but is generally accepted by controller modders and homebrew controller makers, because it’s a natural extension of the two-button protocol, and doesn’t require fancy electronics beyond the button and safety resistor.
The three-button protocol:
- Pin #1: Up, CIA bit 0
- Pin #2: Down, CIA bit 1
- Pin #3: Left, CIA bit 2
- Pin #4: Right, CIA bit 3
- Pin #5: Button C, via POTX
- Pin #6: Button A, CIA bit 4
- Pin #7: +5V
- Pin #8: Ground (GND)
- Pin #9: Button B, via POTY
To read the complete state of a three-button controller, simply combine the techniques for joysticks and paddles. Here’s an example of reading all buttons from port 2 in BASIC:
10 J = JOY(2)
20 D = J AND 128 : REM: THE DIRECTION
30 A = J > 127 : REM: BUTTON A
40 B = POT(3) < 128 : REM: BUTTON B
50 C = POT(4) < 128 : REM: BUTTON C
Reading the additional buttons from machine code is similar to reading the paddle values. A C64 program must still connect the SID to the port, wait for the SID to sense the button value, then read the value from the SID register. A MEGA65 program can just read the paddle registers.
Five buttons??
An 8-way joystick with two or three action buttons brings Commodore gaming one step forward in 1980’s game design language. Math wizards may notice that the NES gamepad has not three but four buttons: A, B, Start, and Select. Can we support all four with minimal changes to the protocol?
5plusbuttonsJoystick, by crystalct, specifies a five-button protocol using a neat trick: button #4 triggers “up” and “down” simultaneously, and button #5 is “left” and “right.” A normal joystick can’t activate these opposing directions at the same time, so they uniquely identify the buttons. This scheme has the disadvantage of not being able to use buttons #4 and #5 simultaneously with the joystick—pressing button #4 and “up” at the same time would only register the button—but they can still plausibly be used as Start and Select buttons, which aren’t typically combined with other buttons during play.
crystalct has published the schematic and board design for a joystick that supports this protocol, and you can order the board from PCBWay. It would be easy to hack a NES-style gamepad to support this with just a few wires. The two buttons are easy to detect with the CIA data registers, though they won’t work with the current version of BASIC 65’s JOY()
function, which interprets the directional buttons to direction values only.
The project includes a C64 joystick test program also useful for trying out three-button controllers (PRG download). It works with the C64 core; I had difficulty running it with the MEGA65 core in GO64 mode. crystalct also personally modded dozens of games to add multi-button features—though none use the 4th and 5th buttons, as far as I can tell.
More buttons and bidirectional protocols
Game consoles that followed the NES had seven or eight buttons in addition to the directional pad. How far can we go, using the same 9-pin joystick port?
The protocols we’ve discussed so far could all be considered passive protocols: the controller can report the state of the joystick and buttons to the computer by mechanically completing circuits across the connector pins, and the computer does all the work to interpret these input signals. To be able to report more sophisticated inputs using the same pins, we need an active protocol, where the computer not only reads signals from the controller, but also sends signals to the controller. Perhaps it’d be more accurate to call these bidirectional protocols, because the output signals could be manipulating otherwise “passive” digital electronics in the controller, such as a key matrix. These days, microcontrollers are cheap, and modern game controllers contain tiny computers of their own, capable of an active dialog with the host computer.
The Amiga CD32 game controller provided seven buttons: red, blue, green, and yellow action buttons, left and right shoulder buttons, and one menu button. It used the same 9-pin connector, and did so in a way that allowed the CD32 to support all previous Commodore-compatible passive controllers and allowed the CD32 controller to be used as a passive two-button controller on other Commodores. This required the computer to treat pin #5 as an output pin to select either active or passive mode: the CD32 would hold this pin low relative to the +5V line to request the active protocol—something other Commodores wouldn’t do. When in active mode, the computer sends pulses to the controller on pin #6. With each pulse, the CD32 controller rotates through the seven buttons, reporting the status of each button on pin #9. This mechanism is called a shift register and is typically implemented with a common shift register chip in the controller.
While the backwards-and-forwards compatibility of this design is impressive, it rules out the ability for C64 programs to support a CD32 controller, because the C64 cannot treat pin #5 as an output. Perhaps someday we could add a CD32 controller mode to the MEGA65 core, but there just aren’t many CD32 controllers around. Would be a fun VHDL experiment, though.
Sega game consoles also used a 9-pin connector, though they did not use Commodore-compatible pin assignments. The Sega Master System started with a passive two-button controller protocol, and the Sega Genesis (aka Mega Drive) added more buttons (first 3+1 then 6+1) with an active protocol: one pin was a dedicated output from the console that marched through two, four, or eight cycles, alternating high and low, and the definition for each of six input pins changed for each cycle. The full state table is a bit complex, trying to be backwards compatible with previous standards. (This appears to be based on timing? I got a bit lost trying to read about it.)
I always feel obligated to mention: Do not connect a Sega Master System or Sega Genesis controller directly to a Commodore. The incompatible wiring protocol could damage the delicate CIA chip. The MEGA65 is a bit more robust in this regard, but the MEGA65 core won’t assign the pins in a way that matches the controller.
These newer controllers weren’t the first to take advantage of bidirectional communication to support more buttons. The ColecoVision Hand Controller sported the usual 8-way joystick, and also had a number pad with twelve buttons. Surprisingly, this protocol only uses seven of the nine pins, and the computer selects between one-button joystick mode or number pad mode by connecting one of two pins to power. In number pad mode, each button is represented as a combination of the pin signals. For example, when the “5” button is pressed in this mode, pins #2 and #3 are pulled low. When the “4” button is pressed, pins #1, #2, and #3 are pulled low. This means that only one button can be recognized reliably at a time. If “4” and “5” are both pressed, only “4” is recognized.
None of these protocols work with the Commodore 64, and due to the lack of a prevalent commercial implementation, there is no real consensus on a common protocol for Commodore 8-bit computers that supports more than three buttons. One glimmer of hope is the in-progress Protovision Protopad, a project that intends to produce an eight-button controller (four action, two shoulder, two menu) with support for both the passive three-button protocol and a proprietary eight-button protocol, selectable by software. The active protocol uses an elegant and fast multiplexing technique compatible with the C64’s CIA bidirectional capabilities. It’s not clear if or when the hardware part of this project will come to fruition, but the Protopad Development Guide defines the protocol. It’s a fun read. (Well I think it’s fun.)
This brings us back to the topic of MEGA65 mainboard revisions. A Commodore-compatible active protocol game controller would use bidirectional communication over the joystick port data lines, and therefore would require an R6 mainboard. That is, if such a controller existed. I’m rooting for the Protopad, but in the meantime, I’m focusing on passive protocol controllers, which work with both R3 and R6 mainboards.
Modern game controllers and adapters
You can find plenty of vintage Commodore-compatible one-button 9-pin game controllers at flea markets, computer conventions, and online auction websites. Many are still in working order, and hobbyists refurbish and re-sell them. You can also get new 9-pin game controllers ranging from hand-assembled hobbyist projects to limited run Kickstarters to fully manufactured products.
There are also quite a few hobbyist electronics projects to make adapters for non-Commodore game controllers, both new and vintage, so that they work as Commodore 9-pin game controllers. A few of these implement the three-button protocol, or have a way to switch between multiple protocols. You can buy some of these pre-assembled; others are only available as schematics, and require ordering the parts separately and assembling them with a soldering iron.
The following are just a few examples of useful and interesting game controllers and adapters.
Game controllers
RetroGameBoyz gamepads. Mike of retrogameboyz.com has been making new game controllers for vintage computers since 2017. Mike offers a wide variety of styles, platforms, and configurations. My favorites are the NES-style game pads, which include 9-pin connectors, long cables, and attractive decorative faceplates. Mike even makes a MEGA65-themed game pad! This one supports the one-button protocol, and wires the second action button to “up,” which is used as “jump” in many C64 platform games. I’m working with Mike—well, I’ve asked Mike and he’s doing all the work—to produce a custom MEGA65-themed controller that supports the three-button protocol, for future MEGA65 multi-button games.
The Commotron wireless gamepad. The Commotron Gamepad Turbo 2000 Super is a fully assembled gamepad with two unique properties. For one, it’s wireless, with a dongle and a range of six meters. And for two, it supports six remappable button layouts including an “up” button in addition to the three-button protocol. It’s currently sold out in the Commotron store, but they’re taking pre-orders for more, and third-party sellers still have some.
The Commotron powers on into a mode compatible with the three-button protocol described above, where button “1” is the primary fire button. I couldn’t find the instructions for the Commotron online, so for the benefit of future web searchers:
- Buttons: directional pad (up, down, left, right), Map, Auto; and four action buttons, starting right-most going counterclockwise: 1, 2, 3, and “up.”
- Button 1 is the primary fire button, for one-button games. In C64 mode, buttons 2 and 3 are POTX and POTY, respectively. The “up” button triggers the “up” direction signal, good for “jump” in one-button platform games.
- The controller takes two AAA batteries. The dongle connects to the joystick port and is powered by the computer.
- Both the controller and the dongle have a light on them:
- Off: no power, or in standby mode.
- Blinking: waiting to connect.
- On: connected.
- To connect, press the Auto button.
- To select a preset, hold the Map button and press a direction:
- Left: Commodore/ZX Spectrum mode (the default). POTX and POTY connect to +5V when active, per the three-button protocol.
- Up: Amiga and Atari ST mode. These computers connect these pins to GND when active.
- Right: Atari 7800 mode. Buttons 1 and 2 are “right” fire; button 3 is “left” fire.
- You can swap the functions of button 1 and the “up” button. To swap, hold Map and press Down.
- You can enable auto-fire to have the buttons trigger repeatedly while held down. To toggle auto-fire mode, press Auto. To change the fire rate, hold Map and press an action button:
- Button 1: 3 clicks per second
- Button 2: 5 clicks per second
- Button 3: 8 clicks per second
- Button “up”: 13 clicks per second
Neo-Atari controllers. The modern-day company that owns the Atari trademark has made a largely successful play for our nostalgia-filled hearts with recreations of vintage consoles with varying degrees of authenticity and modernity. This includes new versions of the classic 9-pin game controllers, including the CX40+ joystick, the CX30+ paddles, and the CX78+ two-button gamepad. (We didn’t get the Atari CX78 in the USA back in the day, so this is news to me!) Wireless models of the CX40+ and the CX78+ are available for pre-order, and will include both 9-pin and USB-A wireless dongles, so you can use them with emulators on a PC and with vintage and retro hardware. I haven’t tested this model of paddles yet and would expect them to support the Atari resistance range.
Hyperkin 9-pin controllers. Hyperkin makes a series of retro gaming consoles, as well as game controller peripherals for consoles old and new. Two of their controllers are compatible with Commodore and Atari computers. The Hyperkin Trooper most resembles the classic Atari CX40, with the fire button duplicated for left-handed and right-handed play. The Hyperkin Ranger is a gamepad-style controller with one fire button, and even includes a single paddle wheel in a unique design. The Ranger also supports left-handed and right-handed play with a switch. Both the Trooper and the Ranger are in stock at Amazon.com.
Note: The Ranger’s paddle wheel is useless on Commodores. The potentiometer covers the full Atari range, 0 Ω to 1 MΩ. Less than a fifth of the throw registers between 0 and 255 with the SID, worse than an Atari paddle. I can barely get a middle value to register in my joystick-paddle tester, and can’t imagine using this paddle knob for Commodore gaming.
Ultimate ArcadeR Classic. The ArcadeR is a one-button protocol 9-pin joystick built to last. It uses arcade-quality parts and is designed to be repairable and moddable, including auto-fire options. The joystick has quite a bit of travel, for better and for worse, and the switches make satisfying click sounds.
Controller adapters
Retro Rewind C64 Genesis adapter. This pre-assembled adapter converts a Sega Genesis controller to a C64/Amiga controller. It supports both the one-button + “up” button configuration and a C64GS-style two-button configuration, selectable by a jumper (a little metal piece you push onto some pins on the adapter). Another jumper changes which pin is used for the second action button: POTX for “C64” mode and POTY for “Amiga” mode. Use this with a vintage Sega Genesis controller, or combine it with the 8BitDo wireless Genesis-compatible controller for cable-free multi-button gaming.
sega-adapter. If you’re handy with a soldering iron, the sega-adapter project is a Sega Genesis controller adapter with some cool features. It supports both the one-button + “up” protocol and the three-button protocol, and you can switch between them by holding the Start button. This project was tested extensively with the 8BitDo wireless Genesis-compatible controller. The microcontroller code is open source, so you can customize it with your own features. Note the special instruction to invert the 2nd and 3rd button signals to comply with the C64 version of the three-button protocol.
mouSTer. I would put the mouSTer multi-function USB 9-pin adapter at the top of my list for lots of reasons, except they’re sold out everywhere, and not available as a DIY board either. This clever versatile device is the best way to connect a modern USB mouse to the MEGA65 or other Commodores, and it also adapts USB gamepads and joysticks with support for the three-button protocol, as well as crystalct’s 5plusbuttonsJoystick protocol. It’s highly configurable: to upload new configuration, put a configuration file on a USB stick and shove the stick into the adapter. I love it, but yeah, it’s currently unavailable.
Unijoysticle 2. This bare board project connects to both joystick ports simultaneously, and pairs with any modern Bluetooth game controller. The C64 model supports the three-button protocol and the 5plusbuttonsJoystick protocol. Normally for sale on Tindie, this one is also out of stock, though designs are available under an open hardware license so you can make your own.
SNES controller adapters. snes2c64 and PadSwitcher64 are two projects with interesting takes on multi-button support. snes2c64 adapts the six-button SNES controller to a three-button C64 controller, using a programmable Arduino Nano for custom button mapping and auto-fire options. PadSwitcher64 connects to both 9-pin joystick ports to support all six SNES buttons with a proprietary passive protocol.
I’m most excited about the possibility of the three-button protocol for MEGA65 games. It’s relatively easy to find pre-assembled controllers, easy to implement in software and modified hardware, compatible with both R3 and R6 mainboards, and is the closest thing we have to an implemented standard for multi-button Commodore-compatible game controllers. I’ll let you know what Mike and I come up with for controllers and software support. If you can get your hands on a Commotron, or are handy enough to build a sega-adapter, those are also good options.
Give joytest65 a try and let me know how it works for your game controllers.
Happy gaming!
— Dan