rlm@1
|
1 #ifndef VBA_GBAINLINE_H
|
rlm@1
|
2 #define VBA_GBAINLINE_H
|
rlm@1
|
3
|
rlm@1
|
4 #if _MSC_VER > 1000
|
rlm@1
|
5 #pragma once
|
rlm@1
|
6 #endif // _MSC_VER > 1000
|
rlm@1
|
7
|
rlm@1
|
8 #include "../Port.h"
|
rlm@1
|
9 #include "../common/System.h"
|
rlm@1
|
10 #include "../common/vbalua.h"
|
rlm@1
|
11 #include "GBAGlobals.h"
|
rlm@1
|
12 #include "EEprom.h"
|
rlm@1
|
13 #include "Flash.h"
|
rlm@1
|
14 #include "RTC.h"
|
rlm@1
|
15
|
rlm@1
|
16 extern bool8 cpuSramEnabled;
|
rlm@1
|
17 extern bool8 cpuFlashEnabled;
|
rlm@1
|
18 extern bool8 cpuEEPROMEnabled;
|
rlm@1
|
19 extern bool8 cpuEEPROMSensorEnabled;
|
rlm@1
|
20
|
rlm@1
|
21 #define CPUReadByteQuick(addr) \
|
rlm@1
|
22 map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
rlm@1
|
23
|
rlm@1
|
24 #define CPUReadHalfWordQuick(addr) \
|
rlm@1
|
25 READ16LE(((u16 *)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
rlm@1
|
26
|
rlm@1
|
27 #define CPUReadMemoryQuick(addr) \
|
rlm@1
|
28 READ32LE(((u32 *)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
|
rlm@1
|
29
|
rlm@1
|
30 //inline u32 CPUReadMemoryQuick(u32 addr)
|
rlm@1
|
31 //{
|
rlm@1
|
32 // u32 addrShift = (addr)>>24;
|
rlm@1
|
33 // u32 rt = (addr) & map[addrShift].mask;
|
rlm@1
|
34 // return READ32LE(((u32*)&map[addrShift].address[rt]));
|
rlm@1
|
35 //}
|
rlm@1
|
36
|
rlm@1
|
37 inline u32 CPUReadMemory(u32 address)
|
rlm@1
|
38 {
|
rlm@1
|
39 #ifdef GBA_LOGGING
|
rlm@1
|
40 if (address & 3)
|
rlm@1
|
41 {
|
rlm@1
|
42 if (systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
rlm@1
|
43 {
|
rlm@1
|
44 log("Unaligned word read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
45 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
46 }
|
rlm@1
|
47 }
|
rlm@1
|
48 #endif
|
rlm@1
|
49
|
rlm@1
|
50 u32 value;
|
rlm@1
|
51 switch (address >> 24)
|
rlm@1
|
52 {
|
rlm@1
|
53 case 0:
|
rlm@1
|
54 if (reg[15].I >> 24)
|
rlm@1
|
55 {
|
rlm@1
|
56 if (address < 0x4000)
|
rlm@1
|
57 {
|
rlm@1
|
58 #ifdef GBA_LOGGING
|
rlm@1
|
59 if (systemVerbose & VERBOSE_ILLEGAL_READ)
|
rlm@1
|
60 {
|
rlm@1
|
61 log("Illegal word read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
62 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
63 }
|
rlm@1
|
64 #endif
|
rlm@1
|
65
|
rlm@1
|
66 value = READ32LE(((u32 *)&biosProtected));
|
rlm@1
|
67 }
|
rlm@1
|
68 else
|
rlm@1
|
69 goto unreadable;
|
rlm@1
|
70 }
|
rlm@1
|
71 else
|
rlm@1
|
72 value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
rlm@1
|
73 break;
|
rlm@1
|
74 case 2:
|
rlm@1
|
75 value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
rlm@1
|
76 break;
|
rlm@1
|
77 case 3:
|
rlm@1
|
78 value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
rlm@1
|
79 break;
|
rlm@1
|
80 case 4:
|
rlm@1
|
81 if ((address < 0x4000400) && ioReadable[address & 0x3fc])
|
rlm@1
|
82 {
|
rlm@1
|
83 if (ioReadable[(address & 0x3fc) + 2])
|
rlm@1
|
84 {
|
rlm@1
|
85 if (address >= 0x400012d && address <= 0x4000131)
|
rlm@1
|
86 GBASystemCounters.lagged = false;
|
rlm@1
|
87 value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
rlm@1
|
88 }
|
rlm@1
|
89 else
|
rlm@1
|
90 {
|
rlm@1
|
91 if (address >= 0x400012f && address <= 0x4000131)
|
rlm@1
|
92 GBASystemCounters.lagged = false;
|
rlm@1
|
93 value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
rlm@1
|
94 }
|
rlm@1
|
95 }
|
rlm@1
|
96 else
|
rlm@1
|
97 goto unreadable;
|
rlm@1
|
98 break;
|
rlm@1
|
99 case 5:
|
rlm@1
|
100 value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
rlm@1
|
101 break;
|
rlm@1
|
102 case 6:
|
rlm@1
|
103 value = READ32LE(((u32 *)&vram[address & 0x1fffc]));
|
rlm@1
|
104 break;
|
rlm@1
|
105 case 7:
|
rlm@1
|
106 value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
rlm@1
|
107 break;
|
rlm@1
|
108 case 8:
|
rlm@1
|
109 case 9:
|
rlm@1
|
110 case 10:
|
rlm@1
|
111 case 11:
|
rlm@1
|
112 case 12:
|
rlm@1
|
113 value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
rlm@1
|
114 break;
|
rlm@1
|
115 case 13:
|
rlm@1
|
116 if (cpuEEPROMEnabled)
|
rlm@1
|
117 // no need to swap this
|
rlm@1
|
118 return eepromRead(address);
|
rlm@1
|
119 goto unreadable;
|
rlm@1
|
120 case 14:
|
rlm@1
|
121 if (cpuFlashEnabled | cpuSramEnabled)
|
rlm@1
|
122 // no need to swap this
|
rlm@1
|
123 return flashRead(address);
|
rlm@1
|
124 // default
|
rlm@1
|
125 default:
|
rlm@1
|
126 unreadable:
|
rlm@1
|
127 #ifdef GBA_LOGGING
|
rlm@1
|
128 if (systemVerbose & VERBOSE_ILLEGAL_READ)
|
rlm@1
|
129 {
|
rlm@1
|
130 log("Illegal word read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
131 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
132 }
|
rlm@1
|
133 #endif
|
rlm@1
|
134
|
rlm@1
|
135 // if(ioMem[0x205] & 0x40) {
|
rlm@1
|
136 if (armState)
|
rlm@1
|
137 {
|
rlm@1
|
138 value = CPUReadMemoryQuick(reg[15].I);
|
rlm@1
|
139 }
|
rlm@1
|
140 else
|
rlm@1
|
141 {
|
rlm@1
|
142 value = CPUReadHalfWordQuick(reg[15].I) |
|
rlm@1
|
143 CPUReadHalfWordQuick(reg[15].I) << 16;
|
rlm@1
|
144 }
|
rlm@1
|
145 // } else {
|
rlm@1
|
146 // value = *((u32 *)&bios[address & 0x3ffc]);
|
rlm@1
|
147 // }
|
rlm@1
|
148 // return 0xFFFFFFFF;
|
rlm@1
|
149 }
|
rlm@1
|
150
|
rlm@1
|
151 if (address & 3)
|
rlm@1
|
152 {
|
rlm@1
|
153 #ifdef C_CORE
|
rlm@1
|
154 int shift = (address & 3) << 3;
|
rlm@1
|
155 value = (value >> shift) | (value << (32 - shift));
|
rlm@1
|
156 #else
|
rlm@1
|
157 #ifdef __GNUC__
|
rlm@1
|
158 asm ("and $3, %%ecx;"
|
rlm@1
|
159 "shl $3 ,%%ecx;"
|
rlm@1
|
160 "ror %%cl, %0"
|
rlm@1
|
161 : "=r" (value)
|
rlm@1
|
162 : "r" (value), "c" (address));
|
rlm@1
|
163 #else
|
rlm@1
|
164 __asm {
|
rlm@1
|
165 mov ecx, address;
|
rlm@1
|
166 and ecx, 3;
|
rlm@1
|
167 shl ecx, 3;
|
rlm@1
|
168 ror [dword ptr value], cl;
|
rlm@1
|
169 }
|
rlm@1
|
170 #endif
|
rlm@1
|
171 #endif
|
rlm@1
|
172 }
|
rlm@1
|
173 return value;
|
rlm@1
|
174 }
|
rlm@1
|
175
|
rlm@1
|
176 extern u32 myROM[];
|
rlm@1
|
177
|
rlm@1
|
178 inline u32 CPUReadHalfWord(u32 address)
|
rlm@1
|
179 {
|
rlm@1
|
180 #ifdef GBA_LOGGING
|
rlm@1
|
181 if (address & 1)
|
rlm@1
|
182 {
|
rlm@1
|
183 if (systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
rlm@1
|
184 {
|
rlm@1
|
185 log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
186 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
187 }
|
rlm@1
|
188 }
|
rlm@1
|
189 #endif
|
rlm@1
|
190
|
rlm@1
|
191 u32 value;
|
rlm@1
|
192
|
rlm@1
|
193 switch (address >> 24)
|
rlm@1
|
194 {
|
rlm@1
|
195 case 0:
|
rlm@1
|
196 if (reg[15].I >> 24)
|
rlm@1
|
197 {
|
rlm@1
|
198 if (address < 0x4000)
|
rlm@1
|
199 {
|
rlm@1
|
200 #ifdef GBA_LOGGING
|
rlm@1
|
201 if (systemVerbose & VERBOSE_ILLEGAL_READ)
|
rlm@1
|
202 {
|
rlm@1
|
203 log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
204 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
205 }
|
rlm@1
|
206 #endif
|
rlm@1
|
207 value = READ16LE(((u16 *)&biosProtected[address&2]));
|
rlm@1
|
208 }
|
rlm@1
|
209 else
|
rlm@1
|
210 goto unreadable;
|
rlm@1
|
211 }
|
rlm@1
|
212 else
|
rlm@1
|
213 value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
rlm@1
|
214 break;
|
rlm@1
|
215 case 2:
|
rlm@1
|
216 value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
rlm@1
|
217 break;
|
rlm@1
|
218 case 3:
|
rlm@1
|
219 value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
rlm@1
|
220 break;
|
rlm@1
|
221 case 4:
|
rlm@1
|
222 if ((address < 0x4000400) && ioReadable[address & 0x3fe])
|
rlm@1
|
223 {
|
rlm@1
|
224 if (address >= 0x400012f && address <= 0x4000131)
|
rlm@1
|
225 GBASystemCounters.lagged = false;
|
rlm@1
|
226 value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
rlm@1
|
227 }
|
rlm@1
|
228 else
|
rlm@1
|
229 goto unreadable;
|
rlm@1
|
230 break;
|
rlm@1
|
231 case 5:
|
rlm@1
|
232 value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
rlm@1
|
233 break;
|
rlm@1
|
234 case 6:
|
rlm@1
|
235 value = READ16LE(((u16 *)&vram[address & 0x1fffe]));
|
rlm@1
|
236 break;
|
rlm@1
|
237 case 7:
|
rlm@1
|
238 value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
rlm@1
|
239 break;
|
rlm@1
|
240 case 8:
|
rlm@1
|
241 case 9:
|
rlm@1
|
242 case 10:
|
rlm@1
|
243 case 11:
|
rlm@1
|
244 case 12:
|
rlm@1
|
245 if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
rlm@1
|
246 value = rtcRead(address);
|
rlm@1
|
247 else
|
rlm@1
|
248 value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
rlm@1
|
249 break;
|
rlm@1
|
250 case 13:
|
rlm@1
|
251 if (cpuEEPROMEnabled)
|
rlm@1
|
252 // no need to swap this
|
rlm@1
|
253 return eepromRead(address);
|
rlm@1
|
254 goto unreadable;
|
rlm@1
|
255 case 14:
|
rlm@1
|
256 if (cpuFlashEnabled | cpuSramEnabled)
|
rlm@1
|
257 // no need to swap this
|
rlm@1
|
258 return flashRead(address);
|
rlm@1
|
259 // default
|
rlm@1
|
260 default:
|
rlm@1
|
261 unreadable:
|
rlm@1
|
262 #ifdef GBA_LOGGING
|
rlm@1
|
263 if (systemVerbose & VERBOSE_ILLEGAL_READ)
|
rlm@1
|
264 {
|
rlm@1
|
265 log("Illegal halfword read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
266 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
267 }
|
rlm@1
|
268 #endif
|
rlm@1
|
269 extern bool8 cpuDmaHack;
|
rlm@1
|
270 extern u32 cpuDmaLast;
|
rlm@1
|
271 extern int32 cpuDmaCount;
|
rlm@1
|
272 if (cpuDmaHack && cpuDmaCount)
|
rlm@1
|
273 {
|
rlm@1
|
274 value = (u16)cpuDmaLast;
|
rlm@1
|
275 }
|
rlm@1
|
276 else
|
rlm@1
|
277 {
|
rlm@1
|
278 if (armState)
|
rlm@1
|
279 {
|
rlm@1
|
280 value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
|
rlm@1
|
281 }
|
rlm@1
|
282 else
|
rlm@1
|
283 {
|
rlm@1
|
284 value = CPUReadHalfWordQuick(reg[15].I);
|
rlm@1
|
285 }
|
rlm@1
|
286 }
|
rlm@1
|
287 // return value;
|
rlm@1
|
288 // if(address & 1)
|
rlm@1
|
289 // value = (value >> 8) | ((value & 0xFF) << 24);
|
rlm@1
|
290 // return 0xFFFF;
|
rlm@1
|
291 break;
|
rlm@1
|
292 }
|
rlm@1
|
293
|
rlm@1
|
294 if (address & 1)
|
rlm@1
|
295 {
|
rlm@1
|
296 value = (value >> 8) | (value << 24);
|
rlm@1
|
297 }
|
rlm@1
|
298
|
rlm@1
|
299 return value;
|
rlm@1
|
300 }
|
rlm@1
|
301
|
rlm@1
|
302 inline u16 CPUReadHalfWordSigned(u32 address)
|
rlm@1
|
303 {
|
rlm@1
|
304 u16 value = CPUReadHalfWord(address);
|
rlm@1
|
305 if ((address & 1))
|
rlm@1
|
306 value = (s8)value;
|
rlm@1
|
307 return value;
|
rlm@1
|
308 }
|
rlm@1
|
309
|
rlm@1
|
310 inline u8 CPUReadByte(u32 address)
|
rlm@1
|
311 {
|
rlm@1
|
312 switch (address >> 24)
|
rlm@1
|
313 {
|
rlm@1
|
314 case 0:
|
rlm@1
|
315 if (reg[15].I >> 24)
|
rlm@1
|
316 {
|
rlm@1
|
317 if (address < 0x4000)
|
rlm@1
|
318 {
|
rlm@1
|
319 #ifdef GBA_LOGGING
|
rlm@1
|
320 if (systemVerbose & VERBOSE_ILLEGAL_READ)
|
rlm@1
|
321 {
|
rlm@1
|
322 log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
323 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
324 }
|
rlm@1
|
325 #endif
|
rlm@1
|
326 return biosProtected[address & 3];
|
rlm@1
|
327 }
|
rlm@1
|
328 else
|
rlm@1
|
329 goto unreadable;
|
rlm@1
|
330 }
|
rlm@1
|
331 return bios[address & 0x3FFF];
|
rlm@1
|
332 case 2:
|
rlm@1
|
333 return workRAM[address & 0x3FFFF];
|
rlm@1
|
334 case 3:
|
rlm@1
|
335 return internalRAM[address & 0x7fff];
|
rlm@1
|
336 case 4:
|
rlm@1
|
337 if ((address < 0x4000400) && ioReadable[address & 0x3ff])
|
rlm@1
|
338 {
|
rlm@1
|
339 if (address == 0x4000130 || address == 0x4000131)
|
rlm@1
|
340 GBASystemCounters.lagged = false;
|
rlm@1
|
341 return ioMem[address & 0x3ff];
|
rlm@1
|
342 }
|
rlm@1
|
343 else
|
rlm@1
|
344 goto unreadable;
|
rlm@1
|
345 case 5:
|
rlm@1
|
346 return paletteRAM[address & 0x3ff];
|
rlm@1
|
347 case 6:
|
rlm@1
|
348 return vram[address & 0x1ffff];
|
rlm@1
|
349 case 7:
|
rlm@1
|
350 return oam[address & 0x3ff];
|
rlm@1
|
351 case 8:
|
rlm@1
|
352 case 9:
|
rlm@1
|
353 case 10:
|
rlm@1
|
354 case 11:
|
rlm@1
|
355 case 12:
|
rlm@1
|
356 return rom[address & 0x1FFFFFF];
|
rlm@1
|
357 case 13:
|
rlm@1
|
358 if (cpuEEPROMEnabled)
|
rlm@1
|
359 return eepromRead(address);
|
rlm@1
|
360 goto unreadable;
|
rlm@1
|
361 case 14:
|
rlm@1
|
362 if (cpuSramEnabled | cpuFlashEnabled)
|
rlm@1
|
363 return flashRead(address);
|
rlm@1
|
364 if (cpuEEPROMSensorEnabled)
|
rlm@1
|
365 {
|
rlm@1
|
366 switch (address & 0x00008f00)
|
rlm@1
|
367 {
|
rlm@1
|
368 case 0x8200:
|
rlm@1
|
369 return systemGetSensorX() & 255;
|
rlm@1
|
370 case 0x8300:
|
rlm@1
|
371 return (systemGetSensorX() >> 8)|0x80;
|
rlm@1
|
372 case 0x8400:
|
rlm@1
|
373 return systemGetSensorY() & 255;
|
rlm@1
|
374 case 0x8500:
|
rlm@1
|
375 return systemGetSensorY() >> 8;
|
rlm@1
|
376 }
|
rlm@1
|
377 }
|
rlm@1
|
378 // default
|
rlm@1
|
379 default:
|
rlm@1
|
380 unreadable:
|
rlm@1
|
381 #ifdef GBA_LOGGING
|
rlm@1
|
382 if (systemVerbose & VERBOSE_ILLEGAL_READ)
|
rlm@1
|
383 {
|
rlm@1
|
384 log("Illegal byte read: %08x at %08x\n", address, armMode ?
|
rlm@1
|
385 armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
386 }
|
rlm@1
|
387 #endif
|
rlm@1
|
388
|
rlm@1
|
389 if (armState)
|
rlm@1
|
390 {
|
rlm@1
|
391 return CPUReadByteQuick(reg[15].I+(address & 3));
|
rlm@1
|
392 }
|
rlm@1
|
393 else
|
rlm@1
|
394 {
|
rlm@1
|
395 return CPUReadByteQuick(reg[15].I+(address & 1));
|
rlm@1
|
396 }
|
rlm@1
|
397 // return 0xFF;
|
rlm@1
|
398 break;
|
rlm@1
|
399 }
|
rlm@1
|
400 }
|
rlm@1
|
401
|
rlm@1
|
402 inline void CPUWriteMemoryWrapped(u32 address, u32 value)
|
rlm@1
|
403 {
|
rlm@1
|
404 #ifdef GBA_LOGGING
|
rlm@1
|
405 if (address & 3)
|
rlm@1
|
406 {
|
rlm@1
|
407 if (systemVerbose & VERBOSE_UNALIGNED_MEMORY)
|
rlm@1
|
408 {
|
rlm@1
|
409 log("Unaliagned word write: %08x to %08x from %08x\n",
|
rlm@1
|
410 value,
|
rlm@1
|
411 address,
|
rlm@1
|
412 armMode ? armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
413 }
|
rlm@1
|
414 }
|
rlm@1
|
415 #endif
|
rlm@1
|
416
|
rlm@1
|
417 switch (address >> 24)
|
rlm@1
|
418 {
|
rlm@1
|
419 case 0x02:
|
rlm@1
|
420 #ifdef SDL
|
rlm@1
|
421 if (*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
|
rlm@1
|
422 cheatsWriteMemory((u32 *)&workRAM[address & 0x3FFFC],
|
rlm@1
|
423 value,
|
rlm@1
|
424 *((u32 *)&freezeWorkRAM[address & 0x3FFFC]));
|
rlm@1
|
425 else
|
rlm@1
|
426 #endif
|
rlm@1
|
427 WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
|
rlm@1
|
428 break;
|
rlm@1
|
429 case 0x03:
|
rlm@1
|
430 #ifdef SDL
|
rlm@1
|
431 if (*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
|
rlm@1
|
432 cheatsWriteMemory((u32 *)&internalRAM[address & 0x7FFC],
|
rlm@1
|
433 value,
|
rlm@1
|
434 *((u32 *)&freezeInternalRAM[address & 0x7ffc]));
|
rlm@1
|
435 else
|
rlm@1
|
436 #endif
|
rlm@1
|
437 WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
|
rlm@1
|
438 break;
|
rlm@1
|
439 case 0x04:
|
rlm@1
|
440 CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
|
rlm@1
|
441 CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
|
rlm@1
|
442 break;
|
rlm@1
|
443 case 0x05:
|
rlm@1
|
444 WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
|
rlm@1
|
445 break;
|
rlm@1
|
446 case 0x06:
|
rlm@1
|
447 if (address & 0x10000)
|
rlm@1
|
448 WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value);
|
rlm@1
|
449 else
|
rlm@1
|
450 WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value);
|
rlm@1
|
451 break;
|
rlm@1
|
452 case 0x07:
|
rlm@1
|
453 WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
|
rlm@1
|
454 break;
|
rlm@1
|
455 case 0x0D:
|
rlm@1
|
456 if (cpuEEPROMEnabled)
|
rlm@1
|
457 {
|
rlm@1
|
458 eepromWrite(address, value);
|
rlm@1
|
459 break;
|
rlm@1
|
460 }
|
rlm@1
|
461 goto unwritable;
|
rlm@1
|
462 case 0x0E:
|
rlm@1
|
463 if (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)
|
rlm@1
|
464 {
|
rlm@1
|
465 (*cpuSaveGameFunc)(address, (u8)value);
|
rlm@1
|
466 break;
|
rlm@1
|
467 }
|
rlm@1
|
468 // default
|
rlm@1
|
469 default:
|
rlm@1
|
470 unwritable:
|
rlm@1
|
471 #ifdef GBA_LOGGING
|
rlm@1
|
472 if (systemVerbose & VERBOSE_ILLEGAL_WRITE)
|
rlm@1
|
473 {
|
rlm@1
|
474 log("Illegal word write: %08x to %08x from %08x\n",
|
rlm@1
|
475 value,
|
rlm@1
|
476 address,
|
rlm@1
|
477 armMode ? armNextPC - 4 : armNextPC - 2);
|
rlm@1
|
478 }
|
rlm@1
|
479 #endif
|
rlm@1
|
480 break;
|
rlm@1
|
481 }
|
rlm@1
|
482 }
|
rlm@1
|
483
|
rlm@1
|
484 inline void CPUWriteMemory(u32 address, u32 value)
|
rlm@1
|
485 {
|
rlm@1
|
486 CPUWriteMemoryWrapped(address, value);
|
rlm@1
|
487 CallRegisteredLuaMemHook(address, 4, value, LUAMEMHOOK_WRITE);
|
rlm@1
|
488 }
|
rlm@1
|
489
|
rlm@1
|
490 #endif // VBA_GBAINLINE_H
|