~ubuntu-branches/debian/experimental/mednafen/experimental

« back to all changes in this revision

Viewing changes to src/pce/mcgenjin.cpp

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2012-01-31 07:21:35 UTC
  • mfrom: (1.2.8)
  • Revision ID: package-import@ubuntu.com-20120131072135-es3dj12y00xcnrsk
Tags: 0.9.19-1
* New upstream WIP version.
* Update copyright information.
* Refresh use-system-tremor.patch and remove psx-big-endian-only.patch.
* Add spelling-fixes.patch based on Lintian's recommendations.
* Build-depend on debhelper 9 or later and remove corresponding Lintian
  override.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Mednafen - Multi-system Emulator
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or modify
 
4
 * it under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software
 
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 */
 
17
 
 
18
#include "pce.h"
 
19
#include "mcgenjin.h"
 
20
 
 
21
MCGenjin_CS_Device::MCGenjin_CS_Device()
 
22
{
 
23
 
 
24
}
 
25
 
 
26
MCGenjin_CS_Device::~MCGenjin_CS_Device()
 
27
{
 
28
 
 
29
}
 
30
 
 
31
void MCGenjin_CS_Device::Power(void)
 
32
{
 
33
 
 
34
}
 
35
 
 
36
void MCGenjin_CS_Device::EndFrame(int32 timestamp)
 
37
{
 
38
 
 
39
}
 
40
 
 
41
int MCGenjin_CS_Device::StateAction(StateMem *sm, int load, int data_only, const char *sname)
 
42
{
 
43
 return 1;
 
44
}
 
45
 
 
46
 
 
47
uint8 MCGenjin_CS_Device::Read(int32 timestamp, uint32 A)
 
48
{
 
49
 return 0xFF;
 
50
}
 
51
 
 
52
void MCGenjin_CS_Device::Write(int32 timestamp, uint32 A, uint8 V)
 
53
{
 
54
 
 
55
}
 
56
 
 
57
uint32 MCGenjin_CS_Device::GetNVSize(void)
 
58
{
 
59
 return 0;
 
60
}
 
61
 
 
62
void MCGenjin_CS_Device::ReadNV(uint8 *buffer, uint32 offset, uint32 count)
 
63
{
 
64
 memset(buffer, 0, count);
 
65
}
 
66
 
 
67
void MCGenjin_CS_Device::WriteNV(const uint8 *buffer, uint32 offset, uint32 count)
 
68
{
 
69
 
 
70
}
 
71
 
 
72
class MCGenjin_CS_Device_RAM : public MCGenjin_CS_Device
 
73
{
 
74
 public:
 
75
 
 
76
 MCGenjin_CS_Device_RAM(uint32 size, bool nv)
 
77
 {
 
78
  assert(round_up_pow2(size) == size);
 
79
 
 
80
  ram.resize(size);
 
81
  nonvolatile = nv;
 
82
 }
 
83
 
 
84
 virtual ~MCGenjin_CS_Device_RAM()
 
85
 {
 
86
 
 
87
 }
 
88
 
 
89
 virtual void Power(void)
 
90
 {
 
91
  if(!nonvolatile)
 
92
   ram.assign(ram.size(), 0xFF);
 
93
 
 
94
  bank_select = 0;
 
95
 }
 
96
 
 
97
 virtual int StateAction(StateMem *sm, int load, int data_only, const char *sname)
 
98
 {
 
99
  SFORMAT StateRegs[] = 
 
100
  {
 
101
   SFARRAY(&ram[0], ram.size()),
 
102
   SFVAR(bank_select),
 
103
   SFEND
 
104
  };
 
105
  int ret = 1;
 
106
 
 
107
  ret &= MDFNSS_StateAction(sm, load, data_only, StateRegs, sname);
 
108
 
 
109
  return ret;
 
110
 }
 
111
 
 
112
 
 
113
 virtual uint8 Read(int32 timestamp, uint32 A)
 
114
 {
 
115
  return ram[(A | (bank_select << 18)) & (ram.size() - 1)];
 
116
 }
 
117
 
 
118
 virtual void Write(int32 timestamp, uint32 A, uint8 V)
 
119
 {
 
120
  if(!A)
 
121
   bank_select = V;
 
122
 
 
123
  ram[(A | (bank_select << 18)) & (ram.size() - 1)] = V;
 
124
 }
 
125
 
 
126
 virtual uint32 GetNVSize(void)
 
127
 {
 
128
  return nonvolatile ? ram.size() : 0;
 
129
 }
 
130
 
 
131
 virtual void ReadNV(uint8 *buffer, uint32 offset, uint32 count)
 
132
 {
 
133
  while(count)
 
134
  {
 
135
   *buffer = ram[offset % ram.size()];
 
136
   buffer++;
 
137
   offset++;
 
138
   count--;
 
139
  }
 
140
 }
 
141
 
 
142
 virtual void WriteNV(const uint8 *buffer, uint32 offset, uint32 count)
 
143
 {
 
144
  while(count)
 
145
  {
 
146
   ram[offset % ram.size()] = *buffer;
 
147
   buffer++;
 
148
   offset++;
 
149
   count--;
 
150
  }
 
151
 }
 
152
 
 
153
 private:
 
154
 std::vector<uint8> ram;
 
155
 bool nonvolatile;
 
156
 uint8 bank_select;
 
157
};
 
158
 
 
159
#include "mcgenjin_ym2413.inc"
 
160
 
 
161
void MCGenjin::Power(void)
 
162
{
 
163
 bank_select = 0;
 
164
 dlr = 0;
 
165
 
 
166
 for(unsigned i = 0; i < 2; i++)
 
167
  cs[i]->Power();
 
168
}
 
169
 
 
170
void MCGenjin::EndFrame(int32 timestamp)
 
171
{
 
172
 for(unsigned i = 0; i < 2; i++)
 
173
  cs[i]->EndFrame(timestamp);
 
174
}
 
175
 
 
176
uint32 MCGenjin::GetNVSize(const unsigned di)
 
177
{
 
178
 return cs[di]->GetNVSize();
 
179
}
 
180
 
 
181
 
 
182
void MCGenjin::ReadNV(const unsigned di, uint8 *buffer, uint32 offset, uint32 count)
 
183
{
 
184
 cs[di]->ReadNV(buffer, offset, count);
 
185
}
 
186
 
 
187
void MCGenjin::WriteNV(const unsigned di, const uint8 *buffer, uint32 offset, uint32 count)
 
188
{
 
189
 cs[di]->WriteNV(buffer, offset, count);
 
190
}
 
191
 
 
192
MCGenjin::MCGenjin(Blip_Buffer *bb, const uint8 *rr, uint32 rr_size)
 
193
{
 
194
 uint8 revision, num256_pages, region, cs_di[2];
 
195
 
 
196
 if(rr_size < 8192)
 
197
  throw MDFN_Error(0, _("MCGenjin ROM size is too small!"));
 
198
 
 
199
 if(memcmp(rr + 0x1FD0, "MCGENJIN", 8))
 
200
  throw MDFN_Error(0, _("MC Genjin header magic missing!"));
 
201
 
 
202
 rom.resize(round_up_pow2(rr_size));
 
203
 
 
204
 memcpy(&rom[0], rr, rr_size);
 
205
 
 
206
 revision = rom[0x1FD8];
 
207
 num256_pages = rom[0x1FD9];
 
208
 region = rom[0x1FDA];
 
209
 cs_di[0] = rom[0x1FDB];
 
210
 cs_di[1] = rom[0x1FDC];
 
211
 
 
212
 for(unsigned i = 0; i < 2; i++)
 
213
 {
 
214
  switch(cs_di[i])
 
215
  {
 
216
   default:
 
217
        for(unsigned si = 0; si < i; si++) // FIXME: auto ptr to make this not necessary
 
218
         delete cs[si];
 
219
 
 
220
        throw MDFN_Error(0, _("Unsupported MCGENJIN device on CS%d: 0x%02x"), i, cs_di[i]);
 
221
        break;
 
222
 
 
223
   case 0x00:
 
224
        MDFN_printf(_("CS%d: Unused\n"), i);
 
225
        cs[i] = new MCGenjin_CS_Device();
 
226
        break;
 
227
 
 
228
   case 0x10 ... 0x18:
 
229
   case 0x20 ... 0x28:
 
230
        MDFN_printf(_("CS%d: %uKiB %sRAM\n"), i, 8 << (cs_di[i] & 0xF), (cs_di[i] & 0x20) ? "Nonvolatile " : "");
 
231
        cs[i] = new MCGenjin_CS_Device_RAM(8192 << (cs_di[i] & 0xF), (bool)(cs_di[i] & 0x20));
 
232
        break;
 
233
  }
 
234
 }
 
235
}
 
236
 
 
237
MCGenjin::~MCGenjin()
 
238
{
 
239
 for(unsigned i = 0; i < 2; i++)
 
240
  delete cs[i];
 
241
}
 
242
 
 
243
int MCGenjin::StateAction(StateMem *sm, int load, int data_only)
 
244
{
 
245
 SFORMAT StateRegs[] =
 
246
 {
 
247
  SFVAR(bank_select),
 
248
  SFVAR(dlr),
 
249
  SFEND
 
250
 };
 
251
 int ret = 1;
 
252
 
 
253
 ret &= MDFNSS_StateAction(sm, load, data_only, StateRegs, "MCGENJIN");
 
254
 
 
255
 for(unsigned i = 0; i < 2; i++)
 
256
  ret &= MDFNSS_StateAction(sm, load, data_only, StateRegs, i ? "MCGENJIN_CS1" : "MCGENJIN_CS0");
 
257
 
 
258
 return ret;
 
259
}
 
260