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 "NstBoardNamcot34xx.hpp"
27 
28 namespace Nes
29 {
30 	namespace Core
31 	{
32 		namespace Boards
33 		{
34 			namespace Namcot
35 			{
36 				#ifdef NST_MSVC_OPTIMIZE
37 				#pragma optimize("s", on)
38 				#endif
39 
SubReset(const bool hard)40 				void N34x3::SubReset(const bool hard)
41 				{
42 					if (hard)
43 						ctrl = 0;
44 
45 					for (uint i=0x8000; i < 0xA000; i += 0x2)
46 					{
47 						Map( i + 0x0, &N34x3::Poke_8000 );
48 						Map( i + 0x1, &N34x3::Poke_8001 );
49 					}
50 				}
51 
SubReset(const bool hard)52 				void N34xx::SubReset(const bool hard)
53 				{
54 					N34x3::SubReset( hard );
55 
56 					for (uint i=0x0000; i < 0x8000; i += 0x2)
57 						Map( 0x8000 + i, &N34xx::Poke_8000 );
58 				}
59 
SubLoad(State::Loader & state,const dword baseChunk)60 				void N34x3::SubLoad(State::Loader& state,const dword baseChunk)
61 				{
62 					NST_VERIFY( baseChunk == (AsciiId<'N','3','4'>::V) );
63 
64 					if (baseChunk == AsciiId<'N','3','4'>::V)
65 					{
66 						while (const dword chunk = state.Begin())
67 						{
68 							if (chunk == AsciiId<'R','E','G'>::V)
69 								ctrl = state.Read8();
70 
71 							state.End();
72 						}
73 					}
74 				}
75 
SubSave(State::Saver & state) const76 				void N34x3::SubSave(State::Saver& state) const
77 				{
78 					state.Begin( AsciiId<'N','3','4'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( ctrl ).End().End();
79 				}
80 
81 				#ifdef NST_MSVC_OPTIMIZE
82 				#pragma optimize("", on)
83 				#endif
84 
85 				NES_POKE_D(N34x3,8000)
86 				{
87 					ctrl = data;
88 				}
89 
90 				NES_POKE_D(N34x3,8001)
91 				{
92 					const uint mode = ctrl & 0x7;
93 
94 					if (mode >= 6)
95 					{
96 						prg.SwapBank<SIZE_8K>( (mode-6) << 13, data );
97 					}
98 					else
99 					{
100 						ppu.Update();
101 						UpdateChr( mode, data & 0x3F );
102 					}
103 				}
104 
UpdateChr(uint mode,uint data) const105 				void NST_FASTCALL N34x3::UpdateChr(uint mode,uint data) const
106 				{
107 					if (mode >= 2)
108 						chr.SwapBank<SIZE_1K>( (mode+2) << 10, data | 0x40 );
109 					else
110 						chr.SwapBank<SIZE_2K>( mode << 11, data >> 1 );
111 				}
112 
UpdateChr(uint mode,uint data) const113 				void NST_FASTCALL N3446::UpdateChr(uint mode,uint data) const
114 				{
115 					NST_VERIFY( mode >= 2 );
116 
117 					if (mode >= 2)
118 						chr.SwapBank<SIZE_2K>( (mode-2) << 11, data );
119 				}
120 
UpdateChr(uint mode,uint data) const121 				void NST_FASTCALL N3425::UpdateChr(uint mode,uint data) const
122 				{
123 					nmt.SwapBank<SIZE_1K>( mode << 9 & 0xC00, data >> 5 );
124 					N34x3::UpdateChr( mode, data );
125 				}
126 
127 				NES_POKE_AD(N34xx,8000)
128 				{
129 					ppu.SetMirroring( (data & 0x40) ? Ppu::NMT_1 : Ppu::NMT_0 );
130 					N34x3::NES_DO_POKE(8000,address,data);
131 				}
132 			}
133 		}
134 	}
135 }
136