1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // Nestopia - NES/Famicom emulator written in C++ 4 // 5 // Copyright (C) 2003-2008 Martin Freij 6 // 7 // This file is part of Nestopia. 8 // 9 // Nestopia is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Nestopia is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Nestopia; if not, write to the Free Software 21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 // 23 //////////////////////////////////////////////////////////////////////////////////////// 24 25 #include "NstState.hpp" 26 #include "NstMemory.hpp" 27 28 namespace Nes 29 { 30 namespace Core 31 { 32 #ifdef NST_MSVC_OPTIMIZE 33 #pragma optimize("s", on) 34 #endif 35 SaveState(State::Saver & state,const dword baseChunk,const Ram * const NST_RESTRICT sources,const uint numSources,const byte * const NST_RESTRICT pages,const uint numPages) const36 void Memory<0,0,0>::SaveState 37 ( 38 State::Saver& state, 39 const dword baseChunk, 40 const Ram* const NST_RESTRICT sources, 41 const uint numSources, 42 const byte* const NST_RESTRICT pages, 43 const uint numPages 44 ) const 45 { 46 NST_ASSERT( numSources >= 1 && numSources <= MAX_SOURCES && numPages ); 47 48 state.Begin( baseChunk ); 49 50 { 51 byte data[MAX_SOURCES]; 52 53 for (uint i=0; i < numSources; ++i) 54 data[i] = (sources[i].Readable() ? 0x1U : 0x0U) | (sources[i].Writable() ? 0x2U : 0x0U); 55 56 state.Begin( AsciiId<'A','C','C'>::V ).Write( data, numSources ).End(); 57 } 58 59 state.Begin( AsciiId<'B','N','K'>::V ).Write( pages, numPages * 3 ).End(); 60 61 state.End(); 62 } 63 LoadState(State::Loader & state,Ram * const NST_RESTRICT sources,const uint numSources,byte * const NST_RESTRICT pages,const uint numPages) const64 bool Memory<0,0,0>::LoadState 65 ( 66 State::Loader& state, 67 Ram* const NST_RESTRICT sources, 68 const uint numSources, 69 byte* const NST_RESTRICT pages, 70 const uint numPages 71 ) const 72 { 73 NST_ASSERT( numSources >= 1 && numSources <= MAX_SOURCES && numPages ); 74 75 bool paged = false; 76 77 while (const dword chunk = state.Begin()) 78 { 79 switch (chunk) 80 { 81 case AsciiId<'A','C','C'>::V: 82 { 83 byte data[MAX_SOURCES]; 84 state.Read( data, numSources ); 85 86 for (uint i=0; i < numSources; ++i) 87 { 88 sources[i].ReadEnable( data[i] & 0x1U ); 89 90 NST_VERIFY( sources[i].GetType() != Ram::ROM || !(data[i] & 0x2U) ); 91 92 if (sources[i].GetType() != Ram::ROM) 93 sources[i].WriteEnable( data[i] & 0x2U ); 94 } 95 break; 96 } 97 98 case AsciiId<'B','N','K'>::V: 99 100 paged = true; 101 state.Read( pages, numPages * 3 ); 102 break; 103 104 default: 105 106 // deprecated 107 108 for (uint i=0; i < numSources; ++i) 109 { 110 if (chunk == AsciiId<'R','M','0'>::R(0,0,i)) 111 { 112 NST_DEBUG_MSG("Memory::LoadState() deprecated!"); 113 state.Uncompress( sources[i].Mem(), sources[i].Size() ); 114 break; 115 } 116 } 117 break; 118 } 119 120 state.End(); 121 } 122 123 return paged; 124 } 125 126 #ifdef NST_MSVC_OPTIMIZE 127 #pragma optimize("", on) 128 #endif 129 } 130 } 131