Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libgambatte/src/memory.h
2 views
1
/***************************************************************************
2
* Copyright (C) 2007 by Sindre AamÄs *
3
* [email protected] *
4
* *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License version 2 as *
7
* published by the Free Software Foundation. *
8
* *
9
* This program is distributed in the hope that it will be useful, *
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
* GNU General Public License version 2 for more details. *
13
* *
14
* You should have received a copy of the GNU General Public License *
15
* version 2 along with this program; if not, write to the *
16
* Free Software Foundation, Inc., *
17
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18
***************************************************************************/
19
#ifndef MEMORY_H
20
#define MEMORY_H
21
22
#include "mem/cartridge.h"
23
#include "video.h"
24
#include "sound.h"
25
#include "interrupter.h"
26
#include "tima.h"
27
#include "newstate.h"
28
#include "gambatte.h"
29
30
namespace gambatte {
31
class InputGetter;
32
class FilterInfo;
33
34
class Memory {
35
Cartridge cart;
36
unsigned char ioamhram[0x200];
37
38
void (*readCallback)(unsigned);
39
void (*writeCallback)(unsigned);
40
void (*execCallback)(unsigned);
41
CDCallback cdCallback;
42
43
unsigned (*getInput)();
44
unsigned long divLastUpdate;
45
unsigned long lastOamDmaUpdate;
46
47
InterruptRequester intreq;
48
Tima tima;
49
LCD display;
50
PSG sound;
51
Interrupter interrupter;
52
53
unsigned short dmaSource;
54
unsigned short dmaDestination;
55
unsigned char oamDmaPos;
56
unsigned char serialCnt;
57
bool blanklcd;
58
59
bool LINKCABLE;
60
bool linkClockTrigger;
61
62
void decEventCycles(MemEventId eventId, unsigned long dec);
63
64
void oamDmaInitSetup();
65
void updateOamDma(unsigned long cycleCounter);
66
void startOamDma(unsigned long cycleCounter);
67
void endOamDma(unsigned long cycleCounter);
68
const unsigned char * oamDmaSrcPtr() const;
69
70
unsigned nontrivial_ff_read(unsigned P, unsigned long cycleCounter);
71
unsigned nontrivial_read(unsigned P, unsigned long cycleCounter);
72
void nontrivial_ff_write(unsigned P, unsigned data, unsigned long cycleCounter);
73
void nontrivial_write(unsigned P, unsigned data, unsigned long cycleCounter);
74
75
unsigned nontrivial_peek(unsigned P);
76
unsigned nontrivial_ff_peek(unsigned P);
77
78
void updateSerial(unsigned long cc);
79
void updateTimaIrq(unsigned long cc);
80
void updateIrqs(unsigned long cc);
81
82
bool isDoubleSpeed() const { return display.isDoubleSpeed(); }
83
84
public:
85
explicit Memory(const Interrupter &interrupter);
86
87
bool loaded() const { return cart.loaded(); }
88
const char * romTitle() const { return cart.romTitle(); }
89
90
int debugGetLY() const { return display.debugGetLY(); }
91
92
void setStatePtrs(SaveState &state);
93
void loadState(const SaveState &state/*, unsigned long oldCc*/);
94
void loadSavedata(const char *data) { cart.loadSavedata(data); }
95
int saveSavedataLength() {return cart.saveSavedataLength(); }
96
void saveSavedata(char *dest) { cart.saveSavedata(dest); }
97
void updateInput();
98
99
bool getMemoryArea(int which, unsigned char **data, int *length); // { return cart.getMemoryArea(which, data, length); }
100
101
unsigned long stop(unsigned long cycleCounter);
102
bool isCgb() const { return display.isCgb(); }
103
bool ime() const { return intreq.ime(); }
104
bool halted() const { return intreq.halted(); }
105
unsigned long nextEventTime() const { return intreq.minEventTime(); }
106
107
void setLayers(unsigned mask) { display.setLayers(mask); }
108
109
bool isActive() const { return intreq.eventTime(END) != DISABLED_TIME; }
110
111
long cyclesSinceBlit(const unsigned long cc) const {
112
return cc < intreq.eventTime(BLIT) ? -1 : static_cast<long>((cc - intreq.eventTime(BLIT)) >> isDoubleSpeed());
113
}
114
115
void halt() { intreq.halt(); }
116
void ei(unsigned long cycleCounter) { if (!ime()) { intreq.ei(cycleCounter); } }
117
118
void di() { intreq.di(); }
119
120
unsigned ff_read(const unsigned P, const unsigned long cycleCounter) {
121
return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00];
122
}
123
124
struct CDMapResult
125
{
126
eCDLog_AddrType type;
127
unsigned addr;
128
};
129
130
CDMapResult CDMap(const unsigned P) const
131
{
132
if(P<0x4000)
133
{
134
CDMapResult ret = { eCDLog_AddrType_ROM, P };
135
return ret;
136
}
137
else if(P<0x8000)
138
{
139
unsigned bank = cart.rmem(P>>12) - cart.rmem(0);
140
unsigned addr = P+bank;
141
CDMapResult ret = { eCDLog_AddrType_ROM, addr };
142
return ret;
143
}
144
else if(P<0xA000) {}
145
else if(P<0xC000)
146
{
147
if(cart.wsrambankptr())
148
{
149
//not bankable. but. we're not sure how much might be here
150
unsigned char *data;
151
int length;
152
bool has = cart.getMemoryArea(3,&data,&length);
153
unsigned addr = P&(length-1);
154
if(has && length!=0)
155
{
156
CDMapResult ret = { eCDLog_AddrType_CartRAM, addr };
157
return ret;
158
}
159
}
160
}
161
else if(P<0xE000)
162
{
163
unsigned bank = cart.wramdata(P >> 12 & 1) - cart.wramdata(0);
164
unsigned addr = (P&0xFFF)+bank;
165
CDMapResult ret = { eCDLog_AddrType_WRAM, addr };
166
return ret;
167
}
168
else if(P<0xFF80) {}
169
else
170
{
171
////this is just for debugging, really, it's pretty useless
172
//CDMapResult ret = { eCDLog_AddrType_HRAM, (P-0xFF80) };
173
//return ret;
174
}
175
176
CDMapResult ret = { eCDLog_AddrType_None };
177
return ret;
178
}
179
180
181
unsigned read(const unsigned P, const unsigned long cycleCounter) {
182
if (readCallback)
183
readCallback(P);
184
if(cdCallback)
185
{
186
CDMapResult map = CDMap(P);
187
if(map.type != eCDLog_AddrType_None)
188
cdCallback(map.addr,map.type,eCDLog_Flags_Data);
189
}
190
return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter);
191
}
192
193
unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) {
194
if (execCallback)
195
execCallback(P);
196
if(cdCallback)
197
{
198
CDMapResult map = CDMap(P);
199
if(map.type != eCDLog_AddrType_None)
200
cdCallback(map.addr,map.type,first?eCDLog_Flags_ExecFirst : eCDLog_Flags_ExecOperand);
201
}
202
return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter);
203
}
204
205
unsigned peek(const unsigned P) {
206
return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_peek(P);
207
}
208
209
void write_nocb(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
210
if (cart.wmem(P >> 12)) {
211
cart.wmem(P >> 12)[P] = data;
212
} else
213
nontrivial_write(P, data, cycleCounter);
214
}
215
216
void write(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
217
if (cart.wmem(P >> 12)) {
218
cart.wmem(P >> 12)[P] = data;
219
} else
220
nontrivial_write(P, data, cycleCounter);
221
if (writeCallback)
222
writeCallback(P);
223
if(cdCallback)
224
{
225
CDMapResult map = CDMap(P);
226
if(map.type != eCDLog_AddrType_None)
227
cdCallback(map.addr,map.type,eCDLog_Flags_Data);
228
}
229
}
230
231
void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
232
if (P - 0xFF80u < 0x7Fu) {
233
ioamhram[P - 0xFE00] = data;
234
} else
235
nontrivial_ff_write(P, data, cycleCounter);
236
if(cdCallback)
237
{
238
CDMapResult map = CDMap(P);
239
if(map.type != eCDLog_AddrType_None)
240
cdCallback(map.addr,map.type,eCDLog_Flags_Data);
241
}
242
}
243
244
unsigned long event(unsigned long cycleCounter);
245
unsigned long resetCounters(unsigned long cycleCounter);
246
247
int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
248
249
void setInputGetter(unsigned (*getInput)()) {
250
this->getInput = getInput;
251
}
252
253
void setReadCallback(void (*callback)(unsigned)) {
254
this->readCallback = callback;
255
}
256
void setWriteCallback(void (*callback)(unsigned)) {
257
this->writeCallback = callback;
258
}
259
void setExecCallback(void (*callback)(unsigned)) {
260
this->execCallback = callback;
261
}
262
void setCDCallback(CDCallback cdc) {
263
this->cdCallback = cdc;
264
}
265
266
void setScanlineCallback(void (*callback)(), int sl) {
267
display.setScanlineCallback(callback, sl);
268
}
269
270
void setRTCCallback(std::uint32_t (*callback)()) {
271
cart.setRTCCallback(callback);
272
}
273
274
void setEndtime(unsigned long cc, unsigned long inc);
275
276
void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); }
277
unsigned fillSoundBuffer(unsigned long cc);
278
279
void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
280
display.setVideoBuffer(videoBuf, pitch);
281
}
282
283
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
284
void setCgbPalette(unsigned *lut);
285
286
int LinkStatus(int which);
287
288
template<bool isReader>void SyncState(NewState *ns);
289
};
290
291
}
292
293
#endif
294
295