all repos — mgba @ 1b68ac4d610ba9efa96db6fd6493cef38a8a0ebe

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