New SRAM Tutorial

Discussion in 'Tutorials' started by Kilo, Feb 23, 2020.

  1. Kilo

    Kilo Foxy Fren Exiled

    Oct 9, 2017
    A warm and lovely place~
    Credits to @AkumaYin for optimizing InitSRAM

    Over the past few days, I've been learning how to work with SRAM (Save RAM), and I think I've gotten it down.
    For those who don't know, SRAM is used for saving data once the Mega Drive is turned off. Sonic 3 uses it to store 6 entries that contain: Your selected character, your current zone, your Chaos Emeralds. And with Sonic 3 and Knuckles, you get 2 more save slots, and your lives and continues are saved.
    Implementing and using SRAM is surprisingly easy. And only requires a few steps.

    First your project needs to be able to actually use SRAM. There's a part of the header that determines this information.
        dc.l    $20202020    ; Null SRAM
        dc.l    $20202020    ; Start of SRAM memory space
        dc.l    $20202020    ; End of SRAM memory space
    As is, the SRAM is using a null value and is therefore inactive. To make it active you'll need to change the contents of SRAM support. The format is pretty simple: "RA",XX,$20. XX is based on the type of SRAM you want. Here are your options:

    • $A0 - No saving, 16-bit addresses
    • $B0 - No saving, even 8-bit addresses
    • $B8 - No saving, odd 8-bit addresses
    • $E0 - Saving, 16-bit addresses
    • $F0 - Saving, even 8-bit addresses
    • $F8 - Saving, odd 8-bit addresses
    You'd most likely want to use $F8 (Saving with odd 8-bit addresses) so here's what that would look like:
        dc.b    "RA",$F8,$20
    You can then choose your space for SRAM memory. Starting from $200001 to $20FFFF.
    The header is now set up to allow for SRAM. From here on out you can do whatever you please. But I still need to go over a few things.
    If you were to attempt and load SRAM data that doesn't exist, you'd most likely get a crash. This can be prevented with a routine to check if SRAM exists.
            move.b  #1,($A130F1).l    ; Enable SRAM writing
            lea ($200001).l,a0      ; Load SRAM memory into a0 (Change the last digit to 0 if you're using even SRAM)
            movep.l 0(a0),d0        ; Get the existing string at the start of SRAM
            move.l  #"SRAM",d1        ; Write the string "SRAM" to d1
            cmp.l   d0,d1            ; Was it already in SRAM?
            beq.s   @Continue           ; If so, skip
            movep.l d1,0(a0)        ; Write string "SRAM"
            ; Here is where you initialize values like lives or level. If you're using 8 bit values, you can only use every other byte.
            ; Example - 8(a0) => $A(a0)
            move.b    #0,($A130F1).l    ; Disable SRAM writing
    I recommend you place this before the main game loop routine.

    Using SRAM
    Everything is ready to be used. How you use it is up to you, here are just some notes.
    • You must enable and disable SRAM writing mode before and after you do SRAM writing, but only if your ROM is larger than 2 MB, otherwise it's always active.
    • You have to lea the SRAM memory into an address register when using 8-bit SRAM and long word values.
    • You must use movep to move memory into SRAM when using 8-bit SRAM and long word values.
    • You cannot directly move values into SRAM, you'd have to do it via a register when using 8-bit SRAM and long word values.
    • You can just directly use move.b into the SRAM memory you want when using byte values.
    If you have suggestions, fixes, additions, or even some cool results, let me know. (Seriously, I got very little feedback on this, and it concerns me because I know I'm not perfect at SRAM yet). Other than that, enjoy saving!
    Last edited: Feb 29, 2020
  2. KingofHarts

    KingofHarts Well-Known Member Member

    Sep 30, 2012
    Sorry for the bump, but I just stumbled upon this and since you wanted feedback, I plan to use this in my hack. I'll edit this post to let you know how it goes. Thank you for the tutorial.

    EDIT: I coupled it with this 10-year old gem:

    Thanks to you both, I've got a fully working Save Game system in Sonic 1. Working on multiple slots, and Time Attack data. Cheers!!
    Last edited: Jun 6, 2020
    Hame, Samey and Kilo like this.