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 
22 mLOG_DEFINE_CATEGORY(GBA_MEM, "GBA Memory", "gba.memory");
23 
24 static void _pristineCow(struct GBA* gba);
25 static void _agbPrintStore(struct GBA* gba, uint32_t address, int16_t value);
26 static int16_t  _agbPrintLoad(struct GBA* gba, uint32_t address);
27 static uint8_t _deadbeef[4] = { 0x10, 0xB7, 0x10, 0xE7 }; // Illegal instruction on both ARM and Thumb
28 static uint8_t _agbPrintFunc[4] = { 0xFA, 0xDF /* swi 0xFF */, 0x70, 0x47 /* bx lr */ };
29 
30 static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
31 static int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait);
32 
33 static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
34 static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 9 };
35 static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
36 static const char GBA_BASE_WAITSTATES_SEQ_32[16] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 9 };
37 static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
38 static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
39 
GBAMemoryInit(struct GBA * gba)40 void 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 
GBAMemoryDeinit(struct GBA * gba)97 void 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 
GBAMemoryReset(struct GBA * gba)107 void 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 
_analyzeForIdleLoop(struct GBA * gba,struct ARMCore * cpu,uint32_t address)137 static 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 
GBASetActiveRegion(struct ARMCore * cpu,uint32_t address)211 static 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 	if (gba->performingDMA) { \
341 		value = gba->bus; \
342 	} else { \
343 		value = cpu->prefetch[1]; \
344 		if (cpu->executionMode == MODE_THUMB) { \
345 			/* http://ngemu.com/threads/gba-open-bus.170809/ */ \
346 			switch (cpu->gprs[ARM_PC] >> BASE_OFFSET) { \
347 			case REGION_BIOS: \
348 			case REGION_OAM: \
349 				/* This isn't right half the time, but we don't have $+6 handy */ \
350 				value <<= 16; \
351 				value |= cpu->prefetch[0]; \
352 				break; \
353 			case REGION_WORKING_IRAM: \
354 				/* This doesn't handle prefetch clobbering */ \
355 				if (cpu->gprs[ARM_PC] & 2) { \
356 					value <<= 16; \
357 					value |= cpu->prefetch[0]; \
358 				} else { \
359 					value |= cpu->prefetch[0] << 16; \
360 				} \
361 				break; \
362 			default: \
363 				value |= value << 16; \
364 			} \
365 		} \
366 	}
367 
368 #define LOAD_BIOS \
369 	if (address < SIZE_BIOS) { \
370 		if (memory->activeRegion == REGION_BIOS) { \
371 			LOAD_32(value, address & -4, memory->bios); \
372 		} else { \
373 			mLOG(GBA_MEM, GAME_ERROR, "Bad BIOS Load32: 0x%08X", address); \
374 			value = memory->biosPrefetch; \
375 		} \
376 	} else { \
377 		mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load32: 0x%08X", address); \
378 		LOAD_BAD; \
379 	}
380 
381 #define LOAD_WORKING_RAM \
382 	LOAD_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram); \
383 	wait += waitstatesRegion[REGION_WORKING_RAM];
384 
385 #define LOAD_WORKING_IRAM LOAD_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
386 #define LOAD_IO value = GBAIORead(gba, address & OFFSET_MASK & ~2) | (GBAIORead(gba, (address & OFFSET_MASK) | 2) << 16);
387 
388 #define LOAD_PALETTE_RAM \
389 	LOAD_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette); \
390 	wait += waitstatesRegion[REGION_PALETTE_RAM];
391 
392 #define LOAD_VRAM \
393 	if ((address & 0x0001FFFF) >= SIZE_VRAM) { \
394 		if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \
395 			mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load32: 0x%08X", address); \
396 			value = 0; \
397 		} else { \
398 			LOAD_32(value, address & 0x00017FFC, gba->video.vram); \
399 		} \
400 	} else { \
401 		LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \
402 	} \
403 	wait += waitstatesRegion[REGION_VRAM];
404 
405 #define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw);
406 
407 #define LOAD_CART \
408 	wait += waitstatesRegion[address >> BASE_OFFSET]; \
409 	if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
410 		LOAD_32(value, address & (SIZE_CART0 - 4), memory->rom); \
411 	} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) { \
412 		LOAD_32(value, address & memory->romMask & -4, memory->rom); \
413 	} else if (memory->vfame.cartType) { \
414 		value = GBAVFameGetPatternValue(address, 32); \
415 	} else { \
416 		mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
417 		value = ((address & ~3) >> 1) & 0xFFFF; \
418 		value |= (((address & ~3) + 2) >> 1) << 16; \
419 	}
420 
421 #define LOAD_SRAM \
422 	wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; \
423 	value = GBALoad8(cpu, address, 0); \
424 	value |= value << 8; \
425 	value |= value << 16;
426 
GBALoadBad(struct ARMCore * cpu)427 uint32_t GBALoadBad(struct ARMCore* cpu) {
428 	struct GBA* gba = (struct GBA*) cpu->master;
429 	uint32_t value = 0;
430 	LOAD_BAD;
431 	return value;
432 }
433 
GBALoad32(struct ARMCore * cpu,uint32_t address,int * cycleCounter)434 uint32_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 
GBALoad16(struct ARMCore * cpu,uint32_t address,int * cycleCounter)493 uint32_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 			LOAD_BAD;
511 			value = (value >> ((address & 2) * 8)) & 0xFFFF;
512 		}
513 		break;
514 	case REGION_WORKING_RAM:
515 		LOAD_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
516 		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
517 		break;
518 	case REGION_WORKING_IRAM:
519 		LOAD_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
520 		break;
521 	case REGION_IO:
522 		value = GBAIORead(gba, address & (OFFSET_MASK - 1));
523 		break;
524 	case REGION_PALETTE_RAM:
525 		LOAD_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
526 		break;
527 	case REGION_VRAM:
528 		if ((address & 0x0001FFFF) >= SIZE_VRAM) {
529 			if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
530 				mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load16: 0x%08X", address);
531 				value = 0;
532 				break;
533 			}
534 			LOAD_16(value, address & 0x00017FFE, gba->video.vram);
535 		} else {
536 			LOAD_16(value, address & 0x0001FFFE, gba->video.vram);
537 		}
538 		break;
539 	case REGION_OAM:
540 		LOAD_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
541 		break;
542 	case REGION_CART0:
543 	case REGION_CART0_EX:
544 	case REGION_CART1:
545 	case REGION_CART1_EX:
546 	case REGION_CART2:
547 		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
548 		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
549 			LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
550 		} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
551 			LOAD_16(value, address & memory->romMask, memory->rom);
552 		} else if (memory->vfame.cartType) {
553 			value = GBAVFameGetPatternValue(address, 16);
554 		} else if ((address & (SIZE_CART0 - 1)) >= AGB_PRINT_BASE) {
555 			uint32_t agbPrintAddr = address & 0x00FFFFFF;
556 			if (agbPrintAddr == AGB_PRINT_PROTECT) {
557 				value = memory->agbPrint;
558 			} else if (agbPrintAddr < AGB_PRINT_TOP || (agbPrintAddr & 0x00FFFFF8) == (AGB_PRINT_STRUCT & 0x00FFFFF8)) {
559 				value = _agbPrintLoad(gba, address);
560 			} else {
561 				mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
562 				value = (address >> 1) & 0xFFFF;
563 			}
564 		} else {
565 			mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
566 			value = (address >> 1) & 0xFFFF;
567 		}
568 		break;
569 	case REGION_CART2_EX:
570 		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
571 		if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) {
572 			value = GBASavedataReadEEPROM(&memory->savedata);
573 		} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
574 			LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);
575 		} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
576 			LOAD_16(value, address & memory->romMask, memory->rom);
577 		} else if (memory->vfame.cartType) {
578 			value = GBAVFameGetPatternValue(address, 16);
579 		} else {
580 			mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
581 			value = (address >> 1) & 0xFFFF;
582 		}
583 		break;
584 	case REGION_CART_SRAM:
585 	case REGION_CART_SRAM_MIRROR:
586 		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
587 		value = GBALoad8(cpu, address, 0);
588 		value |= value << 8;
589 		break;
590 	default:
591 		mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load16: 0x%08X", address);
592 		LOAD_BAD;
593 		value = (value >> ((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 
GBALoad8(struct ARMCore * cpu,uint32_t address,int * cycleCounter)609 uint32_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 			LOAD_BAD;
627 			value = (value >> ((address & 3) * 8)) & 0xFF;
628 		}
629 		break;
630 	case REGION_WORKING_RAM:
631 		value = ((uint8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
632 		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
633 		break;
634 	case REGION_WORKING_IRAM:
635 		value = ((uint8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
636 		break;
637 	case REGION_IO:
638 		value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
639 		break;
640 	case REGION_PALETTE_RAM:
641 		value = ((uint8_t*) gba->video.palette)[address & (SIZE_PALETTE_RAM - 1)];
642 		break;
643 	case REGION_VRAM:
644 		if ((address & 0x0001FFFF) >= SIZE_VRAM) {
645 			if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) {
646 				mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load8: 0x%08X", address);
647 				value = 0;
648 				break;
649 			}
650 			value = ((uint8_t*) gba->video.vram)[address & 0x00017FFF];
651 		} else {
652 			value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF];
653 		}
654 		break;
655 	case REGION_OAM:
656 		value = ((uint8_t*) gba->video.oam.raw)[address & (SIZE_OAM - 1)];
657 		break;
658 	case REGION_CART0:
659 	case REGION_CART0_EX:
660 	case REGION_CART1:
661 	case REGION_CART1_EX:
662 	case REGION_CART2:
663 	case REGION_CART2_EX:
664 		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
665 		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
666 			value = ((uint8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
667 		} else if (memory->mirroring && (address & memory->romMask) < memory->romSize) {
668 			value = ((uint8_t*) memory->rom)[address & memory->romMask];
669 		} else if (memory->vfame.cartType) {
670 			value = GBAVFameGetPatternValue(address, 8);
671 		} else {
672 			mLOG(GBA_MEM, GAME_ERROR, "Out of bounds ROM Load8: 0x%08X", address);
673 			value = (address >> 1) & 0xFF;
674 		}
675 		break;
676 	case REGION_CART_SRAM:
677 	case REGION_CART_SRAM_MIRROR:
678 		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
679 		if (memory->savedata.type == SAVEDATA_AUTODETECT) {
680 			mLOG(GBA_MEM, INFO, "Detected SRAM savegame");
681 			GBASavedataInitSRAM(&memory->savedata);
682 		}
683 		if (gba->performingDMA == 1) {
684 			break;
685 		}
686 		if (memory->savedata.type == SAVEDATA_SRAM) {
687 			value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
688 		} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
689 			value = GBASavedataReadFlash(&memory->savedata, address);
690 		} else if (memory->hw.devices & HW_TILT) {
691 			value = GBAHardwareTiltRead(&memory->hw, address & OFFSET_MASK);
692 		} else {
693 			mLOG(GBA_MEM, GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
694 			value = 0xFF;
695 		}
696 		value &= 0xFF;
697 		break;
698 	default:
699 		mLOG(GBA_MEM, GAME_ERROR, "Bad memory Load8: 0x%08x", address);
700 		LOAD_BAD;
701 		value = (value >> ((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 
GBAStore32(struct ARMCore * cpu,uint32_t address,int32_t value,int * cycleCounter)785 void 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 
GBAStore16(struct ARMCore * cpu,uint32_t address,int16_t value,int * cycleCounter)837 void 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 (memory->savedata.type == SAVEDATA_AUTODETECT) {
915 			mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
916 			GBASavedataInitEEPROM(&memory->savedata);
917 		}
918 		if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) {
919 			GBASavedataWriteEEPROM(&memory->savedata, value, 1);
920 			break;
921 		}
922 		mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store16: 0x%08X", address);
923 		break;
924 	case REGION_CART_SRAM:
925 	case REGION_CART_SRAM_MIRROR:
926 		if (address & 1) {
927 			mLOG(GBA_MEM, GAME_ERROR, "Unaligned SRAM Store16: 0x%08X", address);
928 			break;
929 		}
930 		GBAStore8(cpu, address, value, cycleCounter);
931 		GBAStore8(cpu, address | 1, value, cycleCounter);
932 		break;
933 	default:
934 		mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store16: 0x%08X", address);
935 		break;
936 	}
937 
938 	if (cycleCounter) {
939 		++wait;
940 		if (address >> BASE_OFFSET < REGION_CART0) {
941 			wait = GBAMemoryStall(cpu, wait);
942 		}
943 		*cycleCounter += wait;
944 	}
945 }
946 
GBAStore8(struct ARMCore * cpu,uint32_t address,int8_t value,int * cycleCounter)947 void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
948 	struct GBA* gba = (struct GBA*) cpu->master;
949 	struct GBAMemory* memory = &gba->memory;
950 	int wait = 0;
951 	uint16_t oldValue;
952 
953 	switch (address >> BASE_OFFSET) {
954 	case REGION_WORKING_RAM:
955 		((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
956 		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
957 		break;
958 	case REGION_WORKING_IRAM:
959 		((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
960 		break;
961 	case REGION_IO:
962 		GBAIOWrite8(gba, address & OFFSET_MASK, value);
963 		break;
964 	case REGION_PALETTE_RAM:
965 		GBAStore16(cpu, address & ~1, ((uint8_t) value) | ((uint8_t) value << 8), cycleCounter);
966 		break;
967 	case REGION_VRAM:
968 		if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) {
969 			mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
970 			break;
971 		}
972 		oldValue = gba->video.renderer->vram[(address & 0x1FFFE) >> 1];
973 		if (oldValue != (((uint8_t) value) | (value << 8))) {
974 			gba->video.renderer->vram[(address & 0x1FFFE) >> 1] = ((uint8_t) value) | (value << 8);
975 			gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE);
976 		}
977 		break;
978 	case REGION_OAM:
979 		mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
980 		break;
981 	case REGION_CART0:
982 		mLOG(GBA_MEM, STUB, "Unimplemented memory Store8: 0x%08X", address);
983 		break;
984 	case REGION_CART_SRAM:
985 	case REGION_CART_SRAM_MIRROR:
986 		if (memory->savedata.type == SAVEDATA_AUTODETECT) {
987 			if (address == SAVEDATA_FLASH_BASE) {
988 				mLOG(GBA_MEM, INFO, "Detected Flash savegame");
989 				GBASavedataInitFlash(&memory->savedata);
990 			} else {
991 				mLOG(GBA_MEM, INFO, "Detected SRAM savegame");
992 				GBASavedataInitSRAM(&memory->savedata);
993 			}
994 		}
995 		if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
996 			GBASavedataWriteFlash(&memory->savedata, address, value);
997 		} else if (memory->savedata.type == SAVEDATA_SRAM) {
998 			if (memory->vfame.cartType) {
999 				GBAVFameSramWrite(&memory->vfame, address, value, memory->savedata.data);
1000 			} else {
1001 				memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
1002 			}
1003 			memory->savedata.dirty |= SAVEDATA_DIRT_NEW;
1004 		} else if (memory->hw.devices & HW_TILT) {
1005 			GBAHardwareTiltWrite(&memory->hw, address & OFFSET_MASK, value);
1006 		} else {
1007 			mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1008 		}
1009 		wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
1010 		break;
1011 	default:
1012 		mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store8: 0x%08X", address);
1013 		break;
1014 	}
1015 
1016 	if (cycleCounter) {
1017 		++wait;
1018 		if (address >> BASE_OFFSET < REGION_CART0) {
1019 			wait = GBAMemoryStall(cpu, wait);
1020 		}
1021 		*cycleCounter += wait;
1022 	}
1023 }
1024 
GBAView32(struct ARMCore * cpu,uint32_t address)1025 uint32_t GBAView32(struct ARMCore* cpu, uint32_t address) {
1026 	struct GBA* gba = (struct GBA*) cpu->master;
1027 	uint32_t value = 0;
1028 	address &= ~3;
1029 	switch (address >> BASE_OFFSET) {
1030 	case REGION_BIOS:
1031 		if (address < SIZE_BIOS) {
1032 			LOAD_32(value, address, gba->memory.bios);
1033 		}
1034 		break;
1035 	case REGION_WORKING_RAM:
1036 	case REGION_WORKING_IRAM:
1037 	case REGION_PALETTE_RAM:
1038 	case REGION_VRAM:
1039 	case REGION_OAM:
1040 	case REGION_CART0:
1041 	case REGION_CART0_EX:
1042 	case REGION_CART1:
1043 	case REGION_CART1_EX:
1044 	case REGION_CART2:
1045 	case REGION_CART2_EX:
1046 		value = GBALoad32(cpu, address, 0);
1047 		break;
1048 	case REGION_IO:
1049 		if ((address & OFFSET_MASK) < REG_MAX) {
1050 			value = gba->memory.io[(address & OFFSET_MASK) >> 1];
1051 			value |= gba->memory.io[((address & OFFSET_MASK) >> 1) + 1] << 16;
1052 		}
1053 		break;
1054 	case REGION_CART_SRAM:
1055 		value = GBALoad8(cpu, address, 0);
1056 		value |= GBALoad8(cpu, address + 1, 0) << 8;
1057 		value |= GBALoad8(cpu, address + 2, 0) << 16;
1058 		value |= GBALoad8(cpu, address + 3, 0) << 24;
1059 		break;
1060 	default:
1061 		break;
1062 	}
1063 	return value;
1064 }
1065 
GBAView16(struct ARMCore * cpu,uint32_t address)1066 uint16_t GBAView16(struct ARMCore* cpu, uint32_t address) {
1067 	struct GBA* gba = (struct GBA*) cpu->master;
1068 	uint16_t value = 0;
1069 	address &= ~1;
1070 	switch (address >> BASE_OFFSET) {
1071 	case REGION_BIOS:
1072 		if (address < SIZE_BIOS) {
1073 			LOAD_16(value, address, gba->memory.bios);
1074 		}
1075 		break;
1076 	case REGION_WORKING_RAM:
1077 	case REGION_WORKING_IRAM:
1078 	case REGION_PALETTE_RAM:
1079 	case REGION_VRAM:
1080 	case REGION_OAM:
1081 	case REGION_CART0:
1082 	case REGION_CART0_EX:
1083 	case REGION_CART1:
1084 	case REGION_CART1_EX:
1085 	case REGION_CART2:
1086 	case REGION_CART2_EX:
1087 		value = GBALoad16(cpu, address, 0);
1088 		break;
1089 	case REGION_IO:
1090 		if ((address & OFFSET_MASK) < REG_MAX) {
1091 			value = gba->memory.io[(address & OFFSET_MASK) >> 1];
1092 		}
1093 		break;
1094 	case REGION_CART_SRAM:
1095 		value = GBALoad8(cpu, address, 0);
1096 		value |= GBALoad8(cpu, address + 1, 0) << 8;
1097 		break;
1098 	default:
1099 		break;
1100 	}
1101 	return value;
1102 }
1103 
GBAView8(struct ARMCore * cpu,uint32_t address)1104 uint8_t GBAView8(struct ARMCore* cpu, uint32_t address) {
1105 	struct GBA* gba = (struct GBA*) cpu->master;
1106 	uint8_t value = 0;
1107 	switch (address >> BASE_OFFSET) {
1108 	case REGION_BIOS:
1109 		if (address < SIZE_BIOS) {
1110 			value = ((uint8_t*) gba->memory.bios)[address];
1111 		}
1112 		break;
1113 	case REGION_WORKING_RAM:
1114 	case REGION_WORKING_IRAM:
1115 	case REGION_CART0:
1116 	case REGION_CART0_EX:
1117 	case REGION_CART1:
1118 	case REGION_CART1_EX:
1119 	case REGION_CART2:
1120 	case REGION_CART2_EX:
1121 	case REGION_CART_SRAM:
1122 		value = GBALoad8(cpu, address, 0);
1123 		break;
1124 	case REGION_IO:
1125 	case REGION_PALETTE_RAM:
1126 	case REGION_VRAM:
1127 	case REGION_OAM:
1128 		value = GBAView16(cpu, address) >> ((address & 1) * 8);
1129 		break;
1130 	default:
1131 		break;
1132 	}
1133 	return value;
1134 }
1135 
GBAPatch32(struct ARMCore * cpu,uint32_t address,int32_t value,int32_t * old)1136 void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* old) {
1137 	struct GBA* gba = (struct GBA*) cpu->master;
1138 	struct GBAMemory* memory = &gba->memory;
1139 	int32_t oldValue = -1;
1140 
1141 	switch (address >> BASE_OFFSET) {
1142 	case REGION_WORKING_RAM:
1143 		LOAD_32(oldValue, address & (SIZE_WORKING_RAM - 4), memory->wram);
1144 		STORE_32(value, address & (SIZE_WORKING_RAM - 4), memory->wram);
1145 		break;
1146 	case REGION_WORKING_IRAM:
1147 		LOAD_32(oldValue, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
1148 		STORE_32(value, address & (SIZE_WORKING_IRAM - 4), memory->iwram);
1149 		break;
1150 	case REGION_IO:
1151 		mLOG(GBA_MEM, STUB, "Unimplemented memory Patch32: 0x%08X", address);
1152 		break;
1153 	case REGION_PALETTE_RAM:
1154 		LOAD_32(oldValue, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
1155 		STORE_32(value, address & (SIZE_PALETTE_RAM - 4), gba->video.palette);
1156 		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 4), value);
1157 		gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 4)) + 2, value >> 16);
1158 		break;
1159 	case REGION_VRAM:
1160 		if ((address & 0x0001FFFF) < SIZE_VRAM) {
1161 			LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram);
1162 			STORE_32(value, address & 0x0001FFFC, gba->video.vram);
1163 		} else {
1164 			LOAD_32(oldValue, address & 0x00017FFC, gba->video.vram);
1165 			STORE_32(value, address & 0x00017FFC, gba->video.vram);
1166 		}
1167 		break;
1168 	case REGION_OAM:
1169 		LOAD_32(oldValue, address & (SIZE_OAM - 4), gba->video.oam.raw);
1170 		STORE_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw);
1171 		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
1172 		gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) + 2) >> 1);
1173 		break;
1174 	case REGION_CART0:
1175 	case REGION_CART0_EX:
1176 	case REGION_CART1:
1177 	case REGION_CART1_EX:
1178 	case REGION_CART2:
1179 	case REGION_CART2_EX:
1180 		_pristineCow(gba);
1181 		if ((address & (SIZE_CART0 - 4)) >= gba->memory.romSize) {
1182 			gba->memory.romSize = (address & (SIZE_CART0 - 4)) + 4;
1183 			gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
1184 		}
1185 		LOAD_32(oldValue, address & (SIZE_CART0 - 4), gba->memory.rom);
1186 		STORE_32(value, address & (SIZE_CART0 - 4), gba->memory.rom);
1187 		break;
1188 	case REGION_CART_SRAM:
1189 	case REGION_CART_SRAM_MIRROR:
1190 		if (memory->savedata.type == SAVEDATA_SRAM) {
1191 			LOAD_32(oldValue, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
1192 			STORE_32(value, address & (SIZE_CART_SRAM - 4), memory->savedata.data);
1193 		} else {
1194 			mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1195 		}
1196 		break;
1197 	default:
1198 		mLOG(GBA_MEM, WARN, "Bad memory Patch16: 0x%08X", address);
1199 		break;
1200 	}
1201 	if (old) {
1202 		*old = oldValue;
1203 	}
1204 }
1205 
GBAPatch16(struct ARMCore * cpu,uint32_t address,int16_t value,int16_t * old)1206 void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* old) {
1207 	struct GBA* gba = (struct GBA*) cpu->master;
1208 	struct GBAMemory* memory = &gba->memory;
1209 	int16_t oldValue = -1;
1210 
1211 	switch (address >> BASE_OFFSET) {
1212 	case REGION_WORKING_RAM:
1213 		LOAD_16(oldValue, address & (SIZE_WORKING_RAM - 2), memory->wram);
1214 		STORE_16(value, address & (SIZE_WORKING_RAM - 2), memory->wram);
1215 		break;
1216 	case REGION_WORKING_IRAM:
1217 		LOAD_16(oldValue, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
1218 		STORE_16(value, address & (SIZE_WORKING_IRAM - 2), memory->iwram);
1219 		break;
1220 	case REGION_IO:
1221 		mLOG(GBA_MEM, STUB, "Unimplemented memory Patch16: 0x%08X", address);
1222 		break;
1223 	case REGION_PALETTE_RAM:
1224 		LOAD_16(oldValue, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
1225 		STORE_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette);
1226 		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 2), value);
1227 		break;
1228 	case REGION_VRAM:
1229 		if ((address & 0x0001FFFF) < SIZE_VRAM) {
1230 			LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram);
1231 			STORE_16(value, address & 0x0001FFFE, gba->video.vram);
1232 		} else {
1233 			LOAD_16(oldValue, address & 0x00017FFE, gba->video.vram);
1234 			STORE_16(value, address & 0x00017FFE, gba->video.vram);
1235 		}
1236 		break;
1237 	case REGION_OAM:
1238 		LOAD_16(oldValue, address & (SIZE_OAM - 2), gba->video.oam.raw);
1239 		STORE_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw);
1240 		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 2)) >> 1);
1241 		break;
1242 	case REGION_CART0:
1243 	case REGION_CART0_EX:
1244 	case REGION_CART1:
1245 	case REGION_CART1_EX:
1246 	case REGION_CART2:
1247 	case REGION_CART2_EX:
1248 		_pristineCow(gba);
1249 		if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
1250 			gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2;
1251 			gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
1252 		}
1253 		LOAD_16(oldValue, address & (SIZE_CART0 - 2), gba->memory.rom);
1254 		STORE_16(value, address & (SIZE_CART0 - 2), gba->memory.rom);
1255 		break;
1256 	case REGION_CART_SRAM:
1257 	case REGION_CART_SRAM_MIRROR:
1258 		if (memory->savedata.type == SAVEDATA_SRAM) {
1259 			LOAD_16(oldValue, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
1260 			STORE_16(value, address & (SIZE_CART_SRAM - 2), memory->savedata.data);
1261 		} else {
1262 			mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1263 		}
1264 		break;
1265 	default:
1266 		mLOG(GBA_MEM, WARN, "Bad memory Patch16: 0x%08X", address);
1267 		break;
1268 	}
1269 	if (old) {
1270 		*old = oldValue;
1271 	}
1272 }
1273 
GBAPatch8(struct ARMCore * cpu,uint32_t address,int8_t value,int8_t * old)1274 void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) {
1275 	struct GBA* gba = (struct GBA*) cpu->master;
1276 	struct GBAMemory* memory = &gba->memory;
1277 	int8_t oldValue = -1;
1278 
1279 	switch (address >> BASE_OFFSET) {
1280 	case REGION_WORKING_RAM:
1281 		oldValue = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
1282 		((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
1283 		break;
1284 	case REGION_WORKING_IRAM:
1285 		oldValue = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
1286 		((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
1287 		break;
1288 	case REGION_IO:
1289 		mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1290 		break;
1291 	case REGION_PALETTE_RAM:
1292 		mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1293 		break;
1294 	case REGION_VRAM:
1295 		mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1296 		break;
1297 	case REGION_OAM:
1298 		mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
1299 		break;
1300 	case REGION_CART0:
1301 	case REGION_CART0_EX:
1302 	case REGION_CART1:
1303 	case REGION_CART1_EX:
1304 	case REGION_CART2:
1305 	case REGION_CART2_EX:
1306 		_pristineCow(gba);
1307 		if ((address & (SIZE_CART0 - 1)) >= gba->memory.romSize) {
1308 			gba->memory.romSize = (address & (SIZE_CART0 - 2)) + 2;
1309 			gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
1310 		}
1311 		oldValue = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
1312 		((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)] = value;
1313 		break;
1314 	case REGION_CART_SRAM:
1315 	case REGION_CART_SRAM_MIRROR:
1316 		if (memory->savedata.type == SAVEDATA_SRAM) {
1317 			oldValue = ((int8_t*) memory->savedata.data)[address & (SIZE_CART_SRAM - 1)];
1318 			((int8_t*) memory->savedata.data)[address & (SIZE_CART_SRAM - 1)] = value;
1319 		} else {
1320 			mLOG(GBA_MEM, GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
1321 		}
1322 		break;
1323 	default:
1324 		mLOG(GBA_MEM, WARN, "Bad memory Patch8: 0x%08X", address);
1325 		break;
1326 	}
1327 	if (old) {
1328 		*old = oldValue;
1329 	}
1330 }
1331 
1332 #define LDM_LOOP(LDM) \
1333 	if (UNLIKELY(!mask)) { \
1334 		LDM; \
1335 		cpu->gprs[ARM_PC] = value; \
1336 		wait += 16; \
1337 		address += 64; \
1338 	} \
1339 	for (i = 0; i < 16; i += 4) { \
1340 		if (UNLIKELY(mask & (1 << i))) { \
1341 			LDM; \
1342 			cpu->gprs[i] = value; \
1343 			++wait; \
1344 			address += 4; \
1345 		} \
1346 		if (UNLIKELY(mask & (2 << i))) { \
1347 			LDM; \
1348 			cpu->gprs[i + 1] = value; \
1349 			++wait; \
1350 			address += 4; \
1351 		} \
1352 		if (UNLIKELY(mask & (4 << i))) { \
1353 			LDM; \
1354 			cpu->gprs[i + 2] = value; \
1355 			++wait; \
1356 			address += 4; \
1357 		} \
1358 		if (UNLIKELY(mask & (8 << i))) { \
1359 			LDM; \
1360 			cpu->gprs[i + 3] = value; \
1361 			++wait; \
1362 			address += 4; \
1363 		} \
1364 	}
1365 
GBALoadMultiple(struct ARMCore * cpu,uint32_t address,int mask,enum LSMDirection direction,int * cycleCounter)1366 uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
1367 	struct GBA* gba = (struct GBA*) cpu->master;
1368 	struct GBAMemory* memory = &gba->memory;
1369 	uint32_t value;
1370 	char* waitstatesRegion = memory->waitstatesSeq32;
1371 
1372 	int i;
1373 	int offset = 4;
1374 	int popcount = 0;
1375 	if (direction & LSM_D) {
1376 		offset = -4;
1377 		popcount = popcount32(mask);
1378 		address -= (popcount << 2) - 4;
1379 	}
1380 
1381 	if (direction & LSM_B) {
1382 		address += offset;
1383 	}
1384 
1385 	uint32_t addressMisalign = address & 0x3;
1386 	int region = address >> BASE_OFFSET;
1387 	if (region < REGION_CART_SRAM) {
1388 		address &= 0xFFFFFFFC;
1389 	}
1390 	int wait = memory->waitstatesSeq32[region] - memory->waitstatesNonseq32[region];
1391 
1392 	switch (region) {
1393 	case REGION_BIOS:
1394 		LDM_LOOP(LOAD_BIOS);
1395 		break;
1396 	case REGION_WORKING_RAM:
1397 		LDM_LOOP(LOAD_WORKING_RAM);
1398 		break;
1399 	case REGION_WORKING_IRAM:
1400 		LDM_LOOP(LOAD_WORKING_IRAM);
1401 		break;
1402 	case REGION_IO:
1403 		LDM_LOOP(LOAD_IO);
1404 		break;
1405 	case REGION_PALETTE_RAM:
1406 		LDM_LOOP(LOAD_PALETTE_RAM);
1407 		break;
1408 	case REGION_VRAM:
1409 		LDM_LOOP(LOAD_VRAM);
1410 		break;
1411 	case REGION_OAM:
1412 		LDM_LOOP(LOAD_OAM);
1413 		break;
1414 	case REGION_CART0:
1415 	case REGION_CART0_EX:
1416 	case REGION_CART1:
1417 	case REGION_CART1_EX:
1418 	case REGION_CART2:
1419 	case REGION_CART2_EX:
1420 		LDM_LOOP(LOAD_CART);
1421 		break;
1422 	case REGION_CART_SRAM:
1423 	case REGION_CART_SRAM_MIRROR:
1424 		LDM_LOOP(LOAD_SRAM);
1425 		break;
1426 	default:
1427 		LDM_LOOP(LOAD_BAD);
1428 		break;
1429 	}
1430 
1431 	if (cycleCounter) {
1432 		++wait;
1433 		if (address >> BASE_OFFSET < REGION_CART0) {
1434 			wait = GBAMemoryStall(cpu, wait);
1435 		}
1436 		*cycleCounter += wait;
1437 	}
1438 
1439 	if (direction & LSM_B) {
1440 		address -= offset;
1441 	}
1442 
1443 	if (direction & LSM_D) {
1444 		address -= (popcount << 2) + 4;
1445 	}
1446 
1447 	return address | addressMisalign;
1448 }
1449 
1450 #define STM_LOOP(STM) \
1451 	if (UNLIKELY(!mask)) { \
1452 		value = cpu->gprs[ARM_PC] + (cpu->executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB); \
1453 		STM; \
1454 		wait += 16; \
1455 		address += 64; \
1456 	} \
1457 	for (i = 0; i < 16; i += 4) { \
1458 		if (UNLIKELY(mask & (1 << i))) { \
1459 			value = cpu->gprs[i]; \
1460 			STM; \
1461 			++wait; \
1462 			address += 4; \
1463 		} \
1464 		if (UNLIKELY(mask & (2 << i))) { \
1465 			value = cpu->gprs[i + 1]; \
1466 			STM; \
1467 			++wait; \
1468 			address += 4; \
1469 		} \
1470 		if (UNLIKELY(mask & (4 << i))) { \
1471 			value = cpu->gprs[i + 2]; \
1472 			STM; \
1473 			++wait; \
1474 			address += 4; \
1475 		} \
1476 		if (UNLIKELY(mask & (8 << i))) { \
1477 			value = cpu->gprs[i + 3]; \
1478 			if (i + 3 == ARM_PC) { \
1479 				value += WORD_SIZE_ARM; \
1480 			} \
1481 			STM; \
1482 			++wait; \
1483 			address += 4; \
1484 		} \
1485 	}
1486 
GBAStoreMultiple(struct ARMCore * cpu,uint32_t address,int mask,enum LSMDirection direction,int * cycleCounter)1487 uint32_t GBAStoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
1488 	struct GBA* gba = (struct GBA*) cpu->master;
1489 	struct GBAMemory* memory = &gba->memory;
1490 	uint32_t value;
1491 	uint32_t oldValue;
1492 	char* waitstatesRegion = memory->waitstatesSeq32;
1493 
1494 	int i;
1495 	int offset = 4;
1496 	int popcount = 0;
1497 	if (direction & LSM_D) {
1498 		offset = -4;
1499 		popcount = popcount32(mask);
1500 		address -= (popcount << 2) - 4;
1501 	}
1502 
1503 	if (direction & LSM_B) {
1504 		address += offset;
1505 	}
1506 
1507 	uint32_t addressMisalign = address & 0x3;
1508 	int region = address >> BASE_OFFSET;
1509 	if (region < REGION_CART_SRAM) {
1510 		address &= 0xFFFFFFFC;
1511 	}
1512 	int wait = memory->waitstatesSeq32[region] - memory->waitstatesNonseq32[region];
1513 
1514 	switch (region) {
1515 	case REGION_WORKING_RAM:
1516 		STM_LOOP(STORE_WORKING_RAM);
1517 		break;
1518 	case REGION_WORKING_IRAM:
1519 		STM_LOOP(STORE_WORKING_IRAM);
1520 		break;
1521 	case REGION_IO:
1522 		STM_LOOP(STORE_IO);
1523 		break;
1524 	case REGION_PALETTE_RAM:
1525 		STM_LOOP(STORE_PALETTE_RAM);
1526 		break;
1527 	case REGION_VRAM:
1528 		STM_LOOP(STORE_VRAM);
1529 		break;
1530 	case REGION_OAM:
1531 		STM_LOOP(STORE_OAM);
1532 		break;
1533 	case REGION_CART0:
1534 	case REGION_CART0_EX:
1535 	case REGION_CART1:
1536 	case REGION_CART1_EX:
1537 	case REGION_CART2:
1538 	case REGION_CART2_EX:
1539 		STM_LOOP(STORE_CART);
1540 		break;
1541 	case REGION_CART_SRAM:
1542 	case REGION_CART_SRAM_MIRROR:
1543 		STM_LOOP(STORE_SRAM);
1544 		break;
1545 	default:
1546 		STM_LOOP(STORE_BAD);
1547 		break;
1548 	}
1549 
1550 	if (cycleCounter) {
1551 		if (address >> BASE_OFFSET < REGION_CART0) {
1552 			wait = GBAMemoryStall(cpu, wait);
1553 		}
1554 		*cycleCounter += wait;
1555 	}
1556 
1557 	if (direction & LSM_B) {
1558 		address -= offset;
1559 	}
1560 
1561 	if (direction & LSM_D) {
1562 		address -= (popcount << 2) + 4;
1563 	}
1564 
1565 	return address | addressMisalign;
1566 }
1567 
GBAAdjustWaitstates(struct GBA * gba,uint16_t parameters)1568 void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
1569 	struct GBAMemory* memory = &gba->memory;
1570 	struct ARMCore* cpu = gba->cpu;
1571 	int sram = parameters & 0x0003;
1572 	int ws0 = (parameters & 0x000C) >> 2;
1573 	int ws0seq = (parameters & 0x0010) >> 4;
1574 	int ws1 = (parameters & 0x0060) >> 5;
1575 	int ws1seq = (parameters & 0x0080) >> 7;
1576 	int ws2 = (parameters & 0x0300) >> 8;
1577 	int ws2seq = (parameters & 0x0400) >> 10;
1578 	int prefetch = parameters & 0x4000;
1579 
1580 	memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
1581 	memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
1582 	memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
1583 	memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
1584 
1585 	memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
1586 	memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
1587 	memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
1588 
1589 	memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
1590 	memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
1591 	memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
1592 
1593 	memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
1594 	memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
1595 	memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
1596 
1597 	memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
1598 	memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
1599 	memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
1600 
1601 	memory->prefetch = prefetch;
1602 
1603 	cpu->memory.activeSeqCycles32 = memory->waitstatesSeq32[memory->activeRegion];
1604 	cpu->memory.activeSeqCycles16 = memory->waitstatesSeq16[memory->activeRegion];
1605 
1606 	cpu->memory.activeNonseqCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
1607 	cpu->memory.activeNonseqCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
1608 }
1609 
GBAMemoryStall(struct ARMCore * cpu,int32_t wait)1610 int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait) {
1611 	struct GBA* gba = (struct GBA*) cpu->master;
1612 	struct GBAMemory* memory = &gba->memory;
1613 
1614 	if (memory->activeRegion < REGION_CART0 || !memory->prefetch) {
1615 		// The wait is the stall
1616 		return wait;
1617 	}
1618 
1619 	int32_t previousLoads = 0;
1620 
1621 	// Don't prefetch too much if we're overlapping with a previous prefetch
1622 	uint32_t dist = (memory->lastPrefetchedPc - cpu->gprs[ARM_PC]);
1623 	int32_t maxLoads = 8;
1624 	if (dist < 16) {
1625 		previousLoads = dist >> 1;
1626 		maxLoads -= previousLoads;
1627 	}
1628 
1629 	int32_t s = cpu->memory.activeSeqCycles16 + 1;
1630 	int32_t n2s = cpu->memory.activeNonseqCycles16 - cpu->memory.activeSeqCycles16 + 1;
1631 
1632 	// Figure out how many sequential loads we can jam in
1633 	int32_t stall = s;
1634 	int32_t loads = 1;
1635 
1636 	while (stall < wait && loads < maxLoads) {
1637 		stall += s;
1638 		++loads;
1639 	}
1640 	if (stall > wait) {
1641 		// The wait cannot take less time than the prefetch stalls
1642 		wait = stall;
1643 	}
1644 
1645 	// This instruction used to have an N, convert it to an S.
1646 	wait -= n2s;
1647 
1648 	memory->lastPrefetchedPc = cpu->gprs[ARM_PC] + WORD_SIZE_THUMB * (loads + previousLoads - 1);
1649 
1650 	// The next |loads|S waitstates disappear entirely, so long as they're all in a row
1651 	cpu->cycles -= (s - 1) * loads;
1652 	return wait;
1653 }
1654 
GBAMemorySerialize(const struct GBAMemory * memory,struct GBASerializedState * state)1655 void GBAMemorySerialize(const struct GBAMemory* memory, struct GBASerializedState* state) {
1656 	memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
1657 	memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
1658 }
1659 
GBAMemoryDeserialize(struct GBAMemory * memory,const struct GBASerializedState * state)1660 void GBAMemoryDeserialize(struct GBAMemory* memory, const struct GBASerializedState* state) {
1661 	memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
1662 	memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
1663 }
1664 
_pristineCow(struct GBA * gba)1665 void _pristineCow(struct GBA* gba) {
1666 	if (!gba->isPristine) {
1667 		return;
1668 	}
1669 #if !defined(FIXED_ROM_BUFFER) && !defined(__wii__)
1670 	void* newRom = anonymousMemoryMap(SIZE_CART0);
1671 	memcpy(newRom, gba->memory.rom, gba->memory.romSize);
1672 	memset(((uint8_t*) newRom) + gba->memory.romSize, 0xFF, SIZE_CART0 - gba->memory.romSize);
1673 	if (gba->cpu->memory.activeRegion == gba->memory.rom) {
1674 		gba->cpu->memory.activeRegion = newRom;
1675 	}
1676 	if (gba->romVf) {
1677 		gba->romVf->unmap(gba->romVf, gba->memory.rom, gba->memory.romSize);
1678 		gba->romVf->close(gba->romVf);
1679 		gba->romVf = NULL;
1680 	}
1681 	gba->memory.rom = newRom;
1682 	gba->memory.hw.gpioBase = &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1];
1683 #endif
1684 	gba->isPristine = false;
1685 }
1686 
GBAPrintFlush(struct GBA * gba)1687 void GBAPrintFlush(struct GBA* gba) {
1688 	if (!gba->memory.agbPrintBuffer) {
1689 		return;
1690 	}
1691 
1692 	char oolBuf[0x101];
1693 	size_t i;
1694 	for (i = 0; gba->memory.agbPrintCtx.get != gba->memory.agbPrintCtx.put && i < 0x100; ++i) {
1695 		int16_t value;
1696 		LOAD_16(value, gba->memory.agbPrintCtx.get & -2, gba->memory.agbPrintBuffer);
1697 		if (gba->memory.agbPrintCtx.get & 1) {
1698 			value >>= 8;
1699 		} else {
1700 			value &= 0xFF;
1701 		}
1702 		oolBuf[i] = value;
1703 		oolBuf[i + 1] = 0;
1704 		++gba->memory.agbPrintCtx.get;
1705 	}
1706 	_agbPrintStore(gba, AGB_PRINT_STRUCT + 4, gba->memory.agbPrintCtx.get);
1707 
1708 	mLOG(GBA_DEBUG, INFO, "%s", oolBuf);
1709 }
1710 
_agbPrintStore(struct GBA * gba,uint32_t address,int16_t value)1711 static void _agbPrintStore(struct GBA* gba, uint32_t address, int16_t value) {
1712 	struct GBAMemory* memory = &gba->memory;
1713 	if ((address & 0x00FFFFFF) < AGB_PRINT_TOP) {
1714 		if (!memory->agbPrintBuffer) {
1715 			memory->agbPrintBuffer = anonymousMemoryMap(SIZE_AGB_PRINT);
1716 		}
1717 		STORE_16(value, address & (SIZE_AGB_PRINT - 2), memory->agbPrintBuffer);
1718 	} else if ((address & 0x00FFFFF8) == (AGB_PRINT_STRUCT & 0x00FFFFF8)) {
1719 		(&memory->agbPrintCtx.request)[(address & 7) >> 1] = value;
1720 	}
1721 	if (memory->romSize == SIZE_CART0) {
1722 		_pristineCow(gba);
1723 		memcpy(&memory->rom[AGB_PRINT_FLUSH_ADDR >> 2], _agbPrintFunc, sizeof(_agbPrintFunc));
1724 		STORE_16(value, address & (SIZE_CART0 - 2), memory->rom);
1725 	} else if (memory->agbPrintCtx.bank == 0xFD && memory->romSize >= SIZE_CART0 / 2) {
1726 		_pristineCow(gba);
1727 		STORE_16(value, address & (SIZE_CART0 / 2 - 2), memory->rom);
1728 	}
1729 }
1730 
_agbPrintLoad(struct GBA * gba,uint32_t address)1731 static int16_t _agbPrintLoad(struct GBA* gba, uint32_t address) {
1732 	struct GBAMemory* memory = &gba->memory;
1733 	int16_t value = address >> 1;
1734 	if (address < AGB_PRINT_TOP && memory->agbPrintBuffer) {
1735 		LOAD_16(value, address & (SIZE_AGB_PRINT - 1), memory->agbPrintBuffer);
1736 	} else if ((address & 0x00FFFFF8) == (AGB_PRINT_STRUCT & 0x00FFFFF8)) {
1737 		value = (&memory->agbPrintCtx.request)[(address & 7) >> 1];
1738 	}
1739 	return value;
1740 }
1741