all repos — mgba @ 3c844a9ae9e6de6c1aae1eb5b627ce1d3aa334bc

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