Born2Code presents The Atari 2600 Cheat Collection
December 10, 2012
I've been a programmer on 6502 CPU computers for over 20 years and decided to try Atari 2600 games for a challenge.
All cheats were done using Stella as I don't own an Atari console.
It took me an hour or so to figure out how to use the STELLA emulator debugger and I'm still not entirely
sure how to fully use it. The cheat process would be made a lot easier if a ROM search also existed.
There used to be a website with Cheetah codes but it's now offline. I'm not certain what games were covered so this
archive might contain some redundant games.
While these games are old and nothing in comparison to today's gaming consoles, I recall back when I was a teenager
that the Atari 2600 was a big deal to us. I remember renting one for a weekend and spending all of my free time playing
Pitfall and Defender. Back in the 1980's these games were amazing and there were even magazines dedicated to these
consoles where people sent in photos of their high scores. To think that there was a day where renting these cartridges
earned businesses a profit. Oh how times have changed!
Here is a list of the games covered. I've noticed that many of the games are renamed (example: River Raid) or there
were multiple versions of the same game released. Stella uses a hash value (MD5) to determine which binary file you're
using. For this reason my cheats may not work with your version! I've supplied the binary files used in creating these
Note that some games had the option for unlimited time but I found that upon completing a level, the game would
try to subtract remaining time. This would result in an endless loop and so the cheat was removed.
Some cheats require multiple selections be enabled at once.
Example: Infinite Lives 1, Infinite Lives 2.
The reason for this is that I need to insert different code into the game and as far as I know Stella doesn't support inserting different code for
one selected cheat. Cheats were playtested but some may not be 100%.
L - Infinite Lives
T - Infinite Time
P - Infinite Power
I - Invincibility
F - Infinite Fuel
2600 Invaders (L)
Air Raid -Menavision (L)
Apples and Dolls (L)
Aquaventure (L) buggy
Asteroid Belt aka Time Machine (L)
Astroblast M-Network 1982 (L)
Astrowar aka Meteor Defence (LI)
Bank Heist (L)
Baseattack aka Z-Tack (L)
Beany Bopper (L)
Berzerk (L, I) * Invincibility can get you stuck if you hit a wall *
Buck Rogers (LT)
Bump N Jump (L)
Burning Desire aka Jungle Fever (L) *Activate After Loading *
Cabbage Patch Kits (L,T)
Chopper Command (L)
Commando (L, grenades)
Condor Attack (vulture attack) (L)
Conquest of Mars (LF)
Crazy Balloon (LT)
Crazy Climber (L)
Cross Force (L)
Crystal Castles (L)
Deadly Duck (L)
Death Star aka star Wars (L)
Defender 2 (L + Smart Bombs)
Demon Attack (L)
Donkey Kong Junior (L)
Donkey Kong (L)
Double Dragon (T)
Elevator Action (L)
Encounter at L-5 (L)
Fast Eddie (L) * Must enable both cheats*
Flash Gordon (Space Adventure) (L)
Garfield On the Run (L)
Gas Hog (L)
HERO (L,E and TNT)
Ikari Warriors (L,E and grenades)
Invaders (Erik Mooney) (L)
James Bond (L)
Jungle Hunt (L)
Junior Pac Man (L)
Keystone Capers (L)
Marineflieger aka Seahawk (L)
Mario Brothers (L)
Miner 2049'er (L)
Miner 2049'er Volume 2 (L) *may only work for first level*
Mission 3000 AD (L)
Montezuma's Revenge (L) *enable cheat after you've loaded file *
Moon Patrol (L)
Mr. Do (L)
Mr. Postman (L)
Ms. Pac Man (L)
Pac Kong (L,T)
Pac-Man Space (hack) (L, eat enemies anytime)
Phoenix (L, shields)
Pole Position (T)
Radar Lock (L)
River Raid (aka Galaga) (F)
River Raid 2 (L, F)
Solar Storm (L, no overheat)
Space Chase (L)
Space Invaders (L)
Space Invaders - PAL Version (L)
Star Wars - The Empire Strikes Back (L)
Time Pilot (L)
Tom Boy (aka Pitfall) (LTP)Road Runner (L)
Star Wars - the Arcade Game (L)
Super Cobra (L) * must enable ALL life cheats * fuel is in $c3
Time Warp (L) (includes PAL version)
UFO PAtrol (Time Warp) (L)
Wizard of War (L)
Zaxxon (L, F)
Mr. Do's Castle ($F1 holds lives)
Double Dragon - energy $9c
infinite time set F2Ac = 0
Cheating a game (also called "training" as they help you learn to play a game) is ridiculously easy on the Atari 2600
due to the small area of RAM that is used to store values. By using STELLA you can easily cheat a game.
There are existing tutorials out there on this (also called 'hacking a ROM') but this is basically how it is done:
For the game Gyruss we begin with 3 lives.
Start a new Gyruss game and with 3 lives remaining do the following:
1) Press ` to enter the debugger built into STELLA
2) Click on SRCH because we want to search RAM for our 3 lives
3) Enter a value of 03 (for 3 lives) and click OK
4) Click EXIT and play the game until you lose one life
5) Immediately press ` again to enter the debugger
6) Now we want to see which RAM location went from 3 down to 2 (for a loss of a ship)
7) Click CMP (this means compare locations since the last search)
8) Enter 02 and click OK
9) Any greyed out memory locations are the suspect locations that changed to '02'
10) You'll notice that $8B is greyed out (we read the locations from the vertical column on the left and then
add the value of the horizontal row, so it is $8B. Think of it like that old board game Battleship where you have to
line up the rows and columns.
11) Now we want to find out where in the game code $8B is being decremented
12) In the left area window make sure you are in the 'prompt' area and type in:
"trapwrite $8B" (without quotes)
this will trap all calls to that memory address
13) type "run" to resume the game and then lose another life
14) The emulator SHOULD go back to the debugger upon execution of where the game decrements the memory location $8b
15) If you look in the box labelled PC this gives you the memory location that the emeulator halted at.
16) In the lower right box scroll up to the last instruction given just before the halt (at $d213)
17) Notice at location $d211 the command DEC $8B this means DECREMENT the location $8b (thus, lose a life)
18) By changing this command to something else, such as NO OPERATION (NOP) it will stop the game from subtracting
a life. NOP is a command like REM is to BASIC,. It does nothing.
19) Double click where you see C6 8B side by side. C6 is the code for DECREMENT and 8B is the memory location to be
decremented. Change the codes to EA and EA respectively ($EA is code for NOP)
20) Now resume the game. It works! (or it should)
If you want to save this cheat in Stella (although I've already added it to my cheat collection) this is what you do:
- Press TAB in Stella to get to the CHEAT CODE menu
- ADD a new code and give it a name (eg. INFINITE LIvES)
- For the code, it gets a little complicated. We only enter the last 3 digits of the memory location where we want
to insert new code. So since the DECREMENT $8B was found at $d211 we will enter '211' followed by 'EA' which is the
op-code for NO OPERATION followed by a 1.
The first 3 digits are the memory location / EA (no operation) / 1 repetition
The last digit would be a 0 if you only wanted to insert one EA, but we put a 1 because we want to repeat the
process one time. I found this confusing because I think it should be 1 for 1 opcode, 2 for two, etc.
So the original code was:
$D211 dec $8b c6 8b
and we changed it to
$D211 nop nop ea ea
The two letter values ($ea, $c6) are the actual values that are placed in the Atari's memory while the
words (DEC and NOP) are just a way for humans to understand what those two digit values translate to in machine
The Basics of cheating
The 6502 chip has three registers. Think of a register like a corkboard in your office. You can take a number and staple
it up on the corkboard which is the analogy I'll use for storing values in the registers of the Atari 2600.
There are three registers: A,X and Y. The Atari 2600 and Commodore 64 use these registers in any machine language game
that has been written. The A register is best suited for mathematical use whereas the X and Y are best used for storing
values that don't require mathematical equations.
Picture three corkboards on a wall in your office or home, with labels A X and Y above them respectively.
In machine language if we want to store the value of 03 in the X or Y register we would do this:
LDX #$03 ' load X with 3
STX $44 ' store X in location $44
LDY #$03 ' load Y with 3
STY $55 ' store Y in location $55
The above code takes a value of 3 and places it in location $44 and loads Y with a value of 3 and places it in location $55.
LD means LOAD, ST means store. Simple right?
Note that the #$ means "put this actual number" in that location. So using our analogy, this code takes a number "03" and
places it on our corkboard labelled X and takes a number "03" and places it on the Y whiteboard. The STX and STY means,
"store whatever is on my X/Y corkboard" into the memory location that follows.
We can also load the X or Y registers with the value of what's in a memory location, instead of actual numbers.
(notice the # sign is not present)
This is different from the earlier example. The difference is that this time we don't go through our shoebox and find
a number 03, we go through the Atari's memory and pull out *whatever value* is sitting in location $03.
We can put any number from 0-255 in any of these three registers or we can take a number from any memory location and put it
in any of these three registers.
What's the difference in loading an actual number (eg. LDA #$02) vs. loading a memory location value (eg. LDA $02) ?
Well in the case of an actual number we would use this to put the number of lives into a memory location. '3' is always
going to be 3, right? It will never change nor would we want it to. Three ships for every new game.
Loading the value of what's in a memory location doesn't necessarily mean we'll always get the same number nor would we want
to especially if we're reading a joystick port value or a paddle value.
As it applies to games
For the purposes of cheating a game, we know that a game will use RAM memory to hold the value of your lives, energy, time,
etc. This is because these values need to change (eg. when you lose a ship) and this cannot be done if the values are stored
in ROM. ROM is permanent, RAM is temporary (Computers 101 right?).
A real life way of storing a life in a game is to load a register with the actual number of 3, and place it into a memory
location upon the beginning of a new game. [substitute the 3 for whatever number of lives you have in the game]
In any game on the Atari 2600, you are going to find some code that looks something like the examples I've shown you above.
It might be LDY, it might be LDX or it might be LDA. the LD means LOAD and the last letter is X Y or A.
The second line (ST) is arbitrary, we don't know what location the number 3 will be stored in because every game is different.
This doesn't concern us anyway because we don't want to change this code, we want to change the code that alters the lives when
you lose a ship.
There are a few ways this is done and we'll cover them right after we talk about the Accumulator.
In addition to the X and Y registers we have the A register. It's also called the Accumulator because as the name implies
it can accumulate values. It's used for adding, subtracting, etc. but works just like the X and Y registers.
this takes a value of #$45 and puts it in memory location $ED.
We can also transfer from X or Y to A and vice versa.
This takes the number #$55 and transfers it to X, it then loads A with #$66 and transfers it to Y.
TAX is like saying, take whatever I have stuck to my A cockboard and go put it on my X whiteboard.
TAY is like saying, take whatever I have stuck to my A corkboard and go put it on my Y whiteboard.
Whatever was in your X and Y register is replaced with what is in A. Our corkboard only allows for one number to be stuck
on it at a time
We can also take whats on our X or Y corkboard and put it onto the A board.
TYA ' transfer Y to A
this puts a #$66 on the Y whiteboard and transfers it to the A board as well.
So now that you have a basic understanding of how the registers work, let's move on.
Getting down to business
In any game you're going to have at least one memory location that's used for lives, power, time, etc.
This location will be loaded with the # of lives you have and stored into a memory location upon the start of a new game.
It might be done with the A X or Y register. Here are three samples that could occur in three different games:
In the above, these hypothetic games used $55, $dd and $56 to hold the # of lives that you begin with.
What we are concerned about is when these memory locations are DECREMENTED (loss of a life).
This is where it gets a little complicated as there are many different ways of doing this.
Game One might use:
DEC $55 ' decrement the value of whatever is in location $55
Game Two might use:
LDA $DD ' take number currently in location $dd
SEC ' set carry flag
SBC #$01 ' subtract 1
STA $DD ' store back into location $dd
Game three might use:
LDY $56 ' load Y with number from location $56
DEY ' decrement Y
STY $56 ' store back into location $56
These methods are typical of most Atari 2600 games and they all perform the same function.
Use the Stella emulator to determine the memory location that holds your # of lives. I won't cover the methodology here
as there is already a tutorial on this. You would substitute the $56 for whatever Stella indicates is the RAM location being
altered when you lose a life.
Performing the cheat
Once Stella has given you the memory location where the location containing your number of lives is, you'll find some
code similar to one of the three examples I've shown you. Let's pretend it's location $55 just to be consistent.
If you see a DEC $55, this has to be removed. To do this we'll use the NOP command (NOP means No Operation, much like a
REM command in BASIC. It does...nothing). In the code where you see DEC $55 you'll see the numbers $C6 $55. The $c6 means
DECREMENT and the $55 is the location to be decremented. You COULD change the 55 to something like 88 and the code would
then become DEC $88 but since we don't know whats in location $88, it could make our game buggy. By changing the two values
to $EA you place two NOP's over top of the old code.
Pretending the code is at location $1000 in Stella...
$1000 $C6 $55 (dec $55)
after changing the C^ and 55 it becomes
$1000 $EA EA (nop, nop)
The subtraction method:
This is used mainly for timers and energy levels because the Accumulator register can handle carrying (think back to when you
added numbers on paper and the teacher told you to carry the '1' when you added 9 + 1).
LDA $55 ' load Accumulator with whatever is in location $55
SEC ' sec carry
SBC #$01 ' subtract 1 (notice the # sign meaning the actual number 1)
STA $55 ' store it back in location 55
P.S. A simple DEC $55 would also accomplish same thing.
We could put some NOP's in this code to stop the subtraction, but I have an easier method. Change the 01 to a 00 and it
becomes SBC #$00. Any number subtracted with 0 remains unchanged. So move over to the $E9 $01 and change the 01 to a 00.
Easy isn't it?
Finally the DEY method (or DEX):
LDY $55 ' load Y with location $55 (currently value of 3 ships)
DEY ' DECREMENT Y value
STY $55 ' store Y back in location $55
We can put a NOP where the DEY is, or put two NOPS over top of the STY $55.
LDY $55 ' load Y with location $55 (currently value of 3 ships)
NOP ' do nothing
STY $55 ' put the value held in Y into location 55 and since we didn't DEcrement Y(DEY) it remains unchanged.
LDY $55 ' load Y with location $55 (currently value of 3 ships)
DEY ' decrement Y so it becomes 2
NOP ' do nothing
NOP ' do nothing
There are times where it's not easy to find the location containing the number of lives. This is because there are different
ways to do it.
You could load a location with the value of 3, decrement it and the game ends when the location reaches 0.
You could load a location with the value of 4, decrement it and the game ends when the location reaches 1.
You could load a location with the value of 2, decrement it and the game ends when the location reaches 255 (3,2,1,wraps to 255)
It won't always be as straightforward as looking for a 3, it could be a 4 or it could be a 2. It could also start with a 0
and increment so that when it reaches 3 the game is over. Typically most games decrement though.
One method I use for difficult games is to go in and change the memory locations in Stella, row by row.
Sure, this is liable to cause the game to crash, restart or show odd results but it works. Basically you take it line by line
beginning with the first row of numbers in the Stella debugger. Change them all to zeros and then click EXIT to continue the
game. Did your # of ships disappear? If not, restart the game and try the next row.
When you reach the row that causes your # of ships to be zero, you can narrow down the exact location by trying 4 or 5
locations at a time.
DD 01 DD 3E 1E 05 FF FF ' change this row to all zeros and resume game
E1 3E 2F FF A1 01 02 03 ' if the first row didn't do anything change this row
FF FF FF FF FF 02 02 03 ' and so on...
Exporting the Results
If you'd like to learn how these cheats work, or would like to implement them into other emulator systems you can do so.
I would ask that you leave the credit for my hard work intact though.
1) Load the Stella emulator, ensure that the cheats file is found by Stella and load one of the games covered by my cheats.
2) Press TAB to get to the Cheat menu
3) Click on Edit Cheat and look at the CODE.
4) The code is the key to how the cheat works.
If the code is 6 digits long then it can be read the following:
where xxx is the memory location, yy is the value and d is the repetition of the value.
For example a code of D1C8e00 for Pitfall would mean that at location $D1C a value of $8e is placed ONCE. No repetitions.
A code of C00EA2 would mean that at location $C00 a value of $EA (NOP) is placed three times (once, plus 2 repetitions).
If the code is seven digits long it can be read as the following:
b is the bank #, xxx is the memory location, yy is the value and d is the repetition.
A code of 1FC0EA2 would place a value of $EA at location $FC0 three times (once, two repetitions). This would occur at bank 1.
Some Atari cartridges have memory banks, which you can think of like a different layer. If you don't get the correct layer,
the memory location will not be placed in the correct spot. It will go into the proper location, but for a different 'layer'.
To find the proper bank, look on the debugger screen of Stella and it will show you which bank is in use. You can change it to
reveal the correct bank of code.
By enabling and then disabling the cheat, you can see how the code changes to perform the cheat.
contact: Born2Code (atari Age forum)
Download the CHT file for Stella and the required files here:https://letitbit.net/download/51299.57e8 ... 0.rar.htmlhttps://rapidshare.com/files/3940314466/ ... 202600.rar