all repos — mgba @ 3ad2047855d038006998af37fcf9f957ec450a5a

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	address &= 0xFFFFFFFC;
 680
 681	switch (address >> BASE_OFFSET) {
 682	case REGION_WORKING_RAM:
 683		LDM_LOOP_BEGIN;
 684		LOAD_WORKING_RAM;
 685		LDM_LOOP_END;
 686		break;
 687	case REGION_WORKING_IRAM:
 688		LDM_LOOP_BEGIN;
 689		LOAD_WORKING_IRAM;
 690		LDM_LOOP_END;
 691		break;
 692	case REGION_IO:
 693		LDM_LOOP_BEGIN;
 694		LOAD_IO;
 695		LDM_LOOP_END;
 696		break;
 697	case REGION_PALETTE_RAM:
 698		LDM_LOOP_BEGIN;
 699		LOAD_PALETTE_RAM;
 700		LDM_LOOP_END;
 701		break;
 702	case REGION_VRAM:
 703		LDM_LOOP_BEGIN;
 704		LOAD_VRAM;
 705		LDM_LOOP_END;
 706		break;
 707	case REGION_OAM:
 708		LDM_LOOP_BEGIN;
 709		LOAD_OAM;
 710		LDM_LOOP_END;
 711		break;
 712	case REGION_CART0:
 713	case REGION_CART0_EX:
 714	case REGION_CART1:
 715	case REGION_CART1_EX:
 716	case REGION_CART2:
 717	case REGION_CART2_EX:
 718		LDM_LOOP_BEGIN;
 719		LOAD_CART;
 720		LDM_LOOP_END;
 721		break;
 722	case REGION_CART_SRAM:
 723	case REGION_CART_SRAM_MIRROR:
 724		LDM_LOOP_BEGIN;
 725		LOAD_SRAM;
 726		LDM_LOOP_END;
 727		break;
 728	default:
 729		LDM_LOOP_BEGIN;
 730		LOAD_BAD;
 731		LDM_LOOP_END;
 732		break;
 733	}
 734
 735	if (cycleCounter) {
 736		*cycleCounter += wait;
 737	}
 738
 739	if (direction & LSM_B) {
 740		address -= offset;
 741	}
 742
 743	if (direction & LSM_D) {
 744		address -= (popcount << 2) + 4;
 745	}
 746
 747	return address;
 748}
 749
 750#define STM_LOOP_BEGIN \
 751	for (i = 0; i < 16; ++i) { \
 752		if (!(mask & (1 << i))) { \
 753			continue; \
 754		} \
 755		value = cpu->gprs[i];
 756
 757#define STM_LOOP_END \
 758		waitstatesRegion = memory->waitstatesSeq32; \
 759		++wait; \
 760		address += 4; \
 761	}
 762
 763uint32_t GBAStoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
 764	struct GBA* gba = (struct GBA*) cpu->master;
 765	struct GBAMemory* memory = &gba->memory;
 766	uint32_t value;
 767	int wait = 0;
 768	char* waitstatesRegion = memory->waitstatesNonseq32;
 769
 770	int i;
 771	int offset = 4;
 772	int popcount = 0;
 773	if (direction & LSM_D) {
 774		offset = -4;
 775		popcount = _popcount32(mask);
 776		address -= (popcount << 2) - 4;
 777	}
 778
 779	if (direction & LSM_B) {
 780		address += offset;
 781	}
 782
 783	address &= 0xFFFFFFFC;
 784
 785	switch (address >> BASE_OFFSET) {
 786	case REGION_WORKING_RAM:
 787		STM_LOOP_BEGIN;
 788		STORE_WORKING_RAM;
 789		STM_LOOP_END;
 790		break;
 791	case REGION_WORKING_IRAM:
 792		STM_LOOP_BEGIN;
 793		STORE_WORKING_IRAM;
 794		STM_LOOP_END;
 795		break;
 796	case REGION_IO:
 797		STM_LOOP_BEGIN;
 798		STORE_IO;
 799		STM_LOOP_END;
 800		break;
 801	case REGION_PALETTE_RAM:
 802		STM_LOOP_BEGIN;
 803		STORE_PALETTE_RAM;
 804		STM_LOOP_END;
 805		break;
 806	case REGION_VRAM:
 807		STM_LOOP_BEGIN;
 808		STORE_VRAM;
 809		STM_LOOP_END;
 810		break;
 811	case REGION_OAM:
 812		STM_LOOP_BEGIN;
 813		STORE_OAM;
 814		STM_LOOP_END;
 815		break;
 816	case REGION_CART0:
 817	case REGION_CART0_EX:
 818	case REGION_CART1:
 819	case REGION_CART1_EX:
 820	case REGION_CART2:
 821	case REGION_CART2_EX:
 822		STM_LOOP_BEGIN;
 823		STORE_CART;
 824		STM_LOOP_END;
 825		break;
 826	case REGION_CART_SRAM:
 827	case REGION_CART_SRAM_MIRROR:
 828		STM_LOOP_BEGIN;
 829		STORE_SRAM;
 830		STM_LOOP_END;
 831		break;
 832	default:
 833		STM_LOOP_BEGIN;
 834		STORE_BAD;
 835		STM_LOOP_END;
 836		break;
 837	}
 838
 839	if (cycleCounter) {
 840		*cycleCounter += wait;
 841	}
 842
 843	if (direction & LSM_B) {
 844		address -= offset;
 845	}
 846
 847	if (direction & LSM_D) {
 848		address -= (popcount << 2) + 4;
 849	}
 850
 851	return address;
 852}
 853
 854void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
 855	struct GBAMemory* memory = &gba->memory;
 856	struct ARMCore* cpu = gba->cpu;
 857	int sram = parameters & 0x0003;
 858	int ws0 = (parameters & 0x000C) >> 2;
 859	int ws0seq = (parameters & 0x0010) >> 4;
 860	int ws1 = (parameters & 0x0060) >> 5;
 861	int ws1seq = (parameters & 0x0080) >> 7;
 862	int ws2 = (parameters & 0x0300) >> 8;
 863	int ws2seq = (parameters & 0x0400) >> 10;
 864	int prefetch = parameters & 0x4000;
 865
 866	memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] =  GBA_ROM_WAITSTATES[sram];
 867	memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
 868	memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
 869	memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
 870
 871	memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
 872	memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
 873	memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
 874
 875	memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
 876	memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
 877	memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
 878
 879	memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
 880	memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
 881	memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
 882
 883	memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
 884	memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
 885	memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
 886
 887	if (!prefetch) {
 888		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0];
 889		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1];
 890		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2];
 891
 892		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = memory->waitstatesSeq32[REGION_CART0];
 893		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = memory->waitstatesSeq32[REGION_CART1];
 894		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = memory->waitstatesSeq32[REGION_CART2];
 895
 896		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0];
 897		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1];
 898		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2];
 899
 900		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq32[REGION_CART0];
 901		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq32[REGION_CART1];
 902		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq32[REGION_CART2];
 903	} else {
 904		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = 0;
 905		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = 0;
 906		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = 0;
 907
 908		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = 0;
 909		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = 0;
 910		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = 0;
 911
 912		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = 0;
 913		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = 0;
 914		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = 0;
 915
 916		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = 0;
 917		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = 0;
 918		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = 0;
 919	}
 920
 921	cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
 922	cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
 923
 924	cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
 925	cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
 926
 927	cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
 928	cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
 929}
 930
 931void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
 932	struct GBAMemory* memory = &gba->memory;
 933	memory->dma[dma].source = address & 0xFFFFFFFE;
 934}
 935
 936void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
 937	struct GBAMemory* memory = &gba->memory;
 938	memory->dma[dma].dest = address & 0xFFFFFFFE;
 939}
 940
 941void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
 942	struct GBAMemory* memory = &gba->memory;
 943	memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
 944}
 945
 946uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
 947	struct GBAMemory* memory = &gba->memory;
 948	struct GBADMA* currentDma = &memory->dma[dma];
 949	int wasEnabled = GBADMARegisterIsEnable(currentDma->reg);
 950	currentDma->reg = control;
 951
 952	if (GBADMARegisterIsDRQ(currentDma->reg)) {
 953		GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
 954	}
 955
 956	if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) {
 957		currentDma->nextSource = currentDma->source;
 958		currentDma->nextDest = currentDma->dest;
 959		currentDma->nextCount = currentDma->count;
 960		GBAMemoryScheduleDMA(gba, dma, currentDma);
 961	}
 962	// If the DMA has already occurred, this value might have changed since the function started
 963	return currentDma->reg;
 964};
 965
 966void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
 967	struct ARMCore* cpu = gba->cpu;
 968	switch (GBADMARegisterGetTiming(info->reg)) {
 969	case DMA_TIMING_NOW:
 970		info->nextEvent = cpu->cycles;
 971		GBAMemoryUpdateDMAs(gba, 0);
 972		break;
 973	case DMA_TIMING_HBLANK:
 974		// Handled implicitly
 975		info->nextEvent = INT_MAX;
 976		break;
 977	case DMA_TIMING_VBLANK:
 978		// Handled implicitly
 979		info->nextEvent = INT_MAX;
 980		break;
 981	case DMA_TIMING_CUSTOM:
 982		info->nextEvent = INT_MAX;
 983		switch (number) {
 984		case 0:
 985			GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
 986			break;
 987		case 1:
 988		case 2:
 989			GBAAudioScheduleFifoDma(&gba->audio, number, info);
 990			break;
 991		case 3:
 992			// GBAVideoScheduleVCaptureDma(dma, info);
 993			break;
 994		}
 995	}
 996}
 997
 998void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
 999	struct GBAMemory* memory = &gba->memory;
1000	struct GBADMA* dma;
1001	int i;
1002	for (i = 0; i < 4; ++i) {
1003		dma = &memory->dma[i];
1004		if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_HBLANK) {
1005			dma->nextEvent = cycles;
1006		}
1007	}
1008	GBAMemoryUpdateDMAs(gba, 0);
1009}
1010
1011void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
1012	struct GBAMemory* memory = &gba->memory;
1013	struct GBADMA* dma;
1014	int i;
1015	for (i = 0; i < 4; ++i) {
1016		dma = &memory->dma[i];
1017		if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_VBLANK) {
1018			dma->nextEvent = cycles;
1019		}
1020	}
1021	GBAMemoryUpdateDMAs(gba, 0);
1022}
1023
1024int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
1025	struct GBAMemory* memory = &gba->memory;
1026	if (memory->nextDMA == INT_MAX) {
1027		return INT_MAX;
1028	}
1029	memory->nextDMA -= cycles;
1030	memory->eventDiff += cycles;
1031	if (memory->nextDMA <= 0) {
1032		struct GBADMA* dma = &memory->dma[memory->activeDMA];
1033		GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
1034		GBAMemoryUpdateDMAs(gba, memory->eventDiff);
1035		memory->eventDiff = 0;
1036	}
1037	return memory->nextDMA;
1038}
1039
1040void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
1041	int i;
1042	struct GBAMemory* memory = &gba->memory;
1043	struct ARMCore* cpu = gba->cpu;
1044	memory->activeDMA = -1;
1045	memory->nextDMA = INT_MAX;
1046	for (i = 3; i >= 0; --i) {
1047		struct GBADMA* dma = &memory->dma[i];
1048		if (dma->nextEvent != INT_MAX) {
1049			dma->nextEvent -= cycles;
1050			if (GBADMARegisterIsEnable(dma->reg)) {
1051				memory->activeDMA = i;
1052				memory->nextDMA = dma->nextEvent;
1053			}
1054		}
1055	}
1056	if (memory->nextDMA < cpu->nextEvent) {
1057		cpu->nextEvent = memory->nextDMA;
1058	}
1059}
1060
1061void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
1062	struct GBAMemory* memory = &gba->memory;
1063	struct ARMCore* cpu = gba->cpu;
1064	uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2;
1065	int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width;
1066	int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width;
1067	int32_t wordsRemaining = info->nextCount;
1068	uint32_t source = info->nextSource;
1069	uint32_t dest = info->nextDest;
1070	uint32_t sourceRegion = source >> BASE_OFFSET;
1071	uint32_t destRegion = dest >> BASE_OFFSET;
1072	int32_t cycles = 0;
1073
1074	if (source == info->source) {
1075		// TODO: support 4 cycles for ROM access
1076		cycles += 2;
1077		if (width == 4) {
1078			cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
1079			source &= 0xFFFFFFFC;
1080			dest &= 0xFFFFFFFC;
1081		} else {
1082			cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
1083		}
1084	} else {
1085		if (width == 4) {
1086			cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
1087		} else {
1088			cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
1089		}
1090	}
1091
1092	if (width == 4) {
1093		int32_t word;
1094		word = cpu->memory.load32(cpu, source, 0);
1095		cpu->memory.store32(cpu, dest, word, 0);
1096		source += sourceOffset;
1097		dest += destOffset;
1098		--wordsRemaining;
1099	} else {
1100		uint16_t word;
1101		if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
1102			word = GBASavedataReadEEPROM(&memory->savedata);
1103			cpu->memory.store16(cpu, dest, word, 0);
1104			source += sourceOffset;
1105			dest += destOffset;
1106			--wordsRemaining;
1107		} else if (destRegion == REGION_CART2_EX) {
1108			if (memory->savedata.type == SAVEDATA_NONE) {
1109				GBALog(gba, GBA_LOG_INFO, "Detected EEPROM savegame");
1110				GBASavedataInitEEPROM(&memory->savedata);
1111			}
1112			word = cpu->memory.load16(cpu, source, 0);
1113			GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
1114			source += sourceOffset;
1115			dest += destOffset;
1116			--wordsRemaining;
1117		} else {
1118			word = cpu->memory.load16(cpu, source, 0);
1119			cpu->memory.store16(cpu, dest, word, 0);
1120			source += sourceOffset;
1121			dest += destOffset;
1122			--wordsRemaining;
1123		}
1124	}
1125
1126	if (!wordsRemaining) {
1127		if (!GBADMARegisterIsRepeat(info->reg)) {
1128			info->reg = GBADMARegisterClearEnable(info->reg);
1129			info->nextEvent = INT_MAX;
1130
1131			// Clear the enable bit in memory
1132			memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
1133		} else {
1134			info->nextCount = info->count;
1135			if (GBADMARegisterGetDestControl(info->reg) == DMA_INCREMENT_RELOAD) {
1136				info->nextDest = info->dest;
1137			}
1138			GBAMemoryScheduleDMA(gba, number, info);
1139		}
1140		if (GBADMARegisterIsDoIRQ(info->reg)) {
1141			GBARaiseIRQ(gba, IRQ_DMA0 + number);
1142		}
1143	} else {
1144		info->nextDest = dest;
1145		info->nextCount = wordsRemaining;
1146	}
1147	info->nextSource = source;
1148
1149	if (info->nextEvent != INT_MAX) {
1150		info->nextEvent += cycles;
1151	}
1152	cpu->cycles += cycles;
1153}
1154
1155void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state) {
1156	memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
1157	memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
1158}
1159
1160void GBAMemoryDeserialize(struct GBAMemory* memory, struct GBASerializedState* state) {
1161	memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
1162	memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
1163}
1164
1165uint32_t _popcount32(unsigned bits) {
1166	bits = bits - ((bits >> 1) & 0x55555555);
1167	bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
1168	return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
1169}