Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/wonderswan/memory.cpp
2 views
1
/* Cygne
2
*
3
* Copyright notice for this file:
4
* Copyright (C) 2002 Dox [email protected]
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*/
20
21
#include "system.h"
22
23
#include <math.h>
24
#include <cstring>
25
#include <cstdlib>
26
27
28
namespace MDFN_IEN_WSWAN
29
{
30
void Memory::Write20(uint32 A, uint8 V)
31
{
32
uint32 offset, bank;
33
34
offset = A & 0xffff;
35
bank = (A>>16) & 0xF;
36
37
if(!bank) /*RAM*/
38
{
39
sys->sound.CheckRAMWrite(offset);
40
wsRAM[offset] = V;
41
42
sys->gfx.InvalidByAddr(offset);
43
44
if(offset>=0xfe00) /*WSC palettes*/
45
sys->gfx.PaletteRAMWrite(offset, V);
46
}
47
else if(bank == 1) /* SRAM */
48
{
49
if(sram_size)
50
{
51
wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)] = V;
52
}
53
}
54
}
55
56
57
58
uint8 Memory::Read20(uint32 A)
59
{
60
uint32 offset, bank;
61
62
offset = A & 0xFFFF;
63
bank = (A >> 16) & 0xF;
64
65
switch(bank)
66
{
67
case 0: return wsRAM[offset];
68
case 1: if(sram_size)
69
{
70
return wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)];
71
}
72
else
73
return(0);
74
75
case 2:
76
case 3: return wsCartROM[offset+((BankSelector[bank]&((rom_size>>16)-1))<<16)];
77
78
default:
79
{
80
uint8 bank_num = ((BankSelector[0] & 0xF) << 4) | (bank & 0xf);
81
bank_num &= (rom_size >> 16) - 1;
82
return(wsCartROM[(bank_num << 16) | offset]);
83
}
84
}
85
}
86
87
void Memory::CheckDMA()
88
{
89
if(DMAControl & 0x80)
90
{
91
while(DMALength)
92
{
93
Write20(DMADest, Read20(DMASource));
94
95
DMASource++; // = ((DMASource + 1) & 0xFFFF) | (DMASource & 0xFF0000);
96
//if(!(DMASource & 0xFFFF)) puts("Warning: DMA source bank crossed.");
97
DMADest = ((DMADest + 1) & 0xFFFF) | (DMADest & 0xFF0000);
98
DMALength--;
99
}
100
}
101
DMAControl &= ~0x80;
102
}
103
104
void Memory::CheckSoundDMA()
105
{
106
if(SoundDMAControl & 0x80)
107
{
108
if(SoundDMALength)
109
{
110
uint8 zebyte = Read20(SoundDMASource);
111
112
if(SoundDMAControl & 0x08)
113
zebyte ^= 0x80;
114
115
if(SoundDMAControl & 0x10)
116
sys->sound.Write(0x95, zebyte); // Pick a port, any port?!
117
else
118
sys->sound.Write(0x89, zebyte);
119
120
SoundDMASource++; // = ((SoundDMASource + 1) & 0xFFFF) | (SoundDMASource & 0xFF0000);
121
//if(!(SoundDMASource & 0xFFFF)) puts("Warning: Sound DMA source bank crossed.");
122
SoundDMALength--;
123
}
124
if(!SoundDMALength)
125
SoundDMAControl &= ~0x80;
126
}
127
}
128
129
uint8 Memory::readport(uint32 number)
130
{
131
number &= 0xFF;
132
133
if(number >= 0x80 && number <= 0x9F)
134
return(sys->sound.Read(number));
135
else if(number <= 0x3F || (number >= 0xA0 && number <= 0xAF) || (number == 0x60))
136
return(sys->gfx.Read(number));
137
else if((number >= 0xBA && number <= 0xBE) || (number >= 0xC4 && number <= 0xC8))
138
return(sys->eeprom.Read(number));
139
else if(number >= 0xCA && number <= 0xCB)
140
return(sys->rtc.Read(number));
141
else switch(number)
142
{
143
//default: printf("Read: %04x\n", number); break;
144
case 0x40: return(DMASource >> 0);
145
case 0x41: return(DMASource >> 8);
146
case 0x42: return(DMASource >> 16);
147
148
case 0x43: return(DMADest >> 16);
149
case 0x44: return(DMADest >> 0);
150
case 0x45: return(DMADest >> 8);
151
152
case 0x46: return(DMALength >> 0);
153
case 0x47: return(DMALength >> 8);
154
155
case 0x48: return(DMAControl);
156
157
case 0xB0:
158
case 0xB2:
159
case 0xB6: return(sys->interrupt.Read(number));
160
161
case 0xC0: return(BankSelector[0] | 0x20);
162
case 0xC1: return(BankSelector[1]);
163
case 0xC2: return(BankSelector[2]);
164
case 0xC3: return(BankSelector[3]);
165
166
case 0x4a: return(SoundDMASource >> 0);
167
case 0x4b: return(SoundDMASource >> 8);
168
case 0x4c: return(SoundDMASource >> 16);
169
case 0x4e: return(SoundDMALength >> 0);
170
case 0x4f: return(SoundDMALength >> 8);
171
case 0x52: return(SoundDMAControl);
172
173
case 0xB1: return(CommData);
174
175
case 0xb3:
176
{
177
uint8 ret = CommControl & 0xf0;
178
179
if(CommControl & 0x80)
180
ret |= 0x4; // Send complete
181
182
return(ret);
183
}
184
case 0xb5:
185
{
186
Lagged = false;
187
if (ButtonHook)
188
ButtonHook();
189
uint8 ret = (ButtonWhich << 4) | ButtonReadLatch;
190
return(ret);
191
}
192
}
193
194
if(number >= 0xC8)
195
return language ? 0xD1 : 0xD0;
196
//return(0xD0 | language); // is this right?
197
198
return(0);
199
}
200
201
void Memory::writeport(uint32 IOPort, uint8 V)
202
{
203
IOPort &= 0xFF;
204
205
if(IOPort >= 0x80 && IOPort <= 0x9F)
206
{
207
sys->sound.Write(IOPort, V);
208
}
209
else if((IOPort >= 0x00 && IOPort <= 0x3F) || (IOPort >= 0xA0 && IOPort <= 0xAF) || (IOPort == 0x60))
210
{
211
sys->gfx.Write(IOPort, V);
212
}
213
else if((IOPort >= 0xBA && IOPort <= 0xBE) || (IOPort >= 0xC4 && IOPort <= 0xC8))
214
sys->eeprom.Write(IOPort, V);
215
else if(IOPort >= 0xCA && IOPort <= 0xCB)
216
sys->rtc.Write(IOPort, V);
217
else switch(IOPort)
218
{
219
//default: printf("%04x %02x\n", IOPort, V); break;
220
221
case 0x40: DMASource &= 0xFFFF00; DMASource |= (V << 0); break;
222
case 0x41: DMASource &= 0xFF00FF; DMASource |= (V << 8); break;
223
case 0x42: DMASource &= 0x00FFFF; DMASource |= ((V & 0x0F) << 16); break;
224
225
case 0x43: DMADest &= 0x00FFFF; DMADest |= ((V & 0x0F) << 16); break;
226
case 0x44: DMADest &= 0xFFFF00; DMADest |= (V << 0); break;
227
case 0x45: DMADest &= 0xFF00FF; DMADest |= (V << 8); break;
228
229
case 0x46: DMALength &= 0xFF00; DMALength |= (V << 0); break;
230
case 0x47: DMALength &= 0x00FF; DMALength |= (V << 8); break;
231
232
case 0x48: DMAControl = V;
233
//if(V&0x80)
234
// printf("DMA%02x: %08x %08x %08x\n", V, DMASource, DMADest, DMALength);
235
CheckDMA();
236
break;
237
238
case 0x4a: SoundDMASource &= 0xFFFF00; SoundDMASource |= (V << 0); break;
239
case 0x4b: SoundDMASource &= 0xFF00FF; SoundDMASource |= (V << 8); break;
240
case 0x4c: SoundDMASource &= 0x00FFFF; SoundDMASource |= (V << 16); break;
241
//case 0x4d: break; // Unused?
242
case 0x4e: SoundDMALength &= 0xFF00; SoundDMALength |= (V << 0); break;
243
case 0x4f: SoundDMALength &= 0x00FF; SoundDMALength |= (V << 8); break;
244
//case 0x50: break; // Unused?
245
//case 0x51: break; // Unused?
246
case 0x52: SoundDMAControl = V;
247
//if(V & 0x80) printf("Sound DMA: %02x, %08x %08x\n", V, SoundDMASource, SoundDMALength);
248
break;
249
250
case 0xB0:
251
case 0xB2:
252
case 0xB6: sys->interrupt.Write(IOPort, V); break;
253
254
case 0xB1: CommData = V; break;
255
case 0xB3: CommControl = V & 0xF0; break;
256
257
case 0xb5: ButtonWhich = V >> 4;
258
// Lagged = false; // why was this being set here?
259
ButtonReadLatch = 0;
260
261
if(ButtonWhich & 0x4) /*buttons*/
262
ButtonReadLatch |= ((WSButtonStatus >> 8) << 1) & 0xF;
263
264
if(ButtonWhich & 0x2) /* H/X cursors */
265
ButtonReadLatch |= WSButtonStatus & 0xF;
266
267
if(ButtonWhich & 0x1) /* V/Y cursors */
268
ButtonReadLatch |= (WSButtonStatus >> 4) & 0xF;
269
break;
270
271
case 0xC0: BankSelector[0] = V & 0xF; break;
272
case 0xC1: BankSelector[1] = V; break;
273
case 0xC2: BankSelector[2] = V; break;
274
case 0xC3: BankSelector[3] = V; break;
275
}
276
}
277
278
Memory::~Memory()
279
{
280
if (wsCartROM)
281
{
282
std::free(wsCartROM);
283
wsCartROM = nullptr;
284
}
285
if (wsSRAM)
286
{
287
std::free(wsSRAM);
288
wsSRAM = nullptr;
289
}
290
}
291
292
void Memory::Init(const SyncSettings &settings)
293
{
294
char tmpname[17];
295
std::memcpy(tmpname, settings.name, 16);
296
tmpname[16] = 0;
297
298
language = settings.language;
299
300
// WSwan_EEPROMInit() will also clear wsEEPROM
301
sys->eeprom.Init(tmpname, settings.byear, settings.bmonth, settings.bday, settings.sex, settings.blood);
302
303
if(sram_size)
304
{
305
wsSRAM = (uint8*)malloc(sram_size);
306
memset(wsSRAM, 0, sram_size);
307
}
308
}
309
310
void Memory::Reset()
311
{
312
memset(wsRAM, 0, 65536);
313
314
wsRAM[0x75AC] = 0x41;
315
wsRAM[0x75AD] = 0x5F;
316
wsRAM[0x75AE] = 0x43;
317
wsRAM[0x75AF] = 0x31;
318
wsRAM[0x75B0] = 0x6E;
319
wsRAM[0x75B1] = 0x5F;
320
wsRAM[0x75B2] = 0x63;
321
wsRAM[0x75B3] = 0x31;
322
323
std::memset(BankSelector, 0, sizeof(BankSelector));
324
ButtonWhich = 0;
325
ButtonReadLatch = 0;
326
DMASource = 0;
327
DMADest = 0;
328
DMALength = 0;
329
DMAControl = 0;
330
331
SoundDMASource = 0;
332
SoundDMALength = 0;
333
SoundDMAControl = 0;
334
335
CommControl = 0;
336
CommData = 0;
337
}
338
339
SYNCFUNC(Memory)
340
{
341
NSS(wsRAM);
342
//NSS(rom_size);
343
//PSS(wsCartROM, rom_size);
344
NSS(sram_size);
345
PSS(wsSRAM, sram_size);
346
347
NSS(WSButtonStatus);
348
NSS(Lagged);
349
350
NSS(ButtonWhich);
351
NSS(ButtonReadLatch);
352
353
NSS(DMASource);
354
NSS(DMADest);
355
NSS(DMALength);
356
NSS(DMAControl);
357
358
NSS(SoundDMASource);
359
NSS(SoundDMALength);
360
NSS(SoundDMAControl);
361
362
NSS(BankSelector);
363
364
NSS(CommControl);
365
NSS(CommData);
366
367
NSS(language);
368
}
369
}
370
371