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