Friday, June 25, 2021

Game Controller - SNES MAX - SNES Controller to Apple II Serial Interface Card



The SNES MAX Cable and the SNES MAX Socket.

What is it?

The SNES MAX is a serial interface card that allows an Apple II to communicate with SNES Controllers. It allows a slotted Apple II to read the maximum number of the SNES controller pushbuttons ie all twelve of them. The game "Attack of the PETSCII Robots", developed by David (the 8bit guy) makes use of all twelve buttons. It allows you to do cool stuff like move in one direction and fire in another (which you want to do when being chased by a pesky robot). This game only supports keyboard or SNES MAX control. Ian led the Apple II conversion effort of the PETSCII Robots game and commissioned me to make an SNES adapter, similar to what was done for the Commodore version.

The PETSCII Robots game conversion overlapped the development of the SNES MAX. It's unfortunate that the SNES MAX was not able to be completed in time for the game release (you need to run PETSCII Robots V1.1 or above for the card to work). While putting the first batch of production cards together I also converted a two player game, Mario Bros, to test and make use of SNES MAX's dual controller ability, These are the only software titles currently providing support for the card but we hope other developers come on board and help add more titles. There are a few games I have on my radar which I hope to convert some day. Other great candidates include the recent work to convert the "Game Boy" Tetris to Apple II conversion. By using an SNES controller you can closely resemble the "Game Boy" controls and capture more closely that specific controller feeling. Another great game, Roborton 2084, could use a controller upgrade. Its Apple II version resulted in a gameplay downgrade. The arcade version uses two joysticks, one for movement and one for the shooting direction. Much like the PETSCII Robots game, it could really benefit from having these independent actions. There are many other keyboard based Apple II games where the joystick control was not implemented or was cumbersome to use.

Let's be clear. The SNES MAX is not an Apple II joystick replacement. It does not operate via the Game Port. The SNES MAX uses the SNES controller protocol which reads the controllers serially just like how it's done on an SNES Console.

The SNES MAX comes in two different board layouts (the cable version and the socket version). Both boards are electrically identical. The difference lies in the connection options. The cable version of the board would suit users that predominantly would use wired SNES controllers and the socket version would suit those who plan to use a wireless solution. Either board can be used with wired or wireless controllers. The sockets allow for a cheaper solution but it means that if you are using wired controllers then the plugs will not fit through the back Apple II case slots (unless used on the early Apple II models where the back slots are open) and you will need to keep your hood open.



Things to note:
1 The wireless receivers may consume a lot of power eg the 8BitDo receivers consume about 100mA on the 5V rail. When using multiple receivers or if your system is already highly loaded you may experience power issues. Make sure you use the SNES MAX appropriately based on your power supply and existing card setup.
2. The SNES MAX Socket version results in a tight fit between slots if you have the following Apple II slot populated. Wireless receivers which are larger in physical size than the 8BitDo option may cause issues.
3. The 8BitDo receiver tends to have a very tight plug fit with the SNES sockets. I'm told this is also the case when using the 8BitDo receiver on an original SNES console.
4. The SNES MAX only works with digital signals. Even though some wireless controllers may have analog thumb sticks, the analgue signals are not used. For example the 8BitDo wireless receive converts the thumb stick 1 into the digital direction buttons while thumb stick 2 is not used.
5. Other SNES devices such as guns and multitaps are not supported. Mice may work.

The SNES MAX has been tested using an Apple IIe and a IIGS. Various different revisions of the wired controller and 8BitDo's SNES wireless receivers have been tested. Also all controllers have been tested with a lengthy extension cable.


How it works.

Early 8bit game consoles like the Atari 2600 use joysticks where each button or direction is wired directly to the game console ie parallel communications. With the advent of faster consoles and the requirement for more pushbuttons on the controller, multiplexing was selected over more signal lines (needing bigger plugs and thicker cables). This resulted in the transfer of more signal data over fewer lines ie serial communications. Some controllers try to be backwards compatible with the Atari standard like the Amiga CD32 which is half parallel and half serial and the SEGA Genesis / Mega Drive Controller which is both parallel and serial depending on a selected mode. The following generation (6 button) SEGA Genesis / Mega Drive Controller is backwards compatible and so the controller became an overly complicated solution. Alternately Nintendo's solution for its original game system, the NES, only uses serial communications which results in a very simple and elegant design. For its following generation, the SNES controller, is just an extension of this which is also nice and simple. The SNES controllers are one of the simplest of serial controllers to work with. Hence their preference over alternate controllers.



The way in which an SNES controller works is by using simple latch chips ie 2x4021, 2xW545 or 1xV520B (the NES controller only used one 4021 chip). Only three signal lines are needed between the host and the controller. A latch signal is sent from the host to the SNES controller to tell it to take a snapshot of all its pushbuttons. Then the data line is read by the host to determine if a button is on or off. Clock signals are sent from the host to the controller to tell it to send the next button press status. This results in being able to read up to sixteen digital button signals. However, the controller is physically constricted to only using the first twelve of these signals. There may be third party controllers which make use of the extra four spare buttons.

On the host side (in this case the Apple II) software needs to be written to read the SNES controller data serially. This routine takes about 500 microseconds (for two controllers ie twelve pushbuttons read from each controller) which is much quicker than the roughly 3000 microseconds it takes to read one of the Apple II analog joystick axis. You then have code on top of that which processes the data but you have to do that anyway regardless of which type of interface you have. Example software for the serial import routine can be found in the attached file at the end of this blog post.


Designing the solution.

The first decision was to select which type of interface this project was going to take. The options were

1. Remove the existing cabling out of a SNES controller and wire the twelve pushbuttons directly to a parallel input card (such as the 4Play card). The problem with this solution is that it requires the destruction of the original controller.

2. Build a buffer in between the SNES Controller and a parallel input card (such as the 4Play card). A microcontroller could be used to buffer the pushbutton signals and push these in parallel to the host. This option requires more hardware but simpler software on the Apple II side. The problem with this option is you would need two devices, the adapter and a parallel interface card. These days using a microcontroller to do the buffering is the cheapest option however back in the day this was not the case. The December 1993 copy of Popular Electronics (http://www.americanradiohistory.com/Archive-Poptronics/90s/93/PE-1993-12.pdf), starting at page 34, contains a great article on how this was achieved back in the day.

3. The serial ports on an Apple II (directly from the IIc/IIGS ports or via a serial card) use a different type of serial communication compared to that of the SNES Controller, both in electrical terms and in the terms of the protocol. A microcontroller could be build inbetween to buffer the signals and then serially send them to the host. This would involve a considerable amount of work on the hardware side and the software side.

4. Talk serially directly from the host to the SNES controller. This requires very simple hardware and relatively simple software. Hence this option was chosen for the project. There is always a trade off between designs and in this case, when comparing this solution to the parallel interface option we are sacrificing the speed of reading the data (500 microseconds instead of 40 microseconds) and in doing so make the hardware side much, much simpler. This was deemed an acceptable trade off and fits in well with the ethos of how the Apple II was designed ie optimise the hardware and let the programmer deal with what they get.

Once the type of interface was selected there were two main ways in which this could be implemented. One was to use the 16pin Game Port interface (not the 9pin Game Port because it needs to support output as well as input signals) and the other was to use the slot based interface.

I love the 16pin Game Port as a quick and easy way to do hobby experiments. However, for a durable professional solution I believe that using the Apple II slots is a much better option. I find the 16pin Game Port fiddley and difficult at times to connect in to. It's not something I would want to be plugging to and unplugging from all the time. The SNES controller adapter which uses this interface has been around for decades (https://rich12345.tripod.com/nintendo/nintendo.htm) however one must take care in its design because other circuits use this socket too (shift key mod, open and close apple buttons / joystick PB0 and PB1) meaning if diode protection is not added one can easy cause a short circuit which would not be good for the motherboard. Being such a simple build I did put it together just for laughs. It does work however it does have its issues ie CMOS - TTL theoretical incompatibility, problematic when used with certain controllers (due to region locking) and control-resetting the Apple II due to the open/close apple button tie ins.


Just a few of the official SNES Controller boards. Here are several of the SNES MAX boards used for testing.

For a durable solution, using the slot interface is definitely the way to go. I figured that being such a simple design that I could knock the project over in a day or two. Here we are a few months down the track and I'm finally getting the production boards ready for sale. It's annoying to think how much work there was for such a simple circuit. Most of the delays have come from having to wait for parts and PCBs. I have managed to get every prototype board working however they have not worked in all conditions.

I've never owned an SNES console, therefore, I've never had an SNES controller. Acquiring one was my first step in testing the first prototype. The testing went fine until I found out that Nintendo had not only region locked specific sections of their console but also region locked the controllers. It surprised me to find out how many variations there are of just the official SNES controller circuit boards. For proper testing I needed to source the other types of controllers which I did. The difference in electronics between the US/JAPAN controller and the PAL controller was not very much (pull up resistors on the latch and clock lines) but it was enough to cause issues with the first prototype. Being a tri-state design with pull-ups/pull-downs caused issues because of the region locking differences. Running the controllers via extension cables or when using two controllers at the same time exacerbated the issue. Swapping both the chips to their inverted equivalents meant keeping the same design but having an extra inverter to replace the pull-down latch circuit. This worked but the design was changed anyway to remove the need for tri-state outputs altogether and resulted in a more stable solution.

Measured resistance between 5V and the following lines
US/JAPAN, Model SHVC-005, Design 1990, Clock = 7.3k ohm, Latch = not connected.
US/JAPAN, Model SHVC-005, Design 1992, Clock = 12.8k ohm, Latch = 12.9k ohm.
PAL, Model SNSP-005, Design 1990, Clock = 1.0k ohm, Latch = 3.6k ohm.
PAL, Model SNSP-005, Design 1992, Clock = 1.1k ohm, Latch = 2.4k ohm.
8BitDo Bluetooth Wireless Receiver, Clock = 153.9k ohm, Latch = 153.2k ohm.

This design worked on my ROM1 IIGS and IIe machines but did not work on Ian's ROM3 IIGS. The wired SNES controllers would work but the wireless controllers would not. I tried to setup my IIGS as close as possible to Ian's and even tried his wireless controllers but I could not reproduce the problem. Luckily Ian had a logic analyser and hence was able to provide me with details as to what was going on. We tried a number of changes but to no avail. Having to do remote testing is never easy.

At this stage I started looking more closely at the chip design. The SNES controller is CMOS based and I had been using TTL logic to match the Apple II slots. Signals going from CMOS to TTL are not an issue but going from TTL to CMOS requires greater care. Technically the signals are not compatible and the adapter was only working for me because my TTL chips were manufactured to better tolerances than what the TTL requirement specifies. The right move was to change over to using 74HCT chips instead of the 74LS ones. With this comes extra care since CMOS chips are more prone to static damage. It was decided to include some protection circuitry. No so much to reduce electrical noise or to improve static immunity but mostly to protect the adapter from issues caused by hot plugging of the controllers.



I went back over the Apple II circuit diagrams using several different publications and I came across the signal descriptions that show that during a data output pulse video garbage can be super imposed into the first part of the pulse. I kicked myself for not knowing this. Normally this would not have been a problem since latching circuitry only looks at the pulse during the low to high Apple II clock transition and does not take the rest of the pulse into account. In our case there was no latching circuitry (the latch and clock pulses are being generated by the Apple II system clock and not by any latching chips). I find it strange that I could not reproduce these issues on any of my machines. The adapter design was changed from using the data bus to the address bus for control and this fixed the issue.

Could this design be optimised even further? Definitely. Daniel put forward some great alternative designs including a single chip version and designs where the address bus control was not required ie the clock and the data read actions could be joined together into one action. These designs do work, however, because of the tri-state design it had stability issues just like my first prototypes. Tuning could have been performed but at the expense of other factors such as a larger current draw. The issue with joining the clock and data read actions resulted in the Apple II latching the button read data on the same pulse transition as the change between buttons. It was deemed to risky to use a design that's working on the very edge of what is possible.

Just as I was putting together the first run of boards and performing unit testing, I found that a specific combination of controllers would not work together. Each controller was fine on it's own but since the clock and latch signals are shared between two controllers, a controller can affect the signals going to the other controller. The region locking issue had come back to haunt me. This time thanks to the addition of the protection circuitry. Luckily the fix did not required a PCB board change. However, I had to purchase extra controllers to perform more thorough testing and this just delayed the project even further.

I'm happy to be finally releasing the product.


Availability and distribution.

I've only just received the production boards and have put a few together to get some photos for this blog entry. I've started putting together the first run of boards as the component parts arrive. The boards will be available shortly from the USA using ReactiveMicro https://www.reactivemicro.com/product-category/lukazis-loot/ and from Australia using my "Lukazi's Loot" https://lukazisloot.blogspot.com/ website.


Future work.

I'm working with Nick to include 4Play/SNES MAX support into the AppleWin emulator. This will save me a lot of time when it comes to adding software support for these hardware projects. It will also help games such as the PETSCII Robots be more playable in the emulator.

The Bluetooth version of the 4Play card is in development (using an ESP32 chip solution so hopefully WiFi can be added in as there well). Maybe this can even be worked into a Game Port equivalent version at a later stage. The only reason that I'm mentioning this here is because I know that some people have expressed interest in getting the 4Play card at the same time as getting their SNES MAX. Not that the 4Play card will be discontinued but if you are a wireless junkie then you may wish to wait for the new card.


Thank-you.

I just want to thank all the people involved in the "Attack of the PETSCII Robots" project. Thank-you Ian for approaching me for the build and collaborating on the project. Thank-you to Kevin, Dean and Michael for your expert opinions on some of the technical details and making sure I was heading in the right direction. Thank-you to Daniel for keeping me on my toes and making sure I had double checked all the design decisions. Thank-you to the many people who helped with marketing and distribution of the product. Lastly thank-you to everyone else for your support and I wish you many years of enjoyable gaming.



Order your copy of "Attack of the PETSCII Robots" from here http://www.the8bitguy.com/26654/petscii-robots-for-apple-ii-now-available/


Update: 17th July, 2021.

Thanks to Nick's great disassembly notes, the conversion of Robotron 2084 to use the SNES MAX, was much easier than what I was expecting. The game can be found along side other goodies in the attached file below.
SNES MAX example code, schematics, etc https://docs.google.com/open?id=1MZvEiNi_7AO1DtoYO4dpHIPd7kykrG1q


Update: 20th August, 2021.

The SNES MAX is now avialable from ReActiveMicro and Lukazi's Loot.

The 4Play and SNES MAX cards have been emulated in AppleWin. However, currently the configuration is limited and most things are still hard coded. Tom is helping out in getting the user interface part enhanced and getting the code integrated into the live AppleWin release.

I have tested an NES controller (NES-004) with the SNES MAX and it works well. Since the NES controller contains fewer buttons it can only be used with games like Mario Bros where fewer buttons are required. It's like having a SNES controller but where the upper protocol buttons (A, X, Front Left and Front Right) are contstantly pressed down. I'm not going to keep the cables for these in stock but I can make these up as a special order.


13 comments:

Anonymous said...

Hi Lukazi - there's a few places above where it says "milliseconds" instead of "microseconds", eg. "quicker than the roughly 3000 milliseconds it takes to read one of the Apple II analog joystick", which should be "roughly 3000 microseconds".

>I'm working with Nick to include 4Play/SNES MAX support into the AppleWin emulator.

Great, and I'm happy to assist too!

Tom

Lukazi said...

Hi Tom,

Thanks for actually pointing that out to me. Most people probably would have read that and just laughed at me, thinking "what and idiot, he doesn't know the difference between his milliseconds and microseconds".

Cheers,
Alex.

EriknocTDW said...

Thank you so much for making this. Would you also make a cable to support the NES gamepad?

Will this support the SNES Multitap (or NES Four Score)?

Lukazi said...

My pleasure. It was a fun project (well, for everything except Nintendo's region locking issues). Yes, I am able to create the NES cables. The problem is that I don't have any NES gamepads to test with. If you email me details of what you are after then I can look into it. My email address can be found at the bottom of the "Lukazi's Loot" website. Email me the details of your controller like the model number so that I can obtain something as close as possible to what you have (for testing).
Other Nintendo devices like mice, guns and multitaps are not supported. It was difficult enough trying to get circuit information for all the different controllers. It was decided to keep the circuit simple and I would not have the resources to test all these other devices.
Cheers,
Alex.

xslinger said...

I'm working on a little 2 player vs. game using the MAX. Is there any way to detect the slot the card is in? Or do I need to ask the user?

xslinger said...

Ahh, I should have checked your game examples. I guess prompting in a main menu is friendly enough. Thanks!

Lukazi said...

Hi xslinger. Unfortunately there is not enough electronics on the MAX to allow the A2 to read a unique pattern. The card would need something like rom or hardwired unique default output circuitry such as in the 4Play card. It is possible to send out the requests on each slot and then check to see if the response is what you expect. However, this is fraught with danger because you just don't know what the output is going to do to the cards in the other slots. Asking the user is going to be the best option. Looking forward to seeing your game.
Cheers,
Alex.

xslinger said...

My solution ended up being to ask the user, and then verify that it gets the 16 "zeroes" you'd get if you read two idle controllers. Since the user already picked a slot anyway, the reads would start occurring. So at least i can "reject" an obviously wrong slot and not have the game or menus go nuts with random values. It seems to work well!

I'm going to show the (very simple, set expectations low :D ) game at kansasfest this year, on Friday the 22nd at 4:30 CST. As well as bring a setup along with the MAX and snes controllers to kansasfest in person. So people will get to try out the card in a 2 player game...

Lukazi said...

Sweet. Thanks for the update. I'll be logged into Kansasfest virtually.
Cheers,
Alex.

xCept said...

Hi, my SNES Max at some point became "corrupt" in that it just mindlessly spams all the controller buttons into the game. Testing with PETSCII Robots, which did work when I had first tried it. I don't know about the inner workings of the controller, is it possible one of the two ICs on it have gone bad?

Lukazi said...

Hi xCept,

Email me at lukazi@hotmail.com and we can go through the steps to work out what is not working. It could be the software version or A2 setup or SNES card/chips or the cables or the controllers.

If using PETSCII Robots make sure it is V1.1 or above.
If using IIGS make sure the slot is set to "Your Card".
If using CFFA3000 make sure the slot is not configured for disk access.

There is a program that can be used for debugging:
1. It only works in slot 4. If you can't use slot 4 for testing then let me know and I can generate the diagnosis program but for another slot. Otherwise the following can be used:
2. Download the file "SNES_MAX_V2.zip" which is attached towards the end of this blog post (just after "SNES MAX example code, schematics, etc").
3. Extract the contents.
4. In the directory "SNES_MAX_Programming_Example" there is a disk image called "SNES_MAX.DSK". Get this image onto your Apple II by creating an actual floppy disk or by sending it to your Apple II disk device solution.
5. Boot the disk on your Apple II.
6. Type on your Apple II "BRUN SNES_MAX_ASS4".
7. You will see a subset of the string "BYsSUDLRAXlr BYsSUDLRAXlr 12" every time you press a controller button. The 1 and 2 indicate which of the two controller ports are being used. Each of the characters "BYsSUDLRAXlr" represent a controller button that can be pressed.
8. Alternately if you only have a hard drive solution (no floppy support) then you can copy the file "SNES_MAX_ASS4" off the "SNES_MAX.DSK" image and copy it to a bootable hard disk image.

Note to self: Rewrite the diagnosis program to ask the user which slot to test.

Cheers,
Alex.

Lukazi said...

For now here is a process to use a different slot (other than 4) with the diagnostic software.
1. BLOAD SNES_MAX_ASS4 (Load the program into memory)
2. CALL -151 (Enter into monitor mode)
3. C01: 07 (Change the slot number to slot 7 - substitute 07 with your required slot)
4. C00G (Run the diagnostic program)

Cheers,
Alex.

Lukazi said...

I have modified the blog with the link to SNES_MAX_V3.zip. This contains the 5th version of the SNES MAX diagnostic program called SNES_MAX_ASS5. It's basically the same as version 4 except when it starts it asks for the slot number.

Cheers,
Alex.