all repos — mgba @ 5b41141b0213cfb6f1be273784166ef79aae05e7

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