all repos — mgba @ 1619b760e197bb7762f1d5270864231d2770fd47

mGBA Game Boy Advance Emulator

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

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