1 
2 // NES state snapshot for saving and restoring emulator state
3 
4 // Nes_Emu 0.7.0
5 
6 #ifndef NES_STATE_H
7 #define NES_STATE_H
8 
9 #include "Nes_File.h"
10 #include "Nes_Cpu.h"
11 class Nes_Emu;
12 class Nes_State;
13 
14 typedef long frame_count_t;
15 
16 // Writes state to a file
17 class Nes_State_Writer : public Nes_File_Writer {
18 public:
19 	// Begin writing file
20 	const char * begin( Auto_File_Writer );
21 
22 	// Write emulator's current state to file and end
23 	const char * end( Nes_Emu const& );
24 
25 	// Write state to file and end
26 	const char * end( Nes_State const& );
27 };
28 
29 // Reads state from a file
30 class Nes_State_Reader : public Nes_File_Reader {
31 public:
32 
33 	// Begin reading state snapshot from file
34 	const char * begin( Auto_File_Reader, Nes_State* = 0 );
35 
36 	// Go to next unrecognized block in file
37 	const char * next_block();
38 
39 	// State as read from file. Only valid after all blocks have been read.
40 	Nes_State const& state() const;
41 
42 public:
43 	Nes_State_Reader();
44 	~Nes_State_Reader();
45 private:
46 	Nes_State* owned;
47 	Nes_State* state_;
48 };
49 
50 class Nes_State_ {
51 public:
52 
53 	const char * write_blocks( Nes_File_Writer& ) const;
54 	void set_nes_state( nes_state_t const& );
55 	const char * read_blocks( Nes_File_Reader& );
56 
57 	enum { ram_size = 0x800 };
58 	enum { sram_max = 0x2000 };
59 	enum { spr_ram_size = 0x100 };
60 	enum { nametable_max = 0x800 };
61 	enum { chr_max = 0x2000 };
62 	uint8_t *ram, *sram, *spr_ram, *nametable, *chr;
63 	nes_state_t             nes;
64 	Nes_Cpu::registers_t*   cpu;
65 	joypad_state_t*         joypad;
66 	apu_state_t*            apu;
67 	ppu_state_t*            ppu;
68 	mapper_state_t*         mapper;
69 
70 	bool nes_valid, cpu_valid, joypad_valid, apu_valid, ppu_valid;
71 	bool mapper_valid, ram_valid, spr_ram_valid;
72 	short sram_size, nametable_size, chr_size;
73 
74 	// Invalidate all state
75 	void clear();
76 
77 	// Change timestamp
78 	void set_timestamp( frame_count_t );
79 
80 	// Timestamp snapshot was taken at
81 	frame_count_t timestamp() const;
82 };
83 
84 // Snapshot of emulator state
85 class Nes_State : private Nes_State_ {
86 public:
87 
88 	Nes_State();
89 
90 	// Write snapshot to file
91 	const char * write( Auto_File_Writer ) const;
92 
93 	// Read snapshot from file
94 	const char * read( Auto_File_Reader );
95 
96 private:
97 	Nes_Cpu::registers_t    cpu;
98 	joypad_state_t          joypad;
99 	apu_state_t             apu;
100 	ppu_state_t             ppu;
101 	mapper_state_t          mapper;
102 	uint8_t ram [ram_size];
103 	uint8_t sram [sram_max];
104 	uint8_t spr_ram [spr_ram_size];
105 	uint8_t nametable [nametable_max];
106 	uint8_t chr [chr_max];
107 
108 	friend class Nes_Emu;
109 	friend class Nes_State_Writer;
110 	friend class Nes_State_Reader;
111 };
112 
113 frame_count_t const invalid_frame_count = LONG_MAX / 2 + 1; // a large positive value
114 
115 int mem_differs( void const* in, int compare, unsigned long count );
116 
state()117 inline Nes_State const& Nes_State_Reader::state() const
118 {
119 	return *state_;
120 }
121 
begin(Auto_File_Writer dw)122 inline const char * Nes_State_Writer::begin( Auto_File_Writer dw )
123 {
124 	return Nes_File_Writer::begin( dw, state_file_tag );
125 }
126 
set_timestamp(frame_count_t t)127 inline void Nes_State_::set_timestamp( frame_count_t t ) { nes.frame_count = t; }
128 
timestamp()129 inline frame_count_t Nes_State_::timestamp() const { return nes.frame_count; }
130 
131 #endif
132