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