src/gba/gba-memory.c (view raw)
1#include "gba-memory.h"
2
3#include "macros.h"
4
5#include "gba-gpio.h"
6#include "gba-io.h"
7#include "gba-serialize.h"
8#include "hle-bios.h"
9#include "util/memory.h"
10
11static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
12static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count);
13static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);
14
15static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
16static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };
17static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
18static const char GBA_BASE_WAITSTATES_SEQ_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 5, 5, 9, 9, 17, 17, 9 };
19static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
20static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
21static const int DMA_OFFSET[] = { 1, -1, 0, 1 };
22
23void GBAMemoryInit(struct GBA* gba) {
24 struct ARMCore* cpu = gba->cpu;
25 cpu->memory.load32 = GBALoad32;
26 cpu->memory.load16 = GBALoad16;
27 cpu->memory.loadU16 = GBALoadU16;
28 cpu->memory.load8 = GBALoad8;
29 cpu->memory.loadU8 = GBALoadU8;
30 cpu->memory.store32 = GBAStore32;
31 cpu->memory.store16 = GBAStore16;
32 cpu->memory.store8 = GBAStore8;
33
34 gba->memory.bios = (uint32_t*) hleBios;
35 gba->memory.fullBios = 0;
36 gba->memory.wram = 0;
37 gba->memory.iwram = 0;
38 gba->memory.rom = 0;
39 gba->memory.gpio.p = gba;
40
41 int i;
42 for (i = 0; i < 16; ++i) {
43 gba->memory.waitstatesNonseq16[i] = GBA_BASE_WAITSTATES[i];
44 gba->memory.waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
45 gba->memory.waitstatesPrefetchNonseq16[i] = GBA_BASE_WAITSTATES[i];
46 gba->memory.waitstatesPrefetchSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
47 gba->memory.waitstatesNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
48 gba->memory.waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
49 gba->memory.waitstatesPrefetchNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
50 gba->memory.waitstatesPrefetchSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
51 }
52 for (; i < 256; ++i) {
53 gba->memory.waitstatesNonseq16[i] = 0;
54 gba->memory.waitstatesSeq16[i] = 0;
55 gba->memory.waitstatesNonseq32[i] = 0;
56 gba->memory.waitstatesSeq32[i] = 0;
57 }
58
59 gba->memory.activeRegion = -1;
60 cpu->memory.activeRegion = 0;
61 cpu->memory.activeMask = 0;
62 cpu->memory.setActiveRegion = GBASetActiveRegion;
63 cpu->memory.activeSeqCycles32 = 0;
64 cpu->memory.activeSeqCycles16 = 0;
65 cpu->memory.activeNonseqCycles32 = 0;
66 cpu->memory.activeNonseqCycles16 = 0;
67 cpu->memory.activeUncachedCycles32 = 0;
68 cpu->memory.activeUncachedCycles16 = 0;
69 gba->memory.biosPrefetch = 0;
70 cpu->memory.waitMultiple = GBAWaitMultiple;
71}
72
73void GBAMemoryDeinit(struct GBA* gba) {
74 mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
75 mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
76 if (gba->memory.rom) {
77 mappedMemoryFree(gba->memory.rom, gba->memory.romSize);
78 }
79 GBASavedataDeinit(&gba->memory.savedata);
80}
81
82void GBAMemoryReset(struct GBA* gba) {
83 if (gba->memory.wram) {
84 mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
85 }
86 gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
87
88 if (gba->memory.iwram) {
89 mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
90 }
91 gba->memory.iwram = anonymousMemoryMap(SIZE_WORKING_IRAM);
92
93 memset(gba->memory.io, 0, sizeof(gba->memory.io));
94 memset(gba->memory.dma, 0, sizeof(gba->memory.dma));
95 int i;
96 for (i = 0; i < 4; ++i) {
97 gba->memory.dma[i].count = 0x10000;
98 gba->memory.dma[i].nextEvent = INT_MAX;
99 }
100 gba->memory.activeDMA = -1;
101 gba->memory.nextDMA = INT_MAX;
102 gba->memory.eventDiff = 0;
103
104 if (!gba->memory.wram || !gba->memory.iwram) {
105 GBAMemoryDeinit(gba);
106 GBALog(gba, GBA_LOG_FATAL, "Could not map memory");
107 }
108}
109
110static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
111 struct GBA* gba = (struct GBA*) cpu->master;
112 struct GBAMemory* memory = &gba->memory;
113
114 if (address == gba->busyLoop && memory->activeRegion != REGION_BIOS) {
115 GBAHalt(gba);
116 }
117
118 int newRegion = address >> BASE_OFFSET;
119 if (newRegion == memory->activeRegion) {
120 return;
121 }
122 if (memory->activeRegion == REGION_BIOS) {
123 memory->biosPrefetch = cpu->prefetch;
124 }
125 memory->activeRegion = newRegion;
126 switch (address & ~OFFSET_MASK) {
127 case BASE_BIOS:
128 cpu->memory.activeRegion = memory->bios;
129 cpu->memory.activeMask = SIZE_BIOS - 1;
130 break;
131 case BASE_WORKING_RAM:
132 cpu->memory.activeRegion = memory->wram;
133 cpu->memory.activeMask = SIZE_WORKING_RAM - 1;
134 break;
135 case BASE_WORKING_IRAM:
136 cpu->memory.activeRegion = memory->iwram;
137 cpu->memory.activeMask = SIZE_WORKING_IRAM - 1;
138 break;
139 case BASE_CART0:
140 case BASE_CART0_EX:
141 case BASE_CART1:
142 case BASE_CART1_EX:
143 case BASE_CART2:
144 case BASE_CART2_EX:
145 cpu->memory.activeRegion = memory->rom;
146 cpu->memory.activeMask = SIZE_CART0 - 1;
147 break;
148 default:
149 cpu->memory.activeRegion = 0;
150 cpu->memory.activeMask = 0;
151 GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address");
152 break;
153 }
154 cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
155 cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
156 cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
157 cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
158 cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
159 cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
160}
161
162int32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
163 struct GBA* gba = (struct GBA*) cpu->master;
164 struct GBAMemory* memory = &gba->memory;
165 uint32_t value = 0;
166 int wait = 0;
167
168 switch (address >> BASE_OFFSET) {
169 case REGION_BIOS:
170 if (memory->activeRegion == REGION_BIOS) {
171 if (address < SIZE_BIOS) {
172 LOAD_32(value, address, memory->bios);
173 } else {
174 value = 0;
175 }
176 } else {
177 value = memory->biosPrefetch;
178 }
179 break;
180 case REGION_WORKING_RAM:
181 LOAD_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
182 wait = memory->waitstatesNonseq32[REGION_WORKING_RAM];
183 break;
184 case REGION_WORKING_IRAM:
185 LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
186 break;
187 case REGION_IO:
188 value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
189 break;
190 case REGION_PALETTE_RAM:
191 LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
192 break;
193 case REGION_VRAM:
194 LOAD_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
195 break;
196 case REGION_OAM:
197 LOAD_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
198 break;
199 case REGION_CART0:
200 case REGION_CART0_EX:
201 case REGION_CART1:
202 case REGION_CART1_EX:
203 case REGION_CART2:
204 case REGION_CART2_EX:
205 wait = memory->waitstatesNonseq32[address >> BASE_OFFSET];
206 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
207 LOAD_32(value, address & (SIZE_CART0 - 1), memory->rom);
208 }
209 break;
210 case REGION_CART_SRAM:
211 case REGION_CART_SRAM_MIRROR:
212 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load32: 0x%08X", address);
213 break;
214 default:
215 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address);
216 value = cpu->prefetch;
217 if (cpu->executionMode == MODE_THUMB) {
218 value |= value << 16;
219 }
220 break;
221 }
222
223 if (cycleCounter) {
224 *cycleCounter += 2 + wait;
225 }
226 // Unaligned 32-bit loads are "rotated" so they make some semblance of sense
227 int rotate = (address & 3) << 3;
228 return (value >> rotate) | (value << (32 - rotate));
229}
230
231uint16_t GBALoadU16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
232 return GBALoad16(cpu, address, cycleCounter);
233}
234
235int16_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
236 struct GBA* gba = (struct GBA*) cpu->master;
237 struct GBAMemory* memory = &gba->memory;
238 uint16_t value = 0;
239 int wait = 0;
240
241 switch (address >> BASE_OFFSET) {
242 case REGION_BIOS:
243 if (memory->activeRegion == REGION_BIOS) {
244 if (address < SIZE_BIOS) {
245 LOAD_16(value, address, memory->bios);
246 } else {
247 value = 0;
248 }
249 } else {
250 value = memory->biosPrefetch;
251 }
252 break;
253 case REGION_WORKING_RAM:
254 LOAD_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
255 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
256 break;
257 case REGION_WORKING_IRAM:
258 LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
259 break;
260 case REGION_IO:
261 value = GBAIORead(gba, address & (SIZE_IO - 1));
262 break;
263 case REGION_PALETTE_RAM:
264 LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
265 break;
266 case REGION_VRAM:
267 LOAD_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
268 break;
269 case REGION_OAM:
270 LOAD_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
271 break;
272 case REGION_CART0:
273 case REGION_CART0_EX:
274 case REGION_CART1:
275 case REGION_CART1_EX:
276 case REGION_CART2:
277 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
278 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
279 LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
280 }
281 break;
282 case REGION_CART2_EX:
283 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
284 if (memory->savedata.type == SAVEDATA_EEPROM) {
285 value = GBASavedataReadEEPROM(&memory->savedata);
286 } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
287 LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
288 }
289 break;
290 case REGION_CART_SRAM:
291 case REGION_CART_SRAM_MIRROR:
292 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load16: 0x%08X", address);
293 break;
294 default:
295 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
296 value = cpu->prefetch;
297 break;
298 }
299
300 if (cycleCounter) {
301 *cycleCounter += 2 + wait;
302 }
303 // Unaligned 16-bit loads are "unpredictable", but the GBA rotates them, so we have to, too.
304 int rotate = (address & 1) << 3;
305 return (value >> rotate) | (value << (16 - rotate));
306}
307
308uint8_t GBALoadU8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
309 return GBALoad8(cpu, address, cycleCounter);
310}
311
312int8_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
313 struct GBA* gba = (struct GBA*) cpu->master;
314 struct GBAMemory* memory = &gba->memory;
315 int8_t value = 0;
316 int wait = 0;
317
318 switch (address >> BASE_OFFSET) {
319 case REGION_BIOS:
320 if (memory->activeRegion == REGION_BIOS) {
321 if (address < SIZE_BIOS) {
322 value = ((int8_t*) memory->bios)[address];
323 } else {
324 value = 0;
325 }
326 } else {
327 value = memory->biosPrefetch;
328 }
329 break;
330 case REGION_WORKING_RAM:
331 value = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
332 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
333 break;
334 case REGION_WORKING_IRAM:
335 value = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
336 break;
337 case REGION_IO:
338 value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
339 break;
340 case REGION_PALETTE_RAM:
341 value = ((int8_t*) gba->video.palette)[address & (SIZE_PALETTE_RAM - 1)];
342 break;
343 case REGION_VRAM:
344 value = ((int8_t*) gba->video.renderer->vram)[address & 0x0001FFFF];
345 break;
346 case REGION_OAM:
347 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address);
348 break;
349 case REGION_CART0:
350 case REGION_CART0_EX:
351 case REGION_CART1:
352 case REGION_CART1_EX:
353 case REGION_CART2:
354 case REGION_CART2_EX:
355 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
356 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
357 value = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
358 }
359 break;
360 case REGION_CART_SRAM:
361 case REGION_CART_SRAM_MIRROR:
362 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
363 if (memory->savedata.type == SAVEDATA_NONE) {
364 GBASavedataInitSRAM(&memory->savedata);
365 }
366 if (memory->savedata.type == SAVEDATA_SRAM) {
367 value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
368 } else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
369 value = GBASavedataReadFlash(&memory->savedata, address);
370 }
371 break;
372 default:
373 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
374 value = cpu->prefetch & 0xFF;
375 break;
376 }
377
378 if (cycleCounter) {
379 *cycleCounter += 2 + wait;
380 }
381 return value;
382}
383
384void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
385 struct GBA* gba = (struct GBA*) cpu->master;
386 struct GBAMemory* memory = &gba->memory;
387 int wait = 0;
388
389 switch (address >> BASE_OFFSET) {
390 case REGION_WORKING_RAM:
391 STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
392 wait = memory->waitstatesNonseq32[REGION_WORKING_RAM];
393 break;
394 case REGION_WORKING_IRAM:
395 STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
396 break;
397 case REGION_IO:
398 GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
399 break;
400 case REGION_PALETTE_RAM:
401 STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
402 gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
403 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
404 break;
405 case REGION_VRAM:
406 if ((address & OFFSET_MASK) < SIZE_VRAM) {
407 STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
408 } else if ((address & OFFSET_MASK) < 0x00020000) {
409 STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram);
410 }
411 break;
412 case REGION_OAM:
413 STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
414 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
415 gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
416 break;
417 case REGION_CART0:
418 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
419 break;
420 case REGION_CART_SRAM:
421 case REGION_CART_SRAM_MIRROR:
422 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
423 break;
424 default:
425 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
426 break;
427 }
428
429 if (cycleCounter) {
430 *cycleCounter += 1 + wait;
431 }
432}
433
434void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
435 struct GBA* gba = (struct GBA*) cpu->master;
436 struct GBAMemory* memory = &gba->memory;
437 int wait = 0;
438
439 switch (address >> BASE_OFFSET) {
440 case REGION_WORKING_RAM:
441 STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
442 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
443 break;
444 case REGION_WORKING_IRAM:
445 STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
446 break;
447 case REGION_IO:
448 GBAIOWrite(gba, address & (SIZE_IO - 1), value);
449 break;
450 case REGION_PALETTE_RAM:
451 STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
452 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
453 break;
454 case REGION_VRAM:
455 if ((address & OFFSET_MASK) < SIZE_VRAM) {
456 STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
457 } else if ((address & OFFSET_MASK) < 0x00020000) {
458 STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
459 }
460 break;
461 case REGION_OAM:
462 STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
463 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
464 break;
465 case REGION_CART0:
466 if (IS_GPIO_REGISTER(address & 0xFFFFFF)) {
467 uint32_t reg = address & 0xFFFFFF;
468 GBAGPIOWrite(&memory->gpio, reg, value);
469 } else {
470 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
471 }
472 break;
473 case REGION_CART2_EX:
474 if (memory->savedata.type == SAVEDATA_NONE) {
475 GBASavedataInitEEPROM(&memory->savedata);
476 }
477 GBASavedataWriteEEPROM(&memory->savedata, value, 1);
478 break;
479 case REGION_CART_SRAM:
480 case REGION_CART_SRAM_MIRROR:
481 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
482 break;
483 default:
484 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
485 break;
486 }
487
488 if (cycleCounter) {
489 *cycleCounter += 1 + wait;
490 }
491}
492
493void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
494 struct GBA* gba = (struct GBA*) cpu->master;
495 struct GBAMemory* memory = &gba->memory;
496 int wait = 0;
497
498 switch (address >> BASE_OFFSET) {
499 case REGION_WORKING_RAM:
500 ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
501 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
502 break;
503 case REGION_WORKING_IRAM:
504 ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
505 break;
506 case REGION_IO:
507 GBAIOWrite8(gba, address & (SIZE_IO - 1), value);
508 break;
509 case REGION_PALETTE_RAM:
510 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
511 break;
512 case REGION_VRAM:
513 if (address >= 0x06018000) {
514 // TODO: check BG mode
515 GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
516 break;
517 }
518 ((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value;
519 ((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
520 break;
521 case REGION_OAM:
522 GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
523 break;
524 case REGION_CART0:
525 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
526 break;
527 case REGION_CART_SRAM:
528 case REGION_CART_SRAM_MIRROR:
529 if (memory->savedata.type == SAVEDATA_NONE) {
530 if (address == SAVEDATA_FLASH_BASE) {
531 GBASavedataInitFlash(&memory->savedata);
532 } else {
533 GBASavedataInitSRAM(&memory->savedata);
534 }
535 }
536 if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
537 GBASavedataWriteFlash(&memory->savedata, address, value);
538 } else if (memory->savedata.type == SAVEDATA_SRAM) {
539 memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
540 }
541 wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
542 break;
543 default:
544 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
545 break;
546 }
547
548 if (cycleCounter) {
549 *cycleCounter += 1 + wait;
550 }
551}
552
553static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count) {
554 struct GBA* gba = (struct GBA*) cpu->master;
555 struct GBAMemory* memory = &gba->memory;
556 int wait = 1 + memory->waitstatesNonseq32[startAddress >> BASE_OFFSET];
557 wait += (1 + memory->waitstatesSeq32[startAddress >> BASE_OFFSET]) * (count - 1);
558 return wait;
559}
560
561void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
562 struct GBAMemory* memory = &gba->memory;
563 struct ARMCore* cpu = gba->cpu;
564 int sram = parameters & 0x0003;
565 int ws0 = (parameters & 0x000C) >> 2;
566 int ws0seq = (parameters & 0x0010) >> 4;
567 int ws1 = (parameters & 0x0060) >> 5;
568 int ws1seq = (parameters & 0x0080) >> 7;
569 int ws2 = (parameters & 0x0300) >> 8;
570 int ws2seq = (parameters & 0x0400) >> 10;
571 int prefetch = parameters & 0x4000;
572
573 memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
574 memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
575 memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
576 memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
577
578 memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
579 memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
580 memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
581
582 memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
583 memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
584 memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
585
586 memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
587 memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
588 memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
589
590 memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
591 memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
592 memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
593
594 if (!prefetch) {
595 memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0];
596 memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1];
597 memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2];
598
599 memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = memory->waitstatesSeq32[REGION_CART0];
600 memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = memory->waitstatesSeq32[REGION_CART1];
601 memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = memory->waitstatesSeq32[REGION_CART2];
602
603 memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0];
604 memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1];
605 memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2];
606
607 memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq32[REGION_CART0];
608 memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq32[REGION_CART1];
609 memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq32[REGION_CART2];
610 } else {
611 memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = 0;
612 memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = 0;
613 memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = 0;
614
615 memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = 0;
616 memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = 0;
617 memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = 0;
618
619 memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = 0;
620 memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = 0;
621 memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = 0;
622
623 memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = 0;
624 memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = 0;
625 memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = 0;
626 }
627
628 cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
629 cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
630
631 cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
632 cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
633
634 cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
635 cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
636}
637
638void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
639 struct GBAMemory* memory = &gba->memory;
640 memory->dma[dma].source = address & 0xFFFFFFFE;
641}
642
643void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
644 struct GBAMemory* memory = &gba->memory;
645 memory->dma[dma].dest = address & 0xFFFFFFFE;
646}
647
648void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
649 struct GBAMemory* memory = &gba->memory;
650 memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
651}
652
653uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
654 struct GBAMemory* memory = &gba->memory;
655 struct GBADMA* currentDma = &memory->dma[dma];
656 int wasEnabled = GBADMARegisterIsEnable(currentDma->reg);
657 currentDma->reg = control;
658
659 if (GBADMARegisterIsDRQ(currentDma->reg)) {
660 GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
661 }
662
663 if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) {
664 currentDma->nextSource = currentDma->source;
665 currentDma->nextDest = currentDma->dest;
666 currentDma->nextCount = currentDma->count;
667 GBAMemoryScheduleDMA(gba, dma, currentDma);
668 }
669 // If the DMA has already occurred, this value might have changed since the function started
670 return currentDma->reg;
671};
672
673void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
674 struct ARMCore* cpu = gba->cpu;
675 switch (GBADMARegisterGetTiming(info->reg)) {
676 case DMA_TIMING_NOW:
677 info->nextEvent = cpu->cycles;
678 GBAMemoryUpdateDMAs(gba, 0);
679 break;
680 case DMA_TIMING_HBLANK:
681 // Handled implicitly
682 info->nextEvent = INT_MAX;
683 break;
684 case DMA_TIMING_VBLANK:
685 // Handled implicitly
686 info->nextEvent = INT_MAX;
687 break;
688 case DMA_TIMING_CUSTOM:
689 info->nextEvent = INT_MAX;
690 switch (number) {
691 case 0:
692 GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
693 break;
694 case 1:
695 case 2:
696 GBAAudioScheduleFifoDma(&gba->audio, number, info);
697 break;
698 case 3:
699 // GBAVideoScheduleVCaptureDma(dma, info);
700 break;
701 }
702 }
703}
704
705void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
706 struct GBAMemory* memory = &gba->memory;
707 struct GBADMA* dma;
708 int i;
709 for (i = 0; i < 4; ++i) {
710 dma = &memory->dma[i];
711 if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_HBLANK) {
712 dma->nextEvent = cycles;
713 }
714 }
715 GBAMemoryUpdateDMAs(gba, 0);
716}
717
718void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
719 struct GBAMemory* memory = &gba->memory;
720 struct GBADMA* dma;
721 int i;
722 for (i = 0; i < 4; ++i) {
723 dma = &memory->dma[i];
724 if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_VBLANK) {
725 dma->nextEvent = cycles;
726 }
727 }
728 GBAMemoryUpdateDMAs(gba, 0);
729}
730
731int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
732 struct GBAMemory* memory = &gba->memory;
733 if (memory->nextDMA == INT_MAX) {
734 return INT_MAX;
735 }
736 memory->nextDMA -= cycles;
737 memory->eventDiff += cycles;
738 if (memory->nextDMA <= 0) {
739 struct GBADMA* dma = &memory->dma[memory->activeDMA];
740 GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
741 GBAMemoryUpdateDMAs(gba, memory->eventDiff);
742 memory->eventDiff = 0;
743 }
744 return memory->nextDMA;
745}
746
747void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
748 int i;
749 struct GBAMemory* memory = &gba->memory;
750 struct ARMCore* cpu = gba->cpu;
751 memory->activeDMA = -1;
752 memory->nextDMA = INT_MAX;
753 for (i = 3; i >= 0; --i) {
754 struct GBADMA* dma = &memory->dma[i];
755 if (dma->nextEvent != INT_MAX) {
756 dma->nextEvent -= cycles;
757 if (GBADMARegisterIsEnable(dma->reg)) {
758 memory->activeDMA = i;
759 memory->nextDMA = dma->nextEvent;
760 }
761 }
762 }
763 if (memory->nextDMA < cpu->nextEvent) {
764 cpu->nextEvent = memory->nextDMA;
765 }
766}
767
768void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
769 struct GBAMemory* memory = &gba->memory;
770 struct ARMCore* cpu = gba->cpu;
771 uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2;
772 int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width;
773 int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width;
774 int32_t wordsRemaining = info->nextCount;
775 uint32_t source = info->nextSource;
776 uint32_t dest = info->nextDest;
777 uint32_t sourceRegion = source >> BASE_OFFSET;
778 uint32_t destRegion = dest >> BASE_OFFSET;
779 int32_t cycles = 0;
780
781 if (source == info->source) {
782 // TODO: support 4 cycles for ROM access
783 cycles += 2;
784 if (width == 4) {
785 cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
786 source &= 0xFFFFFFFC;
787 dest &= 0xFFFFFFFC;
788 } else {
789 cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
790 }
791 } else {
792 if (width == 4) {
793 cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
794 } else {
795 cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
796 }
797 }
798
799 if (width == 4) {
800 int32_t word;
801 word = cpu->memory.load32(cpu, source, 0);
802 cpu->memory.store32(cpu, dest, word, 0);
803 source += sourceOffset;
804 dest += destOffset;
805 --wordsRemaining;
806 } else {
807 uint16_t word;
808 if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
809 word = GBASavedataReadEEPROM(&memory->savedata);
810 cpu->memory.store16(cpu, dest, word, 0);
811 source += sourceOffset;
812 dest += destOffset;
813 --wordsRemaining;
814 } else if (destRegion == REGION_CART2_EX) {
815 if (memory->savedata.type == SAVEDATA_NONE) {
816 GBASavedataInitEEPROM(&memory->savedata);
817 }
818 word = cpu->memory.load16(cpu, source, 0);
819 GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
820 source += sourceOffset;
821 dest += destOffset;
822 --wordsRemaining;
823 } else {
824 word = cpu->memory.load16(cpu, source, 0);
825 cpu->memory.store16(cpu, dest, word, 0);
826 source += sourceOffset;
827 dest += destOffset;
828 --wordsRemaining;
829 }
830 }
831
832 if (!wordsRemaining) {
833 if (!GBADMARegisterIsRepeat(info->reg)) {
834 info->reg = GBADMARegisterClearEnable(info->reg);
835 info->nextEvent = INT_MAX;
836
837 // Clear the enable bit in memory
838 memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
839 } else {
840 info->nextCount = info->count;
841 if (GBADMARegisterGetDestControl(info->reg) == DMA_INCREMENT_RELOAD) {
842 info->nextDest = info->dest;
843 }
844 GBAMemoryScheduleDMA(gba, number, info);
845 }
846 if (GBADMARegisterIsDoIRQ(info->reg)) {
847 GBARaiseIRQ(gba, IRQ_DMA0 + number);
848 }
849 } else {
850 info->nextDest = dest;
851 info->nextCount = wordsRemaining;
852 }
853 info->nextSource = source;
854
855 if (info->nextEvent != INT_MAX) {
856 info->nextEvent += cycles;
857 }
858 cpu->cycles += cycles;
859}
860
861void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state) {
862 memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
863 memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
864}
865
866void GBAMemoryDeserialize(struct GBAMemory* memory, struct GBASerializedState* state) {
867 memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
868 memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
869}