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 "NstBoardBmcGoldenGame260in1.hpp" 27 28 namespace Nes 29 { 30 namespace Core 31 { 32 namespace Boards 33 { 34 namespace Bmc 35 { 36 #ifdef NST_MSVC_OPTIMIZE 37 #pragma optimize("s", on) 38 #endif 39 GoldenGame260in1(const Context & c)40 GoldenGame260in1::GoldenGame260in1(const Context& c) 41 : 42 Board (c), 43 selector 44 ( 45 prg.Source().Size() == SIZE_1024K ? 0 : 46 prg.Source().Size() == SIZE_2048K ? 1 : 47 prg.Source().Size() == SIZE_3072K ? 2 : 3 48 ) 49 { 50 } 51 SubReset(const bool hard)52 void GoldenGame260in1::SubReset(const bool hard) 53 { 54 Map( 0x8000U, 0xFFFFU, &GoldenGame260in1::Poke_8000 ); 55 56 if (selector != 3) 57 Map( 0x8000U, 0xFFFFU, &GoldenGame260in1::Peek_8000 ); 58 59 if (hard) 60 { 61 open = false; 62 NES_DO_POKE(8000,0x8000,0x00); 63 } 64 } 65 SubLoad(State::Loader & state,const dword baseChunk)66 void GoldenGame260in1::SubLoad(State::Loader& state,const dword baseChunk) 67 { 68 if (selector != 3) 69 { 70 NST_VERIFY( baseChunk == (AsciiId<'B','G','G'>::V) ); 71 72 if (baseChunk == AsciiId<'B','G','G'>::V) 73 { 74 while (const dword chunk = state.Begin()) 75 { 76 if (chunk == AsciiId<'B','U','S'>::V) 77 open = state.Read8() & 0x1; 78 79 state.End(); 80 } 81 } 82 } 83 } 84 SubSave(State::Saver & state) const85 void GoldenGame260in1::SubSave(State::Saver& state) const 86 { 87 if (selector != 3) 88 state.Begin( AsciiId<'B','G','G'>::V ).Begin( AsciiId<'B','U','S'>::V ).Write8( open != 0 ).End().End(); 89 } 90 91 #ifdef NST_MSVC_OPTIMIZE 92 #pragma optimize("", on) 93 #endif 94 95 NES_POKE_A(GoldenGame260in1,8000) 96 { 97 ppu.SetMirroring 98 ( 99 (address & 0x0400) ? Ppu::NMT_0 : 100 (address & 0x2000) ? Ppu::NMT_H : 101 Ppu::NMT_V 102 ); 103 104 static const byte slots[4][4][2] = 105 { 106 { {0x00,0}, {0x00,1}, {0x00,1}, {0x00,1} }, 107 { {0x00,0}, {0x00,1}, {0x20,0}, {0x00,1} }, 108 { {0x00,0}, {0x00,1}, {0x20,0}, {0x40,0} }, 109 { {0x00,0}, {0x20,0}, {0x40,0}, {0x60,0} } 110 }; 111 112 uint bank = slots[selector][address >> 8 & 0x3][0] | (address & 0x1F); 113 open = slots[selector][address >> 8 & 0x3][1]; 114 115 if (address & 0x800) 116 { 117 bank = (bank << 1) | (address >> 12 & 0x1); 118 prg.SwapBanks<SIZE_16K,0x0000>( bank, bank ); 119 } 120 else 121 { 122 prg.SwapBank<SIZE_32K,0x0000>( bank ); 123 } 124 } 125 126 NES_PEEK_A(GoldenGame260in1,8000) 127 { 128 return !open ? prg.Peek(address - 0x8000) : (address >> 8); 129 } 130 } 131 } 132 } 133 } 134