/[pcsx2_0.9.7]/trunk/pcsx2/SaveState.cpp
ViewVC logotype

Annotation of /trunk/pcsx2/SaveState.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 283 - (hide annotations) (download)
Thu Dec 23 12:39:52 2010 UTC (9 years, 2 months ago) by william
File size: 9363 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4132 local: v0.9.7.282-latest) in ./trunk
1 william 31 /* PCSX2 - PS2 Emulator for PCs
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16    
17     #include "PrecompiledHeader.h"
18     #include "IopCommon.h"
19     #include "SaveState.h"
20    
21     #include "ps2/BiosTools.h"
22     #include "COP0.h"
23 william 283 #include "VUmicro.h"
24 william 31 #include "Cache.h"
25     #include "AppConfig.h"
26    
27     #include "Elfheader.h"
28 william 62 #include "Counters.h"
29 william 31
30 william 62 #include "Utilities/SafeArray.inl"
31    
32 william 31 using namespace R5900;
33    
34    
35     static void PreLoadPrep()
36     {
37     SysClearExecutionCache();
38     }
39    
40     static void PostLoadPrep()
41     {
42     memzero(pCache);
43     // WriteCP0Status(cpuRegs.CP0.n.Status.val);
44     for(int i=0; i<48; i++) MapTLB(i);
45 william 62
46     UpdateVSyncRate();
47 william 31 }
48    
49 william 283 // --------------------------------------------------------------------------------------
50     // SaveStateBase (implementations)
51     // --------------------------------------------------------------------------------------
52 william 31 wxString SaveStateBase::GetFilename( int slot )
53     {
54 william 283 wxString serialName( DiscSerial );
55     if (serialName.IsEmpty()) serialName = L"BIOS";
56    
57 william 31 return (g_Conf->Folders.Savestates +
58 william 283 pxsFmt( L"%s (%08X).%02d.p2s", serialName.c_str(), ElfCRC, slot )).GetFullPath();
59    
60     //return (g_Conf->Folders.Savestates +
61     // pxsFmt( L"%08X.%03d", ElfCRC, slot )).GetFullPath();
62 william 31 }
63    
64     SaveStateBase::SaveStateBase( SafeArray<u8>& memblock )
65     {
66     Init( &memblock );
67     }
68    
69     SaveStateBase::SaveStateBase( SafeArray<u8>* memblock )
70     {
71     Init( memblock );
72     }
73    
74     void SaveStateBase::Init( SafeArray<u8>* memblock )
75     {
76     m_memory = memblock;
77     m_version = g_SaveVersion;
78     m_idx = 0;
79     m_DidBios = false;
80     }
81    
82     void SaveStateBase::PrepBlock( int size )
83     {
84     pxAssumeDev( m_memory, "Savestate memory/buffer pointer is null!" );
85    
86     const int end = m_idx+size;
87     if( IsSaving() )
88     m_memory->MakeRoomFor( end );
89     else
90     {
91     if( m_memory->GetSizeInBytes() < end )
92     throw Exception::SaveStateLoadError();
93     }
94     }
95    
96     void SaveStateBase::FreezeTag( const char* src )
97     {
98     const uint allowedlen = sizeof( m_tagspace )-1;
99 william 283 pxAssertDev( strlen(src) < allowedlen, pxsFmt( L"Tag name exceeds the allowed length of %d chars.", allowedlen) );
100 william 31
101     memzero( m_tagspace );
102     strcpy( m_tagspace, src );
103     Freeze( m_tagspace );
104    
105     if( strcmp( m_tagspace, src ) != 0 )
106     {
107 william 62 wxString msg( L"Savestate data corruption detected while reading tag: " + fromUTF8(src) );
108     pxFail( msg );
109     throw Exception::SaveStateLoadError().SetDiagMsg(msg);
110 william 31 }
111     }
112    
113 william 283 SaveStateBase& SaveStateBase::FreezeBios()
114 william 31 {
115 william 283 FreezeTag( "BIOS" );
116    
117 william 31 // Check the BIOS, and issue a warning if the bios for this state
118     // doesn't match the bios currently being used (chances are it'll still
119     // work fine, but some games are very picky).
120 william 283
121     u32 bioscheck = BiosChecksum;
122     char biosdesc[256];
123 william 31
124 william 283 pxToUTF8 utf8(BiosDescription);
125 william 31
126 william 283 memzero( biosdesc );
127     memcpy_fast( biosdesc, utf8, std::min( sizeof(biosdesc), utf8.Length() ) );
128    
129     Freeze( bioscheck );
130     Freeze( biosdesc );
131 william 31
132 william 283 if (bioscheck != BiosChecksum)
133 william 31 {
134 william 283 Console.Newline();
135     Console.Indent(1).Error( "Warning: BIOS Version Mismatch, savestate may be unstable!" );
136     Console.Indent(2).Error(
137     "Current BIOS: %ls (crc=0x%08x)\n"
138     "Savestate BIOS: %s (crc=0x%08x)\n",
139     BiosDescription.c_str(), BiosChecksum,
140     biosdesc, bioscheck
141     );
142 william 31 }
143 william 283
144     return *this;
145 william 31 }
146    
147 william 283 static const uint MainMemorySizeInBytes =
148     Ps2MemSize::MainRam + Ps2MemSize::Scratch + Ps2MemSize::Hardware +
149     Ps2MemSize::IopRam + Ps2MemSize::IopHardware;
150 william 31
151 william 283 SaveStateBase& SaveStateBase::FreezeMainMemory()
152 william 31 {
153 william 283 if (IsLoading())
154 william 31 PreLoadPrep();
155 william 283 else
156     m_memory->MakeRoomFor( m_idx + MainMemorySizeInBytes );
157 william 31
158     // First Block - Memory Dumps
159     // ---------------------------
160 william 280 FreezeMem(eeMem->Main, Ps2MemSize::MainRam); // 32 MB main memory
161 william 283 FreezeMem(eeMem->Scratch, Ps2MemSize::Scratch); // scratch pad
162     FreezeMem(eeHw, Ps2MemSize::Hardware); // hardware memory
163 william 31
164 william 283 FreezeMem(iopMem->Main, Ps2MemSize::IopRam); // 2 MB main memory
165     FreezeMem(iopHw, Ps2MemSize::IopHardware); // hardware memory
166    
167     FreezeMem(vuRegs[0].Micro, VU0_PROGSIZE);
168     FreezeMem(vuRegs[0].Mem, VU0_MEMSIZE);
169    
170     FreezeMem(vuRegs[1].Micro, VU1_PROGSIZE);
171     FreezeMem(vuRegs[1].Mem, VU1_MEMSIZE);
172    
173     return *this;
174 william 31 }
175    
176 william 283 SaveStateBase& SaveStateBase::FreezeInternals()
177 william 31 {
178     if( IsLoading() )
179     PreLoadPrep();
180    
181     // Second Block - Various CPU Registers and States
182     // -----------------------------------------------
183     FreezeTag( "cpuRegs" );
184     Freeze(cpuRegs); // cpu regs + COP0
185     Freeze(psxRegs); // iop regs
186     Freeze(fpuRegs);
187     Freeze(tlb); // tlbs
188    
189     // Third Block - Cycle Timers and Events
190     // -------------------------------------
191     FreezeTag( "Cycles" );
192     Freeze(EEsCycle);
193     Freeze(EEoCycle);
194 william 62 Freeze(g_nextEventCycle);
195     Freeze(g_iopNextEventCycle);
196 william 31 Freeze(s_iLastCOP0Cycle);
197     Freeze(s_iLastPERFCycle);
198    
199     // Fourth Block - EE-related systems
200     // ---------------------------------
201     FreezeTag( "EE-Subsystems" );
202     rcntFreeze();
203     gsFreeze();
204     vuMicroFreeze();
205     vif0Freeze();
206     vif1Freeze();
207     sifFreeze();
208     ipuFreeze();
209 william 62 ipuDmaFreeze();
210 william 31 gifFreeze();
211     sprFreeze();
212    
213     // Fifth Block - iop-related systems
214     // ---------------------------------
215     FreezeTag( "IOP-Subsystems" );
216 william 283 FreezeMem(iopMem->Sif, sizeof(iopMem->Sif)); // iop's sif memory (not really needed, but oh well)
217    
218 william 31 #ifdef ENABLE_NEW_IOPDMA
219     iopDmacFreeze();
220     #endif
221     psxRcntFreeze();
222     sioFreeze();
223     sio2Freeze();
224     cdrFreeze();
225     cdvdFreeze();
226    
227     // technically this is HLE BIOS territory, but we don't have enough such stuff
228     // to merit an HLE Bios sub-section... yet.
229     deci2Freeze();
230    
231     if( IsLoading() )
232     PostLoadPrep();
233 william 283
234     return *this;
235 william 31 }
236    
237 william 283 SaveStateBase& SaveStateBase::FreezePlugins()
238 william 31 {
239 william 283 for (uint i=0; i<PluginId_Count; ++i)
240 william 31 {
241 william 283 FreezeTag( FastFormatAscii().Write("Plugin:%s", tbl_PluginInfo[i].shortname) );
242     GetCorePlugins().Freeze( (PluginsEnum_t)i, *this );
243 william 31 }
244 william 283
245     return *this;
246 william 31 }
247    
248 william 283 SaveStateBase& SaveStateBase::FreezeAll()
249 william 31 {
250 william 283 FreezeMainMemory();
251     FreezeBios();
252     FreezeInternals();
253     FreezePlugins();
254    
255     return *this;
256 william 31 }
257    
258    
259 william 283 // --------------------------------------------------------------------------------------
260     // memSavingState (implementations)
261     // --------------------------------------------------------------------------------------
262 william 31 // uncompressed to/from memory state saves implementation
263    
264     memSavingState::memSavingState( SafeArray<u8>& save_to )
265     : SaveStateBase( save_to )
266     {
267     }
268    
269     memSavingState::memSavingState( SafeArray<u8>* save_to )
270     : SaveStateBase( save_to )
271     {
272     }
273    
274     // Saving of state data
275     void memSavingState::FreezeMem( void* data, int size )
276     {
277 william 283 if (!size) return;
278    
279     m_memory->MakeRoomFor( m_idx + size );
280 william 31 memcpy_fast( m_memory->GetPtr(m_idx), data, size );
281     m_idx += size;
282     }
283    
284 william 283 void memSavingState::MakeRoomForData()
285 william 31 {
286     pxAssumeDev( m_memory, "Savestate memory/buffer pointer is null!" );
287    
288     m_memory->ChunkSize = ReallocThreshold;
289 william 283 m_memory->MakeRoomFor( m_idx + MemoryBaseAllocSize );
290     }
291 william 31
292 william 283 // Saving of state data to a memory buffer
293     memSavingState& memSavingState::FreezeAll()
294     {
295     MakeRoomForData();
296 william 31 _parent::FreezeAll();
297 william 283 return *this;
298 william 31 }
299    
300 william 283 // --------------------------------------------------------------------------------------
301     // memLoadingState (implementations)
302     // --------------------------------------------------------------------------------------
303 william 31 memLoadingState::memLoadingState( const SafeArray<u8>& load_from )
304     : SaveStateBase( const_cast<SafeArray<u8>&>(load_from) )
305     {
306     }
307    
308     memLoadingState::memLoadingState( const SafeArray<u8>* load_from )
309     : SaveStateBase( const_cast<SafeArray<u8>*>(load_from) )
310     {
311     }
312    
313     memLoadingState::~memLoadingState() throw() { }
314    
315 william 283 // Loading of state data from a memory buffer...
316 william 31 void memLoadingState::FreezeMem( void* data, int size )
317     {
318     const u8* const src = m_memory->GetPtr(m_idx);
319     m_idx += size;
320     memcpy_fast( data, src, size );
321     }
322    
323     // --------------------------------------------------------------------------------------
324     // SaveState Exception Messages
325     // --------------------------------------------------------------------------------------
326    
327     wxString Exception::UnsupportedStateVersion::FormatDiagnosticMessage() const
328     {
329     // Note: no stacktrace needed for this one...
330 william 283 return pxsFmt( L"Unknown or unsupported savestate version: 0x%x", Version );
331 william 31 }
332    
333     wxString Exception::UnsupportedStateVersion::FormatDisplayMessage() const
334     {
335     // m_message_user contains a recoverable savestate error which is helpful to the user.
336 william 283 return
337 william 31 m_message_user + L"\n\n" +
338 william 283 pxsFmt( _("Cannot load savestate. It is of an unknown or unsupported version."), Version );
339 william 31 }
340    
341     wxString Exception::StateCrcMismatch::FormatDiagnosticMessage() const
342     {
343     // Note: no stacktrace needed for this one...
344 william 283 return pxsFmt(
345 william 31 L"Game/CDVD does not match the savestate CRC.\n"
346     L"\tCdvd CRC: 0x%X\n\tGame CRC: 0x%X\n",
347     Crc_Savestate, Crc_Cdvd
348     );
349     }
350    
351     wxString Exception::StateCrcMismatch::FormatDisplayMessage() const
352     {
353 william 283 return
354 william 31 m_message_user + L"\n\n" +
355 william 283 pxsFmt(
356 william 31 L"Savestate game/crc mismatch. Cdvd CRC: 0x%X Game CRC: 0x%X\n",
357     Crc_Savestate, Crc_Cdvd
358 william 283 );
359 william 31 }

  ViewVC Help
Powered by ViewVC 1.1.22