all repos — mgba @ 37f5feb713d5768f2bf5405e5a9db8765248efc2

mGBA Game Boy Advance Emulator

src/gba/memory.c (view raw)

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