src/gba/memory.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "memory.h"
7
8#include "macros.h"
9
10#include "decoder.h"
11#include "gba/hardware.h"
12#include "gba/io.h"
13#include "gba/serialize.h"
14#include "gba/hle-bios.h"
15#include "util/memory.h"
16
17#define IDLE_LOOP_THRESHOLD 10000
18
19static uint32_t _popcount32(unsigned bits);
20static uint32_t _deadbeef[2] = { 0xDEADBEEF, 0xFEEDFACE };
21
22static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
23static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);
24
25static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
26static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };
27static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
28static const char GBA_BASE_WAITSTATES_SEQ_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 5, 5, 9, 9, 17, 17, 9 };
29static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
30static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
31static const int DMA_OFFSET[] = { 1, -1, 0, 1 };
32
33void GBAMemoryInit(struct GBA* gba) {
34 struct ARMCore* cpu = gba->cpu;
35 cpu->memory.load32 = GBALoad32;
36 cpu->memory.load16 = GBALoad16;
37 cpu->memory.load8 = GBALoad8;
38 cpu->memory.loadMultiple = GBALoadMultiple;
39 cpu->memory.store32 = GBAStore32;
40 cpu->memory.store16 = GBAStore16;
41 cpu->memory.store8 = GBAStore8;
42 cpu->memory.storeMultiple = GBAStoreMultiple;
43
44 gba->memory.bios = (uint32_t*) hleBios;
45 gba->memory.fullBios = 0;
46 gba->memory.wram = 0;
47 gba->memory.iwram = 0;
48 gba->memory.rom = 0;
49 gba->memory.hw.p = gba;
50
51 int i;
52 for (i = 0; i < 16; ++i) {
53 gba->memory.waitstatesNonseq16[i] = GBA_BASE_WAITSTATES[i];
54 gba->memory.waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
55 gba->memory.waitstatesPrefetchNonseq16[i] = GBA_BASE_WAITSTATES[i];
56 gba->memory.waitstatesPrefetchSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
57 gba->memory.waitstatesNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
58 gba->memory.waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
59 gba->memory.waitstatesPrefetchNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
60 gba->memory.waitstatesPrefetchSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
61 }
62 for (; i < 256; ++i) {
63 gba->memory.waitstatesNonseq16[i] = 0;
64 gba->memory.waitstatesSeq16[i] = 0;
65 gba->memory.waitstatesNonseq32[i] = 0;
66 gba->memory.waitstatesSeq32[i] = 0;
67 }
68
69 gba->memory.activeRegion = -1;
70 cpu->memory.activeRegion = 0;
71 cpu->memory.activeMask = 0;
72 cpu->memory.setActiveRegion = GBASetActiveRegion;
73 cpu->memory.activeSeqCycles32 = 0;
74 cpu->memory.activeSeqCycles16 = 0;
75 cpu->memory.activeNonseqCycles32 = 0;
76 cpu->memory.activeNonseqCycles16 = 0;
77 cpu->memory.activeUncachedCycles32 = 0;
78 cpu->memory.activeUncachedCycles16 = 0;
79 gba->memory.biosPrefetch = 0;
80}
81
82void GBAMemoryDeinit(struct GBA* gba) {
83 mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
84 mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
85 if (gba->memory.rom) {
86 mappedMemoryFree(gba->memory.rom, gba->memory.romSize);
87 }
88 GBASavedataDeinit(&gba->memory.savedata);
89}
90
91void GBAMemoryReset(struct GBA* gba) {
92 if (gba->memory.wram) {
93 mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
94 }
95 gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
96
97 if (gba->memory.iwram) {
98 mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
99 }
100 gba->memory.iwram = anonymousMemoryMap(SIZE_WORKING_IRAM);
101
102 memset(gba->memory.io, 0, sizeof(gba->memory.io));
103 memset(gba->memory.dma, 0, sizeof(gba->memory.dma));
104 int i;
105 for (i = 0; i < 4; ++i) {
106 gba->memory.dma[i].count = 0x4000;
107 gba->memory.dma[i].nextEvent = INT_MAX;
108 }
109 gba->memory.dma[3].count = 0x10000;
110 gba->memory.activeDMA = -1;
111 gba->memory.nextDMA = INT_MAX;
112 gba->memory.eventDiff = 0;
113
114 if (!gba->memory.wram || !gba->memory.iwram) {
115 GBAMemoryDeinit(gba);
116 GBALog(gba, GBA_LOG_FATAL, "Could not map memory");
117 }
118}
119
120static void _analyzeForIdleLoop(struct GBA* gba, struct ARMCore* cpu, uint32_t address) {
121 struct ARMInstructionInfo info;
122 uint32_t nextAddress = address;
123 memset(gba->taintedRegisters, 0, sizeof(gba->taintedRegisters));
124 if (cpu->executionMode == MODE_THUMB) {
125 while (true) {
126 uint16_t opcode;
127 LOAD_16(opcode, nextAddress & cpu->memory.activeMask, cpu->memory.activeRegion);
128 ARMDecodeThumb(opcode, &info);
129 switch (info.branchType) {
130 case ARM_BRANCH_NONE:
131 if (info.operandFormat & ARM_OPERAND_MEMORY_2) {
132 if (info.mnemonic == ARM_MN_STR || gba->taintedRegisters[info.memory.baseReg]) {
133 gba->idleDetectionStep = -1;
134 return;
135 }
136 uint32_t loadAddress = gba->cachedRegisters[info.memory.baseReg];
137 uint32_t offset = 0;
138 if (info.memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
139 offset = info.memory.offset.immediate;
140 } else if (info.memory.format & ARM_MEMORY_REGISTER_OFFSET) {
141 int reg = info.memory.offset.reg;
142 if (gba->cachedRegisters[reg]) {
143 gba->idleDetectionStep = -1;
144 return;
145 }
146 offset = gba->cachedRegisters[reg];
147 }
148 if (info.memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
149 loadAddress -= offset;
150 } else {
151 loadAddress += offset;
152 }
153 if ((loadAddress >> BASE_OFFSET) == REGION_IO) {
154 gba->idleDetectionStep = -1;
155 return;
156 }
157 if ((loadAddress >> BASE_OFFSET) < REGION_CART0 || (loadAddress >> BASE_OFFSET) > REGION_CART2_EX) {
158 gba->taintedRegisters[info.op1.reg] = true;
159 } else {
160 switch (info.memory.width) {
161 case 1:
162 gba->cachedRegisters[info.op1.reg] = GBALoad8(cpu, loadAddress, 0);
163 break;
164 case 2:
165 gba->cachedRegisters[info.op1.reg] = GBALoad16(cpu, loadAddress, 0);
166 break;
167 case 4:
168 gba->cachedRegisters[info.op1.reg] = GBALoad32(cpu, loadAddress, 0);
169 break;
170 }
171 }
172 } else if (info.operandFormat & ARM_OPERAND_AFFECTED_1) {
173 gba->taintedRegisters[info.op1.reg] = true;
174 }
175 nextAddress += WORD_SIZE_THUMB;
176 break;
177 case ARM_BRANCH:
178 if ((uint32_t) info.op1.immediate + nextAddress + WORD_SIZE_THUMB * 2 == address) {
179 gba->idleLoop = address;
180 gba->idleOptimization = IDLE_LOOP_REMOVE;
181 }
182 gba->idleDetectionStep = -1;
183 return;
184 default:
185 gba->idleDetectionStep = -1;
186 return;
187 }
188 }
189 } else {
190 gba->idleDetectionStep = -1;
191 }
192}
193
194static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
195 struct GBA* gba = (struct GBA*) cpu->master;
196 struct GBAMemory* memory = &gba->memory;
197
198 int newRegion = address >> BASE_OFFSET;
199 if (gba->idleOptimization >= IDLE_LOOP_REMOVE && memory->activeRegion != REGION_BIOS) {
200 if (address == gba->idleLoop) {
201 if (gba->haltPending) {
202 gba->haltPending = false;
203 GBAHalt(gba);
204 } else {
205 gba->haltPending = true;
206 }
207 } else if (gba->idleOptimization >= IDLE_LOOP_DETECT && newRegion == memory->activeRegion) {
208 if (address == gba->lastJump) {
209 switch (gba->idleDetectionStep) {
210 case 0:
211 memcpy(gba->cachedRegisters, cpu->gprs, sizeof(gba->cachedRegisters));
212 ++gba->idleDetectionStep;
213 break;
214 case 1:
215 if (memcmp(gba->cachedRegisters, cpu->gprs, sizeof(gba->cachedRegisters))) {
216 gba->idleDetectionStep = -1;
217 ++gba->idleDetectionFailures;
218 if (gba->idleDetectionFailures > IDLE_LOOP_THRESHOLD) {
219 gba->idleOptimization = IDLE_LOOP_IGNORE;
220 }
221 break;
222 }
223 _analyzeForIdleLoop(gba, cpu, address);
224 break;
225 }
226 } else {
227 gba->idleDetectionStep = 0;
228 }
229 }
230 }
231
232 gba->lastJump = address;
233 if (newRegion == memory->activeRegion) {
234 return;
235 }
236
237 if (memory->activeRegion == REGION_BIOS) {
238 memory->biosPrefetch = cpu->prefetch[1];
239 }
240 memory->activeRegion = newRegion;
241 switch (address & ~OFFSET_MASK) {
242 case BASE_BIOS:
243 cpu->memory.activeRegion = memory->bios;
244 cpu->memory.activeMask = SIZE_BIOS - 1;
245 break;
246 case BASE_WORKING_RAM:
247 cpu->memory.activeRegion = memory->wram;
248 cpu->memory.activeMask = SIZE_WORKING_RAM - 1;
249 break;
250 case BASE_WORKING_IRAM:
251 cpu->memory.activeRegion = memory->iwram;
252 cpu->memory.activeMask = SIZE_WORKING_IRAM - 1;
253 break;
254 case BASE_VRAM:
255 cpu->memory.activeRegion = (uint32_t*) gba->video.renderer->vram;
256 cpu->memory.activeMask = 0x0000FFFF;
257 break;
258 case BASE_CART0:
259 case BASE_CART0_EX:
260 case BASE_CART1:
261 case BASE_CART1_EX:
262 case BASE_CART2:
263 case BASE_CART2_EX:
264 cpu->memory.activeRegion = memory->rom;
265 cpu->memory.activeMask = SIZE_CART0 - 1;
266 break;
267 default:
268 cpu->memory.activeRegion = _deadbeef;
269 cpu->memory.activeMask = 0;
270 GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address");
271 break;
272 }
273 cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
274 cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
275 cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
276 cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
277 cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
278 cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
279}
280
281#define LOAD_BAD \
282 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address); \
283 if (gba->performingDMA) { \
284 value = gba->bus; \
285 } else { \
286 value = cpu->prefetch[1]; \
287 if (cpu->executionMode == MODE_THUMB) { \
288 value |= value << 16; \
289 } \
290 }
291
292#define LOAD_BIOS \
293 if (address < SIZE_BIOS) { \
294 if (memory->activeRegion == REGION_BIOS) { \
295 LOAD_32(value, address, memory->bios); \
296 } else { \
297 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad BIOS Load32: 0x%08X", address); \
298 value = memory->biosPrefetch; \
299 } \
300 } else { \
301 LOAD_BAD; \
302 }
303
304#define LOAD_WORKING_RAM \
305 LOAD_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); \
306 wait += waitstatesRegion[REGION_WORKING_RAM];
307
308#define LOAD_WORKING_IRAM LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
309#define LOAD_IO value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
310
311#define LOAD_PALETTE_RAM \
312 LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \
313 ++wait;
314
315#define LOAD_VRAM \
316 if ((address & 0x0001FFFF) < SIZE_VRAM) { \
317 LOAD_32(value, address & 0x0001FFFF, gba->video.renderer->vram); \
318 } else { \
319 LOAD_32(value, address & 0x00017FFF, gba->video.renderer->vram); \
320 } \
321 ++wait;
322
323#define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
324
325#define LOAD_CART \
326 wait += waitstatesRegion[address >> BASE_OFFSET]; \
327 if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
328 LOAD_32(value, address & (SIZE_CART0 - 1), memory->rom); \
329 } else { \
330 GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
331 value = (address >> 1) & 0xFFFF; \
332 value |= value << 16; \
333 }
334
335#define LOAD_SRAM \
336 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; \
337 value = GBALoad8(cpu, address, 0); \
338 value |= value << 8; \
339 value |= value << 16;
340
341uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
342 struct GBA* gba = (struct GBA*) cpu->master;
343 struct GBAMemory* memory = &gba->memory;
344 uint32_t value = 0;
345 int wait = 0;
346 char* waitstatesRegion = memory->waitstatesNonseq32;
347
348 switch (address >> BASE_OFFSET) {
349 case REGION_BIOS:
350 LOAD_BIOS;
351 break;
352 case REGION_WORKING_RAM:
353 LOAD_WORKING_RAM;
354 break;
355 case REGION_WORKING_IRAM:
356 LOAD_WORKING_IRAM;
357 break;
358 case REGION_IO:
359 LOAD_IO;
360 break;
361 case REGION_PALETTE_RAM:
362 LOAD_PALETTE_RAM;
363 break;
364 case REGION_VRAM:
365 LOAD_VRAM;
366 break;
367 case REGION_OAM:
368 LOAD_OAM;
369 break;
370 case REGION_CART0:
371 case REGION_CART0_EX:
372 case REGION_CART1:
373 case REGION_CART1_EX:
374 case REGION_CART2:
375 case REGION_CART2_EX:
376 LOAD_CART;
377 break;
378 case REGION_CART_SRAM:
379 case REGION_CART_SRAM_MIRROR:
380 LOAD_SRAM;
381 break;
382 default:
383 LOAD_BAD;
384 break;
385 }
386
387 if (cycleCounter) {
388 *cycleCounter += 1 + wait;
389 }
390 // Unaligned 32-bit loads are "rotated" so they make some semblance of sense
391 int rotate = (address & 3) << 3;
392 return ROR(value, rotate);
393}
394
395uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
396 struct GBA* gba = (struct GBA*) cpu->master;
397 struct GBAMemory* memory = &gba->memory;
398 uint32_t value = 0;
399 int wait = 0;
400
401 switch (address >> BASE_OFFSET) {
402 case REGION_BIOS:
403 if (address < SIZE_BIOS) {
404 if (memory->activeRegion == REGION_BIOS) {
405 LOAD_16(value, address, memory->bios);
406 } else {
407 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad BIOS Load16: 0x%08X", address);
408 LOAD_16(value, address & 2, &memory->biosPrefetch);
409 }
410 } else {
411 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
412 if (gba->performingDMA) {
413 LOAD_16(value, address & 2, &gba->bus);
414 } else {
415 uint32_t prefetch = cpu->prefetch[1];
416 if (cpu->executionMode == MODE_THUMB) {
417 prefetch |= prefetch << 16;
418 }
419 LOAD_16(value, address & 2, &prefetch);
420 }
421 }
422 break;
423 case REGION_WORKING_RAM:
424 LOAD_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
425 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
426 break;
427 case REGION_WORKING_IRAM:
428 LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
429 break;
430 case REGION_IO:
431 value = GBAIORead(gba, address & (SIZE_IO - 1));
432 break;
433 case REGION_PALETTE_RAM:
434 LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
435 break;
436 case REGION_VRAM:
437 if ((address & 0x0001FFFF) < SIZE_VRAM) {
438 LOAD_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
439 } else {
440 LOAD_16(value, address & 0x00017FFF, gba->video.renderer->vram);
441 }
442 break;
443 case REGION_OAM:
444 LOAD_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
445 break;
446 case REGION_CART0:
447 case REGION_CART0_EX:
448 case REGION_CART1:
449 case REGION_CART1_EX:
450 case REGION_CART2:
451 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
452 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
453 LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
454 } else {
455 GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
456 value = (address >> 1) & 0xFFFF; \
457 }
458 break;
459 case REGION_CART2_EX:
460 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
461 if (memory->savedata.type == SAVEDATA_EEPROM) {
462 value = GBASavedataReadEEPROM(&memory->savedata);
463 } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
464 LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
465 } else {
466 GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
467 value = (address >> 1) & 0xFFFF; \
468 }
469 break;
470 case REGION_CART_SRAM:
471 case REGION_CART_SRAM_MIRROR:
472 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
473 value = GBALoad8(cpu, address, 0);
474 value |= value << 8;
475 break;
476 default:
477 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
478 if (gba->performingDMA) {
479 LOAD_16(value, address & 2, &gba->bus);
480 } else {
481 uint32_t prefetch = cpu->prefetch[1];
482 if (cpu->executionMode == MODE_THUMB) {
483 prefetch |= prefetch << 16;
484 }
485 LOAD_16(value, address & 2, &prefetch);
486 }
487 break;
488 }
489
490 if (cycleCounter) {
491 *cycleCounter += 1 + wait;
492 }
493 // Unaligned 16-bit loads are "unpredictable", but the GBA rotates them, so we have to, too.
494 int rotate = (address & 1) << 3;
495 return ROR(value, rotate);
496}
497
498uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
499 struct GBA* gba = (struct GBA*) cpu->master;
500 struct GBAMemory* memory = &gba->memory;
501 uint8_t value = 0;
502 int wait = 0;
503
504 switch (address >> BASE_OFFSET) {
505 case REGION_BIOS:
506 if (address < SIZE_BIOS) {
507 if (memory->activeRegion == REGION_BIOS) {
508 value = ((int8_t*) memory->bios)[address];
509 } else {
510 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad BIOS Load8: 0x%08X", address);
511 value = ((uint8_t*) &memory->biosPrefetch)[address & 3];
512 }
513 } else {
514 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
515 if (gba->performingDMA) {
516 value = ((uint8_t*) &gba->bus)[address & 3];
517 } else {
518 uint32_t prefetch = cpu->prefetch[1];
519 if (cpu->executionMode == MODE_THUMB) {
520 prefetch |= prefetch << 16;
521 }
522 value = ((uint8_t*) &prefetch)[address & 3];
523 }
524 }
525 break;
526 case REGION_WORKING_RAM:
527 value = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
528 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
529 break;
530 case REGION_WORKING_IRAM:
531 value = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
532 break;
533 case REGION_IO:
534 value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
535 break;
536 case REGION_PALETTE_RAM:
537 value = ((int8_t*) gba->video.palette)[address & (SIZE_PALETTE_RAM - 1)];
538 break;
539 case REGION_VRAM:
540 if ((address & 0x0001FFFF) < SIZE_VRAM) {
541 value = ((int8_t*) gba->video.renderer->vram)[address & 0x0001FFFF];
542 } else {
543 value = ((int8_t*) gba->video.renderer->vram)[address & 0x00017FFF];
544 }
545 break;
546 case REGION_OAM:
547 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address);
548 break;
549 case REGION_CART0:
550 case REGION_CART0_EX:
551 case REGION_CART1:
552 case REGION_CART1_EX:
553 case REGION_CART2:
554 case REGION_CART2_EX:
555 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
556 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
557 value = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
558 } else {
559 GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load8: 0x%08X", address);
560 value = (address >> 1) & 0xFF; \
561 }
562 break;
563 case REGION_CART_SRAM:
564 case REGION_CART_SRAM_MIRROR:
565 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
566 if (memory->savedata.type == SAVEDATA_AUTODETECT) {
567 GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame");
568 GBASavedataInitSRAM(&memory->savedata);
569 }
570 if (memory->savedata.type == SAVEDATA_SRAM) {
571 value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
572 } else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
573 value = GBASavedataReadFlash(&memory->savedata, address);
574 } else if (memory->hw.devices & HW_TILT) {
575 value = GBAHardwareTiltRead(&memory->hw, address & OFFSET_MASK);
576 } else {
577 GBALog(gba, GBA_LOG_GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
578 value = 0xFF;
579 }
580 break;
581 default:
582 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
583 if (gba->performingDMA) {
584 value = ((uint8_t*) &gba->bus)[address & 3];
585 } else {
586 uint32_t prefetch = cpu->prefetch[1];
587 if (cpu->executionMode == MODE_THUMB) {
588 prefetch |= prefetch << 16;
589 }
590 value = ((uint8_t*) &prefetch)[address & 3];
591 }
592 break;
593 }
594
595 if (cycleCounter) {
596 *cycleCounter += 1 + wait;
597 }
598 return value;
599}
600
601#define STORE_WORKING_RAM \
602 STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); \
603 wait += waitstatesRegion[REGION_WORKING_RAM];
604
605#define STORE_WORKING_IRAM \
606 STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
607
608#define STORE_IO \
609 GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
610
611#define STORE_PALETTE_RAM \
612 STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \
613 gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16); \
614 ++wait; \
615 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
616
617#define STORE_VRAM \
618 if ((address & 0x0001FFFF) < SIZE_VRAM) { \
619 STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram); \
620 } else { \
621 STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram); \
622 } \
623 ++wait;
624
625#define STORE_OAM \
626 STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw); \
627 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1); \
628 gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
629
630#define STORE_CART \
631 wait += waitstatesRegion[address >> BASE_OFFSET]; \
632 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
633
634#define STORE_SRAM \
635 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
636
637#define STORE_BAD \
638 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
639
640void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
641 struct GBA* gba = (struct GBA*) cpu->master;
642 struct GBAMemory* memory = &gba->memory;
643 int wait = 0;
644 char* waitstatesRegion = memory->waitstatesNonseq32;
645
646 switch (address >> BASE_OFFSET) {
647 case REGION_WORKING_RAM:
648 STORE_WORKING_RAM;
649 break;
650 case REGION_WORKING_IRAM:
651 STORE_WORKING_IRAM
652 break;
653 case REGION_IO:
654 STORE_IO;
655 break;
656 case REGION_PALETTE_RAM:
657 STORE_PALETTE_RAM;
658 break;
659 case REGION_VRAM:
660 STORE_VRAM;
661 break;
662 case REGION_OAM:
663 STORE_OAM;
664 break;
665 case REGION_CART0:
666 case REGION_CART0_EX:
667 case REGION_CART1:
668 case REGION_CART1_EX:
669 case REGION_CART2:
670 case REGION_CART2_EX:
671 STORE_CART;
672 break;
673 case REGION_CART_SRAM:
674 case REGION_CART_SRAM_MIRROR:
675 STORE_SRAM;
676 break;
677 default:
678 STORE_BAD;
679 break;
680 }
681
682 if (cycleCounter) {
683 *cycleCounter += 1 + wait;
684 }
685}
686
687void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
688 struct GBA* gba = (struct GBA*) cpu->master;
689 struct GBAMemory* memory = &gba->memory;
690 int wait = 0;
691
692 switch (address >> BASE_OFFSET) {
693 case REGION_WORKING_RAM:
694 STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
695 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
696 break;
697 case REGION_WORKING_IRAM:
698 STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
699 break;
700 case REGION_IO:
701 GBAIOWrite(gba, address & (SIZE_IO - 1), value);
702 break;
703 case REGION_PALETTE_RAM:
704 STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
705 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
706 break;
707 case REGION_VRAM:
708 if ((address & 0x0001FFFF) < SIZE_VRAM) {
709 STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
710 } else {
711 STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
712 }
713 break;
714 case REGION_OAM:
715 STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
716 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
717 break;
718 case REGION_CART0:
719 if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFF)) {
720 uint32_t reg = address & 0xFFFFFF;
721 GBAHardwareGPIOWrite(&memory->hw, reg, value);
722 } else {
723 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
724 }
725 break;
726 case REGION_CART2_EX:
727 if (memory->savedata.type == SAVEDATA_AUTODETECT) {
728 GBALog(gba, GBA_LOG_INFO, "Detected EEPROM savegame");
729 GBASavedataInitEEPROM(&memory->savedata);
730 }
731 GBASavedataWriteEEPROM(&memory->savedata, value, 1);
732 break;
733 case REGION_CART_SRAM:
734 case REGION_CART_SRAM_MIRROR:
735 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
736 break;
737 default:
738 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
739 break;
740 }
741
742 if (cycleCounter) {
743 *cycleCounter += 1 + wait;
744 }
745}
746
747void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
748 struct GBA* gba = (struct GBA*) cpu->master;
749 struct GBAMemory* memory = &gba->memory;
750 int wait = 0;
751
752 switch (address >> BASE_OFFSET) {
753 case REGION_WORKING_RAM:
754 ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
755 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
756 break;
757 case REGION_WORKING_IRAM:
758 ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
759 break;
760 case REGION_IO:
761 GBAIOWrite8(gba, address & (SIZE_IO - 1), value);
762 break;
763 case REGION_PALETTE_RAM:
764 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
765 break;
766 case REGION_VRAM:
767 if (address >= 0x06018000) {
768 // TODO: check BG mode
769 GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
770 break;
771 }
772 ((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value;
773 ((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
774 break;
775 case REGION_OAM:
776 GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
777 break;
778 case REGION_CART0:
779 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
780 break;
781 case REGION_CART_SRAM:
782 case REGION_CART_SRAM_MIRROR:
783 if (memory->savedata.type == SAVEDATA_AUTODETECT) {
784 if (address == SAVEDATA_FLASH_BASE) {
785 GBALog(gba, GBA_LOG_INFO, "Detected Flash savegame");
786 GBASavedataInitFlash(&memory->savedata, gba->realisticTiming);
787 } else {
788 GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame");
789 GBASavedataInitSRAM(&memory->savedata);
790 }
791 }
792 if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
793 GBASavedataWriteFlash(&memory->savedata, address, value);
794 } else if (memory->savedata.type == SAVEDATA_SRAM) {
795 memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
796 } else if (memory->hw.devices & HW_TILT) {
797 GBAHardwareTiltWrite(&memory->hw, address & OFFSET_MASK, value);
798 } else {
799 GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
800 }
801 wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
802 break;
803 default:
804 GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
805 break;
806 }
807
808 if (cycleCounter) {
809 *cycleCounter += 1 + wait;
810 }
811}
812
813void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* old) {
814 struct GBA* gba = (struct GBA*) cpu->master;
815 struct GBAMemory* memory = &gba->memory;
816 int32_t oldValue = -1;
817
818 switch (address >> BASE_OFFSET) {
819 case REGION_WORKING_RAM:
820 LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 1), memory->wram);
821 STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
822 break;
823 case REGION_WORKING_IRAM:
824 LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
825 STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
826 break;
827 case REGION_IO:
828 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch32: 0x%08X", address);
829 break;
830 case REGION_PALETTE_RAM:
831 LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
832 STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
833 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
834 gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
835 break;
836 case REGION_VRAM:
837 if ((address & 0x0001FFFF) < SIZE_VRAM) {
838 LOAD_32(oldValue, address & 0x0001FFFF, gba->video.renderer->vram);
839 STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
840 } else {
841 LOAD_32(oldValue, address & 0x00017FFF, gba->video.renderer->vram);
842 STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram);
843 }
844 break;
845 case REGION_OAM:
846 LOAD_32(oldValue, address & (SIZE_OAM - 1), gba->video.oam.raw);
847 STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
848 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
849 gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 1)) + 2) >> 1);
850 break;
851 case REGION_CART0:
852 case REGION_CART0_EX:
853 case REGION_CART1:
854 case REGION_CART1_EX:
855 case REGION_CART2:
856 case REGION_CART2_EX:
857 if ((address & (SIZE_CART0 - 1)) < gba->memory.romSize) {
858 LOAD_32(oldValue, address & (SIZE_CART0 - 1), gba->memory.rom);
859 STORE_32(value, address & (SIZE_CART0 - 1), gba->memory.rom);
860 } else {
861 GBALog(gba, GBA_LOG_WARN, "Bad memory Patch32: 0x%08X", address);
862 }
863 break;
864 case REGION_CART_SRAM:
865 case REGION_CART_SRAM_MIRROR:
866 if (memory->savedata.type == SAVEDATA_SRAM) {
867 LOAD_32(oldValue, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
868 STORE_32(value, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
869 } else {
870 GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
871 }
872 break;
873 default:
874 GBALog(gba, GBA_LOG_WARN, "Bad memory Patch16: 0x%08X", address);
875 break;
876 }
877 if (old) {
878 *old = oldValue;
879 }
880}
881
882void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* old) {
883 struct GBA* gba = (struct GBA*) cpu->master;
884 struct GBAMemory* memory = &gba->memory;
885 int16_t oldValue = -1;
886
887 switch (address >> BASE_OFFSET) {
888 case REGION_WORKING_RAM:
889 LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 1), memory->wram);
890 STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
891 break;
892 case REGION_WORKING_IRAM:
893 LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
894 STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
895 break;
896 case REGION_IO:
897 GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Patch16: 0x%08X", address);
898 break;
899 case REGION_PALETTE_RAM:
900 LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
901 STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
902 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
903 break;
904 case REGION_VRAM:
905 if ((address & 0x0001FFFF) < SIZE_VRAM) {
906 LOAD_16(oldValue, address & 0x0001FFFF, gba->video.renderer->vram);
907 STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
908 } else {
909 LOAD_16(oldValue, address & 0x00017FFF, gba->video.renderer->vram);
910 STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
911 }
912 break;
913 case REGION_OAM:
914 LOAD_16(oldValue, address & (SIZE_OAM - 1), gba->video.oam.raw);
915 STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
916 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
917 break;
918 case REGION_CART0:
919 case REGION_CART0_EX:
920 case REGION_CART1:
921 case REGION_CART1_EX:
922 case REGION_CART2:
923 case REGION_CART2_EX:
924 if ((address & (SIZE_CART0 - 1)) < gba->memory.romSize) {
925 LOAD_16(oldValue, address & (SIZE_CART0 - 1), gba->memory.rom);
926 STORE_16(value, address & (SIZE_CART0 - 1), gba->memory.rom);
927 } else {
928 GBALog(gba, GBA_LOG_WARN, "Bad memory Patch16: 0x%08X", address);
929 }
930 break;
931 case REGION_CART_SRAM:
932 case REGION_CART_SRAM_MIRROR:
933 if (memory->savedata.type == SAVEDATA_SRAM) {
934 LOAD_16(oldValue, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
935 STORE_16(value, address & (SIZE_CART_SRAM - 1), memory->savedata.data);
936 } else {
937 GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
938 }
939 break;
940 default:
941 GBALog(gba, GBA_LOG_WARN, "Bad memory Patch16: 0x%08X", address);
942 break;
943 }
944 if (old) {
945 *old = oldValue;
946 }
947}
948
949#define LDM_LOOP(LDM) \
950 for (i = 0; i < 16; i += 4) { \
951 if (UNLIKELY(mask & (1 << i))) { \
952 LDM; \
953 waitstatesRegion = memory->waitstatesSeq32; \
954 cpu->gprs[i] = value; \
955 ++wait; \
956 address += 4; \
957 } \
958 if (UNLIKELY(mask & (2 << i))) { \
959 LDM; \
960 waitstatesRegion = memory->waitstatesSeq32; \
961 cpu->gprs[i + 1] = value; \
962 ++wait; \
963 address += 4; \
964 } \
965 if (UNLIKELY(mask & (4 << i))) { \
966 LDM; \
967 waitstatesRegion = memory->waitstatesSeq32; \
968 cpu->gprs[i + 2] = value; \
969 ++wait; \
970 address += 4; \
971 } \
972 if (UNLIKELY(mask & (8 << i))) { \
973 LDM; \
974 waitstatesRegion = memory->waitstatesSeq32; \
975 cpu->gprs[i + 3] = value; \
976 ++wait; \
977 address += 4; \
978 } \
979 }
980
981uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
982 struct GBA* gba = (struct GBA*) cpu->master;
983 struct GBAMemory* memory = &gba->memory;
984 uint32_t value;
985 int wait = 0;
986 char* waitstatesRegion = memory->waitstatesNonseq32;
987
988 int i;
989 int offset = 4;
990 int popcount = 0;
991 if (direction & LSM_D) {
992 offset = -4;
993 popcount = _popcount32(mask);
994 address -= (popcount << 2) - 4;
995 }
996
997 if (direction & LSM_B) {
998 address += offset;
999 }
1000
1001 uint32_t addressMisalign = address & 0x3;
1002 address &= 0xFFFFFFFC;
1003
1004 switch (address >> BASE_OFFSET) {
1005 case REGION_BIOS:
1006 LDM_LOOP(LOAD_BIOS);
1007 break;
1008 case REGION_WORKING_RAM:
1009 LDM_LOOP(LOAD_WORKING_RAM);
1010 break;
1011 case REGION_WORKING_IRAM:
1012 LDM_LOOP(LOAD_WORKING_IRAM);
1013 break;
1014 case REGION_IO:
1015 LDM_LOOP(LOAD_IO);
1016 break;
1017 case REGION_PALETTE_RAM:
1018 LDM_LOOP(LOAD_PALETTE_RAM);
1019 break;
1020 case REGION_VRAM:
1021 LDM_LOOP(LOAD_VRAM);
1022 break;
1023 case REGION_OAM:
1024 LDM_LOOP(LOAD_OAM);
1025 break;
1026 case REGION_CART0:
1027 case REGION_CART0_EX:
1028 case REGION_CART1:
1029 case REGION_CART1_EX:
1030 case REGION_CART2:
1031 case REGION_CART2_EX:
1032 LDM_LOOP(LOAD_CART);
1033 break;
1034 case REGION_CART_SRAM:
1035 case REGION_CART_SRAM_MIRROR:
1036 LDM_LOOP(LOAD_SRAM);
1037 break;
1038 default:
1039 LDM_LOOP(LOAD_BAD);
1040 break;
1041 }
1042
1043 if (cycleCounter) {
1044 *cycleCounter += wait;
1045 }
1046
1047 if (direction & LSM_B) {
1048 address -= offset;
1049 }
1050
1051 if (direction & LSM_D) {
1052 address -= (popcount << 2) + 4;
1053 }
1054
1055 return address | addressMisalign;
1056}
1057
1058#define STM_LOOP(STM) \
1059 for (i = 0; i < 16; i += 4) { \
1060 if (UNLIKELY(mask & (1 << i))) { \
1061 value = cpu->gprs[i]; \
1062 STM; \
1063 waitstatesRegion = memory->waitstatesSeq32; \
1064 ++wait; \
1065 address += 4; \
1066 } \
1067 if (UNLIKELY(mask & (2 << i))) { \
1068 value = cpu->gprs[i + 1]; \
1069 STM; \
1070 waitstatesRegion = memory->waitstatesSeq32; \
1071 ++wait; \
1072 address += 4; \
1073 } \
1074 if (UNLIKELY(mask & (4 << i))) { \
1075 value = cpu->gprs[i + 2]; \
1076 STM; \
1077 waitstatesRegion = memory->waitstatesSeq32; \
1078 ++wait; \
1079 address += 4; \
1080 } \
1081 if (UNLIKELY(mask & (8 << i))) { \
1082 value = cpu->gprs[i + 3]; \
1083 STM; \
1084 waitstatesRegion = memory->waitstatesSeq32; \
1085 ++wait; \
1086 address += 4; \
1087 } \
1088 }
1089
1090uint32_t GBAStoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
1091 struct GBA* gba = (struct GBA*) cpu->master;
1092 struct GBAMemory* memory = &gba->memory;
1093 uint32_t value;
1094 int wait = 0;
1095 char* waitstatesRegion = memory->waitstatesNonseq32;
1096
1097 int i;
1098 int offset = 4;
1099 int popcount = 0;
1100 if (direction & LSM_D) {
1101 offset = -4;
1102 popcount = _popcount32(mask);
1103 address -= (popcount << 2) - 4;
1104 }
1105
1106 if (direction & LSM_B) {
1107 address += offset;
1108 }
1109
1110 uint32_t addressMisalign = address & 0x3;
1111 address &= 0xFFFFFFFC;
1112
1113 switch (address >> BASE_OFFSET) {
1114 case REGION_WORKING_RAM:
1115 STM_LOOP(STORE_WORKING_RAM);
1116 break;
1117 case REGION_WORKING_IRAM:
1118 STM_LOOP(STORE_WORKING_IRAM);
1119 break;
1120 case REGION_IO:
1121 STM_LOOP(STORE_IO);
1122 break;
1123 case REGION_PALETTE_RAM:
1124 STM_LOOP(STORE_PALETTE_RAM);
1125 break;
1126 case REGION_VRAM:
1127 STM_LOOP(STORE_VRAM);
1128 break;
1129 case REGION_OAM:
1130 STM_LOOP(STORE_OAM);
1131 break;
1132 case REGION_CART0:
1133 case REGION_CART0_EX:
1134 case REGION_CART1:
1135 case REGION_CART1_EX:
1136 case REGION_CART2:
1137 case REGION_CART2_EX:
1138 STM_LOOP(STORE_CART);
1139 break;
1140 case REGION_CART_SRAM:
1141 case REGION_CART_SRAM_MIRROR:
1142 STM_LOOP(STORE_SRAM);
1143 break;
1144 default:
1145 STM_LOOP(STORE_BAD);
1146 break;
1147 }
1148
1149 if (cycleCounter) {
1150 *cycleCounter += wait;
1151 }
1152
1153 if (direction & LSM_B) {
1154 address -= offset;
1155 }
1156
1157 if (direction & LSM_D) {
1158 address -= (popcount << 2) + 4;
1159 }
1160
1161 return address | addressMisalign;
1162}
1163
1164void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
1165 struct GBAMemory* memory = &gba->memory;
1166 struct ARMCore* cpu = gba->cpu;
1167 int sram = parameters & 0x0003;
1168 int ws0 = (parameters & 0x000C) >> 2;
1169 int ws0seq = (parameters & 0x0010) >> 4;
1170 int ws1 = (parameters & 0x0060) >> 5;
1171 int ws1seq = (parameters & 0x0080) >> 7;
1172 int ws2 = (parameters & 0x0300) >> 8;
1173 int ws2seq = (parameters & 0x0400) >> 10;
1174 int prefetch = parameters & 0x4000;
1175
1176 memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
1177 memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
1178 memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
1179 memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
1180
1181 memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
1182 memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
1183 memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
1184
1185 memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
1186 memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
1187 memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
1188
1189 memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
1190 memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
1191 memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
1192
1193 memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
1194 memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
1195 memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
1196
1197 if (!prefetch) {
1198 memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0];
1199 memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1];
1200 memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2];
1201
1202 memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = memory->waitstatesSeq32[REGION_CART0];
1203 memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = memory->waitstatesSeq32[REGION_CART1];
1204 memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = memory->waitstatesSeq32[REGION_CART2];
1205
1206 memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0];
1207 memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1];
1208 memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2];
1209
1210 memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq32[REGION_CART0];
1211 memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq32[REGION_CART1];
1212 memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq32[REGION_CART2];
1213 } else {
1214 memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = 0;
1215 memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = 0;
1216 memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = 0;
1217
1218 memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = 0;
1219 memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = 0;
1220 memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = 0;
1221
1222 memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = 0;
1223 memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = 0;
1224 memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = 0;
1225
1226 memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = 0;
1227 memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = 0;
1228 memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = 0;
1229 }
1230
1231 cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
1232 cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
1233
1234 cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
1235 cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
1236
1237 cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
1238 cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
1239}
1240
1241void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
1242 struct GBAMemory* memory = &gba->memory;
1243 memory->dma[dma].source = address & 0x0FFFFFFE;
1244}
1245
1246void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
1247 struct GBAMemory* memory = &gba->memory;
1248 memory->dma[dma].dest = address & 0x0FFFFFFE;
1249}
1250
1251void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
1252 struct GBAMemory* memory = &gba->memory;
1253 memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
1254}
1255
1256uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
1257 struct GBAMemory* memory = &gba->memory;
1258 struct GBADMA* currentDma = &memory->dma[dma];
1259 int wasEnabled = GBADMARegisterIsEnable(currentDma->reg);
1260 int oldTiming = GBADMARegisterGetTiming(currentDma->reg);
1261 int newTiming = GBADMARegisterGetTiming(control);
1262 // This is probably a huge hack...verify what this does on hardware
1263 if (oldTiming && oldTiming != DMA_TIMING_CUSTOM && oldTiming != newTiming) {
1264 wasEnabled = false;
1265 }
1266 currentDma->reg = control;
1267
1268 if (GBADMARegisterIsDRQ(currentDma->reg)) {
1269 GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
1270 }
1271
1272 if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) {
1273 currentDma->nextSource = currentDma->source;
1274 currentDma->nextDest = currentDma->dest;
1275 currentDma->nextCount = currentDma->count;
1276 GBAMemoryScheduleDMA(gba, dma, currentDma);
1277 }
1278 // If the DMA has already occurred, this value might have changed since the function started
1279 return currentDma->reg;
1280};
1281
1282void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
1283 struct ARMCore* cpu = gba->cpu;
1284 switch (GBADMARegisterGetTiming(info->reg)) {
1285 case DMA_TIMING_NOW:
1286 info->nextEvent = cpu->cycles;
1287 GBAMemoryUpdateDMAs(gba, 0);
1288 break;
1289 case DMA_TIMING_HBLANK:
1290 // Handled implicitly
1291 info->nextEvent = INT_MAX;
1292 break;
1293 case DMA_TIMING_VBLANK:
1294 // Handled implicitly
1295 info->nextEvent = INT_MAX;
1296 break;
1297 case DMA_TIMING_CUSTOM:
1298 info->nextEvent = INT_MAX;
1299 switch (number) {
1300 case 0:
1301 GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
1302 break;
1303 case 1:
1304 case 2:
1305 GBAAudioScheduleFifoDma(&gba->audio, number, info);
1306 break;
1307 case 3:
1308 // GBAVideoScheduleVCaptureDma(dma, info);
1309 break;
1310 }
1311 }
1312}
1313
1314void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
1315 struct GBAMemory* memory = &gba->memory;
1316 struct GBADMA* dma;
1317 int i;
1318 for (i = 0; i < 4; ++i) {
1319 dma = &memory->dma[i];
1320 if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_HBLANK) {
1321 dma->nextEvent = cycles;
1322 }
1323 }
1324 GBAMemoryUpdateDMAs(gba, 0);
1325}
1326
1327void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
1328 struct GBAMemory* memory = &gba->memory;
1329 struct GBADMA* dma;
1330 int i;
1331 for (i = 0; i < 4; ++i) {
1332 dma = &memory->dma[i];
1333 if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_VBLANK) {
1334 dma->nextEvent = cycles;
1335 }
1336 }
1337 GBAMemoryUpdateDMAs(gba, 0);
1338}
1339
1340int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
1341 struct GBAMemory* memory = &gba->memory;
1342 if (memory->nextDMA == INT_MAX) {
1343 return INT_MAX;
1344 }
1345 memory->nextDMA -= cycles;
1346 memory->eventDiff += cycles;
1347 if (memory->nextDMA <= 0) {
1348 struct GBADMA* dma = &memory->dma[memory->activeDMA];
1349 GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
1350 GBAMemoryUpdateDMAs(gba, memory->eventDiff);
1351 memory->eventDiff = 0;
1352 }
1353 return memory->nextDMA;
1354}
1355
1356void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
1357 int i;
1358 struct GBAMemory* memory = &gba->memory;
1359 struct ARMCore* cpu = gba->cpu;
1360 memory->activeDMA = -1;
1361 memory->nextDMA = INT_MAX;
1362 for (i = 3; i >= 0; --i) {
1363 struct GBADMA* dma = &memory->dma[i];
1364 if (dma->nextEvent != INT_MAX) {
1365 dma->nextEvent -= cycles;
1366 if (GBADMARegisterIsEnable(dma->reg)) {
1367 memory->activeDMA = i;
1368 memory->nextDMA = dma->nextEvent;
1369 }
1370 }
1371 }
1372 if (memory->nextDMA < cpu->nextEvent) {
1373 cpu->nextEvent = memory->nextDMA;
1374 }
1375}
1376
1377void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
1378 struct GBAMemory* memory = &gba->memory;
1379 struct ARMCore* cpu = gba->cpu;
1380 uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2;
1381 int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width;
1382 int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width;
1383 int32_t wordsRemaining = info->nextCount;
1384 uint32_t source = info->nextSource;
1385 uint32_t dest = info->nextDest;
1386 uint32_t sourceRegion = source >> BASE_OFFSET;
1387 uint32_t destRegion = dest >> BASE_OFFSET;
1388 int32_t cycles = 2;
1389
1390 if (source == info->source) {
1391 // TODO: support 4 cycles for ROM access
1392 cycles += 2;
1393 if (width == 4) {
1394 cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
1395 source &= 0xFFFFFFFC;
1396 dest &= 0xFFFFFFFC;
1397 } else {
1398 cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
1399 }
1400 } else {
1401 if (width == 4) {
1402 cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
1403 } else {
1404 cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
1405 }
1406 }
1407
1408 gba->performingDMA = true;
1409 int32_t word;
1410 if (width == 4) {
1411 word = cpu->memory.load32(cpu, source, 0);
1412 gba->bus = word;
1413 cpu->memory.store32(cpu, dest, word, 0);
1414 source += sourceOffset;
1415 dest += destOffset;
1416 --wordsRemaining;
1417 } else {
1418 if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
1419 word = GBASavedataReadEEPROM(&memory->savedata);
1420 gba->bus = word | (word << 16);
1421 cpu->memory.store16(cpu, dest, word, 0);
1422 source += sourceOffset;
1423 dest += destOffset;
1424 --wordsRemaining;
1425 } else if (destRegion == REGION_CART2_EX) {
1426 if (memory->savedata.type == SAVEDATA_AUTODETECT) {
1427 GBALog(gba, GBA_LOG_INFO, "Detected EEPROM savegame");
1428 GBASavedataInitEEPROM(&memory->savedata);
1429 }
1430 word = cpu->memory.load16(cpu, source, 0);
1431 gba->bus = word | (word << 16);
1432 GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
1433 source += sourceOffset;
1434 dest += destOffset;
1435 --wordsRemaining;
1436 } else {
1437 word = cpu->memory.load16(cpu, source, 0);
1438 gba->bus = word | (word << 16);
1439 cpu->memory.store16(cpu, dest, word, 0);
1440 source += sourceOffset;
1441 dest += destOffset;
1442 --wordsRemaining;
1443 }
1444 }
1445 gba->performingDMA = false;
1446
1447 if (!wordsRemaining) {
1448 if (!GBADMARegisterIsRepeat(info->reg) || GBADMARegisterGetTiming(info->reg) == DMA_TIMING_NOW) {
1449 info->reg = GBADMARegisterClearEnable(info->reg);
1450 info->nextEvent = INT_MAX;
1451
1452 // Clear the enable bit in memory
1453 memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
1454 } else {
1455 info->nextCount = info->count;
1456 if (GBADMARegisterGetDestControl(info->reg) == DMA_INCREMENT_RELOAD) {
1457 info->nextDest = info->dest;
1458 }
1459 GBAMemoryScheduleDMA(gba, number, info);
1460 }
1461 if (GBADMARegisterIsDoIRQ(info->reg)) {
1462 GBARaiseIRQ(gba, IRQ_DMA0 + number);
1463 }
1464 } else {
1465 info->nextDest = dest;
1466 info->nextCount = wordsRemaining;
1467 }
1468 info->nextSource = source;
1469
1470 if (info->nextEvent != INT_MAX) {
1471 info->nextEvent += cycles;
1472 }
1473 cpu->cycles += cycles;
1474}
1475
1476void GBAMemorySerialize(const struct GBAMemory* memory, struct GBASerializedState* state) {
1477 memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
1478 memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
1479}
1480
1481void GBAMemoryDeserialize(struct GBAMemory* memory, const struct GBASerializedState* state) {
1482 memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
1483 memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
1484}
1485
1486uint32_t _popcount32(unsigned bits) {
1487 bits = bits - ((bits >> 1) & 0x55555555);
1488 bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
1489 return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
1490}