all repos — mgba @ 087810a125cabbced5315a05aca105066ca2a210

mGBA Game Boy Advance Emulator

src/gba/gba-memory.c (view raw)

   1/* Copyright (c) 2013-2014 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 "gba-memory.h"
   7
   8#include "macros.h"
   9
  10#include "gba-gpio.h"
  11#include "gba-io.h"
  12#include "gba-serialize.h"
  13#include "hle-bios.h"
  14#include "util/memory.h"
  15
  16static uint32_t _popcount32(unsigned bits);
  17static uint32_t _deadbeef[2] = { 0xDEADBEEF, 0xFEEDFACE };
  18
  19static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
  20static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);
  21
  22static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
  23static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };
  24static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
  25static const char GBA_BASE_WAITSTATES_SEQ_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 5, 5, 9, 9, 17, 17, 9 };
  26static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
  27static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
  28static const int DMA_OFFSET[] = { 1, -1, 0, 1 };
  29
  30void GBAMemoryInit(struct GBA* gba) {
  31	struct ARMCore* cpu = gba->cpu;
  32	cpu->memory.load32 = GBALoad32;
  33	cpu->memory.load16 = GBALoad16;
  34	cpu->memory.load8 = GBALoad8;
  35	cpu->memory.loadMultiple = GBALoadMultiple;
  36	cpu->memory.store32 = GBAStore32;
  37	cpu->memory.store16 = GBAStore16;
  38	cpu->memory.store8 = GBAStore8;
  39	cpu->memory.storeMultiple = GBAStoreMultiple;
  40
  41	gba->memory.bios = (uint32_t*) hleBios;
  42	gba->memory.fullBios = 0;
  43	gba->memory.wram = 0;
  44	gba->memory.iwram = 0;
  45	gba->memory.rom = 0;
  46	gba->memory.gpio.p = gba;
  47
  48	int i;
  49	for (i = 0; i < 16; ++i) {
  50		gba->memory.waitstatesNonseq16[i] = GBA_BASE_WAITSTATES[i];
  51		gba->memory.waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
  52		gba->memory.waitstatesPrefetchNonseq16[i] = GBA_BASE_WAITSTATES[i];
  53		gba->memory.waitstatesPrefetchSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
  54		gba->memory.waitstatesNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
  55		gba->memory.waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
  56		gba->memory.waitstatesPrefetchNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
  57		gba->memory.waitstatesPrefetchSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
  58	}
  59	for (; i < 256; ++i) {
  60		gba->memory.waitstatesNonseq16[i] = 0;
  61		gba->memory.waitstatesSeq16[i] = 0;
  62		gba->memory.waitstatesNonseq32[i] = 0;
  63		gba->memory.waitstatesSeq32[i] = 0;
  64	}
  65
  66	gba->memory.activeRegion = -1;
  67	cpu->memory.activeRegion = 0;
  68	cpu->memory.activeMask = 0;
  69	cpu->memory.setActiveRegion = GBASetActiveRegion;
  70	cpu->memory.activeSeqCycles32 = 0;
  71	cpu->memory.activeSeqCycles16 = 0;
  72	cpu->memory.activeNonseqCycles32 = 0;
  73	cpu->memory.activeNonseqCycles16 = 0;
  74	cpu->memory.activeUncachedCycles32 = 0;
  75	cpu->memory.activeUncachedCycles16 = 0;
  76	gba->memory.biosPrefetch = 0;
  77}
  78
  79void GBAMemoryDeinit(struct GBA* gba) {
  80	mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
  81	mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
  82	if (gba->memory.rom) {
  83		mappedMemoryFree(gba->memory.rom, gba->memory.romSize);
  84	}
  85	GBASavedataDeinit(&gba->memory.savedata);
  86}
  87
  88void GBAMemoryReset(struct GBA* gba) {
  89	if (gba->memory.wram) {
  90		mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
  91	}
  92	gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
  93
  94	if (gba->memory.iwram) {
  95		mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
  96	}
  97	gba->memory.iwram = anonymousMemoryMap(SIZE_WORKING_IRAM);
  98
  99	memset(gba->memory.io, 0, sizeof(gba->memory.io));
 100	memset(gba->memory.dma, 0, sizeof(gba->memory.dma));
 101	int i;
 102	for (i = 0; i < 4; ++i) {
 103		gba->memory.dma[i].count = 0x10000;
 104		gba->memory.dma[i].nextEvent = INT_MAX;
 105	}
 106	gba->memory.activeDMA = -1;
 107	gba->memory.nextDMA = INT_MAX;
 108	gba->memory.eventDiff = 0;
 109
 110	if (!gba->memory.wram || !gba->memory.iwram) {
 111		GBAMemoryDeinit(gba);
 112		GBALog(gba, GBA_LOG_FATAL, "Could not map memory");
 113	}
 114}
 115
 116static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
 117	struct GBA* gba = (struct GBA*) cpu->master;
 118	struct GBAMemory* memory = &gba->memory;
 119
 120	if (address == gba->busyLoop && memory->activeRegion != REGION_BIOS) {
 121		GBAHalt(gba);
 122	}
 123
 124	int newRegion = address >> BASE_OFFSET;
 125	if (newRegion == memory->activeRegion) {
 126		return;
 127	}
 128	if (memory->activeRegion == REGION_BIOS) {
 129		memory->biosPrefetch = cpu->prefetch[1];
 130	}
 131	memory->activeRegion = newRegion;
 132	switch (address & ~OFFSET_MASK) {
 133	case BASE_BIOS:
 134		cpu->memory.activeRegion = memory->bios;
 135		cpu->memory.activeMask = SIZE_BIOS - 1;
 136		break;
 137	case BASE_WORKING_RAM:
 138		cpu->memory.activeRegion = memory->wram;
 139		cpu->memory.activeMask = SIZE_WORKING_RAM - 1;
 140		break;
 141	case BASE_WORKING_IRAM:
 142		cpu->memory.activeRegion = memory->iwram;
 143		cpu->memory.activeMask = SIZE_WORKING_IRAM - 1;
 144		break;
 145	case BASE_VRAM:
 146		cpu->memory.activeRegion = (uint32_t*) gba->video.renderer->vram;
 147		cpu->memory.activeMask = 0x0000FFFF;
 148		break;
 149	case BASE_CART0:
 150	case BASE_CART0_EX:
 151	case BASE_CART1:
 152	case BASE_CART1_EX:
 153	case BASE_CART2:
 154	case BASE_CART2_EX:
 155		cpu->memory.activeRegion = memory->rom;
 156		cpu->memory.activeMask = SIZE_CART0 - 1;
 157		break;
 158	default:
 159		cpu->memory.activeRegion = _deadbeef;
 160		cpu->memory.activeMask = 0;
 161		GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address");
 162		break;
 163	}
 164	cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
 165	cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
 166	cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
 167	cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
 168	cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
 169	cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
 170}
 171
 172#define LOAD_BAD \
 173	GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address); \
 174	if (cpu->cycles >= cpu->nextEvent) { \
 175		value = gba->bus; \
 176	} else { \
 177		value = cpu->prefetch[1]; \
 178		if (cpu->executionMode == MODE_THUMB) { \
 179			value |= value << 16; \
 180		} \
 181	}
 182
 183#define LOAD_BIOS \
 184	if (address < SIZE_BIOS) { \
 185		if (memory->activeRegion == REGION_BIOS) { \
 186			LOAD_32(value, address, memory->bios); \
 187		} else { \
 188			GBALog(gba, GBA_LOG_GAME_ERROR, "Bad BIOS Load32: 0x%08X", address); \
 189			value = memory->biosPrefetch; \
 190		} \
 191	} else { \
 192		LOAD_BAD; \
 193	}
 194
 195#define LOAD_WORKING_RAM \
 196	LOAD_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); \
 197	wait += waitstatesRegion[REGION_WORKING_RAM];
 198
 199#define LOAD_WORKING_IRAM LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
 200#define LOAD_IO value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
 201
 202#define LOAD_PALETTE_RAM \
 203	LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \
 204	++wait;
 205
 206#define LOAD_VRAM \
 207	LOAD_32(value, address & 0x0001FFFF, gba->video.renderer->vram); \
 208	++wait;
 209
 210#define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
 211
 212#define LOAD_CART \
 213	wait += waitstatesRegion[address >> BASE_OFFSET]; \
 214	if ((address & (SIZE_CART0 - 1)) < memory->romSize) { \
 215		LOAD_32(value, address & (SIZE_CART0 - 1), memory->rom); \
 216	} else { \
 217		GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load32: 0x%08X", address); \
 218		value = (address >> 1) & 0xFFFF; \
 219		value |= value << 16; \
 220	}
 221
 222#define LOAD_SRAM \
 223	wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; \
 224	value = GBALoad8(cpu, address, 0); \
 225	value |= value << 8; \
 226	value |= value << 16;
 227
 228uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
 229	struct GBA* gba = (struct GBA*) cpu->master;
 230	struct GBAMemory* memory = &gba->memory;
 231	uint32_t value = 0;
 232	int wait = 0;
 233	char* waitstatesRegion = memory->waitstatesNonseq32;
 234
 235	switch (address >> BASE_OFFSET) {
 236	case REGION_BIOS:
 237		LOAD_BIOS;
 238		break;
 239	case REGION_WORKING_RAM:
 240		LOAD_WORKING_RAM;
 241		break;
 242	case REGION_WORKING_IRAM:
 243		LOAD_WORKING_IRAM;
 244		break;
 245	case REGION_IO:
 246		LOAD_IO;
 247		break;
 248	case REGION_PALETTE_RAM:
 249		LOAD_PALETTE_RAM;
 250		break;
 251	case REGION_VRAM:
 252		LOAD_VRAM;
 253		break;
 254	case REGION_OAM:
 255		LOAD_OAM;
 256		break;
 257	case REGION_CART0:
 258	case REGION_CART0_EX:
 259	case REGION_CART1:
 260	case REGION_CART1_EX:
 261	case REGION_CART2:
 262	case REGION_CART2_EX:
 263		LOAD_CART;
 264		break;
 265	case REGION_CART_SRAM:
 266	case REGION_CART_SRAM_MIRROR:
 267		LOAD_SRAM;
 268		break;
 269	default:
 270		LOAD_BAD;
 271		break;
 272	}
 273
 274	if (cycleCounter) {
 275		*cycleCounter += 2 + wait;
 276	}
 277	// Unaligned 32-bit loads are "rotated" so they make some semblance of sense
 278	int rotate = (address & 3) << 3;
 279	return ROR(value, rotate);
 280}
 281
 282uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
 283	struct GBA* gba = (struct GBA*) cpu->master;
 284	struct GBAMemory* memory = &gba->memory;
 285	uint32_t value = 0;
 286	int wait = 0;
 287
 288	switch (address >> BASE_OFFSET) {
 289	case REGION_BIOS:
 290		if (address < SIZE_BIOS) {
 291			if (memory->activeRegion == REGION_BIOS) {
 292				LOAD_16(value, address, memory->bios);
 293			} else {
 294				GBALog(gba, GBA_LOG_GAME_ERROR, "Bad BIOS Load16: 0x%08X", address);
 295				value = memory->biosPrefetch & 0xFFFF;
 296			}
 297		} else {
 298			GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
 299			if (cpu->cycles >= cpu->nextEvent) {
 300				value = gba->bus & 0xFFFF;
 301			} else {
 302				value = cpu->prefetch[1] & 0xFFFF;
 303			}
 304		}
 305		break;
 306	case REGION_WORKING_RAM:
 307		LOAD_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
 308		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
 309		break;
 310	case REGION_WORKING_IRAM:
 311		LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
 312		break;
 313	case REGION_IO:
 314		value = GBAIORead(gba, address & (SIZE_IO - 1));
 315		break;
 316	case REGION_PALETTE_RAM:
 317		LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
 318		break;
 319	case REGION_VRAM:
 320		LOAD_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
 321		break;
 322	case REGION_OAM:
 323		LOAD_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
 324		break;
 325	case REGION_CART0:
 326	case REGION_CART0_EX:
 327	case REGION_CART1:
 328	case REGION_CART1_EX:
 329	case REGION_CART2:
 330		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
 331		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
 332			LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
 333		} else {
 334			GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
 335			value = (address >> 1) & 0xFFFF; \
 336		}
 337		break;
 338	case REGION_CART2_EX:
 339		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
 340		if (memory->savedata.type == SAVEDATA_EEPROM) {
 341			value = GBASavedataReadEEPROM(&memory->savedata);
 342		} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
 343			LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
 344		} else {
 345			GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load16: 0x%08X", address);
 346			value = (address >> 1) & 0xFFFF; \
 347		}
 348		break;
 349	case REGION_CART_SRAM:
 350	case REGION_CART_SRAM_MIRROR:
 351		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
 352		value = GBALoad8(cpu, address, 0);
 353		value |= value << 8;
 354		break;
 355	default:
 356		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
 357		if (cpu->cycles >= cpu->nextEvent) {
 358			value = gba->bus;
 359		} else {
 360			value = cpu->prefetch[1];
 361		}
 362		break;
 363	}
 364
 365	if (cycleCounter) {
 366		*cycleCounter += 2 + wait;
 367	}
 368	// Unaligned 16-bit loads are "unpredictable", but the GBA rotates them, so we have to, too.
 369	int rotate = (address & 1) << 3;
 370	return ROR(value, rotate);
 371}
 372
 373uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
 374	struct GBA* gba = (struct GBA*) cpu->master;
 375	struct GBAMemory* memory = &gba->memory;
 376	uint8_t value = 0;
 377	int wait = 0;
 378
 379	switch (address >> BASE_OFFSET) {
 380	case REGION_BIOS:
 381		if (address < SIZE_BIOS) {
 382			if (memory->activeRegion == REGION_BIOS) {
 383				value = ((int8_t*) memory->bios)[address];
 384			} else {
 385				GBALog(gba, GBA_LOG_GAME_ERROR, "Bad BIOS Load8: 0x%08X", address);
 386				value = memory->biosPrefetch;
 387			}
 388		} else {
 389			GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
 390			if (cpu->cycles >= cpu->nextEvent) {
 391				value = gba->bus;
 392			} else {
 393				value = cpu->prefetch[1];
 394			}
 395		}
 396		break;
 397	case REGION_WORKING_RAM:
 398		value = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
 399		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
 400		break;
 401	case REGION_WORKING_IRAM:
 402		value = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
 403		break;
 404	case REGION_IO:
 405		value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
 406		break;
 407	case REGION_PALETTE_RAM:
 408		value = ((int8_t*) gba->video.palette)[address & (SIZE_PALETTE_RAM - 1)];
 409		break;
 410	case REGION_VRAM:
 411		value = ((int8_t*) gba->video.renderer->vram)[address & 0x0001FFFF];
 412		break;
 413	case REGION_OAM:
 414		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address);
 415		break;
 416	case REGION_CART0:
 417	case REGION_CART0_EX:
 418	case REGION_CART1:
 419	case REGION_CART1_EX:
 420	case REGION_CART2:
 421	case REGION_CART2_EX:
 422		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
 423		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
 424			value = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
 425		} else {
 426			GBALog(gba, GBA_LOG_GAME_ERROR, "Out of bounds ROM Load8: 0x%08X", address);
 427			value = (address >> 1) & 0xFF; \
 428		}
 429		break;
 430	case REGION_CART_SRAM:
 431	case REGION_CART_SRAM_MIRROR:
 432		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
 433		if (memory->savedata.type == SAVEDATA_NONE) {
 434			GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame");
 435			GBASavedataInitSRAM(&memory->savedata);
 436		}
 437		if (memory->savedata.type == SAVEDATA_SRAM) {
 438			value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
 439		} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
 440			value = GBASavedataReadFlash(&memory->savedata, address);
 441		} else if (memory->gpio.gpioDevices & GPIO_TILT) {
 442			value = GBAGPIOTiltRead(&memory->gpio, address & OFFSET_MASK);
 443		} else {
 444			GBALog(gba, GBA_LOG_GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
 445			value = 0xFF;
 446		}
 447		break;
 448	default:
 449		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
 450		if (cpu->cycles >= cpu->nextEvent) {
 451			value = gba->bus;
 452		} else {
 453			value = cpu->prefetch[1];
 454		}
 455		break;
 456	}
 457
 458	if (cycleCounter) {
 459		*cycleCounter += 2 + wait;
 460	}
 461	return value;
 462}
 463
 464#define STORE_WORKING_RAM \
 465	STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram); \
 466	wait += waitstatesRegion[REGION_WORKING_RAM];
 467
 468#define STORE_WORKING_IRAM \
 469	STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
 470
 471#define STORE_IO \
 472	GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
 473
 474#define STORE_PALETTE_RAM \
 475	STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette); \
 476	gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16); \
 477	++wait; \
 478	gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
 479
 480#define STORE_VRAM \
 481	if ((address & OFFSET_MASK) < SIZE_VRAM) { \
 482		STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram); \
 483	} else if ((address & OFFSET_MASK) < 0x00020000) { \
 484		STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram); \
 485	} \
 486	++wait;
 487
 488#define STORE_OAM \
 489	STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw); \
 490	gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1); \
 491	gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
 492
 493#define STORE_CART \
 494	GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
 495
 496#define STORE_SRAM \
 497	GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
 498
 499#define STORE_BAD \
 500	GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
 501
 502void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
 503	struct GBA* gba = (struct GBA*) cpu->master;
 504	struct GBAMemory* memory = &gba->memory;
 505	int wait = 0;
 506	char* waitstatesRegion = memory->waitstatesNonseq32;
 507
 508	switch (address >> BASE_OFFSET) {
 509	case REGION_WORKING_RAM:
 510		STORE_WORKING_RAM;
 511		break;
 512	case REGION_WORKING_IRAM:
 513		STORE_WORKING_IRAM
 514		break;
 515	case REGION_IO:
 516		STORE_IO;
 517		break;
 518	case REGION_PALETTE_RAM:
 519		STORE_PALETTE_RAM;
 520		break;
 521	case REGION_VRAM:
 522		STORE_VRAM;
 523		break;
 524	case REGION_OAM:
 525		STORE_OAM;
 526		break;
 527	case REGION_CART0:
 528	case REGION_CART0_EX:
 529	case REGION_CART1:
 530	case REGION_CART1_EX:
 531	case REGION_CART2:
 532	case REGION_CART2_EX:
 533		STORE_CART;
 534		break;
 535	case REGION_CART_SRAM:
 536	case REGION_CART_SRAM_MIRROR:
 537		STORE_SRAM;
 538		break;
 539	default:
 540		STORE_BAD;
 541		break;
 542	}
 543
 544	if (cycleCounter) {
 545		*cycleCounter += 1 + wait;
 546	}
 547}
 548
 549void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
 550	struct GBA* gba = (struct GBA*) cpu->master;
 551	struct GBAMemory* memory = &gba->memory;
 552	int wait = 0;
 553
 554	switch (address >> BASE_OFFSET) {
 555	case REGION_WORKING_RAM:
 556		STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
 557		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
 558		break;
 559	case REGION_WORKING_IRAM:
 560		STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
 561		break;
 562	case REGION_IO:
 563		GBAIOWrite(gba, address & (SIZE_IO - 1), value);
 564		break;
 565	case REGION_PALETTE_RAM:
 566		STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
 567		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
 568		break;
 569	case REGION_VRAM:
 570		if ((address & OFFSET_MASK) < SIZE_VRAM) {
 571			STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
 572		} else if ((address & OFFSET_MASK) < 0x00020000) {
 573			STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
 574		}
 575		break;
 576	case REGION_OAM:
 577		STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
 578		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
 579		break;
 580	case REGION_CART0:
 581		if (memory->gpio.gpioDevices != GPIO_NONE && IS_GPIO_REGISTER(address & 0xFFFFFF)) {
 582			uint32_t reg = address & 0xFFFFFF;
 583			GBAGPIOWrite(&memory->gpio, reg, value);
 584		} else {
 585			GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
 586		}
 587		break;
 588	case REGION_CART2_EX:
 589		if (memory->savedata.type == SAVEDATA_NONE) {
 590			GBALog(gba, GBA_LOG_INFO, "Detected EEPROM savegame");
 591			GBASavedataInitEEPROM(&memory->savedata);
 592		}
 593		GBASavedataWriteEEPROM(&memory->savedata, value, 1);
 594		break;
 595	case REGION_CART_SRAM:
 596	case REGION_CART_SRAM_MIRROR:
 597		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
 598		break;
 599	default:
 600		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
 601		break;
 602	}
 603
 604	if (cycleCounter) {
 605		*cycleCounter += 1 + wait;
 606	}
 607}
 608
 609void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
 610	struct GBA* gba = (struct GBA*) cpu->master;
 611	struct GBAMemory* memory = &gba->memory;
 612	int wait = 0;
 613
 614	switch (address >> BASE_OFFSET) {
 615	case REGION_WORKING_RAM:
 616		((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
 617		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
 618		break;
 619	case REGION_WORKING_IRAM:
 620		((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
 621		break;
 622	case REGION_IO:
 623		GBAIOWrite8(gba, address & (SIZE_IO - 1), value);
 624		break;
 625	case REGION_PALETTE_RAM:
 626		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
 627		break;
 628	case REGION_VRAM:
 629		if (address >= 0x06018000) {
 630			// TODO: check BG mode
 631			GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
 632			break;
 633		}
 634		((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value;
 635		((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
 636		break;
 637	case REGION_OAM:
 638		GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
 639		break;
 640	case REGION_CART0:
 641		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
 642		break;
 643	case REGION_CART_SRAM:
 644	case REGION_CART_SRAM_MIRROR:
 645		if (memory->savedata.type == SAVEDATA_NONE) {
 646			if (address == SAVEDATA_FLASH_BASE) {
 647				GBALog(gba, GBA_LOG_INFO, "Detected Flash savegame");
 648				GBASavedataInitFlash(&memory->savedata);
 649			} else {
 650				GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame");
 651				GBASavedataInitSRAM(&memory->savedata);
 652			}
 653		}
 654		if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
 655			GBASavedataWriteFlash(&memory->savedata, address, value);
 656		} else if (memory->savedata.type == SAVEDATA_SRAM) {
 657			memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
 658		} else if (memory->gpio.gpioDevices & GPIO_TILT) {
 659			GBAGPIOTiltWrite(&memory->gpio, address & OFFSET_MASK, value);
 660		} else {
 661			GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
 662		}
 663		wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
 664		break;
 665	default:
 666		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
 667		break;
 668	}
 669
 670	if (cycleCounter) {
 671		*cycleCounter += 1 + wait;
 672	}
 673}
 674
 675#define LDM_LOOP(LDM) \
 676	for (i = 0; i < 16; i += 4) { \
 677		if (UNLIKELY(mask & (1 << i))) { \
 678			LDM; \
 679			waitstatesRegion = memory->waitstatesSeq32; \
 680			cpu->gprs[i] = value; \
 681			++wait; \
 682			address += 4; \
 683		} \
 684		if (UNLIKELY(mask & (2 << i))) { \
 685			LDM; \
 686			waitstatesRegion = memory->waitstatesSeq32; \
 687			cpu->gprs[i + 1] = value; \
 688			++wait; \
 689			address += 4; \
 690		} \
 691		if (UNLIKELY(mask & (4 << i))) { \
 692			LDM; \
 693			waitstatesRegion = memory->waitstatesSeq32; \
 694			cpu->gprs[i + 2] = value; \
 695			++wait; \
 696			address += 4; \
 697		} \
 698		if (UNLIKELY(mask & (8 << i))) { \
 699			LDM; \
 700			waitstatesRegion = memory->waitstatesSeq32; \
 701			cpu->gprs[i + 3] = value; \
 702			++wait; \
 703			address += 4; \
 704		} \
 705	}
 706
 707uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
 708	struct GBA* gba = (struct GBA*) cpu->master;
 709	struct GBAMemory* memory = &gba->memory;
 710	uint32_t value;
 711	int wait = 0;
 712	char* waitstatesRegion = memory->waitstatesNonseq32;
 713
 714	int i;
 715	int offset = 4;
 716	int popcount = 0;
 717	if (direction & LSM_D) {
 718		offset = -4;
 719		popcount = _popcount32(mask);
 720		address -= (popcount << 2) - 4;
 721	}
 722
 723	if (direction & LSM_B) {
 724		address += offset;
 725	}
 726
 727	uint32_t addressMisalign = address & 0x3;
 728	address &= 0xFFFFFFFC;
 729
 730	switch (address >> BASE_OFFSET) {
 731	case REGION_BIOS:
 732		LDM_LOOP(LOAD_BIOS);
 733		break;
 734	case REGION_WORKING_RAM:
 735		LDM_LOOP(LOAD_WORKING_RAM);
 736		break;
 737	case REGION_WORKING_IRAM:
 738		LDM_LOOP(LOAD_WORKING_IRAM);
 739		break;
 740	case REGION_IO:
 741		LDM_LOOP(LOAD_IO);
 742		break;
 743	case REGION_PALETTE_RAM:
 744		LDM_LOOP(LOAD_PALETTE_RAM);
 745		break;
 746	case REGION_VRAM:
 747		LDM_LOOP(LOAD_VRAM);
 748		break;
 749	case REGION_OAM:
 750		LDM_LOOP(LOAD_OAM);
 751		break;
 752	case REGION_CART0:
 753	case REGION_CART0_EX:
 754	case REGION_CART1:
 755	case REGION_CART1_EX:
 756	case REGION_CART2:
 757	case REGION_CART2_EX:
 758		LDM_LOOP(LOAD_CART);
 759		break;
 760	case REGION_CART_SRAM:
 761	case REGION_CART_SRAM_MIRROR:
 762		LDM_LOOP(LOAD_SRAM);
 763		break;
 764	default:
 765		LDM_LOOP(LOAD_BAD);
 766		break;
 767	}
 768
 769	if (cycleCounter) {
 770		*cycleCounter += wait;
 771	}
 772
 773	if (direction & LSM_B) {
 774		address -= offset;
 775	}
 776
 777	if (direction & LSM_D) {
 778		address -= (popcount << 2) + 4;
 779	}
 780
 781	return address | addressMisalign;
 782}
 783
 784#define STM_LOOP(STM) \
 785	for (i = 0; i < 16; i += 4) { \
 786		if (UNLIKELY(mask & (1 << i))) { \
 787			value = cpu->gprs[i]; \
 788			STM; \
 789			waitstatesRegion = memory->waitstatesSeq32; \
 790			++wait; \
 791			address += 4; \
 792		} \
 793		if (UNLIKELY(mask & (2 << i))) { \
 794			value = cpu->gprs[i + 1]; \
 795			STM; \
 796			waitstatesRegion = memory->waitstatesSeq32; \
 797			++wait; \
 798			address += 4; \
 799		} \
 800		if (UNLIKELY(mask & (4 << i))) { \
 801			value = cpu->gprs[i + 2]; \
 802			STM; \
 803			waitstatesRegion = memory->waitstatesSeq32; \
 804			++wait; \
 805			address += 4; \
 806		} \
 807		if (UNLIKELY(mask & (8 << i))) { \
 808			value = cpu->gprs[i + 3]; \
 809			STM; \
 810			waitstatesRegion = memory->waitstatesSeq32; \
 811			++wait; \
 812			address += 4; \
 813		} \
 814	}
 815
 816uint32_t GBAStoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
 817	struct GBA* gba = (struct GBA*) cpu->master;
 818	struct GBAMemory* memory = &gba->memory;
 819	uint32_t value;
 820	int wait = 0;
 821	char* waitstatesRegion = memory->waitstatesNonseq32;
 822
 823	int i;
 824	int offset = 4;
 825	int popcount = 0;
 826	if (direction & LSM_D) {
 827		offset = -4;
 828		popcount = _popcount32(mask);
 829		address -= (popcount << 2) - 4;
 830	}
 831
 832	if (direction & LSM_B) {
 833		address += offset;
 834	}
 835
 836	uint32_t addressMisalign = address & 0x3;
 837	address &= 0xFFFFFFFC;
 838
 839	switch (address >> BASE_OFFSET) {
 840	case REGION_WORKING_RAM:
 841		STM_LOOP(STORE_WORKING_RAM);
 842		break;
 843	case REGION_WORKING_IRAM:
 844		STM_LOOP(STORE_WORKING_IRAM);
 845		break;
 846	case REGION_IO:
 847		STM_LOOP(STORE_IO);
 848		break;
 849	case REGION_PALETTE_RAM:
 850		STM_LOOP(STORE_PALETTE_RAM);
 851		break;
 852	case REGION_VRAM:
 853		STM_LOOP(STORE_VRAM);
 854		break;
 855	case REGION_OAM:
 856		STM_LOOP(STORE_OAM);
 857		break;
 858	case REGION_CART0:
 859	case REGION_CART0_EX:
 860	case REGION_CART1:
 861	case REGION_CART1_EX:
 862	case REGION_CART2:
 863	case REGION_CART2_EX:
 864		STM_LOOP(STORE_CART);
 865		break;
 866	case REGION_CART_SRAM:
 867	case REGION_CART_SRAM_MIRROR:
 868		STM_LOOP(STORE_SRAM);
 869		break;
 870	default:
 871		STM_LOOP(STORE_BAD);
 872		break;
 873	}
 874
 875	if (cycleCounter) {
 876		*cycleCounter += wait;
 877	}
 878
 879	if (direction & LSM_B) {
 880		address -= offset;
 881	}
 882
 883	if (direction & LSM_D) {
 884		address -= (popcount << 2) + 4;
 885	}
 886
 887	return address | addressMisalign;
 888}
 889
 890void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
 891	struct GBAMemory* memory = &gba->memory;
 892	struct ARMCore* cpu = gba->cpu;
 893	int sram = parameters & 0x0003;
 894	int ws0 = (parameters & 0x000C) >> 2;
 895	int ws0seq = (parameters & 0x0010) >> 4;
 896	int ws1 = (parameters & 0x0060) >> 5;
 897	int ws1seq = (parameters & 0x0080) >> 7;
 898	int ws2 = (parameters & 0x0300) >> 8;
 899	int ws2seq = (parameters & 0x0400) >> 10;
 900	int prefetch = parameters & 0x4000;
 901
 902	memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] =  GBA_ROM_WAITSTATES[sram];
 903	memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
 904	memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
 905	memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
 906
 907	memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
 908	memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
 909	memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
 910
 911	memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
 912	memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
 913	memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
 914
 915	memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
 916	memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
 917	memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
 918
 919	memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
 920	memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
 921	memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
 922
 923	if (!prefetch) {
 924		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0];
 925		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1];
 926		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2];
 927
 928		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = memory->waitstatesSeq32[REGION_CART0];
 929		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = memory->waitstatesSeq32[REGION_CART1];
 930		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = memory->waitstatesSeq32[REGION_CART2];
 931
 932		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0];
 933		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1];
 934		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2];
 935
 936		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq32[REGION_CART0];
 937		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq32[REGION_CART1];
 938		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq32[REGION_CART2];
 939	} else {
 940		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = 0;
 941		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = 0;
 942		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = 0;
 943
 944		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = 0;
 945		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = 0;
 946		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = 0;
 947
 948		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = 0;
 949		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = 0;
 950		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = 0;
 951
 952		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = 0;
 953		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = 0;
 954		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = 0;
 955	}
 956
 957	cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
 958	cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
 959
 960	cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
 961	cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
 962
 963	cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
 964	cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
 965}
 966
 967void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
 968	struct GBAMemory* memory = &gba->memory;
 969	memory->dma[dma].source = address & 0x0FFFFFFE;
 970}
 971
 972void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
 973	struct GBAMemory* memory = &gba->memory;
 974	memory->dma[dma].dest = address & 0x0FFFFFFE;
 975}
 976
 977void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
 978	struct GBAMemory* memory = &gba->memory;
 979	memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
 980}
 981
 982uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
 983	struct GBAMemory* memory = &gba->memory;
 984	struct GBADMA* currentDma = &memory->dma[dma];
 985	int wasEnabled = GBADMARegisterIsEnable(currentDma->reg);
 986	currentDma->reg = control;
 987
 988	if (GBADMARegisterIsDRQ(currentDma->reg)) {
 989		GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
 990	}
 991
 992	if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) {
 993		currentDma->nextSource = currentDma->source;
 994		currentDma->nextDest = currentDma->dest;
 995		currentDma->nextCount = currentDma->count;
 996		GBAMemoryScheduleDMA(gba, dma, currentDma);
 997	}
 998	// If the DMA has already occurred, this value might have changed since the function started
 999	return currentDma->reg;
1000};
1001
1002void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
1003	struct ARMCore* cpu = gba->cpu;
1004	switch (GBADMARegisterGetTiming(info->reg)) {
1005	case DMA_TIMING_NOW:
1006		info->nextEvent = cpu->cycles;
1007		GBAMemoryUpdateDMAs(gba, 0);
1008		break;
1009	case DMA_TIMING_HBLANK:
1010		// Handled implicitly
1011		info->nextEvent = INT_MAX;
1012		break;
1013	case DMA_TIMING_VBLANK:
1014		// Handled implicitly
1015		info->nextEvent = INT_MAX;
1016		break;
1017	case DMA_TIMING_CUSTOM:
1018		info->nextEvent = INT_MAX;
1019		switch (number) {
1020		case 0:
1021			GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
1022			break;
1023		case 1:
1024		case 2:
1025			GBAAudioScheduleFifoDma(&gba->audio, number, info);
1026			break;
1027		case 3:
1028			// GBAVideoScheduleVCaptureDma(dma, info);
1029			break;
1030		}
1031	}
1032}
1033
1034void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
1035	struct GBAMemory* memory = &gba->memory;
1036	struct GBADMA* dma;
1037	int i;
1038	for (i = 0; i < 4; ++i) {
1039		dma = &memory->dma[i];
1040		if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_HBLANK) {
1041			dma->nextEvent = cycles;
1042		}
1043	}
1044	GBAMemoryUpdateDMAs(gba, 0);
1045}
1046
1047void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
1048	struct GBAMemory* memory = &gba->memory;
1049	struct GBADMA* dma;
1050	int i;
1051	for (i = 0; i < 4; ++i) {
1052		dma = &memory->dma[i];
1053		if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_VBLANK) {
1054			dma->nextEvent = cycles;
1055		}
1056	}
1057	GBAMemoryUpdateDMAs(gba, 0);
1058}
1059
1060int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
1061	struct GBAMemory* memory = &gba->memory;
1062	if (memory->nextDMA == INT_MAX) {
1063		return INT_MAX;
1064	}
1065	memory->nextDMA -= cycles;
1066	memory->eventDiff += cycles;
1067	if (memory->nextDMA <= 0) {
1068		struct GBADMA* dma = &memory->dma[memory->activeDMA];
1069		GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
1070		GBAMemoryUpdateDMAs(gba, memory->eventDiff);
1071		memory->eventDiff = 0;
1072	}
1073	return memory->nextDMA;
1074}
1075
1076void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
1077	int i;
1078	struct GBAMemory* memory = &gba->memory;
1079	struct ARMCore* cpu = gba->cpu;
1080	memory->activeDMA = -1;
1081	memory->nextDMA = INT_MAX;
1082	for (i = 3; i >= 0; --i) {
1083		struct GBADMA* dma = &memory->dma[i];
1084		if (dma->nextEvent != INT_MAX) {
1085			dma->nextEvent -= cycles;
1086			if (GBADMARegisterIsEnable(dma->reg)) {
1087				memory->activeDMA = i;
1088				memory->nextDMA = dma->nextEvent;
1089			}
1090		}
1091	}
1092	if (memory->nextDMA < cpu->nextEvent) {
1093		cpu->nextEvent = memory->nextDMA;
1094	}
1095}
1096
1097void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
1098	struct GBAMemory* memory = &gba->memory;
1099	struct ARMCore* cpu = gba->cpu;
1100	uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2;
1101	int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width;
1102	int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width;
1103	int32_t wordsRemaining = info->nextCount;
1104	uint32_t source = info->nextSource;
1105	uint32_t dest = info->nextDest;
1106	uint32_t sourceRegion = source >> BASE_OFFSET;
1107	uint32_t destRegion = dest >> BASE_OFFSET;
1108	int32_t cycles = 2;
1109
1110	if (source == info->source) {
1111		// TODO: support 4 cycles for ROM access
1112		cycles += 2;
1113		if (width == 4) {
1114			cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
1115			source &= 0xFFFFFFFC;
1116			dest &= 0xFFFFFFFC;
1117		} else {
1118			cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
1119		}
1120	} else {
1121		if (width == 4) {
1122			cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
1123		} else {
1124			cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
1125		}
1126	}
1127
1128	int32_t word;
1129	if (width == 4) {
1130		word = cpu->memory.load32(cpu, source, 0);
1131		gba->bus = word;
1132		cpu->memory.store32(cpu, dest, word, 0);
1133		source += sourceOffset;
1134		dest += destOffset;
1135		--wordsRemaining;
1136	} else {
1137		if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
1138			word = GBASavedataReadEEPROM(&memory->savedata);
1139			gba->bus = word | (word << 16);
1140			cpu->memory.store16(cpu, dest, word, 0);
1141			source += sourceOffset;
1142			dest += destOffset;
1143			--wordsRemaining;
1144		} else if (destRegion == REGION_CART2_EX) {
1145			if (memory->savedata.type == SAVEDATA_NONE) {
1146				GBALog(gba, GBA_LOG_INFO, "Detected EEPROM savegame");
1147				GBASavedataInitEEPROM(&memory->savedata);
1148			}
1149			word = cpu->memory.load16(cpu, source, 0);
1150			gba->bus = word | (word << 16);
1151			GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
1152			source += sourceOffset;
1153			dest += destOffset;
1154			--wordsRemaining;
1155		} else {
1156			word = cpu->memory.load16(cpu, source, 0);
1157			gba->bus = word | (word << 16);
1158			cpu->memory.store16(cpu, dest, word, 0);
1159			source += sourceOffset;
1160			dest += destOffset;
1161			--wordsRemaining;
1162		}
1163	}
1164
1165	if (!wordsRemaining) {
1166		if (!GBADMARegisterIsRepeat(info->reg) || GBADMARegisterGetTiming(info->reg) == DMA_TIMING_NOW) {
1167			info->reg = GBADMARegisterClearEnable(info->reg);
1168			info->nextEvent = INT_MAX;
1169
1170			// Clear the enable bit in memory
1171			memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
1172		} else {
1173			info->nextCount = info->count;
1174			if (GBADMARegisterGetDestControl(info->reg) == DMA_INCREMENT_RELOAD) {
1175				info->nextDest = info->dest;
1176			}
1177			GBAMemoryScheduleDMA(gba, number, info);
1178		}
1179		if (GBADMARegisterIsDoIRQ(info->reg)) {
1180			GBARaiseIRQ(gba, IRQ_DMA0 + number);
1181		}
1182	} else {
1183		info->nextDest = dest;
1184		info->nextCount = wordsRemaining;
1185	}
1186	info->nextSource = source;
1187
1188	if (info->nextEvent != INT_MAX) {
1189		info->nextEvent += cycles;
1190	}
1191	cpu->cycles += cycles;
1192}
1193
1194void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state) {
1195	memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
1196	memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
1197}
1198
1199void GBAMemoryDeserialize(struct GBAMemory* memory, struct GBASerializedState* state) {
1200	memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
1201	memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
1202}
1203
1204uint32_t _popcount32(unsigned bits) {
1205	bits = bits - ((bits >> 1) & 0x55555555);
1206	bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
1207	return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
1208}