all repos — mgba @ 4d2ccd5df438b988c21af6959c3704aec590a075

mGBA Game Boy Advance Emulator

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

  1#include "gba-memory.h"
  2
  3#include "gba-gpio.h"
  4#include "gba-io.h"
  5#include "gba-serialize.h"
  6#include "hle-bios.h"
  7#include "util/memory.h"
  8
  9static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region);
 10static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count);
 11static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);
 12
 13static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 };
 14static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };
 15static const char GBA_BASE_WAITSTATES_SEQ[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4 };
 16static const char GBA_BASE_WAITSTATES_SEQ_32[16] = { 0, 0, 5, 0, 0, 0, 0, 0, 5, 5, 9, 9, 17, 17, 9 };
 17static const char GBA_ROM_WAITSTATES[] = { 4, 3, 2, 8 };
 18static const char GBA_ROM_WAITSTATES_SEQ[] = { 2, 1, 4, 1, 8, 1 };
 19static const int DMA_OFFSET[] = { 1, -1, 0, 1 };
 20
 21void GBAMemoryInit(struct GBA* gba) {
 22	struct ARMCore* cpu = gba->cpu;
 23	cpu->memory.load32 = GBALoad32;
 24	cpu->memory.load16 = GBALoad16;
 25	cpu->memory.loadU16 = GBALoadU16;
 26	cpu->memory.load8 = GBALoad8;
 27	cpu->memory.loadU8 = GBALoadU8;
 28	cpu->memory.store32 = GBAStore32;
 29	cpu->memory.store16 = GBAStore16;
 30	cpu->memory.store8 = GBAStore8;
 31
 32	gba->memory.bios = (uint32_t*) hleBios;
 33	gba->memory.fullBios = 0;
 34	gba->memory.wram = 0;
 35	gba->memory.iwram = 0;
 36	gba->memory.rom = 0;
 37	gba->memory.gpio.p = gba;
 38
 39	int i;
 40	for (i = 0; i < 16; ++i) {
 41		gba->memory.waitstatesNonseq16[i] = GBA_BASE_WAITSTATES[i];
 42		gba->memory.waitstatesSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
 43		gba->memory.waitstatesPrefetchNonseq16[i] = GBA_BASE_WAITSTATES[i];
 44		gba->memory.waitstatesPrefetchSeq16[i] = GBA_BASE_WAITSTATES_SEQ[i];
 45		gba->memory.waitstatesNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
 46		gba->memory.waitstatesSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
 47		gba->memory.waitstatesPrefetchNonseq32[i] = GBA_BASE_WAITSTATES_32[i];
 48		gba->memory.waitstatesPrefetchSeq32[i] = GBA_BASE_WAITSTATES_SEQ_32[i];
 49	}
 50	for (; i < 256; ++i) {
 51		gba->memory.waitstatesNonseq16[i] = 0;
 52		gba->memory.waitstatesSeq16[i] = 0;
 53		gba->memory.waitstatesNonseq32[i] = 0;
 54		gba->memory.waitstatesSeq32[i] = 0;
 55	}
 56
 57	gba->memory.activeRegion = -1;
 58	cpu->memory.activeRegion = 0;
 59	cpu->memory.activeMask = 0;
 60	cpu->memory.setActiveRegion = GBASetActiveRegion;
 61	cpu->memory.activeSeqCycles32 = 0;
 62	cpu->memory.activeSeqCycles16 = 0;
 63	cpu->memory.activeNonseqCycles32 = 0;
 64	cpu->memory.activeNonseqCycles16 = 0;
 65	cpu->memory.activeUncachedCycles32 = 0;
 66	cpu->memory.activeUncachedCycles16 = 0;
 67	gba->memory.biosPrefetch = 0;
 68	cpu->memory.waitMultiple = GBAWaitMultiple;
 69}
 70
 71void GBAMemoryDeinit(struct GBA* gba) {
 72	mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
 73	mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
 74	if (gba->memory.rom) {
 75		mappedMemoryFree(gba->memory.rom, gba->memory.romSize);
 76	}
 77	GBASavedataDeinit(&gba->memory.savedata);
 78}
 79
 80void GBAMemoryReset(struct GBA* gba) {
 81	if (gba->memory.wram) {
 82		mappedMemoryFree(gba->memory.wram, SIZE_WORKING_RAM);
 83	}
 84	gba->memory.wram = anonymousMemoryMap(SIZE_WORKING_RAM);
 85
 86	if (gba->memory.iwram) {
 87		mappedMemoryFree(gba->memory.iwram, SIZE_WORKING_IRAM);
 88	}
 89	gba->memory.iwram = anonymousMemoryMap(SIZE_WORKING_IRAM);
 90
 91	memset(gba->memory.io, 0, sizeof(gba->memory.io));
 92	memset(gba->memory.dma, 0, sizeof(gba->memory.dma));
 93	int i;
 94	for (i = 0; i < 4; ++i) {
 95		gba->memory.dma[i].count = 0x10000;
 96		gba->memory.dma[i].nextEvent = INT_MAX;
 97	}
 98	gba->memory.activeDMA = -1;
 99	gba->memory.nextDMA = INT_MAX;
100	gba->memory.eventDiff = 0;
101
102	if (!gba->memory.wram || !gba->memory.iwram) {
103		GBAMemoryDeinit(gba);
104		GBALog(gba, GBA_LOG_FATAL, "Could not map memory");
105	}
106}
107
108static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
109	struct GBA* gba = (struct GBA*) cpu->master;
110	struct GBAMemory* memory = &gba->memory;
111
112	if (address == gba->busyLoop && memory->activeRegion != REGION_BIOS) {
113		GBAHalt(gba);
114	}
115
116	int newRegion = address >> BASE_OFFSET;
117	if (newRegion == memory->activeRegion) {
118		return;
119	}
120	if (memory->activeRegion == REGION_BIOS) {
121		memory->biosPrefetch = cpu->prefetch;
122	}
123	memory->activeRegion = newRegion;
124	switch (address & ~OFFSET_MASK) {
125	case BASE_BIOS:
126		cpu->memory.activeRegion = memory->bios;
127		cpu->memory.activeMask = SIZE_BIOS - 1;
128		break;
129	case BASE_WORKING_RAM:
130		cpu->memory.activeRegion = memory->wram;
131		cpu->memory.activeMask = SIZE_WORKING_RAM - 1;
132		break;
133	case BASE_WORKING_IRAM:
134		cpu->memory.activeRegion = memory->iwram;
135		cpu->memory.activeMask = SIZE_WORKING_IRAM - 1;
136		break;
137	case BASE_CART0:
138	case BASE_CART0_EX:
139	case BASE_CART1:
140	case BASE_CART1_EX:
141	case BASE_CART2:
142	case BASE_CART2_EX:
143		cpu->memory.activeRegion = memory->rom;
144		cpu->memory.activeMask = SIZE_CART0 - 1;
145		break;
146	default:
147		cpu->memory.activeRegion = 0;
148		cpu->memory.activeMask = 0;
149		GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address");
150		break;
151	}
152	cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
153	cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
154	cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
155	cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
156	cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
157	cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
158}
159
160int32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
161	struct GBA* gba = (struct GBA*) cpu->master;
162	struct GBAMemory* memory = &gba->memory;
163	uint32_t value = 0;
164	int wait = 0;
165
166	switch (address & ~OFFSET_MASK) {
167	case BASE_BIOS:
168		if (cpu->gprs[ARM_PC] >> BASE_OFFSET == REGION_BIOS) {
169			if (address < SIZE_BIOS) {
170				LOAD_32(value, address, memory->bios);
171			} else {
172				value = 0;
173			}
174		} else {
175			value = memory->biosPrefetch;
176		}
177		break;
178	case BASE_WORKING_RAM:
179		LOAD_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
180		wait = memory->waitstatesNonseq32[REGION_WORKING_RAM];
181		break;
182	case BASE_WORKING_IRAM:
183		LOAD_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
184		break;
185	case BASE_IO:
186		value = GBAIORead(gba, (address & (SIZE_IO - 1)) & ~2) | (GBAIORead(gba, (address & (SIZE_IO - 1)) | 2) << 16);
187		break;
188	case BASE_PALETTE_RAM:
189		LOAD_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
190		break;
191	case BASE_VRAM:
192		LOAD_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
193		break;
194	case BASE_OAM:
195		LOAD_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
196		break;
197	case BASE_CART0:
198	case BASE_CART0_EX:
199	case BASE_CART1:
200	case BASE_CART1_EX:
201	case BASE_CART2:
202	case BASE_CART2_EX:
203		wait = memory->waitstatesNonseq32[address >> BASE_OFFSET];
204		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
205			LOAD_32(value, address & (SIZE_CART0 - 1), memory->rom);
206		}
207		break;
208	case BASE_CART_SRAM:
209	case BASE_CART_SRAM_MIRROR:
210		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load32: 0x%08X", address);
211		break;
212	default:
213		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address);
214		value = cpu->prefetch;
215		if (cpu->executionMode == MODE_THUMB) {
216			value |= value << 16;
217		}
218		break;
219	}
220
221
222	if (cycleCounter) {
223		*cycleCounter += 2 + wait;
224	}
225	// Unaligned 32-bit loads are "rotated" so they make some semblance of sense
226	int rotate = (address & 3) << 3;
227	return (value >> rotate) | (value << (32 - rotate));
228}
229
230uint16_t GBALoadU16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
231	return GBALoad16(cpu, address, cycleCounter);
232}
233
234int16_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
235	struct GBA* gba = (struct GBA*) cpu->master;
236	struct GBAMemory* memory = &gba->memory;
237	uint16_t value = 0;
238	int wait = 0;
239
240	switch (address & ~OFFSET_MASK) {
241	case BASE_BIOS:
242		if (cpu->gprs[ARM_PC] >> BASE_OFFSET == REGION_BIOS) {
243			if (address < SIZE_BIOS) {
244				LOAD_16(value, address, memory->bios);
245			} else {
246				value = 0;
247			}
248		} else {
249			value = memory->biosPrefetch;
250		}
251		break;
252	case BASE_WORKING_RAM:
253		LOAD_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
254		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
255		break;
256	case BASE_WORKING_IRAM:
257		LOAD_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
258		break;
259	case BASE_IO:
260		value = GBAIORead(gba, address & (SIZE_IO - 1));
261		break;
262	case BASE_PALETTE_RAM:
263		LOAD_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
264		break;
265	case BASE_VRAM:
266		LOAD_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
267		break;
268	case BASE_OAM:
269		LOAD_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
270		break;
271	case BASE_CART0:
272	case BASE_CART0_EX:
273	case BASE_CART1:
274	case BASE_CART1_EX:
275	case BASE_CART2:
276		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
277		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
278			LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
279		}
280		break;
281	case BASE_CART2_EX:
282		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
283		if (memory->savedata.type == SAVEDATA_EEPROM) {
284			value = GBASavedataReadEEPROM(&memory->savedata);
285		} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
286			LOAD_16(value, address & (SIZE_CART0 - 1), memory->rom);
287		}
288		break;
289	case BASE_CART_SRAM:
290	case BASE_CART_SRAM_MIRROR:
291		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load16: 0x%08X", address);
292		break;
293	default:
294		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
295		value = cpu->prefetch;
296		break;
297	}
298
299	if (cycleCounter) {
300		*cycleCounter += 2 + wait;
301	}
302	// Unaligned 16-bit loads are "unpredictable", but the GBA rotates them, so we have to, too.
303	int rotate = (address & 1) << 3;
304	return (value >> rotate) | (value << (16 - rotate));
305}
306
307uint8_t GBALoadU8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
308	return GBALoad8(cpu, address, cycleCounter);
309}
310
311int8_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
312	struct GBA* gba = (struct GBA*) cpu->master;
313	struct GBAMemory* memory = &gba->memory;
314	int8_t value = 0;
315	int wait = 0;
316
317	switch (address & ~OFFSET_MASK) {
318	case BASE_BIOS:
319		if (cpu->gprs[ARM_PC] >> BASE_OFFSET == REGION_BIOS) {
320			if (address < SIZE_BIOS) {
321				value = ((int8_t*) memory->bios)[address];
322			} else {
323				value = 0;
324			}
325		} else {
326			value = memory->biosPrefetch;
327		}
328		break;
329	case BASE_WORKING_RAM:
330		value = ((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)];
331		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
332		break;
333	case BASE_WORKING_IRAM:
334		value = ((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
335		break;
336	case BASE_IO:
337		value = (GBAIORead(gba, address & 0xFFFE) >> ((address & 0x0001) << 3)) & 0xFF;
338		break;
339	case BASE_PALETTE_RAM:
340		value = ((int8_t*) gba->video.renderer->palette)[address & (SIZE_PALETTE_RAM - 1)];
341		break;
342	case BASE_VRAM:
343		value = ((int8_t*) gba->video.renderer->vram)[address & 0x0001FFFF];
344		break;
345	case BASE_OAM:
346		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Load8: 0x%08X", address);
347		break;
348	case BASE_CART0:
349	case BASE_CART0_EX:
350	case BASE_CART1:
351	case BASE_CART1_EX:
352	case BASE_CART2:
353	case BASE_CART2_EX:
354		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
355		if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
356			value = ((int8_t*) memory->rom)[address & (SIZE_CART0 - 1)];
357		}
358		break;
359	case BASE_CART_SRAM:
360	case BASE_CART_SRAM_MIRROR:
361		wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
362		if (memory->savedata.type == SAVEDATA_NONE) {
363			GBASavedataInitSRAM(&memory->savedata);
364		}
365		if (memory->savedata.type == SAVEDATA_SRAM) {
366			value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
367		} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
368			value = GBASavedataReadFlash(&memory->savedata, address);
369		}
370		break;
371	default:
372		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
373		value = cpu->prefetch & 0xFF;
374		break;
375	}
376
377	if (cycleCounter) {
378		*cycleCounter += 2 + wait;
379	}
380	return value;
381}
382
383void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
384	struct GBA* gba = (struct GBA*) cpu->master;
385	struct GBAMemory* memory = &gba->memory;
386	int wait = 0;
387
388	switch (address & ~OFFSET_MASK) {
389	case BASE_WORKING_RAM:
390		STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
391		wait = memory->waitstatesNonseq32[REGION_WORKING_RAM];
392		break;
393	case BASE_WORKING_IRAM:
394		STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
395		break;
396	case BASE_IO:
397		GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
398		break;
399	case BASE_PALETTE_RAM:
400		STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
401		gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
402		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
403		break;
404	case BASE_VRAM:
405		if ((address & OFFSET_MASK) < SIZE_VRAM) {
406			STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
407		} else if ((address & OFFSET_MASK) < 0x00020000) {
408			STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram);
409		}
410		break;
411	case BASE_OAM:
412		STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
413		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
414		gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
415		break;
416	case BASE_CART0:
417		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
418		break;
419	case BASE_CART_SRAM:
420	case BASE_CART_SRAM_MIRROR:
421		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
422		break;
423	default:
424		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
425		break;
426	}
427
428	if (cycleCounter) {
429		*cycleCounter += 1 + wait;
430	}
431}
432
433void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
434	struct GBA* gba = (struct GBA*) cpu->master;
435	struct GBAMemory* memory = &gba->memory;
436	int wait = 0;
437
438	switch (address & ~OFFSET_MASK) {
439	case BASE_WORKING_RAM:
440		STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
441		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
442		break;
443	case BASE_WORKING_IRAM:
444		STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
445		break;
446	case BASE_IO:
447		GBAIOWrite(gba, address & (SIZE_IO - 1), value);
448		break;
449	case BASE_PALETTE_RAM:
450		STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
451		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
452		break;
453	case BASE_VRAM:
454		if ((address & OFFSET_MASK) < SIZE_VRAM) {
455			STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
456		} else if ((address & OFFSET_MASK) < 0x00020000) {
457			STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
458		}
459		break;
460	case BASE_OAM:
461		STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
462		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
463		break;
464	case BASE_CART0:
465		if (IS_GPIO_REGISTER(address & 0xFFFFFF)) {
466			uint32_t reg = address & 0xFFFFFF;
467			GBAGPIOWrite(&memory->gpio, reg, value);
468		} else {
469			GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
470		}
471		break;
472	case BASE_CART2_EX:
473		if (memory->savedata.type == SAVEDATA_NONE) {
474			GBASavedataInitEEPROM(&memory->savedata);
475		}
476		GBASavedataWriteEEPROM(&memory->savedata, value, 1);
477		break;
478	case BASE_CART_SRAM:
479	case BASE_CART_SRAM_MIRROR:
480		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
481		break;
482	default:
483		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
484		break;
485	}
486
487	if (cycleCounter) {
488		*cycleCounter += 1 + wait;
489	}
490}
491
492void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
493	struct GBA* gba = (struct GBA*) cpu->master;
494	struct GBAMemory* memory = &gba->memory;
495	int wait = 0;
496
497	switch (address & ~OFFSET_MASK) {
498	case BASE_WORKING_RAM:
499		((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
500		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
501		break;
502	case BASE_WORKING_IRAM:
503		((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
504		break;
505	case BASE_IO:
506		GBAIOWrite8(gba, address & (SIZE_IO - 1), value);
507		break;
508	case BASE_PALETTE_RAM:
509		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
510		break;
511	case BASE_VRAM:
512		if (address >= 0x06018000) {
513			// TODO: check BG mode
514			GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
515			break;
516		}
517		((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value;
518		((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
519		break;
520	case BASE_OAM:
521		GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
522		break;
523	case BASE_CART0:
524		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
525		break;
526	case BASE_CART_SRAM:
527	case BASE_CART_SRAM_MIRROR:
528		if (memory->savedata.type == SAVEDATA_NONE) {
529			if (address == SAVEDATA_FLASH_BASE) {
530				GBASavedataInitFlash(&memory->savedata);
531			} else {
532				GBASavedataInitSRAM(&memory->savedata);
533			}
534		}
535		if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
536			GBASavedataWriteFlash(&memory->savedata, address, value);
537		} else if (memory->savedata.type == SAVEDATA_SRAM) {
538			memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
539		}
540		wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
541		break;
542	default:
543		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
544		break;
545	}
546
547	if (cycleCounter) {
548		*cycleCounter += 1 + wait;
549	}
550}
551
552static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count) {
553	struct GBA* gba = (struct GBA*) cpu->master;
554	struct GBAMemory* memory = &gba->memory;
555	int wait = 1 + memory->waitstatesNonseq32[startAddress >> BASE_OFFSET];
556	wait += (1 + memory->waitstatesSeq32[startAddress >> BASE_OFFSET]) * (count - 1);
557	return wait;
558}
559
560void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
561	struct GBAMemory* memory = &gba->memory;
562	struct ARMCore* cpu = gba->cpu;
563	int sram = parameters & 0x0003;
564	int ws0 = (parameters & 0x000C) >> 2;
565	int ws0seq = (parameters & 0x0010) >> 4;
566	int ws1 = (parameters & 0x0060) >> 5;
567	int ws1seq = (parameters & 0x0080) >> 7;
568	int ws2 = (parameters & 0x0300) >> 8;
569	int ws2seq = (parameters & 0x0400) >> 10;
570	int prefetch = parameters & 0x4000;
571
572	memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] =  GBA_ROM_WAITSTATES[sram];
573	memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
574	memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
575	memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
576
577	memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
578	memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
579	memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
580
581	memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
582	memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
583	memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
584
585	memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
586	memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
587	memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
588
589	memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
590	memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
591	memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
592
593	if (!prefetch) {
594		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0];
595		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1];
596		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2];
597
598		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = memory->waitstatesSeq32[REGION_CART0];
599		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = memory->waitstatesSeq32[REGION_CART1];
600		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = memory->waitstatesSeq32[REGION_CART2];
601
602		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0];
603		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1];
604		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2];
605
606		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq32[REGION_CART0];
607		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq32[REGION_CART1];
608		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq32[REGION_CART2];
609	} else {
610		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = 0;
611		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = 0;
612		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = 0;
613
614		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = 0;
615		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = 0;
616		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = 0;
617
618		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = 0;
619		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = 0;
620		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = 0;
621
622		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = 0;
623		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = 0;
624		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = 0;
625	}
626
627	cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
628	cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
629
630	cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
631	cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
632
633	cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
634	cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
635}
636
637void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
638	struct GBAMemory* memory = &gba->memory;
639	memory->dma[dma].source = address & 0xFFFFFFFE;
640}
641
642void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
643	struct GBAMemory* memory = &gba->memory;
644	memory->dma[dma].dest = address & 0xFFFFFFFE;
645}
646
647void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
648	struct GBAMemory* memory = &gba->memory;
649	memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
650}
651
652uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
653	struct GBAMemory* memory = &gba->memory;
654	struct GBADMA* currentDma = &memory->dma[dma];
655	int wasEnabled = currentDma->enable;
656	currentDma->packed = control;
657
658	if (currentDma->drq) {
659		GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
660	}
661
662	if (!wasEnabled && currentDma->enable) {
663		currentDma->nextSource = currentDma->source;
664		currentDma->nextDest = currentDma->dest;
665		currentDma->nextCount = currentDma->count;
666		GBAMemoryScheduleDMA(gba, dma, currentDma);
667	}
668	// If the DMA has already occurred, this value might have changed since the function started
669	return currentDma->packed;
670};
671
672void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
673	struct ARMCore* cpu = gba->cpu;
674	switch (info->timing) {
675	case DMA_TIMING_NOW:
676		info->nextEvent = cpu->cycles;
677		GBAMemoryUpdateDMAs(gba, 0);
678		break;
679	case DMA_TIMING_HBLANK:
680		// Handled implicitly
681		info->nextEvent = INT_MAX;
682		break;
683	case DMA_TIMING_VBLANK:
684		// Handled implicitly
685		info->nextEvent = INT_MAX;
686		break;
687	case DMA_TIMING_CUSTOM:
688		info->nextEvent = INT_MAX;
689		switch (number) {
690		case 0:
691			GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
692			break;
693		case 1:
694		case 2:
695			GBAAudioScheduleFifoDma(&gba->audio, number, info);
696			break;
697		case 3:
698			// GBAVideoScheduleVCaptureDma(dma, info);
699			break;
700		}
701	}
702}
703
704void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
705	struct GBAMemory* memory = &gba->memory;
706	struct GBADMA* dma;
707	int i;
708	for (i = 0; i < 4; ++i) {
709		dma = &memory->dma[i];
710		if (dma->enable && dma->timing == DMA_TIMING_HBLANK) {
711			dma->nextEvent = cycles;
712		}
713	}
714	GBAMemoryUpdateDMAs(gba, 0);
715}
716
717void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
718	struct GBAMemory* memory = &gba->memory;
719	struct GBADMA* dma;
720	int i;
721	for (i = 0; i < 4; ++i) {
722		dma = &memory->dma[i];
723		if (dma->enable && dma->timing == DMA_TIMING_VBLANK) {
724			dma->nextEvent = cycles;
725		}
726	}
727	GBAMemoryUpdateDMAs(gba, 0);
728}
729
730int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
731	struct GBAMemory* memory = &gba->memory;
732	if (memory->nextDMA == INT_MAX) {
733		return INT_MAX;
734	}
735	memory->nextDMA -= cycles;
736	memory->eventDiff += cycles;
737	if (memory->nextDMA <= 0) {
738		struct GBADMA* dma = &memory->dma[memory->activeDMA];
739		GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
740		GBAMemoryUpdateDMAs(gba, memory->eventDiff);
741		memory->eventDiff = 0;
742	}
743	return memory->nextDMA;
744}
745
746void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
747	int i;
748	struct GBAMemory* memory = &gba->memory;
749	struct ARMCore* cpu = gba->cpu;
750	memory->activeDMA = -1;
751	memory->nextDMA = INT_MAX;
752	for (i = 3; i >= 0; --i) {
753		struct GBADMA* dma = &memory->dma[i];
754		if (dma->nextEvent != INT_MAX) {
755			dma->nextEvent -= cycles;
756			if (dma->enable) {
757				memory->activeDMA = i;
758				memory->nextDMA = dma->nextEvent;
759			}
760		}
761	}
762	if (memory->nextDMA < cpu->nextEvent) {
763		cpu->nextEvent = memory->nextDMA;
764	}
765}
766
767void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
768	struct GBAMemory* memory = &gba->memory;
769	struct ARMCore* cpu = gba->cpu;
770	uint32_t width = info->width ? 4 : 2;
771	int sourceOffset = DMA_OFFSET[info->srcControl] * width;
772	int destOffset = DMA_OFFSET[info->dstControl] * width;
773	int32_t wordsRemaining = info->nextCount;
774	uint32_t source = info->nextSource;
775	uint32_t dest = info->nextDest;
776	uint32_t sourceRegion = source >> BASE_OFFSET;
777	uint32_t destRegion = dest >> BASE_OFFSET;
778	int32_t cycles = 0;
779
780	if (source == info->source) {
781		// TODO: support 4 cycles for ROM access
782		cycles += 2;
783		if (width == 4) {
784			cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
785			source &= 0xFFFFFFFC;
786			dest &= 0xFFFFFFFC;
787		} else {
788			cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
789		}
790	} else {
791		if (width == 4) {
792			cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
793		} else {
794			cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
795		}
796	}
797
798	if (width == 4) {
799		int32_t word;
800		word = cpu->memory.load32(cpu, source, 0);
801		cpu->memory.store32(cpu, dest, word, 0);
802		source += sourceOffset;
803		dest += destOffset;
804		--wordsRemaining;
805	} else {
806		uint16_t word;
807		if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
808			word = GBASavedataReadEEPROM(&memory->savedata);
809			cpu->memory.store16(cpu, dest, word, 0);
810			source += sourceOffset;
811			dest += destOffset;
812			--wordsRemaining;
813		} else if (destRegion == REGION_CART2_EX) {
814			if (memory->savedata.type == SAVEDATA_NONE) {
815				GBASavedataInitEEPROM(&memory->savedata);
816			}
817			word = cpu->memory.load16(cpu, source, 0);
818			GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
819			source += sourceOffset;
820			dest += destOffset;
821			--wordsRemaining;
822		} else {
823			word = cpu->memory.load16(cpu, source, 0);
824			cpu->memory.store16(cpu, dest, word, 0);
825			source += sourceOffset;
826			dest += destOffset;
827			--wordsRemaining;
828		}
829	}
830
831	if (!wordsRemaining) {
832		if (!info->repeat) {
833			info->enable = 0;
834			info->nextEvent = INT_MAX;
835
836			// Clear the enable bit in memory
837			memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
838		} else {
839			info->nextCount = info->count;
840			if (info->dstControl == DMA_INCREMENT_RELOAD) {
841				info->nextDest = info->dest;
842			}
843			GBAMemoryScheduleDMA(gba, number, info);
844		}
845		if (info->doIrq) {
846			GBARaiseIRQ(gba, IRQ_DMA0 + number);
847		}
848	} else {
849		info->nextDest = dest;
850		info->nextCount = wordsRemaining;
851	}
852	info->nextSource = source;
853
854	int i;
855	for (i = 0; i < 4; ++i) {
856		if (memory->dma[i].nextEvent != INT_MAX) {
857			memory->dma[i].nextEvent += cycles;
858		}
859	}
860	cpu->cycles += cycles;
861}
862
863void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state) {
864	memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
865	memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
866}
867
868void GBAMemoryDeserialize(struct GBAMemory* memory, struct GBASerializedState* state) {
869	memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
870	memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
871}