292 lines
16 KiB
HTML
292 lines
16 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html><head><title>Savestate (.fcs)</title>
|
|
<meta http-equiv="Content-Style-Type" content="text/css">
|
|
<style type="text/css"><!--
|
|
body {
|
|
margin: 5px 5px 5px 5px;
|
|
background-color: #ffffff;
|
|
}
|
|
/* ========== Text Styles ========== */
|
|
hr { color: #000000}
|
|
body, table /* Normal text */
|
|
{
|
|
font-size: 10pt;
|
|
font-family: 'Arial', 'Helvetica', sans-serif;
|
|
font-style: normal;
|
|
font-weight: normal;
|
|
color: #000000;
|
|
text-decoration: none;
|
|
;
|
|
}
|
|
span.rvts1 /* Heading */
|
|
{
|
|
font-weight: bold;
|
|
color: #0000ff;
|
|
}
|
|
span.rvts2 /* Subheading */
|
|
{
|
|
font-weight: bold;
|
|
color: #000080;
|
|
}
|
|
span.rvts3 /* Keywords */
|
|
{
|
|
font-style: italic;
|
|
color: #800000;
|
|
}
|
|
a.rvts4, span.rvts4 /* Jump 1 */
|
|
{
|
|
color: #008000;
|
|
text-decoration: underline;
|
|
}
|
|
a.rvts5, span.rvts5 /* Jump 2 */
|
|
{
|
|
color: #008000;
|
|
text-decoration: underline;
|
|
}
|
|
span.rvts6 /* Font Hint */
|
|
{
|
|
color: #808080;
|
|
}
|
|
span.rvts7 /* Font Hint Title */
|
|
{
|
|
font-size: 15pt;
|
|
font-family: 'Tahoma', 'Geneva', sans-serif;
|
|
font-weight: bold;
|
|
color: #404040;
|
|
}
|
|
span.rvts8 /* Font Hint Bold */
|
|
{
|
|
font-weight: bold;
|
|
color: #808080;
|
|
}
|
|
span.rvts9 /* Font Hint Italic */
|
|
{
|
|
font-style: italic;
|
|
color: #808080;
|
|
}
|
|
span.rvts10 /* Font Style */
|
|
{
|
|
font-size: 16pt;
|
|
font-family: 'Tahoma', 'Geneva', sans-serif;
|
|
color: #ffffff;
|
|
}
|
|
span.rvts11 /* Font Style */
|
|
{
|
|
font-family: 'MS Sans Serif', 'Geneva', sans-serif;
|
|
color: #808080;
|
|
}
|
|
span.rvts12 /* Font Style */
|
|
{
|
|
font-family: 'Verdana', 'Geneva', sans-serif;
|
|
font-style: italic;
|
|
color: #c0c0c0;
|
|
}
|
|
a.rvts13, span.rvts13 /* Font Style */
|
|
{
|
|
font-family: 'Verdana', 'Geneva', sans-serif;
|
|
font-style: italic;
|
|
color: #6666ff;
|
|
text-decoration: underline;
|
|
}
|
|
/* ========== Para Styles ========== */
|
|
p,ul,ol /* Paragraph Style */
|
|
{
|
|
text-align: left;
|
|
text-indent: 0px;
|
|
padding: 0px 0px 0px 0px;
|
|
margin: 0px 0px 0px 0px;
|
|
}
|
|
.rvps1 /* Centered */
|
|
{
|
|
text-align: center;
|
|
}
|
|
.rvps2 /* Paragraph Style */
|
|
{
|
|
background: #9fbed0;
|
|
margin: 0px 0px 20px 0px;
|
|
}
|
|
.rvps3 /* Paragraph Style */
|
|
{
|
|
text-align: center;
|
|
background: #e4e4e4;
|
|
margin: 20px 0px 0px 0px;
|
|
}
|
|
.rvps4 /* Paragraph Style */
|
|
{
|
|
border-color: #c0c0c0;
|
|
border-style: solid;
|
|
border-width: 1px;
|
|
border-right: none;
|
|
border-bottom: none;
|
|
border-left: none;
|
|
background: #ffffff;
|
|
padding: 3px 0px 0px 0px;
|
|
margin: 27px 0px 0px 0px;
|
|
}
|
|
--></style>
|
|
<script type="text/javascript">if(top.frames.length == 0) { top.location.href="../fceux-2.0.2.htm?{8C035D09-D641-451D-ADEC-7226AE495EDD}.htm"; }</script>
|
|
<meta name="generator" content="HelpNDoc Free"></head>
|
|
<body>
|
|
|
|
<p class=rvps2><span class=rvts10>Savestate (.fcs)</span></p>
|
|
<p>FCE Ultra Save State Format</p>
|
|
<p> Updated: Mar 9, 2003</p>
|
|
<p>---------------------------------------</p>
|
|
<p><br></p>
|
|
<p>FCE Ultra's save state format is now designed to be as forward and backwards</p>
|
|
<p>compatible as possible. This is achieved through the (over)use of chunks.</p>
|
|
<p>All multiple-byte variables are stored LSB(least significant byte)-first.</p>
|
|
<p>Data types:</p>
|
|
<p><br></p>
|
|
<p> (u)int8 - (un)signed 8 bit variable(also referred to as "byte")</p>
|
|
<p> (u)int16 - (un)signed 16 bit variable</p>
|
|
<p> (u)int32 - (un)signed 32 bit variable</p>
|
|
<p><br></p>
|
|
<p>-- Main File Header:</p>
|
|
<p><br></p>
|
|
<p>The main file header is 16-bytes in length. The first three bytes contain</p>
|
|
<p>the string "FCS". The next byte contains the version of FCE Ultra that saved</p>
|
|
<p>this save state. This document only applies to version "53"(.53) and higher.</p>
|
|
<p>After the version byte, the size of the entire file in bytes(minus the 16 byte</p>
|
|
<p>main file header) is stored. If oldversion is set to 255, the 32-bit version</p>
|
|
<p>field will be used. In this field, a version such as 0.98.10 is stored as "9810"(decimal).</p>
|
|
<p>The rest of the header is currently unused and should be nulled out. </p>
|
|
<p>Example of relevant parts:</p>
|
|
<p><br></p>
|
|
<p> FCS <uint8 oldversion> <uint32 totalsize> <uint32 version></p>
|
|
<p><br></p>
|
|
<p>-- Section Chunks:</p>
|
|
<p><br></p>
|
|
<p>Sections chunk headers are 5-bytes in length. The first byte defines what </p>
|
|
<p>section it is, the next four bytes define the total size of the section</p>
|
|
<p>(including the section chunk header).</p>
|
|
<p><br></p>
|
|
<p> <uint8 section> <uint32 size></p>
|
|
<p><br></p>
|
|
<p>Section definitions:</p>
|
|
<p><br></p>
|
|
<p> 1 - "CPU"</p>
|
|
<p> 2 - "CPUC"</p>
|
|
<p> 3 - "PPU"</p>
|
|
<p> 4 - "CTLR"</p>
|
|
<p> 5 - "SND"</p>
|
|
<p> 16 - "EXTRA"</p>
|
|
<p><br></p>
|
|
<p>-- Subsection Chunks</p>
|
|
<p><br></p>
|
|
<p>Subsection chunks are stored within section chunks. They contain the actual</p>
|
|
<p>state data. Each subsection chunk is composed of an 8-byte header and the data.</p>
|
|
<p>The header contains a description(a name) and the size of the data contained </p>
|
|
<p>in the chunk:</p>
|
|
<p> <uint8 description[4]> <uint32 size></p>
|
|
<p><br></p>
|
|
<p>The name is a four-byte string. It does not need to be null-terminated.</p>
|
|
<p>If the string is less than four bytes in length, the remaining unused bytes</p>
|
|
<p>must be null.</p>
|
|
<p><br></p>
|
|
<p>-- Subsection Chunk Description Definitions</p>
|
|
<p><br></p>
|
|
<p>Note that not all subsection chunk description definitions listed below</p>
|
|
<p>are guaranteed to be in the section chunk. It's just a list of what CAN</p>
|
|
<p>be in a section chunk. This especially applies to the "EXTRA" subsection.</p>
|
|
<p><br></p>
|
|
<p>---- Section "CPU"</p>
|
|
<p><br></p>
|
|
<p> Name: Type: Description:</p>
|
|
<p> </p>
|
|
<p> PC uint16 Program Counter</p>
|
|
<p> A uint8 Accumulator</p>
|
|
<p> P uint8 Processor status register</p>
|
|
<p> X uint8 X register</p>
|
|
<p> Y uint8 Y register</p>
|
|
<p> S uint8 Stack pointer</p>
|
|
<p> RAM uint8[0x800] 2KB work RAM</p>
|
|
<p><br></p>
|
|
<p>---- Section "CPUC" (emulator specific)</p>
|
|
<p><br></p>
|
|
<p> Name: Type: Description:</p>
|
|
<p><br></p>
|
|
<p> JAMM uint8 Non-zero value if CPU in a "jammed" state</p>
|
|
<p> IRQL uint8 Non-zero value if IRQs are to be generated constantly</p>
|
|
<p> ICoa int32 Temporary cycle counter</p>
|
|
<p> ICou int32 Cycle counter</p>
|
|
<p><br></p>
|
|
<p>---- Section "PPU"</p>
|
|
<p><br></p>
|
|
<p> Name: Type: Description:</p>
|
|
<p><br></p>
|
|
<p> NTAR uint8[0x800] 2 KB of name/attribute table RAM</p>
|
|
<p> PRAM uint8[32] 32 bytes of palette index RAM</p>
|
|
<p> SPRA uint8[0x100] 256 bytes of sprite RAM</p>
|
|
<p> PPU uint8[4] Last values written to $2000 and $2001, the PPU</p>
|
|
<p> status register, and the last value written to</p>
|
|
<p> $2003.</p>
|
|
<p> XOFF uint8 Tile X-offset.</p>
|
|
<p> VTOG uint8 Toggle used by $2005 and $2006.</p>
|
|
<p> RADD uint16 PPU Address Register(address written to/read from</p>
|
|
<p> when $2007 is accessed).</p>
|
|
<p> TADD uint16 PPU Address Register</p>
|
|
<p> VBUF uint8 VRAM Read Buffer</p>
|
|
<p> PGEN uint8 PPU "general" latch. See Ki's document.</p>
|
|
<p><br></p>
|
|
<p>---- Section "CTLR" (somewhat emulator specific)</p>
|
|
<p><br></p>
|
|
<p> Name: Type: Description:</p>
|
|
<p><br></p>
|
|
<p> J1RB uint8 Bit to be returned when first joystick is read.</p>
|
|
<p> J2RB uint8 Bit to be returned when second joystick is read.</p>
|
|
<p><br></p>
|
|
<p>---- Section "SND" (somewhat emulator specific)</p>
|
|
<p><br></p>
|
|
<p> NREG uint16 Noise LFSR.</p>
|
|
<p> P17 uint8 Last byte written to $4017.</p>
|
|
<p> PBIN uint8 DMC bit index.</p>
|
|
<p> PAIN uint32 DMC address index(from $8000).</p>
|
|
<p> PSIN uint32 DMC length counter(how many bytes left </p>
|
|
<p> to fetch).</p>
|
|
<p><br></p>
|
|
<p> <to be finished></p>
|
|
<p><br></p>
|
|
<p>---- Section "EXTRA" (varying emulator specificness)</p>
|
|
<p><br></p>
|
|
<p> For iNES-format games(incomplete, and doesn't apply to every game):</p>
|
|
<p><br></p>
|
|
<p> Name: Type: Description:</p>
|
|
<p><br></p>
|
|
<p> WRAM uint8[0x2000] 8KB of WRAM at $6000-$7fff</p>
|
|
<p> MEXR uint8[0x8000] (very emulator specific)</p>
|
|
<p> CHRR uint8[0x2000] 8KB of CHR RAM at $0000-$1fff(in PPU address space).</p>
|
|
<p> EXNR uint8[0x800] Extra 2KB of name/attribute table RAM.</p>
|
|
<p> MPBY uint8[32] (very emulator specific)</p>
|
|
<p> MIRR uint8 Current mirroring:</p>
|
|
<p> 0 = "Horizontal"</p>
|
|
<p> 1 = "Vertical"</p>
|
|
<p> $10 = Mirror from $2000</p>
|
|
<p> $11 = Mirror from $2400</p>
|
|
<p> IRQC uint32 Generic IRQ counter</p>
|
|
<p> IQL1 uint32 Generic IRQ latch</p>
|
|
<p> IQL2 uint32 Generic IRQ latch</p>
|
|
<p> IRQA uint8 Generic IRQ on/off register.</p>
|
|
<p> PBL uint8[4] List of 4 8KB ROM banks paged in at $8000-$FFFF</p>
|
|
<p> CBL uint8[8] List of 8 1KB VROM banks page in at $0000-$1FFF(PPU).</p>
|
|
<p><br></p>
|
|
<p> For FDS games(incomplete):</p>
|
|
<p><br></p>
|
|
<p> Name: Type: Description:</p>
|
|
<p><br></p>
|
|
<p> DDT<x> uint8[65500] Disk data for side x(0-3).</p>
|
|
<p> FDSR uint8[0x8000] 32 KB of work RAM</p>
|
|
<p> CHRR uint8[0x2000] 8 KB of CHR RAM</p>
|
|
<p> IRQC uint32 IRQ counter</p>
|
|
<p> IQL1 uint32 IRQ latch</p>
|
|
<p> IRQA uint8 IRQ on/off.</p>
|
|
<p><br></p>
|
|
<p> WAVE uint8[64] Carrier waveform data.</p>
|
|
<p> MWAV uint8[32] Modulator waveform data.</p>
|
|
<p> AMPL uint8[2] Amplitude data.</p>
|
|
<p><br></p>
|
|
<p class=rvps3><span class=rvts11>2008</span></p>
|
|
<p class=rvps4><span class=rvts12>This help file has been generated by the freeware version of </span><a class=rvts13 href="http://www.ibe-software.com/products/software/helpndoc/" target="_blank">HelpNDoc</a></p>
|
|
|
|
</body></html>
|