src/gba/memory.c (view raw)
1/* Copyright (c) 2013-2016 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 <mgba/internal/gba/memory.h>
7
8#include <mgba/internal/arm/decoder.h>
9#include <mgba/internal/arm/macros.h>
10#include <mgba/internal/gba/gba.h>
11#include <mgba/internal/gba/dma.h>
12#include <mgba/internal/gba/io.h>
13#include <mgba/internal/gba/serialize.h>
14#include "gba/hle-bios.h"
15
16#include <mgba-util/math.h>
17#include <mgba-util/memory.h>
18#include <mgba-util/vfs.h>
19
20#define IDLE_LOOP_THRESHOLD 10000
21
22mLOG_DEFINE_CATEGORY(GBA_MEM, "GBA Memory", "gba.memory");
23
24static void _pristineCow(struct GBA* gba);
25static void _agbPrintStore(struct GBA* gba, uint32_t address, int16_t value);
26static int16_t _agbPrintLoad(struct GBA* gba, uint32_t address);
27static uint8_t _deadbeef[4] = { 0x10, 0xB7, 0x10, 0xE7 }; // Illegal instruction on both ARM and Thumb
28static const uint32_t _agbPrintFunc = 0x4770DFFA; // swi 0xFA; bx lr
29
30static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
31static int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait);
32static int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra);
33
34static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
35static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 9 };
36static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
37static const char GBA_BASE_WAITSTATES_SEQ_32[16] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 9 };
38static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
39static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
40
41void GBAMemoryInit(struct GBA* gba) {
42 struct ARMCore* cpu = gba->cpu;
43 cpu->memory.load32 = GBALoad32;
44 cpu->memory.load16 = GBALoad16;
45 cpu->memory.load8 = GBALoad8;
46 cpu->memory.loadMultiple = GBALoadMultiple;
47 cpu->memory.store32 = GBAStore32;
48 cpu->memory.store16 = GBAStore16;
49 cpu->memory.store8 = GBAStore8;
50 cpu->memory.storeMultiple = GBAStoreMultiple;
51 cpu->memory.stall = GBAMemoryStall;
52
53 gba->memory.bios = (uint32_t*) hleBios;
54 gba->memory.fullBios = 0;
55 gba->memory.wram = 0;
56 gba->memory.iwram = 0;
57 gba->memory.rom = 0;
58 gba->memory.romSize = 0;
59 gba->memory.romMask = 0;
60 gba->memory.hw.p = gba;
61
62 int i;
63 for (i = 0; i < 16; ++i) {
64 gba->memory.waitstatesNonseq16[i] = GBA_BASE_WAITSTATES[i];
65 gba->memory.waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
66 gba->memory.waitstatesNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
67 gba->memory.waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
68 }
69 for (; i < 256; ++i) {
70 gba->memory.waitstatesNonseq16[i] = 0;
71 gba->memory.waitstatesSeq16[i] = 0;
72 gba->memory.waitstatesNonseq32[i] = 0;
73 gba->memory.waitstatesSeq32[i] = 0;
74 }
75
76 gba->memory.activeRegion = -1;
77 cpu->memory.activeRegion = 0;
78 cpu->memory.activeMask = 0;
79 cpu->memory.setActiveRegion = GBASetActiveRegion;
80 cpu->memory.activeSeqCycles32 = 0;
81 cpu->memory.activeSeqCycles16 = 0;
82 cpu->memory.activeNonseqCycles32 = 0;
83 cpu->memory.activeNonseqCycles16 = 0;
84 gba->memory.biosPrefetch = 0;
85 gba->memory.mirroring = false;
86
87 gba->memory.agbPrintProtect = 0;
88 memset(&gba->memory.agbPrintCtx, 0, sizeof(gba->memory.agbPrintCtx));
89 gba->memory.agbPrintBuffer = NULL;
90 gba->memory.agbPrintBufferBackup = NULL;
91
92 gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM + SIZE_WORKING_IRAM);
93 gba->memory.iwram = &gba->memory.wram[SIZE_WORKING_RAM >> 2];
94
95 GBADMAInit(gba);
96 GBAVFameInit(&gba->memory.vfame);
97}
98
99void GBAMemoryDeinit(struct GBA* gba) {
100 mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM + SIZE_WORKING_IRAM);
101 if (gba->memory.rom) {
102 mappedMemoryFree(gba->memory.rom, gba->memory.romSize);
103 }
104 if (gba->memory.agbPrintBuffer) {
105 mappedMemoryFree(gba->memory.agbPrintBuffer, SIZE_AGB_PRINT);
106 }
107 if (gba->memory.agbPrintBufferBackup) {
108 mappedMemoryFree(gba->memory.agbPrintBufferBackup, SIZE_AGB_PRINT);
109 }
110}
111
112void GBAMemoryReset(struct GBA* gba) {
113 if (gba->memory.wram && gba->memory.rom) {
114 memset(gba->memory.wram, 0, SIZE_WORKING_RAM);
115 }
116
117 if (gba->memory.iwram) {
118 memset(gba->memory.iwram, 0, SIZE_WORKING_IRAM);
119 }
120
121 memset(gba->memory.io, 0, sizeof(gba->memory.io));
122 GBAAdjustWaitstates(gba, 0);
123
124 gba->memory.agbPrintProtect = 0;
125 gba->memory.agbPrintBase = 0;
126 memset(&gba->memory.agbPrintCtx, 0, sizeof(gba->memory.agbPrintCtx));
127 if (gba->memory.agbPrintBuffer) {
128 mappedMemoryFree(gba->memory.agbPrintBuffer, SIZE_AGB_PRINT);
129 gba->memory.agbPrintBuffer = NULL;
130 }
131 if (gba->memory.agbPrintBufferBackup) {
132 mappedMemoryFree(gba->memory.agbPrintBufferBackup, SIZE_AGB_PRINT);
133 gba->memory.agbPrintBufferBackup = NULL;
134 }
135
136 gba->memory.prefetch = false;
137 gba->memory.lastPrefetchedPc = 0;
138
139 if (!gba->memory.wram || !gba->memory.iwram) {
140 GBAMemoryDeinit(gba);
141 mLOG(GBA_MEM, FATAL, "Could not map memory");
142 }
143
144 GBADMAReset(gba);
145 memset(&gba->memory.matrix, 0, sizeof(gba->memory.matrix));
146}
147
148static void _analyzeForIdleLoop(struct GBA* gba, struct ARMCore* cpu, uint32_t address) {
149 struct ARMInstructionInfo info;
150 uint32_t nextAddress = address;
151 memset(gba->taintedRegisters, 0, sizeof(gba->taintedRegisters));
152 if (cpu->executionMode == MODE_THUMB) {
153 while (true) {
154 uint16_t opcode;
155 LOAD_16(opcode, nextAddress & cpu->memory.activeMask, cpu->memory.activeRegion);
156 ARMDecodeThumb(opcode, &info);
157 switch (info.branchType) {
158 case ARM_BRANCH_NONE:
159 if (info.operandFormat & ARM_OPERAND_MEMORY_2) {
160 if (info.mnemonic == ARM_MN_STR || gba->taintedRegisters[info.memory.baseReg]) {
161 gba->idleDetectionStep = -1;
162 return;
163 }
164 uint32_t loadAddress = gba->cachedRegisters[info.memory.baseReg];
165 uint32_t offset = 0;
166 if (info.memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
167 offset = info.memory.offset.immediate;
168 } else if (info.memory.format & ARM_MEMORY_REGISTER_OFFSET) {
169 int reg = info.memory.offset.reg;
170 if (gba->cachedRegisters[reg]) {
171 gba->idleDetectionStep = -1;
172 return;
173 }
174 offset = gba->cachedRegisters[reg];
175 }
176 if (info.memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
177 loadAddress -= offset;
178 } else {
179 loadAddress += offset;
180 }
181 if ((loadAddress >> BASE_OFFSET) == REGION_IO && !GBAIOIsReadConstant(loadAddress)) {
182 gba->idleDetectionStep = -1;
183 return;
184 }
185 if ((loadAddress >> BASE_OFFSET) < REGION_CART0 || (loadAddress >> BASE_OFFSET) > REGION_CART2_EX) {
186 gba->taintedRegisters[info.op1.reg] = true;
187 } else {
188 switch (info.memory.width) {
189 case 1:
190 gba->cachedRegisters[info.op1.reg] = GBALoad8(cpu, loadAddress, 0);
191 break;
192 case 2:
193 gba->cachedRegisters[info.op1.reg] = GBALoad16(cpu, loadAddress, 0);
194 break;
195 case 4:
196 gba->cachedRegisters[info.op1.reg] = GBALoad32(cpu, loadAddress, 0);
197 break;
198 }
199 }
200 } else if (info.operandFormat & ARM_OPERAND_AFFECTED_1) {
201 gba->taintedRegisters[info.op1.reg] = true;
202 }
203 nextAddress += WORD_SIZE_THUMB;
204 break;
205 case ARM_BRANCH:
206 if ((uint32_t) info.op1.immediate + nextAddress + WORD_SIZE_THUMB * 2 == address) {
207 gba->idleLoop = address;
208 gba->idleOptimization = IDLE_LOOP_REMOVE;
209 }
210 gba->idleDetectionStep = -1;
211 return;
212 default:
213 gba->idleDetectionStep = -1;
214 return;
215 }
216 }
217 } else {
218 gba->idleDetectionStep = -1;
219 }
220}
221
222static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
223 struct GBA* gba = (struct GBA*) cpu->master;
224 struct GBAMemory* memory = &gba->memory;
225
226 int newRegion = address >> BASE_OFFSET;
227 if (gba->idleOptimization >= IDLE_LOOP_REMOVE && memory->activeRegion != REGION_BIOS) {
228 if (address == gba->idleLoop) {
229 if (gba->haltPending) {
230 gba->haltPending = false;
231 GBAHalt(gba);
232 } else {
233 gba->haltPending = true;
234 }
235 } else if (gba->idleOptimization >= IDLE_LOOP_DETECT && newRegion == memory->activeRegion) {
236 if (address == gba->lastJump) {
237 switch (gba->idleDetectionStep) {
238 case 0:
239 memcpy(gba->cachedRegisters, cpu->gprs, sizeof(gba->cachedRegisters));
240 ++gba->idleDetectionStep;
241 break;
242 case 1:
243 if (memcmp(gba->cachedRegisters, cpu->gprs, sizeof(gba->cachedRegisters))) {
244 gba->idleDetectionStep = -1;
245 ++gba->idleDetectionFailures;
246 if (gba->idleDetectionFailures > IDLE_LOOP_THRESHOLD) {
247 gba->idleOptimization = IDLE_LOOP_IGNORE;
248 }
249 break;
250 }
251 _analyzeForIdleLoop(gba, cpu, address);
252 break;
253 }
254 } else {
255 gba->idleDetectionStep = 0;
256 }
257 }
258 }
259
260 gba->lastJump = address;
261 memory->lastPrefetchedPc = 0;
262 if (newRegion == memory->activeRegion) {
263 if (newRegion < REGION_CART0 || (address & (SIZE_CART0 - 1)) < memory->romSize) {
264 return;
265 }
266 if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
267 return;
268 }
269 }
270
271 if (memory->activeRegion == REGION_BIOS) {
272 memory->biosPrefetch = cpu->prefetch[1];
273 }
274 memory->activeRegion = newRegion;
275 switch (newRegion) {
276 case REGION_BIOS:
277 cpu->memory.activeRegion = memory->bios;
278 cpu->memory.activeMask = SIZE_BIOS - 1;
279 break;
280 case REGION_WORKING_RAM:
281 cpu->memory.activeRegion = memory->wram;
282 cpu->memory.activeMask = SIZE_WORKING_RAM - 1;
283 break;
284 case REGION_WORKING_IRAM:
285 cpu->memory.activeRegion = memory->iwram;
286 cpu->memory.activeMask = SIZE_WORKING_IRAM - 1;
287 break;
288 case REGION_PALETTE_RAM:
289 cpu->memory.activeRegion = (uint32_t*) gba->video.palette;
290 cpu->memory.activeMask = SIZE_PALETTE_RAM - 1;
291 break;
292 case REGION_VRAM:
293 if (address & 0x10000) {
294 cpu->memory.activeRegion = (uint32_t*) &gba->video.vram[0x8000];
295 cpu->memory.activeMask = 0x00007FFF;
296 } else {
297 cpu->memory.activeRegion = (uint32_t*) gba->video.vram;
298 cpu->memory.activeMask = 0x0000FFFF;
299 }
300 break;
301 case REGION_OAM:
302 cpu->memory.activeRegion = (uint32_t*) gba->video.oam.raw;
303 cpu->memory.activeMask = SIZE_OAM - 1;
304 break;
305 case REGION_CART0:
306 case REGION_CART0_EX:
307 case REGION_CART1:
308 case REGION_CART1_EX:
309 case REGION_CART2:
310 case REGION_CART2_EX:
311 cpu->memory.activeRegion = memory->rom;
312 cpu->memory.activeMask = memory->romMask;
313 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
314 break;
315 }
316 if ((address & 0x00FFFFFE) == AGB_PRINT_FLUSH_ADDR && memory->agbPrintProtect == 0x20) {
317 cpu->memory.activeRegion = &_agbPrintFunc;
318 cpu->memory.activeMask = sizeof(_agbPrintFunc) - 1;
319 break;
320 }
321 // Fall through
322 default:
323 memory->activeRegion = -1;
324 cpu->memory.activeRegion = (uint32_t*) _deadbeef;
325 cpu->memory.activeMask = 0;
326
327 if (!gba->yankedRomSize && mCoreCallbacksListSize(&gba->coreCallbacks)) {
328 size_t c;
329 for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
330 struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
331 if (callbacks->coreCrashed) {
332 callbacks->coreCrashed(callbacks->context);
333 }
334 }
335 }
336
337 if (gba->yankedRomSize || !gba->hardCrash) {
338 mLOG(GBA_MEM, GAME_ERROR, "Jumped to invalid address: %08X", address);
339 } else {
340 mLOG(GBA_MEM, FATAL, "Jumped to invalid address: %08X", address);
341 }
342 return;
343 }
344 cpu->memory.activeSeqCycles32 = memory->waitstatesSeq32[memory->activeRegion];
345 cpu->memory.activeSeqCycles16 = memory->waitstatesSeq16[memory->activeRegion];
346 cpu->memory.activeNonseqCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
347 cpu->memory.activeNonseqCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
348 cpu->memory.activeMask &= -(cpu->executionMode == MODE_THUMB ? WORD_SIZE_THUMB : WORD_SIZE_ARM);
349}
350
351#define LOAD_BAD \
352 value = GBALoadBad(cpu);
353
354#define LOAD_BIOS \
355 if (address < SIZE_BIOS) { \
356 if (memory->activeRegion == REGION_BIOS) { \
357 LOAD_32(value, address & -4, memory->bios); \
358 } else { \
359 mLOG(GBA_MEM, GAME_ERROR, "Bad BIOS Load32: 0x%08X", address); \
360 value = memory->biosPrefetch; \
361 } \
362 } else { \
363 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load32: 0x%08X", address); \
364 value = GBALoadBad(cpu); \
365 }
366
367#define LOAD_WORKING_RAM \
368 LOAD_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram); \
369 wait += waitstatesRegion[REGION_WORKING_RAM];
370
371#define LOAD_WORKING_IRAM LOAD_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
372#define LOAD_IO value = GBAIORead(gba, address & OFFSET_MASK & ~2) | (GBAIORead(gba, (address & OFFSET_MASK) | 2) << 16);
373
374#define LOAD_PALETTE_RAM \
375 LOAD_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
376 wait += waitstatesRegion[REGION_PALETTE_RAM];
377
378#define LOAD_VRAM \
379 if ((address & 0x0001FFFF) >= SIZE_VRAM) { \
380 if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \
381 mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load32: 0x%08X", address); \
382 value = 0; \
383 } else { \
384 LOAD_32(value, address & 0x00017FFC, gba->video.vram); \
385 } \
386 } else { \
387 LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \
388 } \
389 ++wait; \
390 if (gba->video.shouldStall) { \
391 wait += GBAMemoryStallVRAM(gba, wait, 1); \
392 }
393
394#define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw);
395
396#define LOAD_CART \
397 wait += waitstatesRegion[address >> BASE_OFFSET]; \
398 if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
399 LOAD_32(value, address & (SIZE_CART0 - 4), memory->rom); \
400 } else if (memory->mirroring && (address & memory->romMask) < memory->romSize) { \
401 LOAD_32(value, address & memory->romMask & -4, memory->rom); \
402 } else if (memory->vfame.cartType) { \
403 value = GBAVFameGetPatternValue(address, 32); \
404 } else { \
405 mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
406 value = ((address & ~3) >> 1) & 0xFFFF; \
407 value |= (((address & ~3) + 2) >> 1) << 16; \
408 }
409
410#define LOAD_SRAM \
411 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; \
412 value = GBALoad8(cpu, address, 0); \
413 value |= value << 8; \
414 value |= value << 16;
415
416uint32_t GBALoadBad(struct ARMCore* cpu) {
417 struct GBA* gba = (struct GBA*) cpu->master;
418 uint32_t value = 0;
419 if (gba->performingDMA || cpu->gprs[ARM_PC] - gba->dmaPC == (gba->cpu->executionMode == MODE_THUMB ? WORD_SIZE_THUMB : WORD_SIZE_ARM)) {
420 value = gba->bus;
421 } else {
422 value = cpu->prefetch[1];
423 if (cpu->executionMode == MODE_THUMB) {
424 /* http://ngemu.com/threads/gba-open-bus.170809/ */
425 switch (cpu->gprs[ARM_PC] >> BASE_OFFSET) {
426 case REGION_BIOS:
427 case REGION_OAM:
428 /* This isn't right half the time, but we don't have $+6 handy */
429 value <<= 16;
430 value |= cpu->prefetch[0];
431 break;
432 case REGION_WORKING_IRAM:
433 /* This doesn't handle prefetch clobbering */
434 if (cpu->gprs[ARM_PC] & 2) {
435 value <<= 16;
436 value |= cpu->prefetch[0];
437 } else {
438 value |= cpu->prefetch[0] << 16;
439 }
440 break;
441 default:
442 value |= value << 16;
443 }
444 }
445 }
446 return value;
447}
448
449uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
450 struct GBA* gba = (struct GBA*) cpu->master;
451 struct GBAMemory* memory = &gba->memory;
452 uint32_t value = 0;
453 int wait = 0;
454 char* waitstatesRegion = memory->waitstatesNonseq32;
455
456 switch (address >> BASE_OFFSET) {
457 case REGION_BIOS:
458 LOAD_BIOS;
459 break;
460 case REGION_WORKING_RAM:
461 LOAD_WORKING_RAM;
462 break;
463 case REGION_WORKING_IRAM:
464 LOAD_WORKING_IRAM;
465 break;
466 case REGION_IO:
467 LOAD_IO;
468 break;
469 case REGION_PALETTE_RAM:
470 LOAD_PALETTE_RAM;
471 break;
472 case REGION_VRAM:
473 LOAD_VRAM;
474 break;
475 case REGION_OAM:
476 LOAD_OAM;
477 break;
478 case REGION_CART0:
479 case REGION_CART0_EX:
480 case REGION_CART1:
481 case REGION_CART1_EX:
482 case REGION_CART2:
483 case REGION_CART2_EX:
484 LOAD_CART;
485 break;
486 case REGION_CART_SRAM:
487 case REGION_CART_SRAM_MIRROR:
488 LOAD_SRAM;
489 break;
490 default:
491 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load32: 0x%08X", address);
492 LOAD_BAD;
493 break;
494 }
495
496 if (cycleCounter) {
497 wait += 2;
498 if (address < BASE_CART0) {
499 wait = GBAMemoryStall(cpu, wait);
500 }
501 *cycleCounter += wait;
502 }
503 // Unaligned 32-bit loads are "rotated" so they make some semblance of sense
504 int rotate = (address & 3) << 3;
505 return ROR(value, rotate);
506}
507
508uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
509 struct GBA* gba = (struct GBA*) cpu->master;
510 struct GBAMemory* memory = &gba->memory;
511 uint32_t value = 0;
512 int wait = 0;
513
514 switch (address >> BASE_OFFSET) {
515 case REGION_BIOS:
516 if (address < SIZE_BIOS) {
517 if (memory->activeRegion == REGION_BIOS) {
518 LOAD_16(value, address & -2, memory->bios);
519 } else {
520 mLOG(GBA_MEM, GAME_ERROR, "Bad BIOS Load16: 0x%08X", address);
521 value = (memory->biosPrefetch >> ((address & 2) * 8)) & 0xFFFF;
522 }
523 } else {
524 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load16: 0x%08X", address);
525 value = (GBALoadBad(cpu) >> ((address & 2) * 8)) & 0xFFFF;
526 }
527 break;
528 case REGION_WORKING_RAM:
529 LOAD_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
530 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
531 break;
532 case REGION_WORKING_IRAM:
533 LOAD_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
534 break;
535 case REGION_IO:
536 value = GBAIORead(gba, address & (OFFSET_MASK - 1));
537 break;
538 case REGION_PALETTE_RAM:
539 LOAD_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
540 break;
541 case REGION_VRAM:
542 if ((address & 0x0001FFFF) >= SIZE_VRAM) {
543 if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
544 mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load16: 0x%08X", address);
545 value = 0;
546 break;
547 }
548 LOAD_16(value, address & 0x00017FFE, gba->video.vram);
549 } else {
550 LOAD_16(value, address & 0x0001FFFE, gba->video.vram);
551 }
552 if (gba->video.shouldStall) {
553 wait += GBAMemoryStallVRAM(gba, wait, 0);
554 }
555 break;
556 case REGION_OAM:
557 LOAD_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
558 break;
559 case REGION_CART0:
560 case REGION_CART0_EX:
561 case REGION_CART1:
562 case REGION_CART1_EX:
563 case REGION_CART2:
564 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
565 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
566 LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
567 } else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
568 LOAD_16(value, address & memory->romMask, memory->rom);
569 } else if (memory->vfame.cartType) {
570 value = GBAVFameGetPatternValue(address, 16);
571 } else if ((address & (SIZE_CART0 - 1)) >= AGB_PRINT_BASE) {
572 uint32_t agbPrintAddr = address & 0x00FFFFFF;
573 if (agbPrintAddr == AGB_PRINT_PROTECT) {
574 value = memory->agbPrintProtect;
575 } else if (agbPrintAddr < AGB_PRINT_TOP || (agbPrintAddr & 0x00FFFFF8) == AGB_PRINT_STRUCT) {
576 value = _agbPrintLoad(gba, address);
577 } else {
578 mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
579 value = (address >> 1) & 0xFFFF;
580 }
581 } else {
582 mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
583 value = (address >> 1) & 0xFFFF;
584 }
585 break;
586 case REGION_CART2_EX:
587 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
588 if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) {
589 value = GBASavedataReadEEPROM(&memory->savedata);
590 } else if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) {
591 value = GBAHardwareEReaderRead(&memory->hw, address);
592 } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
593 LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
594 } else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
595 LOAD_16(value, address & memory->romMask, memory->rom);
596 } else if (memory->vfame.cartType) {
597 value = GBAVFameGetPatternValue(address, 16);
598 } else {
599 mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
600 value = (address >> 1) & 0xFFFF;
601 }
602 break;
603 case REGION_CART_SRAM:
604 case REGION_CART_SRAM_MIRROR:
605 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
606 value = GBALoad8(cpu, address, 0);
607 value |= value << 8;
608 break;
609 default:
610 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load16: 0x%08X", address);
611 value = (GBALoadBad(cpu) >> ((address & 2) * 8)) & 0xFFFF;
612 break;
613 }
614
615 if (cycleCounter) {
616 wait += 2;
617 if (address < BASE_CART0) {
618 wait = GBAMemoryStall(cpu, wait);
619 }
620 *cycleCounter += wait;
621 }
622 // Unaligned 16-bit loads are "unpredictable", but the GBA rotates them, so we have to, too.
623 int rotate = (address & 1) << 3;
624 return ROR(value, rotate);
625}
626
627uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
628 struct GBA* gba = (struct GBA*) cpu->master;
629 struct GBAMemory* memory = &gba->memory;
630 uint32_t value = 0;
631 int wait = 0;
632
633 switch (address >> BASE_OFFSET) {
634 case REGION_BIOS:
635 if (address < SIZE_BIOS) {
636 if (memory->activeRegion == REGION_BIOS) {
637 value = ((uint8_t*) memory->bios)[address];
638 } else {
639 mLOG(GBA_MEM, GAME_ERROR, "Bad BIOS Load8: 0x%08X", address);
640 value = (memory->biosPrefetch >> ((address & 3) * 8)) & 0xFF;
641 }
642 } else {
643 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load8: 0x%08x", address);
644 value = (GBALoadBad(cpu) >> ((address & 3) * 8)) & 0xFF;
645 }
646 break;
647 case REGION_WORKING_RAM:
648 value = ((uint8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
649 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
650 break;
651 case REGION_WORKING_IRAM:
652 value = ((uint8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
653 break;
654 case REGION_IO:
655 value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
656 break;
657 case REGION_PALETTE_RAM:
658 value = ((uint8_t*) gba->video.palette)[address & (SIZE_PALETTE_RAM - 1)];
659 break;
660 case REGION_VRAM:
661 if ((address & 0x0001FFFF) >= SIZE_VRAM) {
662 if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
663 mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load8: 0x%08X", address);
664 value = 0;
665 break;
666 }
667 value = ((uint8_t*) gba->video.vram)[address & 0x00017FFF];
668 } else {
669 value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF];
670 }
671 if (gba->video.shouldStall) {
672 wait += GBAMemoryStallVRAM(gba, wait, 0);
673 }
674 break;
675 case REGION_OAM:
676 value = ((uint8_t*) gba->video.oam.raw)[address & (SIZE_OAM - 1)];
677 break;
678 case REGION_CART0:
679 case REGION_CART0_EX:
680 case REGION_CART1:
681 case REGION_CART1_EX:
682 case REGION_CART2:
683 case REGION_CART2_EX:
684 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
685 if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
686 value = ((uint8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
687 } else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
688 value = ((uint8_t*) memory->rom)[address & memory->romMask];
689 } else if (memory->vfame.cartType) {
690 value = GBAVFameGetPatternValue(address, 8);
691 } else {
692 mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load8: 0x%08X", address);
693 value = ((address >> 1) >> ((address & 1) * 8)) & 0xFF;
694 }
695 break;
696 case REGION_CART_SRAM:
697 case REGION_CART_SRAM_MIRROR:
698 wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
699 if (memory->savedata.type == SAVEDATA_AUTODETECT) {
700 mLOG(GBA_MEM, INFO, "Detected SRAM savegame");
701 GBASavedataInitSRAM(&memory->savedata);
702 }
703 if (gba->performingDMA == 1) {
704 break;
705 }
706 if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) {
707 value = GBAHardwareEReaderReadFlash(&memory->hw, address);
708 } else if (memory->savedata.type == SAVEDATA_SRAM) {
709 value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
710 } else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
711 value = GBASavedataReadFlash(&memory->savedata, address);
712 } else if (memory->hw.devices & HW_TILT) {
713 value = GBAHardwareTiltRead(&memory->hw, address & OFFSET_MASK);
714 } else {
715 mLOG(GBA_MEM, GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
716 value = 0xFF;
717 }
718 value &= 0xFF;
719 break;
720 default:
721 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load8: 0x%08x", address);
722 value = (GBALoadBad(cpu) >> ((address & 3) * 8)) & 0xFF;
723 break;
724 }
725
726 if (cycleCounter) {
727 wait += 2;
728 if (address < BASE_CART0) {
729 wait = GBAMemoryStall(cpu, wait);
730 }
731 *cycleCounter += wait;
732 }
733 return value;
734}
735
736#define STORE_WORKING_RAM \
737 STORE_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram); \
738 wait += waitstatesRegion[REGION_WORKING_RAM];
739
740#define STORE_WORKING_IRAM \
741 STORE_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
742
743#define STORE_IO \
744 GBAIOWrite32(gba, address & (OFFSET_MASK - 3), value);
745
746#define STORE_PALETTE_RAM \
747 LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
748 if (oldValue != value) { \
749 STORE_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
750 gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16); \
751 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 4), value); \
752 } \
753 wait += waitstatesRegion[REGION_PALETTE_RAM];
754
755#define STORE_VRAM \
756 if ((address & 0x0001FFFF) >= SIZE_VRAM) { \
757 if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \
758 mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store32: 0x%08X", address); \
759 } else { \
760 LOAD_32(oldValue, address & 0x00017FFC, gba->video.vram); \
761 if (oldValue != value) { \
762 STORE_32(value, address & 0x00017FFC, gba->video.vram); \
763 gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC) + 2); \
764 gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC)); \
765 } \
766 } \
767 } else { \
768 LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram); \
769 if (oldValue != value) { \
770 STORE_32(value, address & 0x0001FFFC, gba->video.vram); \
771 gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC) + 2); \
772 gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC)); \
773 } \
774 } \
775 ++wait; \
776 if (gba->video.shouldStall) { \
777 wait += GBAMemoryStallVRAM(gba, wait, 1); \
778 }
779
780#define STORE_OAM \
781 LOAD_32(oldValue, address & (SIZE_OAM - 4), gba->video.oam.raw); \
782 if (oldValue != value) { \
783 STORE_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw); \
784 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1); \
785 gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1); \
786 }
787
788#define STORE_CART \
789 wait += waitstatesRegion[address >> BASE_OFFSET]; \
790 if (memory->matrix.size && (address & 0x01FFFF00) == 0x00800100) { \
791 GBAMatrixWrite(gba, address & 0x3C, value); \
792 break; \
793 } \
794 mLOG(GBA_MEM, STUB, "Unimplemented memory Store32: 0x%08X", address);
795
796#define STORE_SRAM \
797 if (address & 0x3) { \
798 mLOG(GBA_MEM, GAME_ERROR, "Unaligned SRAM Store32: 0x%08X", address); \
799 } else { \
800 GBAStore8(cpu, address, value, cycleCounter); \
801 GBAStore8(cpu, address | 1, value, cycleCounter); \
802 GBAStore8(cpu, address | 2, value, cycleCounter); \
803 GBAStore8(cpu, address | 3, value, cycleCounter); \
804 }
805
806#define STORE_BAD \
807 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store32: 0x%08X", address);
808
809void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
810 struct GBA* gba = (struct GBA*) cpu->master;
811 struct GBAMemory* memory = &gba->memory;
812 int wait = 0;
813 int32_t oldValue;
814 char* waitstatesRegion = memory->waitstatesNonseq32;
815
816 switch (address >> BASE_OFFSET) {
817 case REGION_WORKING_RAM:
818 STORE_WORKING_RAM;
819 break;
820 case REGION_WORKING_IRAM:
821 STORE_WORKING_IRAM
822 break;
823 case REGION_IO:
824 STORE_IO;
825 break;
826 case REGION_PALETTE_RAM:
827 STORE_PALETTE_RAM;
828 break;
829 case REGION_VRAM:
830 STORE_VRAM;
831 break;
832 case REGION_OAM:
833 STORE_OAM;
834 break;
835 case REGION_CART0:
836 case REGION_CART0_EX:
837 case REGION_CART1:
838 case REGION_CART1_EX:
839 case REGION_CART2:
840 case REGION_CART2_EX:
841 STORE_CART;
842 break;
843 case REGION_CART_SRAM:
844 case REGION_CART_SRAM_MIRROR:
845 STORE_SRAM;
846 break;
847 default:
848 STORE_BAD;
849 break;
850 }
851
852 if (cycleCounter) {
853 ++wait;
854 if (address < BASE_CART0) {
855 wait = GBAMemoryStall(cpu, wait);
856 }
857 *cycleCounter += wait;
858 }
859}
860
861void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
862 struct GBA* gba = (struct GBA*) cpu->master;
863 struct GBAMemory* memory = &gba->memory;
864 int wait = 0;
865 int16_t oldValue;
866
867 switch (address >> BASE_OFFSET) {
868 case REGION_WORKING_RAM:
869 STORE_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
870 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
871 break;
872 case REGION_WORKING_IRAM:
873 STORE_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
874 break;
875 case REGION_IO:
876 GBAIOWrite(gba, address & (OFFSET_MASK - 1), value);
877 break;
878 case REGION_PALETTE_RAM:
879 LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
880 if (oldValue != value) {
881 STORE_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
882 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
883 }
884 break;
885 case REGION_VRAM:
886 if ((address & 0x0001FFFF) >= SIZE_VRAM) {
887 if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
888 mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store16: 0x%08X", address);
889 break;
890 }
891 LOAD_16(oldValue, address & 0x00017FFE, gba->video.vram);
892 if (value != oldValue) {
893 STORE_16(value, address & 0x00017FFE, gba->video.vram);
894 gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE);
895 }
896 } else {
897 LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram);
898 if (value != oldValue) {
899 STORE_16(value, address & 0x0001FFFE, gba->video.vram);
900 gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE);
901 }
902 }
903 if (gba->video.shouldStall) {
904 wait += GBAMemoryStallVRAM(gba, wait, 0);
905 }
906 break;
907 case REGION_OAM:
908 LOAD_16(oldValue, address & (SIZE_OAM - 2), gba->video.oam.raw);
909 if (value != oldValue) {
910 STORE_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
911 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
912 }
913 break;
914 case REGION_CART0:
915 if (memory->hw.devices != HW_NONE && IS_GPIO_REGISTER(address & 0xFFFFFE)) {
916 uint32_t reg = address & 0xFFFFFE;
917 GBAHardwareGPIOWrite(&memory->hw, reg, value);
918 break;
919 }
920 if (memory->matrix.size && (address & 0x01FFFF00) == 0x00800100) {
921 GBAMatrixWrite16(gba, address & 0x3C, value);
922 break;
923 }
924 // Fall through
925 case REGION_CART0_EX:
926 if ((address & 0x00FFFFFF) >= AGB_PRINT_BASE) {
927 uint32_t agbPrintAddr = address & 0x00FFFFFF;
928 if (agbPrintAddr == AGB_PRINT_PROTECT) {
929 bool wasProtected = memory->agbPrintProtect != 0x20;
930 memory->agbPrintProtect = value;
931
932 if (!memory->agbPrintBuffer) {
933 memory->agbPrintBuffer = anonymousMemoryMap(SIZE_AGB_PRINT);
934 if (memory->romSize >= SIZE_CART0 / 2) {
935 int base = 0;
936 if (memory->romSize == SIZE_CART0) {
937 base = address & 0x01000000;
938 }
939 memory->agbPrintBase = base;
940 memory->agbPrintBufferBackup = anonymousMemoryMap(SIZE_AGB_PRINT);
941 memcpy(memory->agbPrintBufferBackup, &memory->rom[(AGB_PRINT_TOP | base) >> 2], SIZE_AGB_PRINT);
942 LOAD_16(memory->agbPrintProtectBackup, AGB_PRINT_PROTECT | base, memory->rom);
943 LOAD_16(memory->agbPrintCtxBackup.request, AGB_PRINT_STRUCT | base, memory->rom);
944 LOAD_16(memory->agbPrintCtxBackup.bank, (AGB_PRINT_STRUCT | base) + 2, memory->rom);
945 LOAD_16(memory->agbPrintCtxBackup.get, (AGB_PRINT_STRUCT | base) + 4, memory->rom);
946 LOAD_16(memory->agbPrintCtxBackup.put, (AGB_PRINT_STRUCT | base) + 6, memory->rom);
947 LOAD_32(memory->agbPrintFuncBackup, AGB_PRINT_FLUSH_ADDR | base, memory->rom);
948 }
949 }
950
951 if (value == 0x20) {
952 _agbPrintStore(gba, address, value);
953 }
954 break;
955 }
956 if (memory->agbPrintProtect == 0x20 && (agbPrintAddr < AGB_PRINT_TOP || (agbPrintAddr & 0x00FFFFF8) == AGB_PRINT_STRUCT)) {
957 _agbPrintStore(gba, address, value);
958 break;
959 }
960 }
961 mLOG(GBA_MEM, GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
962 break;
963 case REGION_CART2_EX:
964 if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) {
965 GBAHardwareEReaderWrite(&memory->hw, address, value);
966 break;
967 } else if (memory->savedata.type == SAVEDATA_AUTODETECT) {
968 mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
969 GBASavedataInitEEPROM(&memory->savedata);
970 }
971 if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) {
972 GBASavedataWriteEEPROM(&memory->savedata, value, 1);
973 break;
974 }
975 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store16: 0x%08X", address);
976 break;
977 case REGION_CART_SRAM:
978 case REGION_CART_SRAM_MIRROR:
979 if (address & 1) {
980 mLOG(GBA_MEM, GAME_ERROR, "Unaligned SRAM Store16: 0x%08X", address);
981 break;
982 }
983 GBAStore8(cpu, address, value, cycleCounter);
984 GBAStore8(cpu, address | 1, value, cycleCounter);
985 break;
986 default:
987 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store16: 0x%08X", address);
988 break;
989 }
990
991 if (cycleCounter) {
992 ++wait;
993 if (address < BASE_CART0) {
994 wait = GBAMemoryStall(cpu, wait);
995 }
996 *cycleCounter += wait;
997 }
998}
999
1000void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
1001 struct GBA* gba = (struct GBA*) cpu->master;
1002 struct GBAMemory* memory = &gba->memory;
1003 int wait = 0;
1004 uint16_t oldValue;
1005
1006 switch (address >> BASE_OFFSET) {
1007 case REGION_WORKING_RAM:
1008 ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
1009 wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
1010 break;
1011 case REGION_WORKING_IRAM:
1012 ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
1013 break;
1014 case REGION_IO:
1015 GBAIOWrite8(gba, address & OFFSET_MASK, value);
1016 break;
1017 case REGION_PALETTE_RAM:
1018 GBAStore16(cpu, address & ~1, ((uint8_t) value) | ((uint8_t) value << 8), cycleCounter);
1019 break;
1020 case REGION_VRAM:
1021 if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) {
1022 mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
1023 break;
1024 }
1025 oldValue = gba->video.renderer->vram[(address & 0x1FFFE) >> 1];
1026 if (oldValue != (((uint8_t) value) | (value << 8))) {
1027 gba->video.renderer->vram[(address & 0x1FFFE) >> 1] = ((uint8_t) value) | (value << 8);
1028 gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE);
1029 }
1030 if (gba->video.shouldStall) {
1031 wait += GBAMemoryStallVRAM(gba, wait, 0);
1032 }
1033 break;
1034 case REGION_OAM:
1035 mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
1036 break;
1037 case REGION_CART0:
1038 mLOG(GBA_MEM, STUB, "Unimplemented memory Store8: 0x%08X", address);
1039 break;
1040 case REGION_CART_SRAM:
1041 case REGION_CART_SRAM_MIRROR:
1042 if (memory->savedata.type == SAVEDATA_AUTODETECT) {
1043 if (address == SAVEDATA_FLASH_BASE) {
1044 mLOG(GBA_MEM, INFO, "Detected Flash savegame");
1045 GBASavedataInitFlash(&memory->savedata);
1046 } else {
1047 mLOG(GBA_MEM, INFO, "Detected SRAM savegame");
1048 GBASavedataInitSRAM(&memory->savedata);
1049 }
1050 }
1051 if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) {
1052 GBAHardwareEReaderWriteFlash(&memory->hw, address, value);
1053 } else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
1054 GBASavedataWriteFlash(&memory->savedata, address, value);
1055 } else if (memory->savedata.type == SAVEDATA_SRAM) {
1056 if (memory->vfame.cartType) {
1057 GBAVFameSramWrite(&memory->vfame, address, value, memory->savedata.data);
1058 } else {
1059 memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
1060 }
1061 memory->savedata.dirty |= SAVEDATA_DIRT_NEW;
1062 } else if (memory->hw.devices & HW_TILT) {
1063 GBAHardwareTiltWrite(&memory->hw, address & OFFSET_MASK, value);
1064 } else {
1065 mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1066 }
1067 wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
1068 break;
1069 default:
1070 mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store8: 0x%08X", address);
1071 break;
1072 }
1073
1074 if (cycleCounter) {
1075 ++wait;
1076 if (address < BASE_CART0) {
1077 wait = GBAMemoryStall(cpu, wait);
1078 }
1079 *cycleCounter += wait;
1080 }
1081}
1082
1083uint32_t GBAView32(struct ARMCore* cpu, uint32_t address) {
1084 struct GBA* gba = (struct GBA*) cpu->master;
1085 uint32_t value = 0;
1086 address &= ~3;
1087 switch (address >> BASE_OFFSET) {
1088 case REGION_BIOS:
1089 if (address < SIZE_BIOS) {
1090 LOAD_32(value, address, gba->memory.bios);
1091 }
1092 break;
1093 case REGION_WORKING_RAM:
1094 case REGION_WORKING_IRAM:
1095 case REGION_PALETTE_RAM:
1096 case REGION_VRAM:
1097 case REGION_OAM:
1098 case REGION_CART0:
1099 case REGION_CART0_EX:
1100 case REGION_CART1:
1101 case REGION_CART1_EX:
1102 case REGION_CART2:
1103 case REGION_CART2_EX:
1104 value = GBALoad32(cpu, address, 0);
1105 break;
1106 case REGION_IO:
1107 if ((address & OFFSET_MASK) < REG_MAX) {
1108 value = gba->memory.io[(address & OFFSET_MASK) >> 1];
1109 value |= gba->memory.io[((address & OFFSET_MASK) >> 1) + 1] << 16;
1110 }
1111 break;
1112 case REGION_CART_SRAM:
1113 value = GBALoad8(cpu, address, 0);
1114 value |= GBALoad8(cpu, address + 1, 0) << 8;
1115 value |= GBALoad8(cpu, address + 2, 0) << 16;
1116 value |= GBALoad8(cpu, address + 3, 0) << 24;
1117 break;
1118 default:
1119 break;
1120 }
1121 return value;
1122}
1123
1124uint16_t GBAView16(struct ARMCore* cpu, uint32_t address) {
1125 struct GBA* gba = (struct GBA*) cpu->master;
1126 uint16_t value = 0;
1127 address &= ~1;
1128 switch (address >> BASE_OFFSET) {
1129 case REGION_BIOS:
1130 if (address < SIZE_BIOS) {
1131 LOAD_16(value, address, gba->memory.bios);
1132 }
1133 break;
1134 case REGION_WORKING_RAM:
1135 case REGION_WORKING_IRAM:
1136 case REGION_PALETTE_RAM:
1137 case REGION_VRAM:
1138 case REGION_OAM:
1139 case REGION_CART0:
1140 case REGION_CART0_EX:
1141 case REGION_CART1:
1142 case REGION_CART1_EX:
1143 case REGION_CART2:
1144 case REGION_CART2_EX:
1145 value = GBALoad16(cpu, address, 0);
1146 break;
1147 case REGION_IO:
1148 if ((address & OFFSET_MASK) < REG_MAX) {
1149 value = gba->memory.io[(address & OFFSET_MASK) >> 1];
1150 }
1151 break;
1152 case REGION_CART_SRAM:
1153 value = GBALoad8(cpu, address, 0);
1154 value |= GBALoad8(cpu, address + 1, 0) << 8;
1155 break;
1156 default:
1157 break;
1158 }
1159 return value;
1160}
1161
1162uint8_t GBAView8(struct ARMCore* cpu, uint32_t address) {
1163 struct GBA* gba = (struct GBA*) cpu->master;
1164 uint8_t value = 0;
1165 switch (address >> BASE_OFFSET) {
1166 case REGION_BIOS:
1167 if (address < SIZE_BIOS) {
1168 value = ((uint8_t*) gba->memory.bios)[address];
1169 }
1170 break;
1171 case REGION_WORKING_RAM:
1172 case REGION_WORKING_IRAM:
1173 case REGION_CART0:
1174 case REGION_CART0_EX:
1175 case REGION_CART1:
1176 case REGION_CART1_EX:
1177 case REGION_CART2:
1178 case REGION_CART2_EX:
1179 case REGION_CART_SRAM:
1180 value = GBALoad8(cpu, address, 0);
1181 break;
1182 case REGION_IO:
1183 case REGION_PALETTE_RAM:
1184 case REGION_VRAM:
1185 case REGION_OAM:
1186 value = GBAView16(cpu, address) >> ((address & 1) * 8);
1187 break;
1188 default:
1189 break;
1190 }
1191 return value;
1192}
1193
1194void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* old) {
1195 struct GBA* gba = (struct GBA*) cpu->master;
1196 struct GBAMemory* memory = &gba->memory;
1197 int32_t oldValue = -1;
1198
1199 switch (address >> BASE_OFFSET) {
1200 case REGION_WORKING_RAM:
1201 LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 4), memory->wram);
1202 STORE_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram);
1203 break;
1204 case REGION_WORKING_IRAM:
1205 LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
1206 STORE_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
1207 break;
1208 case REGION_IO:
1209 mLOG(GBA_MEM, STUB, "Unimplemented memory Patch32: 0x%08X", address);
1210 break;
1211 case REGION_PALETTE_RAM:
1212 LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
1213 STORE_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette);
1214 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 4), value);
1215 gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16);
1216 break;
1217 case REGION_VRAM:
1218 if ((address & 0x0001FFFF) < SIZE_VRAM) {
1219 LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram);
1220 STORE_32(value, address & 0x0001FFFC, gba->video.vram);
1221 } else {
1222 LOAD_32(oldValue, address & 0x00017FFC, gba->video.vram);
1223 STORE_32(value, address & 0x00017FFC, gba->video.vram);
1224 }
1225 break;
1226 case REGION_OAM:
1227 LOAD_32(oldValue, address & (SIZE_OAM - 4), gba->video.oam.raw);
1228 STORE_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw);
1229 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
1230 gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) + 2) >> 1);
1231 break;
1232 case REGION_CART0:
1233 case REGION_CART0_EX:
1234 case REGION_CART1:
1235 case REGION_CART1_EX:
1236 case REGION_CART2:
1237 case REGION_CART2_EX:
1238 _pristineCow(gba);
1239 if ((address & (SIZE_CART0 - 4)) >= gba->memory.romSize) {
1240 gba->memory.romSize = (address & (SIZE_CART0 - 4)) + 4;
1241 gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
1242 }
1243 LOAD_32(oldValue, address & (SIZE_CART0 - 4), gba->memory.rom);
1244 STORE_32(value, address & (SIZE_CART0 - 4), gba->memory.rom);
1245 break;
1246 case REGION_CART_SRAM:
1247 case REGION_CART_SRAM_MIRROR:
1248 if (memory->savedata.type == SAVEDATA_SRAM) {
1249 LOAD_32(oldValue, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
1250 STORE_32(value, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
1251 } else {
1252 mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1253 }
1254 break;
1255 default:
1256 mLOG(GBA_MEM, WARN, "Bad memory Patch16: 0x%08X", address);
1257 break;
1258 }
1259 if (old) {
1260 *old = oldValue;
1261 }
1262}
1263
1264void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* old) {
1265 struct GBA* gba = (struct GBA*) cpu->master;
1266 struct GBAMemory* memory = &gba->memory;
1267 int16_t oldValue = -1;
1268
1269 switch (address >> BASE_OFFSET) {
1270 case REGION_WORKING_RAM:
1271 LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 2), memory->wram);
1272 STORE_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
1273 break;
1274 case REGION_WORKING_IRAM:
1275 LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
1276 STORE_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
1277 break;
1278 case REGION_IO:
1279 mLOG(GBA_MEM, STUB, "Unimplemented memory Patch16: 0x%08X", address);
1280 break;
1281 case REGION_PALETTE_RAM:
1282 LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
1283 STORE_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
1284 gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
1285 break;
1286 case REGION_VRAM:
1287 if ((address & 0x0001FFFF) < SIZE_VRAM) {
1288 LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram);
1289 STORE_16(value, address & 0x0001FFFE, gba->video.vram);
1290 } else {
1291 LOAD_16(oldValue, address & 0x00017FFE, gba->video.vram);
1292 STORE_16(value, address & 0x00017FFE, gba->video.vram);
1293 }
1294 break;
1295 case REGION_OAM:
1296 LOAD_16(oldValue, address & (SIZE_OAM - 2), gba->video.oam.raw);
1297 STORE_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
1298 gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
1299 break;
1300 case REGION_CART0:
1301 case REGION_CART0_EX:
1302 case REGION_CART1:
1303 case REGION_CART1_EX:
1304 case REGION_CART2:
1305 case REGION_CART2_EX:
1306 _pristineCow(gba);
1307 if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
1308 gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2;
1309 gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
1310 }
1311 LOAD_16(oldValue, address & (SIZE_CART0 - 2), gba->memory.rom);
1312 STORE_16(value, address & (SIZE_CART0 - 2), gba->memory.rom);
1313 break;
1314 case REGION_CART_SRAM:
1315 case REGION_CART_SRAM_MIRROR:
1316 if (memory->savedata.type == SAVEDATA_SRAM) {
1317 LOAD_16(oldValue, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
1318 STORE_16(value, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
1319 } else {
1320 mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1321 }
1322 break;
1323 default:
1324 mLOG(GBA_MEM, WARN, "Bad memory Patch16: 0x%08X", address);
1325 break;
1326 }
1327 if (old) {
1328 *old = oldValue;
1329 }
1330}
1331
1332void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) {
1333 struct GBA* gba = (struct GBA*) cpu->master;
1334 struct GBAMemory* memory = &gba->memory;
1335 int8_t oldValue = -1;
1336
1337 switch (address >> BASE_OFFSET) {
1338 case REGION_WORKING_RAM:
1339 oldValue = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
1340 ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
1341 break;
1342 case REGION_WORKING_IRAM:
1343 oldValue = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
1344 ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
1345 break;
1346 case REGION_IO:
1347 mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1348 break;
1349 case REGION_PALETTE_RAM:
1350 mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1351 break;
1352 case REGION_VRAM:
1353 mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1354 break;
1355 case REGION_OAM:
1356 mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1357 break;
1358 case REGION_CART0:
1359 case REGION_CART0_EX:
1360 case REGION_CART1:
1361 case REGION_CART1_EX:
1362 case REGION_CART2:
1363 case REGION_CART2_EX:
1364 _pristineCow(gba);
1365 if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
1366 gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2;
1367 gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
1368 }
1369 oldValue = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
1370 ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)] = value;
1371 break;
1372 case REGION_CART_SRAM:
1373 case REGION_CART_SRAM_MIRROR:
1374 if (memory->savedata.type == SAVEDATA_SRAM) {
1375 oldValue = ((int8_t*) memory->savedata.data)[address & (SIZE_CART_SRAM - 1)];
1376 ((int8_t*) memory->savedata.data)[address & (SIZE_CART_SRAM - 1)] = value;
1377 } else {
1378 mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1379 }
1380 break;
1381 default:
1382 mLOG(GBA_MEM, WARN, "Bad memory Patch8: 0x%08X", address);
1383 break;
1384 }
1385 if (old) {
1386 *old = oldValue;
1387 }
1388}
1389
1390#define LDM_LOOP(LDM) \
1391 if (UNLIKELY(!mask)) { \
1392 LDM; \
1393 cpu->gprs[ARM_PC] = value; \
1394 wait += 16; \
1395 address += 64; \
1396 } \
1397 for (i = 0; i < 16; i += 4) { \
1398 if (UNLIKELY(mask & (1 << i))) { \
1399 LDM; \
1400 cpu->gprs[i] = value; \
1401 ++wait; \
1402 address += 4; \
1403 } \
1404 if (UNLIKELY(mask & (2 << i))) { \
1405 LDM; \
1406 cpu->gprs[i + 1] = value; \
1407 ++wait; \
1408 address += 4; \
1409 } \
1410 if (UNLIKELY(mask & (4 << i))) { \
1411 LDM; \
1412 cpu->gprs[i + 2] = value; \
1413 ++wait; \
1414 address += 4; \
1415 } \
1416 if (UNLIKELY(mask & (8 << i))) { \
1417 LDM; \
1418 cpu->gprs[i + 3] = value; \
1419 ++wait; \
1420 address += 4; \
1421 } \
1422 }
1423
1424uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
1425 struct GBA* gba = (struct GBA*) cpu->master;
1426 struct GBAMemory* memory = &gba->memory;
1427 uint32_t value;
1428 char* waitstatesRegion = memory->waitstatesSeq32;
1429
1430 int i;
1431 int offset = 4;
1432 int popcount = 0;
1433 if (direction & LSM_D) {
1434 offset = -4;
1435 popcount = popcount32(mask);
1436 address -= (popcount << 2) - 4;
1437 }
1438
1439 if (direction & LSM_B) {
1440 address += offset;
1441 }
1442
1443 uint32_t addressMisalign = address & 0x3;
1444 int region = address >> BASE_OFFSET;
1445 if (region < REGION_CART_SRAM) {
1446 address &= 0xFFFFFFFC;
1447 }
1448 int wait = memory->waitstatesSeq32[region] - memory->waitstatesNonseq32[region];
1449
1450 switch (region) {
1451 case REGION_BIOS:
1452 LDM_LOOP(LOAD_BIOS);
1453 break;
1454 case REGION_WORKING_RAM:
1455 LDM_LOOP(LOAD_WORKING_RAM);
1456 break;
1457 case REGION_WORKING_IRAM:
1458 LDM_LOOP(LOAD_WORKING_IRAM);
1459 break;
1460 case REGION_IO:
1461 LDM_LOOP(LOAD_IO);
1462 break;
1463 case REGION_PALETTE_RAM:
1464 LDM_LOOP(LOAD_PALETTE_RAM);
1465 break;
1466 case REGION_VRAM:
1467 LDM_LOOP(LOAD_VRAM);
1468 break;
1469 case REGION_OAM:
1470 LDM_LOOP(LOAD_OAM);
1471 break;
1472 case REGION_CART0:
1473 case REGION_CART0_EX:
1474 case REGION_CART1:
1475 case REGION_CART1_EX:
1476 case REGION_CART2:
1477 case REGION_CART2_EX:
1478 LDM_LOOP(LOAD_CART);
1479 break;
1480 case REGION_CART_SRAM:
1481 case REGION_CART_SRAM_MIRROR:
1482 LDM_LOOP(LOAD_SRAM);
1483 break;
1484 default:
1485 LDM_LOOP(LOAD_BAD);
1486 break;
1487 }
1488
1489 if (cycleCounter) {
1490 ++wait;
1491 if (address < BASE_CART0) {
1492 wait = GBAMemoryStall(cpu, wait);
1493 }
1494 *cycleCounter += wait;
1495 }
1496
1497 if (direction & LSM_B) {
1498 address -= offset;
1499 }
1500
1501 if (direction & LSM_D) {
1502 address -= (popcount << 2) + 4;
1503 }
1504
1505 return address | addressMisalign;
1506}
1507
1508#define STM_LOOP(STM) \
1509 if (UNLIKELY(!mask)) { \
1510 value = cpu->gprs[ARM_PC] + (cpu->executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB); \
1511 STM; \
1512 wait += 16; \
1513 address += 64; \
1514 } \
1515 for (i = 0; i < 16; i += 4) { \
1516 if (UNLIKELY(mask & (1 << i))) { \
1517 value = cpu->gprs[i]; \
1518 STM; \
1519 ++wait; \
1520 address += 4; \
1521 } \
1522 if (UNLIKELY(mask & (2 << i))) { \
1523 value = cpu->gprs[i + 1]; \
1524 STM; \
1525 ++wait; \
1526 address += 4; \
1527 } \
1528 if (UNLIKELY(mask & (4 << i))) { \
1529 value = cpu->gprs[i + 2]; \
1530 STM; \
1531 ++wait; \
1532 address += 4; \
1533 } \
1534 if (UNLIKELY(mask & (8 << i))) { \
1535 value = cpu->gprs[i + 3]; \
1536 if (i + 3 == ARM_PC) { \
1537 value += WORD_SIZE_ARM; \
1538 } \
1539 STM; \
1540 ++wait; \
1541 address += 4; \
1542 } \
1543 }
1544
1545uint32_t GBAStoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
1546 struct GBA* gba = (struct GBA*) cpu->master;
1547 struct GBAMemory* memory = &gba->memory;
1548 uint32_t value;
1549 uint32_t oldValue;
1550 char* waitstatesRegion = memory->waitstatesSeq32;
1551
1552 int i;
1553 int offset = 4;
1554 int popcount = 0;
1555 if (direction & LSM_D) {
1556 offset = -4;
1557 popcount = popcount32(mask);
1558 address -= (popcount << 2) - 4;
1559 }
1560
1561 if (direction & LSM_B) {
1562 address += offset;
1563 }
1564
1565 uint32_t addressMisalign = address & 0x3;
1566 int region = address >> BASE_OFFSET;
1567 if (region < REGION_CART_SRAM) {
1568 address &= 0xFFFFFFFC;
1569 }
1570 int wait = memory->waitstatesSeq32[region] - memory->waitstatesNonseq32[region];
1571
1572 switch (region) {
1573 case REGION_WORKING_RAM:
1574 STM_LOOP(STORE_WORKING_RAM);
1575 break;
1576 case REGION_WORKING_IRAM:
1577 STM_LOOP(STORE_WORKING_IRAM);
1578 break;
1579 case REGION_IO:
1580 STM_LOOP(STORE_IO);
1581 break;
1582 case REGION_PALETTE_RAM:
1583 STM_LOOP(STORE_PALETTE_RAM);
1584 break;
1585 case REGION_VRAM:
1586 STM_LOOP(STORE_VRAM);
1587 break;
1588 case REGION_OAM:
1589 STM_LOOP(STORE_OAM);
1590 break;
1591 case REGION_CART0:
1592 case REGION_CART0_EX:
1593 case REGION_CART1:
1594 case REGION_CART1_EX:
1595 case REGION_CART2:
1596 case REGION_CART2_EX:
1597 STM_LOOP(STORE_CART);
1598 break;
1599 case REGION_CART_SRAM:
1600 case REGION_CART_SRAM_MIRROR:
1601 STM_LOOP(STORE_SRAM);
1602 break;
1603 default:
1604 STM_LOOP(STORE_BAD);
1605 break;
1606 }
1607
1608 if (cycleCounter) {
1609 if (address < BASE_CART0) {
1610 wait = GBAMemoryStall(cpu, wait);
1611 }
1612 *cycleCounter += wait;
1613 }
1614
1615 if (direction & LSM_B) {
1616 address -= offset;
1617 }
1618
1619 if (direction & LSM_D) {
1620 address -= (popcount << 2) + 4;
1621 }
1622
1623 return address | addressMisalign;
1624}
1625
1626void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
1627 struct GBAMemory* memory = &gba->memory;
1628 struct ARMCore* cpu = gba->cpu;
1629 int sram = parameters & 0x0003;
1630 int ws0 = (parameters & 0x000C) >> 2;
1631 int ws0seq = (parameters & 0x0010) >> 4;
1632 int ws1 = (parameters & 0x0060) >> 5;
1633 int ws1seq = (parameters & 0x0080) >> 7;
1634 int ws2 = (parameters & 0x0300) >> 8;
1635 int ws2seq = (parameters & 0x0400) >> 10;
1636 int prefetch = parameters & 0x4000;
1637
1638 memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
1639 memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
1640 memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
1641 memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
1642
1643 memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
1644 memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
1645 memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
1646
1647 memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
1648 memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
1649 memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
1650
1651 memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
1652 memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
1653 memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
1654
1655 memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
1656 memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
1657 memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
1658
1659 memory->prefetch = prefetch;
1660
1661 cpu->memory.activeSeqCycles32 = memory->waitstatesSeq32[memory->activeRegion];
1662 cpu->memory.activeSeqCycles16 = memory->waitstatesSeq16[memory->activeRegion];
1663
1664 cpu->memory.activeNonseqCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
1665 cpu->memory.activeNonseqCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
1666
1667 if (memory->agbPrintBufferBackup) {
1668 int phi = (parameters >> 11) & 3;
1669 uint32_t base = memory->agbPrintBase;
1670 if (phi == 3) {
1671 memcpy(&memory->rom[(AGB_PRINT_TOP | base) >> 2], memory->agbPrintBuffer, SIZE_AGB_PRINT);
1672 STORE_16(memory->agbPrintProtect, AGB_PRINT_PROTECT | base, memory->rom);
1673 STORE_16(memory->agbPrintCtx.request, AGB_PRINT_STRUCT | base, memory->rom);
1674 STORE_16(memory->agbPrintCtx.bank, (AGB_PRINT_STRUCT | base) + 2, memory->rom);
1675 STORE_16(memory->agbPrintCtx.get, (AGB_PRINT_STRUCT | base) + 4, memory->rom);
1676 STORE_16(memory->agbPrintCtx.put, (AGB_PRINT_STRUCT | base) + 6, memory->rom);
1677 STORE_32(_agbPrintFunc, AGB_PRINT_FLUSH_ADDR | base, memory->rom);
1678 } else {
1679 memcpy(&memory->rom[(AGB_PRINT_TOP | base) >> 2], memory->agbPrintBufferBackup, SIZE_AGB_PRINT);
1680 STORE_16(memory->agbPrintProtectBackup, AGB_PRINT_PROTECT | base, memory->rom);
1681 STORE_16(memory->agbPrintCtxBackup.request, AGB_PRINT_STRUCT | base, memory->rom);
1682 STORE_16(memory->agbPrintCtxBackup.bank, (AGB_PRINT_STRUCT | base) + 2, memory->rom);
1683 STORE_16(memory->agbPrintCtxBackup.get, (AGB_PRINT_STRUCT | base) + 4, memory->rom);
1684 STORE_16(memory->agbPrintCtxBackup.put, (AGB_PRINT_STRUCT | base) + 6, memory->rom);
1685 STORE_32(memory->agbPrintFuncBackup, AGB_PRINT_FLUSH_ADDR | base, memory->rom);
1686 }
1687 }
1688}
1689
1690int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait) {
1691 struct GBA* gba = (struct GBA*) cpu->master;
1692 struct GBAMemory* memory = &gba->memory;
1693
1694 if (memory->activeRegion < REGION_CART0 || !memory->prefetch) {
1695 // The wait is the stall
1696 return wait;
1697 }
1698
1699 int32_t previousLoads = 0;
1700
1701 // Don't prefetch too much if we're overlapping with a previous prefetch
1702 uint32_t dist = (memory->lastPrefetchedPc - cpu->gprs[ARM_PC]);
1703 int32_t maxLoads = 8;
1704 if (dist < 16) {
1705 previousLoads = dist >> 1;
1706 maxLoads -= previousLoads;
1707 }
1708
1709 int32_t s = cpu->memory.activeSeqCycles16;
1710 int32_t n2s = cpu->memory.activeNonseqCycles16 - cpu->memory.activeSeqCycles16 + 1;
1711
1712 // Figure out how many sequential loads we can jam in
1713 int32_t stall = s + 1;
1714 int32_t loads = 1;
1715
1716 while (stall < wait && loads < maxLoads) {
1717 stall += s;
1718 ++loads;
1719 }
1720 memory->lastPrefetchedPc = cpu->gprs[ARM_PC] + WORD_SIZE_THUMB * (loads + previousLoads - 1);
1721
1722 if (stall > wait) {
1723 // The wait cannot take less time than the prefetch stalls
1724 wait = stall;
1725 }
1726
1727 // This instruction used to have an N, convert it to an S.
1728 wait -= n2s;
1729
1730 // The next |loads|S waitstates disappear entirely, so long as they're all in a row
1731 wait -= stall - 1;
1732
1733 return wait;
1734}
1735
1736int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra) {
1737 UNUSED(extra);
1738 // TODO
1739 uint16_t dispcnt = gba->memory.io[REG_DISPCNT >> 1];
1740 int32_t stall = 0;
1741 switch (GBARegisterDISPCNTGetMode(dispcnt)) {
1742 case 2:
1743 if (GBARegisterDISPCNTIsBg2Enable(dispcnt) && GBARegisterDISPCNTIsBg3Enable(dispcnt)) {
1744 // If both backgrounds are enabled, VRAM access is entirely blocked during hdraw
1745 stall = mTimingUntil(&gba->timing, &gba->video.event);
1746 }
1747 break;
1748 default:
1749 return 0;
1750 }
1751 stall -= wait;
1752 if (stall < 0) {
1753 return 0;
1754 }
1755 return stall;
1756}
1757
1758void GBAMemorySerialize(const struct GBAMemory* memory, struct GBASerializedState* state) {
1759 memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
1760 memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
1761}
1762
1763void GBAMemoryDeserialize(struct GBAMemory* memory, const struct GBASerializedState* state) {
1764 memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
1765 memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
1766}
1767
1768void _pristineCow(struct GBA* gba) {
1769 if (!gba->isPristine) {
1770 return;
1771 }
1772#if !defined(FIXED_ROM_BUFFER) && !defined(__wii__)
1773 void* newRom = anonymousMemoryMap(SIZE_CART0);
1774 memcpy(newRom, gba->memory.rom, gba->memory.romSize);
1775 memset(((uint8_t*) newRom) + gba->memory.romSize, 0xFF, SIZE_CART0 - gba->memory.romSize);
1776 if (gba->cpu->memory.activeRegion == gba->memory.rom) {
1777 gba->cpu->memory.activeRegion = newRom;
1778 }
1779 if (gba->romVf) {
1780 gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->memory.romSize);
1781 gba->romVf->close(gba->romVf);
1782 gba->romVf = NULL;
1783 }
1784 gba->memory.rom = newRom;
1785 gba->memory.hw.gpioBase = &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1];
1786#endif
1787 gba->isPristine = false;
1788}
1789
1790void GBAPrintFlush(struct GBA* gba) {
1791 if (!gba->memory.agbPrintBuffer) {
1792 return;
1793 }
1794
1795 char oolBuf[0x101];
1796 size_t i;
1797 for (i = 0; gba->memory.agbPrintCtx.get != gba->memory.agbPrintCtx.put && i < 0x100; ++i) {
1798 int16_t value;
1799 LOAD_16(value, gba->memory.agbPrintCtx.get & -2, gba->memory.agbPrintBuffer);
1800 if (gba->memory.agbPrintCtx.get & 1) {
1801 value >>= 8;
1802 } else {
1803 value &= 0xFF;
1804 }
1805 oolBuf[i] = value;
1806 oolBuf[i + 1] = 0;
1807 ++gba->memory.agbPrintCtx.get;
1808 }
1809 _agbPrintStore(gba, (AGB_PRINT_STRUCT + 4) | gba->memory.agbPrintBase, gba->memory.agbPrintCtx.get);
1810
1811 mLOG(GBA_DEBUG, INFO, "%s", oolBuf);
1812}
1813
1814static void _agbPrintStore(struct GBA* gba, uint32_t address, int16_t value) {
1815 struct GBAMemory* memory = &gba->memory;
1816 if ((address & 0x00FFFFFF) < AGB_PRINT_TOP) {
1817 STORE_16(value, address & (SIZE_AGB_PRINT - 2), memory->agbPrintBuffer);
1818 } else if ((address & 0x00FFFFF8) == AGB_PRINT_STRUCT) {
1819 (&memory->agbPrintCtx.request)[(address & 7) >> 1] = value;
1820 }
1821 if (memory->romSize == SIZE_CART0) {
1822 _pristineCow(gba);
1823 STORE_16(value, address & (SIZE_CART0 - 2), memory->rom);
1824 } else if (memory->agbPrintCtx.bank == 0xFD && memory->romSize >= SIZE_CART0 / 2) {
1825 _pristineCow(gba);
1826 STORE_16(value, address & (SIZE_CART0 / 2 - 2), memory->rom);
1827 }
1828}
1829
1830static int16_t _agbPrintLoad(struct GBA* gba, uint32_t address) {
1831 struct GBAMemory* memory = &gba->memory;
1832 int16_t value = address >> 1;
1833 if (address < AGB_PRINT_TOP && memory->agbPrintBuffer) {
1834 LOAD_16(value, address & (SIZE_AGB_PRINT - 1), memory->agbPrintBuffer);
1835 } else if ((address & 0x00FFFFF8) == AGB_PRINT_STRUCT) {
1836 value = (&memory->agbPrintCtx.request)[(address & 7) >> 1];
1837 }
1838 return value;
1839}