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 "NstBoard.hpp" 26 #include "NstBoardMmc3.hpp" 27 #include "NstBoardSuperGamePocahontas2.hpp" 28 29 namespace Nes 30 { 31 namespace Core 32 { 33 namespace Boards 34 { 35 namespace SuperGame 36 { 37 #ifdef NST_MSVC_OPTIMIZE 38 #pragma optimize("s", on) 39 #endif 40 SubReset(const bool hard)41 void Pocahontas2::SubReset(const bool hard) 42 { 43 if (hard) 44 { 45 exRegs[0] = 0x00; 46 exRegs[1] = 0x00; 47 } 48 49 exRegs[2] = false; 50 51 Mmc3::SubReset( hard ); 52 53 Map( 0x5000U, &Pocahontas2::Poke_5000 ); 54 Map( 0x5001U, &Pocahontas2::Poke_5001 ); 55 Map( 0x8000U, 0x9FFFU, &Pocahontas2::Poke_8000 ); 56 Map( 0xA000U, 0xBFFFU, &Pocahontas2::Poke_A000 ); 57 Map( 0xC000U, 0xDFFFU, &Pocahontas2::Poke_C000 ); 58 Map( 0xE000U, 0xEFFFU, &Pocahontas2::Poke_E000 ); 59 Map( 0xF000U, 0xFFFFU, &Pocahontas2::Poke_F000 ); 60 } 61 SubLoad(State::Loader & state,const dword baseChunk)62 void Pocahontas2::SubLoad(State::Loader& state,const dword baseChunk) 63 { 64 if (baseChunk == AsciiId<'S','P','2'>::V) 65 { 66 while (const dword chunk = state.Begin()) 67 { 68 if (chunk == AsciiId<'R','E','G'>::V) 69 { 70 State::Loader::Data<3> data( state ); 71 72 exRegs[0] = data[0]; 73 exRegs[1] = data[1]; 74 exRegs[2] = data[2] & 0x1; 75 } 76 77 state.End(); 78 } 79 } 80 else 81 { 82 Mmc3::SubLoad( state, baseChunk ); 83 } 84 } 85 SubSave(State::Saver & state) const86 void Pocahontas2::SubSave(State::Saver& state) const 87 { 88 Mmc3::SubSave( state ); 89 90 const byte data[3] = 91 { 92 exRegs[0], 93 exRegs[1], 94 exRegs[2] 95 }; 96 97 state.Begin( AsciiId<'S','P','2'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write( data ).End().End(); 98 } 99 100 #ifdef NST_MSVC_OPTIMIZE 101 #pragma optimize("", on) 102 #endif 103 UpdatePrg(uint address,uint bank)104 void NST_FASTCALL Pocahontas2::UpdatePrg(uint address,uint bank) 105 { 106 if (!(exRegs[0] & 0x80)) 107 prg.SwapBank<SIZE_8K>( address, bank ); 108 } 109 UpdateChr(uint address,uint bank) const110 void NST_FASTCALL Pocahontas2::UpdateChr(uint address,uint bank) const 111 { 112 chr.SwapBank<SIZE_1K>( address, (exRegs[1] << 6 & 0x100) | bank ); 113 } 114 115 NES_POKE_D(Pocahontas2,5000) 116 { 117 if (exRegs[0] != data) 118 { 119 exRegs[0] = data; 120 121 if (exRegs[0] & 0x80) 122 { 123 const uint bank = exRegs[0] & 0xF; 124 125 if (exRegs[0] & 0x20) 126 prg.SwapBank<SIZE_32K,0x0000>( bank >> 1 ); 127 else 128 prg.SwapBanks<SIZE_16K,0x0000>( bank, bank ); 129 } 130 else 131 { 132 Mmc3::UpdatePrg(); 133 } 134 } 135 } 136 137 NES_POKE_D(Pocahontas2,5001) 138 { 139 if (exRegs[1] != data) 140 { 141 exRegs[1] = data; 142 Mmc3::UpdateChr(); 143 } 144 } 145 146 NES_POKE_D(Pocahontas2,8000) 147 { 148 SetMirroringHV( data >> 7 | data ); 149 } 150 NES_POKE_D(Pocahontas2,A000)151 NES_POKE_D(Pocahontas2,A000) 152 { 153 static const byte lut[8] = {0,2,6,1,7,3,4,5}; 154 155 data = (data & 0xC0) | lut[data & 0x07]; 156 exRegs[2] = true; 157 158 Mmc3::NES_DO_POKE(8000,0x8000,data); 159 } 160 NES_POKE_D(Pocahontas2,C000)161 NES_POKE_D(Pocahontas2,C000) 162 { 163 if (exRegs[2]) 164 { 165 exRegs[2] = false; 166 Mmc3::NES_DO_POKE(8001,0x8001,data); 167 } 168 } 169 NES_POKE_D(Pocahontas2,F000)170 NES_POKE_D(Pocahontas2,F000) 171 { 172 Mmc3::NES_DO_POKE(E001,0xE001,data); 173 Mmc3::NES_DO_POKE(C000,0xC000,data); 174 Mmc3::NES_DO_POKE(C001,0xC001,data); 175 } 176 } 177 } 178 } 179 } 180