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