Skip to main content

## Savestate (.fcs)

FCE Ultra Save State Format

Updated: Mar 9, 2003

---------------------------------------

FCE Ultra's save state format is now designed to be as forward and backwards

compatible as possible. This is achieved through the (over)use of chunks.

All multiple-byte variables are stored LSB(least significant byte)-first.

Data types:

(u)int8 - (un)signed 8 bit variable(also referred to as "byte")

(u)int16 - (un)signed 16 bit variable

(u)int32 - (un)signed 32 bit variable

-- Main File Header:

The main file header is 16-bytes in length. The first three bytes contain

the string "FCS". The next byte contains the version of FCE Ultra that saved

this save state. This document only applies to version "53"(.53) and higher.

After the version byte, the size of the entire file in bytes(minus the 16 byte

main file header) is stored. If oldversion is set to 255, the 32-bit version

field will be used. In this field, a version such as 0.98.10 is stored as "9810"(decimal).

The rest of the header is currently unused and should be nulled out.

Example of relevant parts:

FCS <uint8 oldversion> <uint32 totalsize> <uint32 version>

-- Section Chunks:

Sections chunk headers are 5-bytes in length. The first byte defines what

section it is, the next four bytes define the total size of the section

(including the section chunk header).

<uint8 section> <uint32 size>

Section definitions:

1 - "CPU"

2 - "CPUC"

3 - "PPU"

4 - "CTLR"

5 - "SND"

16 - "EXTRA"

-- Subsection Chunks

Subsection chunks are stored within section chunks. They contain the actual

state data. Each subsection chunk is composed of an 8-byte header and the data.

The header contains a description(a name) and the size of the data contained

in the chunk:

<uint8 description[4]> <uint32 size>

The name is a four-byte string. It does not need to be null-terminated.

If the string is less than four bytes in length, the remaining unused bytes

must be null.

-- Subsection Chunk Description Definitions

Note that not all subsection chunk description definitions listed below

are guaranteed to be in the section chunk. It's just a list of what CAN

be in a section chunk. This especially applies to the "EXTRA" subsection.

---- Section "CPU"

Name: Type: Description:

PC uint16 Program Counter

A uint8 Accumulator

P uint8 Processor status register

X uint8 X register

Y uint8 Y register

S uint8 Stack pointer

RAM uint8[0x800] 2KB work RAM

---- Section "CPUC" (emulator specific)

Name: Type: Description:

JAMM uint8 Non-zero value if CPU in a "jammed" state

IRQL uint8 Non-zero value if IRQs are to be generated constantly

ICoa int32 Temporary cycle counter

ICou int32 Cycle counter

---- Section "PPU"

Name: Type: Description:

NTAR uint8[0x800] 2 KB of name/attribute table RAM

PRAM uint8[32] 32 bytes of palette index RAM

SPRA uint8[0x100] 256 bytes of sprite RAM

PPU uint8[4] Last values written to $2000 and $2001, the PPU

status register, and the last value written to

$2003.

XOFF uint8 Tile X-offset.

VTOG uint8 Toggle used by $2005 and $2006.

RADD uint16 PPU Address Register(address written to/read from

when $2007 is accessed).

TADD uint16 PPU Address Register

VBUF uint8 VRAM Read Buffer

PGEN uint8 PPU "general" latch. See Ki's document.

---- Section "CTLR" (somewhat emulator specific)

Name: Type: Description:

J1RB uint8 Bit to be returned when first joystick is read.

J2RB uint8 Bit to be returned when second joystick is read.

---- Section "SND" (somewhat emulator specific)

NREG uint16 Noise LFSR.

P17 uint8 Last byte written to $4017.

PBIN uint8 DMC bit index.

PAIN uint32 DMC address index(from $8000).

PSIN uint32 DMC length counter(how many bytes left

to fetch).

<to be finished>

---- Section "EXTRA" (varying emulator specificness)

For iNES-format games(incomplete, and doesn't apply to every game):

Name: Type: Description:

WRAM uint8[0x2000] 8KB of WRAM at $6000-$7fff

MEXR uint8[0x8000] (very emulator specific)

CHRR uint8[0x2000] 8KB of CHR RAM at $0000-$1fff(in PPU address space).

EXNR uint8[0x800] Extra 2KB of name/attribute table RAM.

MPBY uint8[32] (very emulator specific)

MIRR uint8 Current mirroring:

0 = "Horizontal"

1 = "Vertical"

$10 = Mirror from $2000

$11 = Mirror from $2400

IRQC uint32 Generic IRQ counter

IQL1 uint32 Generic IRQ latch

IQL2 uint32 Generic IRQ latch

IRQA uint8 Generic IRQ on/off register.

PBL uint8[4] List of 4 8KB ROM banks paged in at $8000-$FFFF

CBL uint8[8] List of 8 1KB VROM banks page in at $0000-$1FFF(PPU).

For FDS games(incomplete):

Name: Type: Description:

DDT<x> uint8[65500] Disk data for side x(0-3).

FDSR uint8[0x8000] 32 KB of work RAM

CHRR uint8[0x2000] 8 KB of CHR RAM

IRQC uint32 IRQ counter

IQL1 uint32 IRQ latch

IRQA uint8 IRQ on/off.

WAVE uint8[64] Carrier waveform data.

MWAV uint8[32] Modulator waveform data.

AMPL uint8[2] Amplitude data.

Created with the Personal Edition of HelpNDoc: Benefits of a Help Authoring Tool

####