Nintendulator Save State Format
 Updated:  February 25, 2022
---------------------------------------

For simplicity, savestates should only be saved during VBLANK; otherwise,
the entire video buffer would have to be saved.

Current implementation only saves states during scanline 240.

All multiple-byte variables are stored LSB-first (little endian).

Data types:
	char[N]  - plain text
	(u)int8  - (un)signed 8 bit variable
	(u)int16 - (un)signed 16 bit variable
	(u)int32 - (un)signed 32 bit variable

-- Filename:
	<ROM Filename, extension stripped>.NS# for savestates
	<ROM Filename, extension stripped>.NMV for movies

-- Main File Header:

	Identification	- <char[4] = "NSS",0x1A>
	Version		- <char[4], see below>
	Filesize	- <uint32 = filesize, not including this header>
	Type		- <char[4] = "NSAV" for normal savestate, "NREC"
			   for movie savestate, "NMOV" for finished movie>

For versions prior to 0.980, the version was a 4-character ASCII number:

	"0950" - 0.950
	"0955" - 0.955 Beta
	"0960" - 0.960
	"0965" - 0.965 Beta
	"0970" - 0.970
	"0975" - 0.975 Beta

Subsequent versions will start at "1001" and count upward each time the
actual data format changes. The current version is "1004".

Each field is listed with the first and last version which contains it.

-- Section blocks:

Section block headers are 8 bytes in length.  The first DWORD defines what
section it is, the second DWORD defines the total size of the section (not
including the header).

	<char[4] section> <uint32 size>

---- Section "CPUS" - CPU State - Required

Version		Type		Description

0950-		uint8		Program Counter, low byte
0950-		uint8		Program Counter, high byte
0950-		uint8		Accumulator
0950-		uint8		X register
0950-		uint8		Y register
0950-		uint8		Stack pointer
0950-		uint8		Processor status register
0950-		uint8		Last contents of data bus
0950-		uint8		TRUE if falling edge detected on /NMI
0950-		uint8		IRQ flags - D0=FRAME, D1=DPCM, D2=EXTERNAL, D3=DEBUG
				(FRAME/DPCM are also stored in block "APUS")
0950-		uint8[0x800]	2KB system RAM

---- Section "PPUS" - PPU State - Required

Version		Type		Description

0950-		uint8[0x1000]	4 KB of name/attribute table RAM
0950-		uint8[0x100]	256 bytes of sprite RAM
0950-		uint8[0x20]	32 bytes of palette index RAM
0950-		uint8		Last value written to $2000
0950-		uint8		Last value written to $2001
0950-		uint8		Current contents of $2002
0950-		uint8		SPR-RAM Address ($2003)

0950-		uint8		Tile X-offset.
0950-		uint8		Toggle used by $2005 and $2006.
0950-		uint16		VRAM Address
0950-		uint16		VRAM Address Latch
0950-		uint8		VRAM Read Buffer
0950-		uint8		PPU I/O bus last contents

0950-0955	uint16		Clock Ticks (0..340)
0960-		uint16		Clock Ticks (0..340) and PAL sub-cycles (upper 4 bits)
0950-		uint16		Scanline number
0950-		uint8		Short frame (first scanline 1 tick shorter, NTSC only)

0950-0975	uint16		External I/O Address
0950-		uint8		External I/O Value
0950-		uint8		External I/O Counter (6/4/2 for read, 5/3/1 for write)

0950-0970	uint8		0 for NTSC, 1 for PAL
0975-		uint8		0 for NTSC, 1 for PAL, 2 for Dendy

---- Section "APUS" - APU State - Required

Version		Type		Description

0950-		uint8		Last value written to $4015, lower 4 bits

0950-		uint8		Last value written to $4001
0950-		uint16		Square0 frequency
0950-		uint8		Square0 timer
0950-		uint8		Square0 duty cycle pointer
0950-		uint8		Boolean, Square0 envelope(D1)/sweep(D0) reload requests
0950-		uint8		Square0 envelope counter
0950-		uint8		Square0 envelope value
0950-		uint8		Square0 bend counter
0950-1003	uint16		Square0 CPU cycles
1004-		uint16		Square0 APU cycles
0950-		uint8		Last value written to $4000

0950-		uint8		Last value written to $4005
0950-		uint16		Square1 frequency
0950-		uint8		Square1 timer
0950-		uint8		Square1 duty cycle pointer
0950-		uint8		Boolean, Square1 envelope(D1)/sweep(D0) reload requests
0950-		uint8		Square1 envelope counter
0950-		uint8		Square1 envelope value
0950-		uint8		Square1 bend counter
0950-1003	uint16		Square1 CPU cycles
1004-		uint16		Square1 APU cycles
0950-		uint8		Last value written to $4004

0950-		uint16		Triangle frequency
0950-		uint8		Triangle timer
0950-		uint8		Triangle duty cycle pointer
0950-		uint8		Boolean, linear counter reload request
0950-		uint8		Triangle linear counter
0950-		uint16		Triangle CPU cycles
0950-		uint8		Last value written to $4008

0950-		uint8		Last value written to $400E
0950-		uint8		Noise timer
0950-		uint16		Noise duty cycle pointer
0950-		uint8		Boolean, Noise envelope reload request
0950-		uint8		Noise envelope counter
0950-		uint8		Noise envelope value
0950-1003	uint16		Noise CPU cycles
1004-		uint16		Noise APU cycles
0950-		uint8		Last value written to $400C

0950-		uint8		Last value written to $4010
0950-		uint8		Last value written to $4011
0950-		uint8		Last value written to $4012
0950-		uint8		Last value written to $4013
0950-		uint16		DPCM current address
0950-		uint16		DPCM current length
0950-		uint8		DPCM shift register
0950-0970	uint8		DPCM output mode(D1)/buffer full(D0)
0975-1003	uint8		DPCM fetching(D2)/!silenced(D1)/!empty(D0)
1004-		uint8		DPCM incrementing(D4)/resetting(D3)/fetching(D2)/!silenced(D1)/!empty(D0)
0950-		uint8		DPCM shift count
0950-		uint8		DPCM read buffer
0950-1003	uint16		DPCM CPU cycles
1004-		uint16		DPCM APU cycles
0950-		uint16		DPCM length counter

0950-		uint8		Last value written to $4017
0950-1003	uint16		Frame counter CPU cycles
1004-		uint16		Frame counter APU cycles
0950-0975	uint8		Frame counter phase
1004-		uint8		Frame counter Zero(D3)/IRQ(D2)/Half(D1)/Quarter(D0) pending

0950-		uint8		APU-related IRQs (PCM and FRAME, as-is)
1004-		uint8		APU clock, lower 8 bits (for phase)

---- Section "CTRL" - Controller Data - OBSOLETE, dropped in version 0970

Version		Type		Description

0950-0965	uint32		Four-Score port 1 controller type
0950-0965	uint32		Four-Score port 1 controller type
0950-0965	uint32		Four-Score port 1 controller type
0950-0965	uint32		Four-Score port 1 controller type
0950-0965	uint32		Controller port 1 controller type
0950-0965	uint32		Controller port 2 controller type (ignored if Port 1 type is STD_FOURSCORE)
0950-0965	uint32		Expansion port controller type

0950-0965	uint8[...]	Controller port 1 state data
0950-0965	uint8[...]	Controller port 2 state data
0950-0965	uint8[...]	Four-Score port 1 state data
0950-0965	uint8[...]	Four-Score port 2 state data
0950-0965	uint8[...]	Four-Score port 3 state data
0950-0965	uint8[...]	Four-Score port 4 state data
0950-0965	uint8[...]	Expansion port state data

---- Section "CONT" - Controller Data - Optional, added in version 0970

Version		Type		Description

0970-		uint8		Controller port 1 controller type
0970-1001	uint16		Controller port 1 state data length
0970-		uint8[...]	Controller port 1 state data

0970-		uint8		Controller port 2 controller type (ignored if Port 1 type is STD_FOURSCORE)
0970-1001	uint16		Controller port 2 state data length
0970-		uint8[...]	Controller port 2 state data

0970-		uint8		Expansion port controller type
0970-1001	uint16		Expansion port state data length
0970-		uint8[...]	Expansion port state data

0970-		uint8		Four-Score port 1 controller type
0970-1001	uint16		Four-Score port 1 state data length
0970-		uint8[...]	Four-Score port 1 state data

0970-		uint8		Four-Score port 2 controller type
0970-1001	uint16		Four-Score port 2 state data length
0970-		uint8[...]	Four-Score port 2 state data

0970-		uint8		Four-Score port 3 controller type
0970-1001	uint16		Four-Score port 3 state data length
0970-		uint8[...]	Four-Score port 3 state data

0970-		uint8		Four-Score port 4 controller type
0970-1001	uint16		Four-Score port 4 state data length
0970-		uint8[...]	Four-Score port 4 state data

---- Section "NPRA" - NES PRG RAM State - Optional

Version		Type		Description

0950-		uint8[...]	PRG_RAM data

---- Section "NCRA" - NES CHR RAM State - Optional

Version		Type		Description

0950-		uint8[...]	CHR_RAM data

---- Section "MAPR" - Mapper State - Optional

Version		Type		Description

0950-1002	uint8[...]	Custom mapper data without version tags
1003-		uint8[...]	Custom mapper data with version tags

---- Section "GENI" - Game Genie State - Optional

Version		Type		Description

0950-		uint8		1 if Game Genie codes are currently active, 0 if not
0950-		uint8		Game Genie code status (value written to $8000, XORed with 0x7E)

0950-		uint16		Address for code #1
0950-		uint8		Original value for code #1
0950-		uint8		New value for code #1	

0950-		uint16		Address for code #2
0950-		uint8		Original value for code #2
0950-		uint8		New value for code #2	

0950-		uint16		Address for code #3
0950-		uint8		Original value for code #3
0950-		uint8		New value for code #3	

---- Section "DISK" - Mapper State - Optional, only allowed for Famicom Disk System games

Version		Type		Description

0950-		uint32		Number of modified disk bytes
0950-		uint32[...]	Modified disk bytes: modified data in upper 8 bits, disk offset in lower 16 bits, disk number in remaining 8 bits
				(data << 24) | (disknum << 16) | (offset)

---- Section "NMOV" - Movie Data - Not allowed in NSAV, required in NREC/NMOV
							(must be LAST block)

Version		Type		Description

0950-		uint8		Controller present in port 0
0950-		uint8		If CTRL0 == STD_FOURSCORE, bitmask indicating
				which subcontrollers are used
				else, Controller present in port 1
0950-		uint8		Controller present in expansion port

0950-		uint8		Frame size in bytes + 0x00 for NTSC, 0x80 for PAL + 0x40 if Game Genie is active

0950-		uint32		Number of re-records used

0950-		uint32		Length of info field
0950-		char[...]	Description of the movie, null-terminated (UTF-8)

0950-		uint32		Length of movie data
0950-		uint8[...]	Movie data

-- EOF