Bankswitching in cartridge based games is most famous on the NES, especially its Japanese version, the Famicom. The NES, Famicom and their unofficial clones were popular in many parts of the world, but the inherent limitations of its 8-bit CPU required software developers to devise ever more complicated systems to increase the amount of memory the system could address.
But the NES did not invent bankswitching. Most, but not all, 8-bit home consoles, home computers and handheld systems had cartridges with extra hardware to allow the system to address more memory. In this article I will trace the evolution of that hardware outside the NES and give links to sites and documents where the user can find more technical information.
Atari's Invention :
In 1980, Atari was faced with a problem. Some of its games in development for its popular video game console, the Atari Video Computer System (2600), required more ROM storage capacity than the console was designed to address. Atari's cartridges released from 1977-1979 were either 2KB or 4KB in size. Inside each cartridge was nothing more than a PCB containing a single Mask ROM chip.
The Atari 2600 used a 6507 CPU, a cut down version of the 6502 CPU. The 6507 could address 8,192 distinct memory locations (8KB), using a 13-bit address bus (A0-A12) and an 8-bit data bus (D0-D7). The system was designed so that the lower half the addressing space was allocated to the registers for the TIA (graphics, sound, paddle and joystick fire button inputs) and the 6532 RIOT chip (RAM (128 bytes), joystick directional and option switches inputs, system timer). The upper half was dedicated to the cartridge ROM.
There is a lot of wasted space in the lower 4KB, between the TIA, RAM and the RIOT only 182 bytes of that addressing space is used. However, the rest of the lower 4KB contains mirrors of these RAM and register values, so they cannot be used by cartridges except in a very few limited instances.
Atari's solution to the problem was use extra logic inside its cartridges, starting with Asteroids, to switch in 4KB chunks of game code when the program required it. Asteroids was an 8KB game, so it had 2 banks of 4KB of ROM. When a programmer wanted to switch banks, he would read or write to a certain memory location in the ROM address area. Each memory location accessed would select a different bank. Physically, the cartridge would contain one 8KB chip, but it would appear to the 2600's CPU that a 4KB ROM chip had been hot-swapped between lines of code using this method. The bankswitching logic would manipulate the upper address line(s) on the ROM chip to dictate the portion of the ROM which was exposed to the CPU.
Later variations of the scheme would extend this method to cartridges using 12KB, 16KB, 32KB and even 64KB. While an 8KB cartridge would require two memory addresses for bankswitching, a 32KB cartridge requires eight.
The next challenge Atari faced was trying to add extra RAM in its cartridges. The 128 bytes of RAM inside the 2600 limited the complexity of the games that could be released for the 2600. Unlike ROM, RAM can be written to as well as read from. Unfortunately the 2600's cartridge connector that connected the cartridge to the 2600 contains only the 13 address lines, the 8 data lines, +5v and GND. The 6507 has a combined read/write line that tells a device whether it is sending a value to it or requesting a value from it. There is no Read/Write line available to a cartridge. What Atari did was to split the cartridge RAM memory addresses into read locations and write locations. So in order to write a value into a byte of RAM, you wrote to a particular memory address. In order to read that value from that byte of RAM, you read to that memory address plus 128 bytes. Because the ROM and RAM overlap in this cartridge addressing area, you could not use area set aside for RAM as ROM using Atari's simple method.
There were some bankswitching methods that were more complicated. Some allowed you to switch slices of ROM smaller than 4KB. Others allowed you to bankswitch RAM. Some allowed you to switch a portion of ROM while fixing a bank for the game's kernel. While some of these methods could be done with discrete logic, Atari used a custom chip when it came to implementing both the bankswitching and the extra RAM.
Atari 2600 ROMs are always simple binary byte dumps of the chips contained in the cartridges. These ROM images do not contain an internal header to tell an emulator or a flash cart how to handle their bankswitching methods. The number of games that use bankswitching is rather small compared to the number of standard 2K/4K games, so emulators can check the ROM's size, a pattern of identical bytes if there is RAM present and then use quick tests to trigger the bankswitching to figure out the type used.
The following document contains most of the known information about bankswitching methods used in Atari 2600 cartridges ; http://blog.kevtris.org/blogfiles/Atari%202600%20Mappers.txt This is kevtris' most up-to-date documentation, but some information is missing from it. You can use an older version of his document, located here : http://atariage.com/2600/programming/bankswitch_sizes.txt to fill in some of the missing links.
The Atari homebrew scene has been in existence for over 20 years, and it has developed its own memory mapping schemes to allow for more complex games than were dreamt of during the system's lifetime. The most popular scheme these days is the DPC+, scheme. This is an extension of the hardware used for Pitfall 2, and allows programs up to 32KB in size and also supports 8KB of RAM. The DPC and DPC+ also have extra features to help speed up the graphics drawing and produce more complex sounds than the TIA can on its own.
Bankswitching was rarely needed on other home consoles in the pre-crash days. The Colecovision had 32KB of addressing space dedicated to cartridges, and this was more than sufficient for games released during its lifetime. Ditto for the Vectrex. The Intellivision had a very flexible memory map, the ECS does have built-in bankswitching : http://atariage.com/forums/topic/196015-need-all-information-on-the-ecs-computer-module/?p=2494003
Atari Home Computers & the Commodore 64 :
Like the Atari 2600, Atari's 8-bit computers hard a cartridge slot, They used the 6502, which could address 65,536 memory locations. The Commodore 64 also used the same CPU and had a cartridge slot. But the Atari and Commodore computers allocated one-quarter of that addressing space to cartridges. In Atari's case, while the default cartridges have 8KB available, they can also replace the adjacent 8KB of RAM with ROM to address 16KB of cartridge memory. By contrast, the Atari 5200 allows addressing 32KB of cartridges. The C64 always assigned 16KB to Cartridge ROMs and it came with built-in bankswitching of RAM for locations otherwise dedicated to ROM or I/O ports.
Most bankswitching schemes were reserved for utility programs prior to the Tramiel takeover of Atari. Only one game, Bounty Bob Strikes Back!, from this period requires bankswitching on the 8-bit Atari home computers. It is also the only known game to require bankswitching on the 5200. When Atari released the XE Games Systems, it released cartridges in size of 32, 64 and 128KB. Most of these cartridges refuse to work on an Atari 400 or 800 computer. More information can be found here : https://www.atarimax.com/jindroush.atari.org/acarts.html
Commodore 64 cartridges often contained special hardware inside them. The fast loader cartridges often would have, in addition to their code in ROM, extra hardware inside them to disable them for compatibility or to "freeze" the console to assist in hacking. Only a few cartridge games prior to the home video console like Zaxxon and Super Zaxxon used any form of bankswitching. In Europe companies like Ocean Software, System 3 and Dinamic released some of their games on larger cartridges, requiring bankswitching. Game cartridges reached 512KB in size, but these were expensive to make. C64 cartridges use the .CRT format and a 128-byte header. http://ist.uwaterloo.ca/~schepers/formats/CRT.TXT
Nintendo's Competitors :
The Atari 7800 devoted 48KB of its addressing space to cartridges. 16KB of that space could be used by a POKEY chip for better sound inside the cartridge without any additional logic. Ballblazer and Commando are the only games with a POKEY chip. A few cartridges had an 8KB or 16KB SRAM chip in that area instead or an additional 16KB of ROM. The Atari 7800 only had 4KB of internal RAM, so certain home computer ports may have found that too limiting. Cartridges released during the life of the 7800 maxed out at 144KB of RAM. 7800 ROMs use the .a78 format, which has a 128 byte header added to the binary cartridge dump. This header tells an emulator many things, (more than it needs to) most importantly what kind of bankswitching scheme the game uses. Since there were very few games released for the 7800, there were only a few bankswitching schemes used : http://www.atarihq.com/danb/7800cart/7800%20bankswithcing%20guide.txt
The Sega Master System used used both cards and cartridges. It uses a Z80 CPU, which like the 6502 is limited to a 64KB addressing space. However, it does have a special 256 byte I/O bus that can be used for communication with the graphics and sound chips. Cartridge bankswitching is still done by using memory locations in the ROM portion of the addressing space.
The cards only came with no more than 32KB and were not bankswitched. The cartridges could come with up to 512KB of ROM for the Master System and 1MB for Game Gear, and a few of them supported 8KB of battery backed SRAM. As Sega manufactured almost all the cartridges, they had a standard bankswitching scheme used regardless of cartridge size. Codemasters was allowed to make its own SMS cartridges and they use a somewhat different bankswitcching scheme. Unlicensed cartridges have their own schemes as well, but they tend to be obscure.
The Game Boy and Game Boy Color :
The Nintendo Game Boy and Game Boy Color uses Sharp LR35902 8080/Z80 Hybrid CPU. Thus these systems have the same address restrictions as the Sega 8-bit systems but do not have the I/O address bus. Without extra hardware, the Game Boy could address 32KB of ROM. Like the NES, it had a special memory region for mapping in 8KB of RAM.
This would not be enough even for some of the launch titles, Super Mario Land and Baseball are 64KB. Nintendo used several Memory Bank Controller (MBC) chips during the Game Boy's lifespan. 99% of Licensed Game Boy and Game Boy Color that use MBC chips use only four, the MBC1, 2, 3 & 5. The MBC1 could access more ROM and RAM than the MBC2, but the MBC2 had a small amount of RAM built into the chip. The MBC5 officially supported Game Boy Color speeds, but the MBC3 could run Game Boy Color code as well. The MBC3 supported an optional Real Time Clock, which was used in the later Pokemon games and a few others. The MBC5 could support a Rumble feature with an oversized cartridge with a cover for an AA battery. The MBC5 could support a maximum of 8MB of ROM and 128KB of RAM, and at least one Japanese game supported the former.
There are a handful of games that use more custom chips. The Pocket Camera is a device that uses very custom hardware. Kirby's Tilt 'N Tumble uses MBC7 with a Tilt Sensor. Robopon Sun Version uses an oversized cartridge an Hudson/Bandai HuC-3 chip which supports a Real Time Clock, an Infrared communication port, a speaker that emits sound when your game is off and another battery to power the speaker. Some Japanese games use custom chips, but they are very obscure.
Game Boy and Game Boy Color ROM files are binary dumps of the ROM chips contained inside the cartridges. These ROMs contain their own file header which tells you everything you need to know about the hardware inside the cartridge. Thus Game Boy and Game Boy Color ROMs should always have a true power of 2 size.
The other major Game Boy competitor, the Atari Lynx, uses a 65C02 CPU but has built in paging hardware for bankswitching ROMs up to 1MB. The PC Engine and its variants, which also uses a 65C02, also has built in paging for 1MB of ROM.
16-bits and Beyond
Traditional Bankswitching does not really have a place in discussions of true 16-bit consoles like the Sega Genesis and Super Nintendo. They can address up to 8MB of ROM without any extra hardware inside their cartridges (decoding circuitry for two ROM chips or ROM and RAM doesn't count). The Super Nintendo has many games which use special co-processors inside their cartridges, but these add functionality, not addressing space. The largest official Genesis game is 5MB and the larges official SNES (Super Famicom) game is 6MB. One of those 6MB games, Star Ocean, has a special compression chip called the SDD-1 that allows the graphics to be decompressed in real time, so the actual size of the uncompressed ROM is 12MB. The SNES PowerPak and the SD2SNES can handle the uncompressed ROM. The last cartridge system, the N64, can handle 64MB cartridges and that was more than enough during its lifetime.
While the Genesis could address a lot more storage memory with the Sega CD add-on unit, the SNES CD add-on, the original Sony Playstation, was never released. However, in the past couple of years, the MSU-1 homebrew expansion has been realized in both software (bsnes/higan) and hardware (sd2snes). The MSU1 allows the SNES to access up to 4GB of storage memory! Many SNES games have been hacked to add support for higher quality music tracks and full motion video sequences. A Laserdisc game called (Super) Road Blaster has also been ported to the SNES using this chip. Information about it is here : http://helmet.kafuka.org/msu1.htm
Similarly, the Game Boy Advance and other later handheld consoles also have no issue with memory addressing. Game Boy Advance games can be a little coy because they do not tell what method they use for saving games, and there are four : battery-backed SRAM, EEPROM, Flash RAM and none. The GBA can address up to 32MB of ROM, but there were five GBA video cartridges that use 64MB. They use a complex chip to bankswitch that memory for the system. More information about it is here : https://mgba.io/2015/10/20/dumping-the-undumped/