OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
sram.h File Reference

SNES SRAM (Save RAM) Functions. More...

#include <snes/types.h>

Go to the source code of this file.

Macros

#define SRAM_SIZE_16KB   0x04
 16KB SRAM (128Kbit)
#define SRAM_SIZE_2KB   0x01
 2KB SRAM (16Kbit)
#define SRAM_SIZE_32KB   0x05
 32KB SRAM (256Kbit)
#define SRAM_SIZE_4KB   0x02
 4KB SRAM (32Kbit)
#define SRAM_SIZE_8KB   0x03
 8KB SRAM (64Kbit) - Most common
#define SRAM_SIZE_NONE   0x00
 No SRAM (0KB).
SRAM return codes

Returned by sramSave(), sramLoad(), sramSaveOffset(), sramLoadOffset() and sramClear(). The family returned nothing until 2026-09-21 and copied whatever it was asked; a refused transfer now copies NOTHING.

The capacity checked against is the one your ROM declares: the SRAMSIZE byte of its header (SRAM_SIZE in your Makefile, 8 KB by default), capped by what this module addresses in one bank (32 KB on LoROM, 8 KB on HiROM).

#define SRAM_ERR_NO_SRAM   2
 The ROM header declares no SRAM (USE_SRAM := 1 is missing).
#define SRAM_ERR_RANGE   1
 offset + size exceeds the declared SRAM; nothing was copied.
#define SRAM_OK   0
 The transfer fits and was done (a size of 0 is also OK).

Functions

u8 sramChecksum (const u8 *data, u16 size)
 Calculate simple checksum.
u8 sramClear (u16 size)
 Clear SRAM to zero.
u8 sramLoad (u8 FAR *data, u16 size)
 Load data from SRAM.
u8 sramLoadOffset (u8 FAR *data, u16 size, u16 offset)
 Load data from SRAM at offset.
u8 sramSave (const u8 *data, u16 size)
 Save data to SRAM.
u8 sramSaveOffset (const u8 *data, u16 size, u16 offset)
 Save data to SRAM at offset.

Detailed Description

SNES SRAM (Save RAM) Functions.

Functions for saving and loading game data to battery-backed SRAM.

SRAM Overview

SRAM (Static RAM) on SNES cartridges is battery-backed RAM that persists when the console is powered off. It's used for save games.

Memory Layout

  • LoROM: bank $70, $0000-$7FFF (32 KB max).
  • HiROM (USE_HIROM=1): bank $30, $6000-$7FFF — the hardware exposes battery RAM in 8 KB windows there, and this module addresses the first one only, so offset + size must stay within 8 KB (the default SRAM_SIZE). Until 2026-09-20 the LoROM address was used on HiROM too.
  • SA-1 (USE_SA1=1, since 2026-09-26): BW-RAM at bank $40, $0000-$7FFF (the header declares 32 KB). crt0 enables SNES-side writes (SBWE); before that the combination was refused because the writes were dropped.
  • Super FX (USE_SUPERFX=1, since 2026-10-03): there is no separate save chip. The battery keeps the GSU's Game Pak RAM ($70:0000-$FFFF, sized by GSU_RAM_KB), and "offset" is an offset into it. That RAM is also where the GSU draws: use the Offset functions and pick a region your framebuffers do not cover (two 16 KB buffers end at $8000; the tests use $E000). sramSave(), sramLoad() and sramClear() work from offset 0, the first framebuffer. While a job runs the module takes the RAM for the transfer and gives it back; the GSU waits meanwhile, so keep a save small or do it between jobs.

Source pointers may be in any bank (a const save template in ROM works); destination pointers are work RAM. Most games use 2 KB-8 KB of SRAM.

Usage Example

// Define your save data structure
typedef struct {
u8 magic[4]; // "SAVE" to detect valid save
u8 checksum;
} SaveData;
SaveData save;
// Load save data at game start
sramLoad((u8*)&save, sizeof(SaveData));
if (save.magic[0] != 'S' || save.magic[1] != 'A') {
// No valid save, initialize defaults
save.score = 0;
save.level = 1;
save.lives = 3;
}
// Save when needed (e.g., at checkpoint)
save.magic[0] = 'S'; save.magic[1] = 'A';
save.magic[2] = 'V'; save.magic[3] = 'E';
sramSave((u8*)&save, sizeof(SaveData));
u16 score
Probe oracle: coins collected.
Definition main.c:70
static u16 lives
Definition main.c:164
static u16 level
Definition main.c:163
unsigned short u16
16-bit unsigned integer (0 to 65535)
Definition types.h:53
unsigned char u8
8-bit unsigned integer (0 to 255)
Definition types.h:47
u8 sramLoad(u8 FAR *data, u16 size)
Load data from SRAM.
u8 sramSave(const u8 *data, u16 size)
Save data to SRAM.

ROM Header Requirement

To enable SRAM, your ROM header (hdr.asm) must set:

  • CARTRIDGETYPE $02 (ROM + SRAM)
  • SRAMSIZE $03 (8KB) or appropriate size
Author
OpenSNES Team

Macro Definition Documentation

◆ SRAM_ERR_NO_SRAM

#define SRAM_ERR_NO_SRAM   2

The ROM header declares no SRAM (USE_SRAM := 1 is missing).

◆ SRAM_ERR_RANGE

#define SRAM_ERR_RANGE   1

offset + size exceeds the declared SRAM; nothing was copied.

◆ SRAM_OK

#define SRAM_OK   0

The transfer fits and was done (a size of 0 is also OK).

◆ SRAM_SIZE_16KB

#define SRAM_SIZE_16KB   0x04

16KB SRAM (128Kbit)

◆ SRAM_SIZE_2KB

#define SRAM_SIZE_2KB   0x01

2KB SRAM (16Kbit)

◆ SRAM_SIZE_32KB

#define SRAM_SIZE_32KB   0x05

32KB SRAM (256Kbit)

◆ SRAM_SIZE_4KB

#define SRAM_SIZE_4KB   0x02

4KB SRAM (32Kbit)

◆ SRAM_SIZE_8KB

#define SRAM_SIZE_8KB   0x03

8KB SRAM (64Kbit) - Most common

◆ SRAM_SIZE_NONE

#define SRAM_SIZE_NONE   0x00

No SRAM (0KB).

Function Documentation

◆ sramChecksum()

u8 sramChecksum ( const u8 * data,
u16 size )

Calculate simple checksum.

Calculates a simple 8-bit checksum of data. Use this to verify save data integrity.

Parameters
dataPointer to data
sizeNumber of bytes
Returns
8-bit checksum (XOR of all bytes)
// Before saving:
save.checksum = 0;
save.checksum = sramChecksum((u8*)&save, sizeof(save));
sramSave((u8*)&save, sizeof(save));
// After loading:
u8 storedChecksum = save.checksum;
save.checksum = 0;
if (sramChecksum((u8*)&save, sizeof(save)) != storedChecksum) {
// Save data corrupted!
}
u8 sramChecksum(const u8 *data, u16 size)
Calculate simple checksum.

◆ sramClear()

u8 sramClear ( u16 size)

Clear SRAM to zero.

Erases all SRAM contents by filling with zeros. Useful for "delete save" functionality.

Parameters
sizeNumber of bytes to clear (usually your save data size)
Returns
SRAM_OK, or SRAM_ERR_RANGE / SRAM_ERR_NO_SRAM (nothing cleared)
// Clear first 256 bytes (one save slot)
sramClear(256);
u8 sramClear(u16 size)
Clear SRAM to zero.

◆ sramLoad()

u8 sramLoad ( u8 FAR * data,
u16 size )

Load data from SRAM.

Copies data from battery-backed SRAM to Work RAM.

Parameters
dataPointer to destination buffer in Work RAM — a bank-0 object or a FAR (bank $7E) one; the copy runs as a block move into bank $7E, whose first 8 KB mirror bank 0
sizeNumber of bytes to load
Returns
SRAM_OK, or SRAM_ERR_RANGE / SRAM_ERR_NO_SRAM (data untouched)
u8 saveData[64];
sramLoad(saveData, 64);
Note
If no valid save exists, SRAM contents are undefined

◆ sramLoadOffset()

u8 sramLoadOffset ( u8 FAR * data,
u16 size,
u16 offset )

Load data from SRAM at offset.

Like sramLoad() but reads from a specific offset within SRAM. Useful for multiple save slots.

Parameters
dataPointer to destination buffer in Work RAM
sizeNumber of bytes to load
offsetStarting offset in SRAM
Returns
SRAM_OK, or SRAM_ERR_RANGE / SRAM_ERR_NO_SRAM (data untouched)
// Load slot 2 (each slot is 256 bytes)
sramLoadOffset(saveData, 256, 512);
u8 sramLoadOffset(u8 FAR *data, u16 size, u16 offset)
Load data from SRAM at offset.

◆ sramSave()

u8 sramSave ( const u8 * data,
u16 size )

Save data to SRAM.

Copies data from Work RAM to battery-backed SRAM. The data will persist when the console is powered off.

Parameters
dataPointer to data in Work RAM to save
sizeNumber of bytes to save
Returns
SRAM_OK, or SRAM_ERR_RANGE / SRAM_ERR_NO_SRAM (nothing written)
u8 saveData[64] = { ... };
sramSave(saveData, 64);
Note
Writes from SRAM offset 0 — $70:0000 on LoROM, $30:6000 on HiROM
Warning
The ROM header must declare SRAM (USE_SRAM := 1); without it this returns SRAM_ERR_NO_SRAM.

◆ sramSaveOffset()

u8 sramSaveOffset ( const u8 * data,
u16 size,
u16 offset )

Save data to SRAM at offset.

Like sramSave() but writes to a specific offset within SRAM. Useful for multiple save slots.

Parameters
dataPointer to data in Work RAM to save
sizeNumber of bytes to save
offsetStarting offset in SRAM
Returns
SRAM_OK, or SRAM_ERR_RANGE / SRAM_ERR_NO_SRAM (nothing written)
// Save slot 2 (each slot is 256 bytes)
sramSaveOffset(saveData, 256, 512);
u8 sramSaveOffset(const u8 *data, u16 size, u16 offset)
Save data to SRAM at offset.