all repos — mgba @ d8bee5d34bf4f5a44b7eff4c57948b03154531c0

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