Improving obscure plug-in adapters

New: if you want to test Muzer’s latest improvements on VCS2600 and TG16/PCE support, please try Firmware v0.18b alpha for Retrode 1 and Retrode 2. Please find updating instructions on this page.

My (incredibly messy) workspace for Retrode development

My (incredibly messy) workspace for Retrode development

Many design and development decisions that turned the Retrode into its current form originate from community input. Today, I’m delighted to introduce one of our most prolific forum members, Muzer. He’s been following the project for quite some time now, during which he has done a great job starting and maintaining the feature suggestion thread where ideas for future features are collected and structured in an easily accessible way. The plug-in adapter thread follows a similar idea, serving all those users who are getting tired of constantly having to ask me about plug-in adapter news. Besides, he keeps on providing all other sorts of constructive input which we’re incredibly grateful for. It is also plug-ins that he is going to write about here, especially the ones I haven’t been able to give my full attention lately. In the past few days, he has been investigating issues with the Atari 2600 plug-in, and made some important improvements to the firmware that will greatly benefit auto-detection of the different bank-switching mechanisms, and compatibility in general. His changes will be merged into the next official firmware update for all of us to enjoy. Next on his agenda is better plug-in support for TG16 and PC Engine. Please join me in welcoming him to the Retrode blog! Matthias


This is quite a long and technical write-up of the changes I made to the Atari 2600 code and how I came up with them. The firmware version that implements them isn’t (at the time of writing this!) released yet, but it should probably be soon. Feel free to skip this post if you’re not interested in the technical side of things.

So, at first I wanted to know why many 2600 games, especially first-party ones, returned complete garbage when you tried to read them, no matter how many times you cleaned the contacts. This problem turned out to be what I suspected all along – the CPU on the Retrode is around 8MHz, yet the Atari 2600’s CPU is only around 1.2MHz, and most Atari 2600 instructions take a number of clock cycles to execute… the Retrode was trying to read the cartridges faster than the cartridges could handle! A quick addition of a few calls to a delay function fixed this. Now I had Atari’s 2600 games reading beautifully!

Missile Command works!

So, I started going through my (modest) collection of games, one-by-one. Many of these I’ve picked up from car boot sales and never even tried, so I was amazed at the quality level of some of them (both poor and good ;)). I finally got to one that didn’t work, though: “Crystal Castles”.

When I tried to load it in an emulator, it just produced a black screen. Not a good sign. After trying to clean the contacts to no avail, I finally had a look at the file size. It was 4096 bytes, the same as other Atari games. Looks good. But then I found a (very useful, as it turned out) list of games and their bankswitching methods. It turns out that Crystal Castles was a 16384-byte game, using the F6 bankswitching method. So, it seemed that, for whatever reason, the bankswitching wasn’t being picked up by the Retrode. Not good.

I’ll first give you a quick explanation on how Atari 2600 bankswitching works. It’s very simple. Essentially, the Atari 2600 only gives cartridges 4096 bytes in which to have their ROM, which is obviously not good for games that turn out bigger than that. So, Atari made a chip to be incorporated into cartridges that would allow you to swap between four different “banks” of 4096 bytes, making the ROM 16384 bytes in total. How did it do this? Well, the chip detected if you tried to read data from certain “hotspots”, ie specific addresses of memory not designed to store data but to send this chip a message. The chip then let the Atari 2600 see a different bank depending on which of the four hotspots was triggered. So, if you wanted bank 1, you’d have an instruction in your code to read from the first hotspot, and suddenly when the CPU tried to read from the ROM, it would find the bank 1 part of the ROM. If you wanted bank 2, you’d read from the second hotspot, and when the CPU tried to read the ROM, it would find the bank 2 part instead. This is the F6 type of bankswitching – there are other methods which are essentially the same but have different numbers/sizes of banks and different hotspots. Some split the address space into a number of “slices” and let you choose a different bank for each slice, which made coding a bit easier, but I won’t go into that now.

So, I did a bit of investigating. I found that the bankswitching detection code in the Retrode firmware basically involved taking a checksum of the first four bytes of each bank, triggering various combinations of the possible hotspots in between, and comparing the checksums to see which were the same and which were different. It would then work out from this which hotspots were effective in switching banks and which weren’t, and thus deduce the type of bankswitching used. I checked the code that created the checksums first of all – it looked all right, but again, it lacked the delays required for some Atari games, so I added those in in the hope that it would improve things. Nope, still a black screen. I left them in, though, because it will probably help reliability of detection anyway judging by how non-bankswitched Atari 2600 games behave when you try to read them too quickly.

I then had a look at the F6 code in particular to see if I could see anything that looked obviously wrong – a different type of bankswitching, F8, I had already tested successfully in the game Centipede, so I knew that at least some games worked. But I still couldn’t see any issues.

I finally decided to have a look at a working ROM. I finally found the issue when doing this – the first 256 bytes of every bank were null! So, the checksum code was taking the checksum for the same data each time, as it operated on the first four bytes of each bank! I changed the code to get the checksum of the 257th, 258th, 259th and 260th bytes, tested it out, and…

Crystal Castles working!

Hooray! I now had bankswitching detection working fine! Of course, there could still be a problem if a game has the  257th, 258th, 259th and 260th bytes the same in multiple banks.

As it turned out, many games had this feature of the first 256 bytes being null in every bank, so this fixed a lot more than just that one game. More good news!

I later found out that these  games had the first 256 bytes for RAM access, and also found out that two games have 512 bytes of this RAM (not games that I have), so I moved the checksum code again to detect the 513th, 514th, 515th and 516th bytes. I again retested all of my games with mappers, and all of them still worked. Great!

So, I continued moving through my Atari games, until I came to Dig Dug, another F6 bankswitching game. When I tried to launch this, I got a title screen – great! – but when I tried to run the game, it appeared to almost work, but it looked like this:

Weird Dig Dug problems...

Weird! The game actually played, but the graphics were messed up and jerky and the right side of the screen was flipped. Obviously this wasn’t supposed to be like this.

I started by checking that the cart worked in a real console. I blew the dust off my 2600 and plugged it in – the game worked perfectly. So there was a bug somewhere.

I once again tried comparing to a known good dump. There were a few minor differences probably caused by PAL/NTSC differences (most dumps on the internet appear to be NTSC, so I’d found this with many games), but nothing really jumped out at me as being wrong. Hmm…

I then noticed that the areas in my Retrode’s ROM that were supposed to be bankswitching hotspots contained data, when I’d previously seen code in the main read function specifically meant to return null bytes when a bankswitching hotspot was requested. This was, of course, to stop accidental bankswitching during a ROM dump… so that code was obviously not working.

The code itself looked fine, so I had a look at the function call. Something didn’t look right – it was passing a variable to the function that only ever seemed to vary between 0 and 511 (from what I’d seen elsewhere). Aha, so it wasn’t passing the full address to the read function, only the least significant nine bits (another function was called less regularly to set the most significant few bits of the address). Since the read function stripped out all but the least significant byte for the bulk of the code, I  modified the function call to pass the full address rather than the least significant byte of it.

But still, same problem. I then, of course, realised that the address I was passing to the function was an address in the file rather than an Atari 2600 address – so the bankswitching hotspot was passed multiple times in the dumping process, only one of which was caught by the protection code because it had the good fortune of the file address and the 2600 address lining up. Since it is trivial to convert file addresses back to 2600 addresses when you know the type of bankswitching, I added a function to do that. I uploaded the new firmware, and…

Dig Dug works!


All of my 2600 games now work. However, it’s worth pointing out that I have only non-bankswitched, F6, and F8 games, and none of the more exotic ones like the Parker Brothers bankswitching. Once the firmware is out, I’d appreciate any testers for these other bankswitching methods. Use the list I linked to above if you don’t know what your game has and hasn’t got.

19 comments to Improving obscure plug-in adapters

  • A (Maybe) interesting detail related to the new Firmware v0.18b alpha : N64 ROM Dumping
    Explanation here:

  • Very Big Thanks to You Muzer:-D

    I redumped my little A2600 collection and the new Firmware make alot of them finally work :-)

    Only problematic cartridges are “Centipede P” and “31in1 Game Cartridge”.
    The “32in1″ produced everytime an overdump of following game: “Space Jockey (32-in-1) (Atari) (PAL) [o1]“.
    Is there ANY CHANCE that the rom-switching could be implemented in the Retrode? At the Atari 2600 (and on the Atari 7800 which I use) you change games by simply press RESET.

    • Muzer

      No problem!

      I’m currently having some issues with my Retrode – Matthias said it’s most likely a hardware bug as he’s also experienced it, but it can be worked around in my software, so I’ll try and sort it out today. If you’re getting a problem where the Retrode just freezes completely when you try to read some games, leaving the LED on, the drive on your computer disappears and you have to press reset, that’s it. If your games aren’t doing this, obviously I have it worse on my Retrode than yours ;)

      But after I’ve sorted that, I’ll have a look. I don’t know about Centipede P, is it the same as normal Centipede? Because that works fine for me. The ROM should be 8192 bytes in size, can you check that? If you can’t get it to work, and it IS giving you a dump (just not a working one), send that dump to me via a private message on the forum or my email address at . If it’s not giving you a dump but just freezing the Retrode, causing the LED to stay on and the drive to disappear, see above; I’m fixing that (hopefully!) today.

      As for the 32-in-1 cartridge… well, I specifically didn’t include support for homebrew and pirate bankswitching because I didn’t think anyone would want it! I’ve discovered that the reset switch doesn’t actually do any resetting or send any data directly to the cart. This means that the multicart must detect the reset being switched in software, then do something else to change banks. This means that the multicart should be possible to support – the only question is how. I can find little to no documentation about how it works.

      • “Centipede P” seems to stand for “Centipede PAL Version” I think. ROM seems to work fine, but the “GoodTools” doesn’t recognized the game.
        Centipede also freezes my Retrode one time. Then I had to reset it and it works fine again.
        For the “32in1 Game Cartridge”: It was actually no pirated or homebrew cartridge, it was something official from Atari only released in PAL regions in 1988.

        PS: I PN with the dump was send to you :-)

        • Muzer

          Ah, that explains it – PAL versions of the game are slightly different, and often aren’t actually in the GoodROM database.

          In addition, many cartridges (can’t remember if Centipede is one of them) have 256 or 512 bytes of RAM at the start, which is effectively random when you turn the console (or Retrode) on, so this can cause the checksums of the ROMs to not be the same as online dumps.

          Still trying to fix the freezes on my end.

  • Muzer

    I’m finding that for some reason, though I haven’t changed anything that could cause this (as far as I can tell?), I’m getting read errors causing the Retrode to apparently freeze whenever I try some mappered games. I’ll investigate more when I get back, but can anyone else see if they are having this problem?

  • Felix

    Thanks, Muzer. As Matthias can probably tell you I am a big 2600 fan :)

  • MasterOfPuppets

    Both firmware links go to the firmware for Retrode 1, just so you know.

  • Muzer

    An update!

    After another minor change (caused by a bug I added in a moment of stupidity :P), the two games I received today (Polaris, using the Tigervision 3F bankswitching method; and Super Cobra, using the Parker Brothers E0 bankswitching method) work fine! I’ve just got a few games left to arrive (some coming from the States because it was cheaper), then I’ll call it a day with Atari support, hopefully nobody will have to touch that ever again ;)

  • Muzer

    Right! Call me crazy, but I’ve just bought a load of games using the more exotic mappers off eBay to test, about £40 worth… hang on, I must be crazy :p

  • zerothis

    Ya, some parts of the Atari are practically analogue. Good work on sorting some of it out.

    • Muzer

      I wouldn’t quite go that far! But yeah, the lack of any form of read/write pin on the cartridge pinout really made it hard for people to include RAM in their cartridges for instance – they had to have one set of addresses for reading and one set for writing, because otherwise the RAM wouldn’t know whether you wanted to read or write!

  • MasterOfPuppets

    Excellent work, keep it up!

  • Interesting post Muzer, good work, and check your PM’s :)

    • Muzer

      Thanks! I hope I didn’t make it too rambly, I’m very good at rambling ;)

      Checked my PMs; there’s nothing there :/