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 "../NstDipSwitches.hpp" 27 #include "NstBoardBmc8157.hpp" 28 29 namespace Nes 30 { 31 namespace Core 32 { 33 namespace Boards 34 { 35 namespace Bmc 36 { 37 #ifdef NST_MSVC_OPTIMIZE 38 #pragma optimize("s", on) 39 #endif 40 CartSwitches()41 B8157::CartSwitches::CartSwitches() 42 : mode(0x100) {} 43 SetMode(uint value)44 inline void B8157::CartSwitches::SetMode(uint value) 45 { 46 mode = value ? 0x100 : 0x000; 47 } 48 GetMode() const49 inline uint B8157::CartSwitches::GetMode() const 50 { 51 return mode; 52 } 53 GetValue(uint) const54 uint B8157::CartSwitches::GetValue(uint) const 55 { 56 return mode ? 0 : 1; 57 } 58 SetValue(uint,uint value)59 void B8157::CartSwitches::SetValue(uint,uint value) 60 { 61 mode = value ? 0x000 : 0x100; 62 } 63 NumDips() const64 uint B8157::CartSwitches::NumDips() const 65 { 66 return 1; 67 } 68 NumValues(uint) const69 uint B8157::CartSwitches::NumValues(uint) const 70 { 71 return 2; 72 } 73 GetDipName(uint) const74 cstring B8157::CartSwitches::GetDipName(uint) const 75 { 76 return "Mode"; 77 } 78 GetValueName(uint,uint i) const79 cstring B8157::CartSwitches::GetValueName(uint,uint i) const 80 { 81 return i ? "20-in-1" : "4-in-1"; 82 } 83 QueryDevice(DeviceType type)84 B8157::Device B8157::QueryDevice(DeviceType type) 85 { 86 if (type == DEVICE_DIP_SWITCHES) 87 return &cartSwitches; 88 else 89 return Board::QueryDevice( type ); 90 } 91 SubReset(const bool hard)92 void B8157::SubReset(const bool hard) 93 { 94 Map( 0x8000U, 0xFFFFU, &B8157::Peek_8000, &B8157::Poke_8000 ); 95 96 trash = 0x00; 97 98 if (hard) 99 NES_DO_POKE(8000,0x8000,0x00); 100 } 101 SubLoad(State::Loader & state,const dword baseChunk)102 void B8157::SubLoad(State::Loader& state,const dword baseChunk) 103 { 104 NST_VERIFY( baseChunk == (AsciiId<'B','8','1'>::V) ); 105 106 if (baseChunk == AsciiId<'B','8','1'>::V) 107 { 108 while (const dword chunk = state.Begin()) 109 { 110 if (chunk == AsciiId<'R','E','G'>::V) 111 { 112 const uint data = state.Read8(); 113 trash = (data & 0x2) ? 0xFF : 0x00; 114 cartSwitches.SetMode( data & 0x1 ); 115 } 116 117 state.End(); 118 } 119 } 120 } 121 SubSave(State::Saver & state) const122 void B8157::SubSave(State::Saver& state) const 123 { 124 state.Begin( AsciiId<'B','8','1'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( (cartSwitches.GetMode() ? 0x1U : 0x0U) | (trash ? 0x2U : 0x0U) ).End().End(); 125 } 126 127 #ifdef NST_MSVC_OPTIMIZE 128 #pragma optimize("", on) 129 #endif 130 131 NES_PEEK_A(B8157,8000) 132 { 133 return prg.Peek( address - 0x8000 ) | trash; 134 } 135 136 NES_POKE_A(B8157,8000) 137 { 138 trash = (address & cartSwitches.GetMode()) ? 0xFF : 0x00; 139 140 prg.SwapBanks<SIZE_16K,0x0000> 141 ( 142 (address >> 2 & 0x18) | (address >> 2 & 0x7), 143 (address >> 2 & 0x18) | ((address & 0x200) ? 0x7 : 0x0) 144 ); 145 146 ppu.SetMirroring( (address & 0x2) ? Ppu::NMT_H : Ppu::NMT_V ); 147 } 148 } 149 } 150 } 151 } 152