all repos — mgba @ e3f66ba458d33334d59f70d33ae24fb1b55c8b52

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