all repos — mgba @ 03b5e2d78eb58a1aac3fccd4bd0e6fff5d13bc59

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