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 "NstBoardBmcY2k64in1.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 
SubReset(bool)40 				void Y2k64in1::SubReset(bool)
41 				{
42 					Map( 0x5000U, 0x5003U, &Y2k64in1::Poke_5000 );
43 					Map( 0x8000U, 0xFFFFU, &Y2k64in1::Poke_8000 );
44 
45 					regs[0] = 0x80;
46 					regs[1] = 0x43;
47 					regs[2] = 0x00;
48 					regs[3] = 0x00;
49 
50 					Update();
51 				}
52 
SubLoad(State::Loader & state,const dword baseChunk)53 				void Y2k64in1::SubLoad(State::Loader& state,const dword baseChunk)
54 				{
55 					NST_VERIFY( baseChunk == (AsciiId<'B','Y','2'>::V) );
56 
57 					if (baseChunk == AsciiId<'B','Y','2'>::V)
58 					{
59 						while (const dword chunk = state.Begin())
60 						{
61 							if (chunk == AsciiId<'R','E','G'>::V)
62 								state.Read( regs );
63 
64 							state.End();
65 						}
66 					}
67 				}
68 
SubSave(State::Saver & state) const69 				void Y2k64in1::SubSave(State::Saver& state) const
70 				{
71 					state.Begin(AsciiId<'B','Y','2'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write( regs ).End().End();
72 				}
73 
74 				#ifdef NST_MSVC_OPTIMIZE
75 				#pragma optimize("", on)
76 				#endif
77 
Update()78 				void Y2k64in1::Update()
79 				{
80 					uint bank = regs[1] & 0x1FU;
81 
82 					if (regs[0] & 0x80U & regs[1])
83 					{
84 						prg.SwapBank<SIZE_32K,0x0000>( bank );
85 					}
86 					else
87 					{
88 						bank = (bank << 1) | (regs[1] >> 6 & 0x1U);
89 						prg.SwapBank<SIZE_16K,0x4000>( bank );
90 
91 						if (regs[0] & 0x80U)
92 							prg.SwapBank<SIZE_16K,0x0000>( bank );
93 					}
94 
95 					ppu.SetMirroring( (regs[0] & 0x20U) ? Ppu::NMT_H : Ppu::NMT_V );
96 					chr.SwapBank<SIZE_8K,0x0000>( (regs[2] << 2) | (regs[0] >> 1 & 0x3U) );
97 				}
98 
99 				NES_POKE_AD(Y2k64in1,5000)
100 				{
101 					regs[address & 0x3] = data;
102 					Update();
103 				}
104 
105 				NES_POKE_D(Y2k64in1,8000)
106 				{
107 					regs[3] = data;
108 					Update();
109 				}
110 			}
111 		}
112 	}
113 }
114