hide results

    SRAM Hacking Guide by jdratlif

    Version: 1.0 | Updated: 10/15/05 | Search Guide | Bookmark Guide

    | Super Metroid SRAM Document 1.0
    | by John David Ratliff
    | The most recent version of this guide can always be found at
    | http://games.technoplaza.net/smse/sram-doc.txt
    | Copyright (C) 2005 emuWorks (http://games.technoplaza.net/)
    |   Permission is granted to copy, distribute and/or modify this document
    |   under the terms of the GNU Free Documentation License, Version 1.2
    |   or any later version published by the Free Software Foundation;
    |   with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
    |   Texts.  A copy of the license can be found at
    |   http://www.gnu.org/licenses/fdl.html
    | Table of Contents
      - 1.0 Introduction
      - 2.0 Copyright Notice
      - 3.0 Revision History
      - 4.0 The Super Metroid SRAM
        - 4.1 SRAM Basics
        - 4.2 SRAM Offsets
        - 4.3 The Sanity Algorithm
        - 4.4 Checksum Repair Program (sanity.c)
      - 5.0 smse - The Super Metroid SRAM Editor
      - 6.0 Credits & Acknowledgements
      - 7.0 Contact Information
    | 1.0 Introduction
      This document is a guide to the SRAM format used by Super Metroid for the
      Super Nintendo and Super Famicom. It is not a walkthrough or guide to
      anything else about the game or any other topic.
      Save RAM, abbreviated SRAM, was used in nearly all Nintendo games to save
      progress in the cartridge prior to the advent of memory cards and built-in
      hard drives that came with third-generation (and later) systems such as the
      Playstation and X-Box. SRAM is a special segment of memory which is preserved
      using a battery built into the cartridge, and enables games to keep a limited
      area of memory from being erased when the console (SNES) was turned off.
      SRAM was reliable so long as the battery lasted, and the batteries were
      generally guaranteed for 5 years from the date of cartridge production, and
      often outlasted their guarantee period. Many Nintendo and Super Nintendo
      cartridges with SRAM still have working batteries, and many others are now
      Why have I spent two paragraphs talking about SRAM? Because it was the
      storage medium used to save game progress for Super Metroid. All three games,
      along with some other information was stored in a block of memory 0x2000
      bytes long. (Note: all numbers prefixed with 0x are in the hexadecimal
      This document is a guide to what is stored in the SRAM and where. It is
      useful only if you wish to alter the SRAM in some way. See section 5.0 for
      a program that helps edit Super Metroid SRAM files.
      Why would you want to edit the SRAM file? To edit your games; either to cheat
      or to try things out. For example, say you wanted to try a new way of
      beating Draygon, but didn't have any save games. Rather than play all the
      way through to Draygon, you might just start a game, get past the space
      colony, save the game on Zebes and edit the SRAM to put you near Draygon
      with whatever equipment you might need to try your new method. Of course,
      cheating is probably the more popular use for SRAM editing.
    | 2.0 Copyright Notice
      This document is Copyright (C) 2005 emuWorks (http://games.technoplaza.net/) 
        Permission is granted to copy, distribute and/or modify this document
        under the terms of the GNU Free Documentation License, Version 1.2
        or any later version published by the Free Software Foundation;
        with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
        Texts.  A copy of the license can be found at
      Basically, it is free documentation in much the same way software under the
      GNU General Public License is free software. You can modify it, redistribute
      it, sell it, publish it, etc.
    | 3.0 Revision History
      Version 1.0 - Saturday, October 15, 2005
        - First Public Release
    | 4.0 The Super Metroid SRAM
        This section details the SRAM format used by Super Metroid.
    | 4.1 SRAM Basics
        As was discused in section 1.0, Super Metroid used an SRAM of 0x2000 bytes
        to store game progress.
        Each game occupied 0x65C bytes of the SAM for a total of 0x1314 bytes.
        There are 8 bytes of meta-data kept on each game for a total of 0x18 bytes,
        bringing us to a total of 0x132C bytes. The remaining 0xCD4 bytes are
        largely unused. There are a few game properties that are stored in the
        SRAM, but these are not documented here (nor do I know any of them).
        Because the SRAM is simply a block of RAM, it can lose its value if there
        is no power. The battery in the cartridge feeds power to the memory when
        the console is off, but if the battery dies, the SRAM will cease to
        function. Because the battery must eventually die, nearly every game that
        used SRAM added a sanity algorithm to confirm that the SRAM was still in
        working order. Data within the SRAM acts to confirm that the remainder of
        the SRAM data is valid. 8 bytes of SRAM data for each game are reserved for
        this purpose. They are the checksum (2 bytes), the checksum compliment
        (2 bytes), the redundant checksum (2 bytes), and the redundant checksum
        compliment (2 bytes). The sanity algorithm will be discussed in detail in
        section 4.4.
        The SRAM is largely composed of game data, the majority of which is of
        little importance for most purposes. There are only around 300 bits of
        really important data. These include the majority of Samus' progress,
        including her current and max energy and reserve energy, her current and
        max inventory (missiles, super missiles, and power bombs), which bosses
        have been defeated, the save point, the area maps Samus has downloaded,
        the game time, the controller and game configuration, which items Samus
        has found (morphing ball, screw attack, ice beam, etc.), which missile,
        super missile, and power bomb packs Samus has found, which energy and
        reserve tanks Samus has found, and which doors Samus has opened. The
        majority of the remaining data in the SRAM corresponds to Samus' personal
        map for each area, which is a listing of all the rooms Samus has entered in
        each area. The specifics of this personal map data are of little interest
        to me, and so are undocumented (and unknown).
        The data documented here is generally edited in a single bit of the SRAM.
        The next section will present a listing of all the known offsets and
        which bit within the offset is used.
        The three games, which are 0x65C bytes in length begin at offset 0x10 in
        the SRAM. SRAM offset 0x10 is the start of Game A. 0x66C is the start of
        Game B, and 0xCC8 is the start of Game C. The offset data in the next
        section is all relative to the start of each game. So offset 0x60 in game 1
        is really 0x70 from the start of the SRAM, 0x6CC in game 2, and 0xD28 in
        game 3.
    | 4.2 SRAM Offsets
      These offsets will be presented in no special order other than similar things
      will be grouped together.
      The energy and reserve energy are words (2 bytes). Words are special in the
      SRAM because they must be stored in little endian format. If you don't know
      what the is, you can google for it if you're interested.
      Here is what it means for our purposes. It means you need to take the value
      you want, convert it to hex, and reverse the bytes. For example, 1499, the
      max energy is 0x5DB in hex. This word becomes the two bytes, 0x5 and 0xDB.
      If you want to change the current energy to 1499, you need to put 0xDB in
      offset 0x20 and 0x5 in offset 0x21. This looks backwards to us, but is
      the way the 65c816 processor (used in the Super Nintendo/Famicom) reads
      Energy - Max energy is 1499 (0x5DB)
        0x20 (Current)
        0x22 (Max)
      Reserve Energy - Max reserve energy is 400 (0x190)
        0x34 (Current)
        0x32 (Max)
      Missiles - Max missiles is 230 (0xE6)
        0x24 (Current)
        0x26 (Max)
      Super Missiles - Max super missiles is 50 (0x32)
        0x28 (Current)
        0x2A (Max)
      Power Bombs - Max power bombs is 50 (0x32)
        0x2C (Current)
        0x2E (Max)
      The next group of offsets detail Samus' equipment (morphing ball, screw
      attack, ice beam, etc). The first offset is whether the item has been
      taken, and therefore will not appear in the game. The second one is whether
      Samus has the item in her inventory or not. The third one is whether the
      item is equipped or not.
      The grappling beam and the X-Ray scope are special in that you must have
      them in the inventory and be equipped for Samus to be able to use them. If
      they are not equipped, they won't show up or be selectable.
      These offsets, as well as almost all others, are specified in the format
      offset:bit where the offset is the byte location from the start of the
      game data and the bit is the bit number within the byte, from 0-7 starting
      at the rightmost bit. For example, if you had a byte with the following
      bit pattern: 10010110, then bit 0 is off and bit 7 is on.
      Morphing Ball
        0xB3:2, 0x2:2, 0x0:2
        0xB0:7, 0x3:4, 0x1:4
      Spring Ball
        0xC2:6, 0x2:1, 0x0:1
      High Jump Boots
        0xB6:5, 0x3:0, 0x1:0
      Varia Suit
        0xB6:0, 0x2:0, 0x0:0
      Gravity Suit
        0xC0:7, 0x2:5, 0x0:5
      Speed Booster
        0xB8:2, 0x3:5, 0x1:5
      Space Jump
        0xC3:2, 0x3:1, 0x1:1
      Screw Attack
        0xB9:7, 0x2:3, 0x0:3
      Charge Beam
        0xB2:7, 0x7:4, 0x5:4
      Ice Beam
        0xB6:2, 0x6:1, 0x4:1
      Wave Beam
        0xB8:4, 0x6:0, 0x4:0
        0xB5:2, 0x6:2, 0x4:2
      Plasma Beam
        0xC1:7, 0x6:3, 0x4:3
      Grappling Beam
        0xB7:4, 0x3:6, 0x1:6
      X-Ray Scope
        0xB4:6, 0x3:7, 0x1:7
      The next set of bits list the bosses and mini-bosses in the game. For the
      four major bosses (Kraid, Phantoon, Draygon, and Ridley), the first bit
      is whether they have been defeated, and the second is whether their statue
      has been broken in the Tourian Elevator room.
      Silver Torizo
      Spore Spawn
        0x69:0, 0x61:1
        0x6B:0, 0x60:6
        0x6C:0, 0x61:0
      Golden Torizo
        0x6A:0, 0x60:7
      The metroid rooms determine if one of the four rooms in Tourian with
      metroids has been cleared or not. If the room is cleared, there will not
      be metroids in it if you go back into that room.
      Metroid Rooms
      The Zebetites byte is a little confusing. First, only three bits are used,
      and five values: 000, 001, 010, 011, and 100. Each value represents the
      number of destroyed Zebetites, 0-4. You cannot specify an individual
      Zebetite to destroy, only the total number destroyed.
      To change the number, pick the zebetite number you want, left shift it by
      3 and bitwise OR it into the offset byte. You must bitwise OR because there
      are other bits in the same byte used for other purposes.
      The next three bits are miscellaneous useful things I found.
      Tourian Elevator: Whether the elevator to Tourian is present or not
      Maridia Glass Tube Broken: Whether the glass tube is broken or not
      Rescued Animals: Whether Samus rescued the Animals during her escape or not
      Tourian Elevator
      Maridia Glass Tube Broken
      Rescued Animals
      The missile packs, super missile packs, power bomb packs, energy tanks, and
      reserve tanks determine whether the particular item has been taken or not.
      These may be used in the item percent calculation at the end, but I haven't
      tested this.
      I do not know which bit corresponds to which item.
      Crateria Missile Packs (8)
        0xB0:1, 0xB0:2, 0xB0:3, 0xB0:4
        0xB0:6, 0xB1:1, 0xB1:2, 0xB1:4
      Brinstar Missile Packs (12)
        0xB1:7, 0xB2:2, 0xB2:3, 0xB2:5
        0xB2:6, 0xB3:1, 0xB3:4, 0xB4:2
        0xB4:4, 0xB4:5, 0xB5:1, 0xB5:4
      Norfair Missile Packs (15)
        0xB6:1, 0xB6:3, 0xB6:6, 0xB6:7
        0xB7:2, 0xB7:3, 0xB7:6, 0xB7:7
        0xB8:0, 0xB8:1, 0xB8:3, 0xB8:6
        0xB9:1, 0xB9:2, 0xB9:5
      Wrecked Ship Missile Packs (3)
        0xC0:0, 0xC0:2, 0xC0:3
      Maridia Missile Packs (8)
        0xC1:0, 0xC1:3, 0xC1:5, 0xC1:6
        0xC2:0, 0xC2:2, 0xC2:4, 0xC2:7
      Crateria Super Missile Packs (1)
      Brinstar Super Missile Packs (3)
        0xB1:6, 0xB2:0, 0xB3:7
      Norfair Super Missile Packs (1)
      Wrecked Ship Super Missile Packs (2)
        0xC0:5, 0xC0:6
      Maridia Super Missile Packs (3)
        0xC1:1, 0xC1:4, 0xC2:5
      Crateria Power Bomb Packs (1)
      Brinstar Power Bomb Packs (5)
        0xB1:5, 0xB3:0, 0xB3:3, 0xB4:7,
      Norfair Power Bomb Packs (3)
        0xB7:1, 0xB9:3, 0xB9:4
      Maridia Power Bomb Packs (1)
      Crateria Energy Tanks (2)
        0xB0:5, 0xB1:0
      Brinstar Energy Tanks (5)
        0xB3:5, 0xB3:6, 0xB4:1, 0xB4:3, 0xB5:3
      Norfair Energy Tanks (4)
        0xB6:4, 0xB7:0, 0xB9:6, 0xBA:0
      Wrecked Ship Energy Tanks (1) 
      Maridia Energy Tanks (2)
        0xC1:2, 0xC3:0
      Brinstar Reserve Tank
      Norfair Reserve Tank
      Wrecked Ship Reserve Tank
      Maridia Reserve Tank
      The door bits determine whether a door has been opened or not. I know some
      doors, while others are unknown. I have put comments by all the doors I
      Crateria Red Doors (3)
        0xF0:5 (Crateria Map)
        0xF3:5 (Bombs)
        0xF3:6 (Tourian Elevator)
      Brinstar Red Doors (10)
        0xF4:0 (Brinstar Map)
        0xF4:6 (Brinstar Reserve Tank)
        0xF5:2 (Spore Spawn)
        0xF7:2 (X-Ray Scope)
      Norfair Red Doors (7)
        0xF9:5 (High Jump Boots)
        0xFA:5 (Speed Booster)
        0xFA:7 (Wave Beam)
      Wrecked Ship Red Doors (1)
        0x101:3 (Reserve Tank)
      Maridia Red Doors (8)
        0x102:0 (Maridia Map)
      Tourian Red Doors (2)
        0x105:1 (Mother Brain)
      Crateria Green Doors (2)
        0xF1:4 (Wrecked Ship)
      Brinstar Green Doors (10)
        0xF5:6 (Spore Spawn Exit)
        0xF7:7 (Spazer)
      Norfair Green Doors (6)
        0xF9:3 (Ice Beam)
        0xFA:4 (Speed Booster)
      Wrecked Ship Green Doors (1)
      Maridia Green Doors (4)
        0x103:2 (Draygon)
      Crateria Yellow Doors (6)
      Brinstar Yellow Doors (4)
        0xF7:1 (X-Ray Scope)
      Norfair Yellow Doors (3)
        0xF9:4 (Norfair Map)
      Crateria Metal Doors (1)
        0xF3:3 (Bombs Exit)
      Brinstar Metal Doors (16)
        0xF3:1 (Old Tourian Right)
        0xF3:2 (Old Tourian Left)
        0xF4:5 (Brinstar Map Exit)
        0xF8:2 (Mini-Kraid Right)
        0xF8:3 (Mini-Kraid Left)
        0xF8:6 (Varia Suit)
        0xF8:7 (Kraid Exit)
      Norfair Metal Doors (6)
        0xF9:7 (Crocomire Exit)
        0xFA:0 (High Jump Boots Exit)
        0xFB:1 (Screw Attack)
        0xFB:2 (Ridley Exit)
        0xFB:3 (Ridley Left)
        0xFC:0 (Gold Space Pirates)
      Wrecked Ship Metal Doors (5)
        0x100:6 (Phantoon Exit)
      Maridia Metal Doors (7)
        0x102:1 (Plasma Exit)
        0x102:3 (Plasma)
        0x103:5 (Botwoon Exit)
        0x103:6 (Draygon Exit)
        0x103:7 (Space Jump)
      Tourian Metal Doors (5)
        0x104:5 (Dust Chozo - Point of No Return)
      Brinstar Eye Door (Kraid)
      Norfair Eye Door (Ridley)
      Wrecked Ship Eye Door (Phantoon)
      Maridia Eye Door (Draygon)
      Tourian Eye Door
      The six area maps are simple. A value of 0 means you don't have the area
      map, and a value of 0xFF means you do.
      Crateria Map
      Brinstar Map
      Norfair Map
      Wrecked Ship Map
      Maridia Map
      Tourian Map
      The save point is slightly, but not overly complicated. The first offset
      determines which area you are in. 0 = Crateria, 1 = Brinstar, 2 = Norfair,
      3 = Wrecked Ship, 4 = Maridia, and 5 = Tourian. The second offset
      determines which save point within the area you are at starting at.
      There are 2 save points in Crateria, 5 in Brinstar, 6 in Norfair, 1 in the
      Wrecked Ship, 4 in Maridia, and 2 in Tourian.
      Save Spot
        0x158 (Area)
        0x156 (Point)
      Game time determines how much time the game has been played for. The max
      game time is 99 hours and 59 minutes, after which the game stops tracking
      your time.
      Game Time
        0x3E (Hours)
        0x3C (Minutes)
      Shot Button
      The controller configuration is slightly complicated. Each button is a
      word (2 bytes), but you don't need to worry about converting to little
      ending here, because each button value is simple.
      A = 0x80, 0
      B = 0, 0x80
      X = 0x40, 0
      Y = 0, 0x40
      L = 0x20, 0
      R = 0x10, 0
      Select = 0, 0x20
      Don't duplicate any buttons and remember that Angle Up/Down can only be
      assigned to R/L. If you change this, the game will simply ignore it.
      Jump Button
      Dash Button
      Item Cancel Button
      Item Select Button
      Angle Down Button
      Angle Up Button
      These last three bits are the other part of the game configuration. They
      are pretty straightforward.
      Language (English or Japanese)
      Moon Walk (Off or On)
      Icon Cancel (Manual or Automatic)
    | 4.3 The Sanity Algorithm
      The sanity algorithm, used to ensure the SRAM is still valid is not very
      complex, but hard to calculate by hand. If you want to edit the SRAM, but
      don't want to do sanity algorithm math, you can either use smse (see section
      5.0) or edit the SRAM by hand and use my checksum repair program (see section
      4.4) to fix the sanity values for you.
      The sanity values are comprised of eight bytes. A primary checksum (2 bytes),
      a checksum compliment (the checksum XOR 0xFF -- 2 bytes), and redundant
      copies of each of these two values for a total of 8 bytes.
      The game requires at least one checksum and one checksum compliment to be
      correct for it to consider a game to be valid. If both checksums or both
      compliments are invalid, the game is considered invalid and is not playable.
      To calculate the checksum, you will need two counter variables. I will call
      them low and high. Set the low and high counter to 0 initially. Now, take the
      SRAM data for a single game and do the following:
        1. For the current byte, add it to the high counter. If the counter exceeds
           255, subtract 255 from the high counter and increment the low counter by
        2. Take the next byte and add it to the low counter. If the counter exceeds
           255, subtract 255 from the low counter. Do NOT increment the high
      Continue until you have added all the bytes (half to the high counter, and
      half to the low counter). When you are done, you should have two bytes, the
      high counter and the low counter. The high counter is the high byte of the
      checksum word, and the low counter is the low byte of the checksum word.
      For the compliment, simply take the XOR of 0xFF with each byte of the
      checksum. The high and low byte XOR values becomes the compliment value.
      The redundant values are simply copies of the checksum and the compliment.
      The values should be put in the SRAM at the following offsets (these are from
      the start of the SRAM).
      0x0, 0x1 Checksum High/Low Bytes Game 1
      0x8, 0x9 Compliment High/Low Bytes Game 1
      0x1FF0, 0x1FF1 Checksum High/Low Bytes Game 1
      0x1FF8, 0x1FF9 Compliment High/Low Bytes Game 1
      Game 2 and 3 are the bytes following game 1.
    | 4.4 Checksum Repair Program (sanity.c)
      This is a small program in ANSI C that can be used to repair sanity values in
      a Super Metroid SRAM file.
      There are a couple minor problems with this program. First, no file
      validation is performed. Any file with at least 0x2000 bytes will be
      accepted and overwritten. Be carewhat what arguments you pass to this
      program. Second, invalid games are fixed. This means games that were blank
      will become valid games that are unplayable. Just be aware of this when you
      start Super Metroid in Snes9x or ZSNES (or whatever SNES emulator you use).
      If you see a game where Samus has 0 energy, the game is useless. Samus will
      die as soon as the game begins.
      This program is standard ANSI C and should compile on any operating system
      with an ANSI C compiler. I have put a windows binary up at
      To run the program, simply type ./sanity [SRAM file]. If you want to compile
      the program and have gcc, you can do "gcc sanity.c -o sanity"
      I don't think there are any bugs, but I tested it all of one time, so who
      knows. Write me a letter if it doesn't work or compile or something.
     * Super Metroid SRAM Checksum Repair Program
     * Copyright (C) 2005 emuWorks
     * http://games.technoplaza.net/
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * GNU General Public License for more details.
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    #include <stdio.h>
    void sanitize(char *sram) {
        int game, i;
        short high, low;
        unsigned char value;
        unsigned char hb, lb, hc, lc;
        char *ptr;
        for (game = 0; game < 3; ++game) {
            ptr = (sram + 0x10 + (0x65C * game));
            high = 0;
            low = 0;
            for (i = 0; i < 0x65C; ++i) {
                value = ptr[i];
                if ((high += value) > 0xFF) {
                    high &= 0xFF;
                value = ptr[++i];
                if ((low += value) > 0xFF) {
                    low &= 0xFF;
            hb = (unsigned char)high;
            lb = (unsigned char)low;
            hc = (hb ^ 0xFF);
            lc = (lb ^ 0xFF);
            sram[game * 2] = hb;
            sram[game * 2 + 1] = lb;
            sram[8 + game * 2] = hc;
            sram[8 + game * 2 + 1] = lc;
            sram[0x1FF0 + game * 2] = hb;
            sram[0x1FF0 + game * 2 + 1] = lb;
            sram[0x1FF8 + game * 2] = hc;
            sram[0x1FF8 + game * 2 + 1] = lc;
    int main(int argc, char **argv) {
        FILE *f;
        char sram[0x2000];
        if (argc != 2) {
            fprintf(stderr, "syntax: sanity [Super Metroid SRAM File]\n");
            return -1;
        if ((f = fopen(argv[1], "rb")) == NULL) {
                "error: unable to open Super Metroid SRAM file for reading\n");
            return -1;
        if (fread(sram, 0x2000, 1, f) != 1) {
            fprintf(stderr, "error: invalid SRAM file\n");
            return -1;
        if ((f = fopen(argv[1], "wb")) == NULL) {
                "error: unable to open Super Metroid SRAM file for writing\n");
            return -1;
        if (fwrite(sram, 0x2000, 1, f) != 1) {
            fprintf(stderr, "error: unable to write SRAM data\n");
            return -1;
        printf("successfully fixed sanity data in file: [%s]\n", argv[1]);
        return 0;
    | 5.0 smse - The Super Metroid SRAM Editor
      If you really want to edit the SRAM, I recommend a program called 'smse', the
      Super Metroid SRAM Editor. Not surprisingly, I wrote it.
      It will edit any of the offsets I have outlined in this document an will
      keep fix the sanity values for you so you don't need to. It's far simpler
      than trying to edit by hand, unless you need to edit parts of the SRAM I
      haven't documented.
      If you want to try it out, head over to http://games.technoplaza.net/smse/.
      It's free software under the GNU GPL, tested in Windows, Linux, and Mac OS X,
      and is likely to run on almost any unix that support GTK+.
    | 6.0 Credits & Acknowledgements
      I want to thank phonymike for discovering and documenting the checksum
      algorithm used by Super Metroid. In addition, I want to thank him for the
      many offsets he discovered and documented in his original Metroid 3 editor.
    | 7.0 Contact Information
      The author (John Ratliff) can be contacted at
      webmaster [AT] technoplaza [DOT] net. Replace as necessary.
      I can also be reached via an online feedback form at

    View in: