all repos — mgba @ 74fc29fc68e7ae84f0c27130d1d98299434ce6f2

mGBA Game Boy Advance Emulator

src/gba/memory.c (view raw)

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