all repos — mgba @ b11528c69df86c3be49ac4715495d38b1309b53e

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			GBASavedataInitSRAM(&memory->savedata);
369		}
370		if (memory->savedata.type == SAVEDATA_SRAM) {
371			value = memory->savedata.data[address & (SIZE_CART_SRAM - 1)];
372		} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
373			value = GBASavedataReadFlash(&memory->savedata, address);
374		}
375		break;
376	default:
377		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
378		value = cpu->prefetch & 0xFF;
379		break;
380	}
381
382	if (cycleCounter) {
383		*cycleCounter += 2 + wait;
384	}
385	return value;
386}
387
388void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
389	struct GBA* gba = (struct GBA*) cpu->master;
390	struct GBAMemory* memory = &gba->memory;
391	int wait = 0;
392
393	switch (address >> BASE_OFFSET) {
394	case REGION_WORKING_RAM:
395		STORE_32(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
396		wait = memory->waitstatesNonseq32[REGION_WORKING_RAM];
397		break;
398	case REGION_WORKING_IRAM:
399		STORE_32(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
400		break;
401	case REGION_IO:
402		GBAIOWrite32(gba, address & (SIZE_IO - 1), value);
403		break;
404	case REGION_PALETTE_RAM:
405		STORE_32(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
406		gba->video.renderer->writePalette(gba->video.renderer, (address & (SIZE_PALETTE_RAM - 1)) + 2, value >> 16);
407		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
408		break;
409	case REGION_VRAM:
410		if ((address & OFFSET_MASK) < SIZE_VRAM) {
411			STORE_32(value, address & 0x0001FFFF, gba->video.renderer->vram);
412		} else if ((address & OFFSET_MASK) < 0x00020000) {
413			STORE_32(value, address & 0x00017FFF, gba->video.renderer->vram);
414		}
415		break;
416	case REGION_OAM:
417		STORE_32(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
418		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 4)) >> 1);
419		gba->video.renderer->writeOAM(gba->video.renderer, ((address & (SIZE_OAM - 4)) >> 1) + 1);
420		break;
421	case REGION_CART0:
422		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
423		break;
424	case REGION_CART_SRAM:
425	case REGION_CART_SRAM_MIRROR:
426		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store32: 0x%08X", address);
427		break;
428	default:
429		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store32: 0x%08X", address);
430		break;
431	}
432
433	if (cycleCounter) {
434		*cycleCounter += 1 + wait;
435	}
436}
437
438void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
439	struct GBA* gba = (struct GBA*) cpu->master;
440	struct GBAMemory* memory = &gba->memory;
441	int wait = 0;
442
443	switch (address >> BASE_OFFSET) {
444	case REGION_WORKING_RAM:
445		STORE_16(value, address & (SIZE_WORKING_RAM - 1), memory->wram);
446		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
447		break;
448	case REGION_WORKING_IRAM:
449		STORE_16(value, address & (SIZE_WORKING_IRAM - 1), memory->iwram);
450		break;
451	case REGION_IO:
452		GBAIOWrite(gba, address & (SIZE_IO - 1), value);
453		break;
454	case REGION_PALETTE_RAM:
455		STORE_16(value, address & (SIZE_PALETTE_RAM - 1), gba->video.palette);
456		gba->video.renderer->writePalette(gba->video.renderer, address & (SIZE_PALETTE_RAM - 1), value);
457		break;
458	case REGION_VRAM:
459		if ((address & OFFSET_MASK) < SIZE_VRAM) {
460			STORE_16(value, address & 0x0001FFFF, gba->video.renderer->vram);
461		} else if ((address & OFFSET_MASK) < 0x00020000) {
462			STORE_16(value, address & 0x00017FFF, gba->video.renderer->vram);
463		}
464		break;
465	case REGION_OAM:
466		STORE_16(value, address & (SIZE_OAM - 1), gba->video.oam.raw);
467		gba->video.renderer->writeOAM(gba->video.renderer, (address & (SIZE_OAM - 1)) >> 1);
468		break;
469	case REGION_CART0:
470		if (IS_GPIO_REGISTER(address & 0xFFFFFF)) {
471			uint32_t reg = address & 0xFFFFFF;
472			GBAGPIOWrite(&memory->gpio, reg, value);
473		} else {
474			GBALog(gba, GBA_LOG_GAME_ERROR, "Bad cartridge Store16: 0x%08X", address);
475		}
476		break;
477	case REGION_CART2_EX:
478		if (memory->savedata.type == SAVEDATA_NONE) {
479			GBASavedataInitEEPROM(&memory->savedata);
480		}
481		GBASavedataWriteEEPROM(&memory->savedata, value, 1);
482		break;
483	case REGION_CART_SRAM:
484	case REGION_CART_SRAM_MIRROR:
485		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store16: 0x%08X", address);
486		break;
487	default:
488		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store16: 0x%08X", address);
489		break;
490	}
491
492	if (cycleCounter) {
493		*cycleCounter += 1 + wait;
494	}
495}
496
497void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
498	struct GBA* gba = (struct GBA*) cpu->master;
499	struct GBAMemory* memory = &gba->memory;
500	int wait = 0;
501
502	switch (address >> BASE_OFFSET) {
503	case REGION_WORKING_RAM:
504		((int8_t*) memory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
505		wait = memory->waitstatesNonseq16[REGION_WORKING_RAM];
506		break;
507	case REGION_WORKING_IRAM:
508		((int8_t*) memory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
509		break;
510	case REGION_IO:
511		GBAIOWrite8(gba, address & (SIZE_IO - 1), value);
512		break;
513	case REGION_PALETTE_RAM:
514		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
515		break;
516	case REGION_VRAM:
517		if (address >= 0x06018000) {
518			// TODO: check BG mode
519			GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address);
520			break;
521		}
522		((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value;
523		((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value;
524		break;
525	case REGION_OAM:
526		GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address);
527		break;
528	case REGION_CART0:
529		GBALog(gba, GBA_LOG_STUB, "Unimplemented memory Store8: 0x%08X", address);
530		break;
531	case REGION_CART_SRAM:
532	case REGION_CART_SRAM_MIRROR:
533		if (memory->savedata.type == SAVEDATA_NONE) {
534			if (address == SAVEDATA_FLASH_BASE) {
535				GBASavedataInitFlash(&memory->savedata);
536			} else {
537				GBASavedataInitSRAM(&memory->savedata);
538			}
539		}
540		if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
541			GBASavedataWriteFlash(&memory->savedata, address, value);
542		} else if (memory->savedata.type == SAVEDATA_SRAM) {
543			memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
544		}
545		wait = memory->waitstatesNonseq16[REGION_CART_SRAM];
546		break;
547	default:
548		GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Store8: 0x%08X", address);
549		break;
550	}
551
552	if (cycleCounter) {
553		*cycleCounter += 1 + wait;
554	}
555}
556
557static int GBAWaitMultiple(struct ARMCore* cpu, uint32_t startAddress, int count) {
558	struct GBA* gba = (struct GBA*) cpu->master;
559	struct GBAMemory* memory = &gba->memory;
560	int wait = 1 + memory->waitstatesNonseq32[startAddress >> BASE_OFFSET];
561	wait += (1 + memory->waitstatesSeq32[startAddress >> BASE_OFFSET]) * (count - 1);
562	return wait;
563}
564
565void GBAAdjustWaitstates(struct GBA* gba, uint16_t parameters) {
566	struct GBAMemory* memory = &gba->memory;
567	struct ARMCore* cpu = gba->cpu;
568	int sram = parameters & 0x0003;
569	int ws0 = (parameters & 0x000C) >> 2;
570	int ws0seq = (parameters & 0x0010) >> 4;
571	int ws1 = (parameters & 0x0060) >> 5;
572	int ws1seq = (parameters & 0x0080) >> 7;
573	int ws2 = (parameters & 0x0300) >> 8;
574	int ws2seq = (parameters & 0x0400) >> 10;
575	int prefetch = parameters & 0x4000;
576
577	memory->waitstatesNonseq16[REGION_CART_SRAM] = memory->waitstatesNonseq16[REGION_CART_SRAM_MIRROR] =  GBA_ROM_WAITSTATES[sram];
578	memory->waitstatesSeq16[REGION_CART_SRAM] = memory->waitstatesSeq16[REGION_CART_SRAM_MIRROR] = GBA_ROM_WAITSTATES[sram];
579	memory->waitstatesNonseq32[REGION_CART_SRAM] = memory->waitstatesNonseq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
580	memory->waitstatesSeq32[REGION_CART_SRAM] = memory->waitstatesSeq32[REGION_CART_SRAM_MIRROR] = 2 * GBA_ROM_WAITSTATES[sram] + 1;
581
582	memory->waitstatesNonseq16[REGION_CART0] = memory->waitstatesNonseq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES[ws0];
583	memory->waitstatesNonseq16[REGION_CART1] = memory->waitstatesNonseq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES[ws1];
584	memory->waitstatesNonseq16[REGION_CART2] = memory->waitstatesNonseq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES[ws2];
585
586	memory->waitstatesSeq16[REGION_CART0] = memory->waitstatesSeq16[REGION_CART0_EX] = GBA_ROM_WAITSTATES_SEQ[ws0seq];
587	memory->waitstatesSeq16[REGION_CART1] = memory->waitstatesSeq16[REGION_CART1_EX] = GBA_ROM_WAITSTATES_SEQ[ws1seq + 2];
588	memory->waitstatesSeq16[REGION_CART2] = memory->waitstatesSeq16[REGION_CART2_EX] = GBA_ROM_WAITSTATES_SEQ[ws2seq + 4];
589
590	memory->waitstatesNonseq32[REGION_CART0] = memory->waitstatesNonseq32[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0] + 1 + memory->waitstatesSeq16[REGION_CART0];
591	memory->waitstatesNonseq32[REGION_CART1] = memory->waitstatesNonseq32[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1] + 1 + memory->waitstatesSeq16[REGION_CART1];
592	memory->waitstatesNonseq32[REGION_CART2] = memory->waitstatesNonseq32[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2] + 1 + memory->waitstatesSeq16[REGION_CART2];
593
594	memory->waitstatesSeq32[REGION_CART0] = memory->waitstatesSeq32[REGION_CART0_EX] = 2 * memory->waitstatesSeq16[REGION_CART0] + 1;
595	memory->waitstatesSeq32[REGION_CART1] = memory->waitstatesSeq32[REGION_CART1_EX] = 2 * memory->waitstatesSeq16[REGION_CART1] + 1;
596	memory->waitstatesSeq32[REGION_CART2] = memory->waitstatesSeq32[REGION_CART2_EX] = 2 * memory->waitstatesSeq16[REGION_CART2] + 1;
597
598	if (!prefetch) {
599		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = memory->waitstatesSeq16[REGION_CART0];
600		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = memory->waitstatesSeq16[REGION_CART1];
601		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = memory->waitstatesSeq16[REGION_CART2];
602
603		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = memory->waitstatesSeq32[REGION_CART0];
604		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = memory->waitstatesSeq32[REGION_CART1];
605		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = memory->waitstatesSeq32[REGION_CART2];
606
607		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = memory->waitstatesNonseq16[REGION_CART0];
608		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = memory->waitstatesNonseq16[REGION_CART1];
609		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = memory->waitstatesNonseq16[REGION_CART2];
610
611		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = memory->waitstatesNonseq32[REGION_CART0];
612		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = memory->waitstatesNonseq32[REGION_CART1];
613		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = memory->waitstatesNonseq32[REGION_CART2];
614	} else {
615		memory->waitstatesPrefetchSeq16[REGION_CART0] = memory->waitstatesPrefetchSeq16[REGION_CART0_EX] = 0;
616		memory->waitstatesPrefetchSeq16[REGION_CART1] = memory->waitstatesPrefetchSeq16[REGION_CART1_EX] = 0;
617		memory->waitstatesPrefetchSeq16[REGION_CART2] = memory->waitstatesPrefetchSeq16[REGION_CART2_EX] = 0;
618
619		memory->waitstatesPrefetchSeq32[REGION_CART0] = memory->waitstatesPrefetchSeq32[REGION_CART0_EX] = 0;
620		memory->waitstatesPrefetchSeq32[REGION_CART1] = memory->waitstatesPrefetchSeq32[REGION_CART1_EX] = 0;
621		memory->waitstatesPrefetchSeq32[REGION_CART2] = memory->waitstatesPrefetchSeq32[REGION_CART2_EX] = 0;
622
623		memory->waitstatesPrefetchNonseq16[REGION_CART0] = memory->waitstatesPrefetchNonseq16[REGION_CART0_EX] = 0;
624		memory->waitstatesPrefetchNonseq16[REGION_CART1] = memory->waitstatesPrefetchNonseq16[REGION_CART1_EX] = 0;
625		memory->waitstatesPrefetchNonseq16[REGION_CART2] = memory->waitstatesPrefetchNonseq16[REGION_CART2_EX] = 0;
626
627		memory->waitstatesPrefetchNonseq32[REGION_CART0] = memory->waitstatesPrefetchNonseq32[REGION_CART0_EX] = 0;
628		memory->waitstatesPrefetchNonseq32[REGION_CART1] = memory->waitstatesPrefetchNonseq32[REGION_CART1_EX] = 0;
629		memory->waitstatesPrefetchNonseq32[REGION_CART2] = memory->waitstatesPrefetchNonseq32[REGION_CART2_EX] = 0;
630	}
631
632	cpu->memory.activeSeqCycles32 = memory->waitstatesPrefetchSeq32[memory->activeRegion];
633	cpu->memory.activeSeqCycles16 = memory->waitstatesPrefetchSeq16[memory->activeRegion];
634
635	cpu->memory.activeNonseqCycles32 = memory->waitstatesPrefetchNonseq32[memory->activeRegion];
636	cpu->memory.activeNonseqCycles16 = memory->waitstatesPrefetchNonseq16[memory->activeRegion];
637
638	cpu->memory.activeUncachedCycles32 = memory->waitstatesNonseq32[memory->activeRegion];
639	cpu->memory.activeUncachedCycles16 = memory->waitstatesNonseq16[memory->activeRegion];
640}
641
642void GBAMemoryWriteDMASAD(struct GBA* gba, int dma, uint32_t address) {
643	struct GBAMemory* memory = &gba->memory;
644	memory->dma[dma].source = address & 0xFFFFFFFE;
645}
646
647void GBAMemoryWriteDMADAD(struct GBA* gba, int dma, uint32_t address) {
648	struct GBAMemory* memory = &gba->memory;
649	memory->dma[dma].dest = address & 0xFFFFFFFE;
650}
651
652void GBAMemoryWriteDMACNT_LO(struct GBA* gba, int dma, uint16_t count) {
653	struct GBAMemory* memory = &gba->memory;
654	memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
655}
656
657uint16_t GBAMemoryWriteDMACNT_HI(struct GBA* gba, int dma, uint16_t control) {
658	struct GBAMemory* memory = &gba->memory;
659	struct GBADMA* currentDma = &memory->dma[dma];
660	int wasEnabled = GBADMARegisterIsEnable(currentDma->reg);
661	currentDma->reg = control;
662
663	if (GBADMARegisterIsDRQ(currentDma->reg)) {
664		GBALog(gba, GBA_LOG_STUB, "DRQ not implemented");
665	}
666
667	if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) {
668		currentDma->nextSource = currentDma->source;
669		currentDma->nextDest = currentDma->dest;
670		currentDma->nextCount = currentDma->count;
671		GBAMemoryScheduleDMA(gba, dma, currentDma);
672	}
673	// If the DMA has already occurred, this value might have changed since the function started
674	return currentDma->reg;
675};
676
677void GBAMemoryScheduleDMA(struct GBA* gba, int number, struct GBADMA* info) {
678	struct ARMCore* cpu = gba->cpu;
679	switch (GBADMARegisterGetTiming(info->reg)) {
680	case DMA_TIMING_NOW:
681		info->nextEvent = cpu->cycles;
682		GBAMemoryUpdateDMAs(gba, 0);
683		break;
684	case DMA_TIMING_HBLANK:
685		// Handled implicitly
686		info->nextEvent = INT_MAX;
687		break;
688	case DMA_TIMING_VBLANK:
689		// Handled implicitly
690		info->nextEvent = INT_MAX;
691		break;
692	case DMA_TIMING_CUSTOM:
693		info->nextEvent = INT_MAX;
694		switch (number) {
695		case 0:
696			GBALog(gba, GBA_LOG_WARN, "Discarding invalid DMA0 scheduling");
697			break;
698		case 1:
699		case 2:
700			GBAAudioScheduleFifoDma(&gba->audio, number, info);
701			break;
702		case 3:
703			// GBAVideoScheduleVCaptureDma(dma, info);
704			break;
705		}
706	}
707}
708
709void GBAMemoryRunHblankDMAs(struct GBA* gba, int32_t cycles) {
710	struct GBAMemory* memory = &gba->memory;
711	struct GBADMA* dma;
712	int i;
713	for (i = 0; i < 4; ++i) {
714		dma = &memory->dma[i];
715		if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_HBLANK) {
716			dma->nextEvent = cycles;
717		}
718	}
719	GBAMemoryUpdateDMAs(gba, 0);
720}
721
722void GBAMemoryRunVblankDMAs(struct GBA* gba, int32_t cycles) {
723	struct GBAMemory* memory = &gba->memory;
724	struct GBADMA* dma;
725	int i;
726	for (i = 0; i < 4; ++i) {
727		dma = &memory->dma[i];
728		if (GBADMARegisterIsEnable(dma->reg) && GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_VBLANK) {
729			dma->nextEvent = cycles;
730		}
731	}
732	GBAMemoryUpdateDMAs(gba, 0);
733}
734
735int32_t GBAMemoryRunDMAs(struct GBA* gba, int32_t cycles) {
736	struct GBAMemory* memory = &gba->memory;
737	if (memory->nextDMA == INT_MAX) {
738		return INT_MAX;
739	}
740	memory->nextDMA -= cycles;
741	memory->eventDiff += cycles;
742	if (memory->nextDMA <= 0) {
743		struct GBADMA* dma = &memory->dma[memory->activeDMA];
744		GBAMemoryServiceDMA(gba, memory->activeDMA, dma);
745		GBAMemoryUpdateDMAs(gba, memory->eventDiff);
746		memory->eventDiff = 0;
747	}
748	return memory->nextDMA;
749}
750
751void GBAMemoryUpdateDMAs(struct GBA* gba, int32_t cycles) {
752	int i;
753	struct GBAMemory* memory = &gba->memory;
754	struct ARMCore* cpu = gba->cpu;
755	memory->activeDMA = -1;
756	memory->nextDMA = INT_MAX;
757	for (i = 3; i >= 0; --i) {
758		struct GBADMA* dma = &memory->dma[i];
759		if (dma->nextEvent != INT_MAX) {
760			dma->nextEvent -= cycles;
761			if (GBADMARegisterIsEnable(dma->reg)) {
762				memory->activeDMA = i;
763				memory->nextDMA = dma->nextEvent;
764			}
765		}
766	}
767	if (memory->nextDMA < cpu->nextEvent) {
768		cpu->nextEvent = memory->nextDMA;
769	}
770}
771
772void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
773	struct GBAMemory* memory = &gba->memory;
774	struct ARMCore* cpu = gba->cpu;
775	uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2;
776	int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width;
777	int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width;
778	int32_t wordsRemaining = info->nextCount;
779	uint32_t source = info->nextSource;
780	uint32_t dest = info->nextDest;
781	uint32_t sourceRegion = source >> BASE_OFFSET;
782	uint32_t destRegion = dest >> BASE_OFFSET;
783	int32_t cycles = 0;
784
785	if (source == info->source) {
786		// TODO: support 4 cycles for ROM access
787		cycles += 2;
788		if (width == 4) {
789			cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion];
790			source &= 0xFFFFFFFC;
791			dest &= 0xFFFFFFFC;
792		} else {
793			cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion];
794		}
795	} else {
796		if (width == 4) {
797			cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];
798		} else {
799			cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
800		}
801	}
802
803	if (width == 4) {
804		int32_t word;
805		word = cpu->memory.load32(cpu, source, 0);
806		cpu->memory.store32(cpu, dest, word, 0);
807		source += sourceOffset;
808		dest += destOffset;
809		--wordsRemaining;
810	} else {
811		uint16_t word;
812		if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) {
813			word = GBASavedataReadEEPROM(&memory->savedata);
814			cpu->memory.store16(cpu, dest, word, 0);
815			source += sourceOffset;
816			dest += destOffset;
817			--wordsRemaining;
818		} else if (destRegion == REGION_CART2_EX) {
819			if (memory->savedata.type == SAVEDATA_NONE) {
820				GBASavedataInitEEPROM(&memory->savedata);
821			}
822			word = cpu->memory.load16(cpu, source, 0);
823			GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining);
824			source += sourceOffset;
825			dest += destOffset;
826			--wordsRemaining;
827		} else {
828			word = cpu->memory.load16(cpu, source, 0);
829			cpu->memory.store16(cpu, dest, word, 0);
830			source += sourceOffset;
831			dest += destOffset;
832			--wordsRemaining;
833		}
834	}
835
836	if (!wordsRemaining) {
837		if (!GBADMARegisterIsRepeat(info->reg)) {
838			info->reg = GBADMARegisterClearEnable(info->reg);
839			info->nextEvent = INT_MAX;
840
841			// Clear the enable bit in memory
842			memory->io[(REG_DMA0CNT_HI + number * (REG_DMA1CNT_HI - REG_DMA0CNT_HI)) >> 1] &= 0x7FE0;
843		} else {
844			info->nextCount = info->count;
845			if (GBADMARegisterGetDestControl(info->reg) == DMA_INCREMENT_RELOAD) {
846				info->nextDest = info->dest;
847			}
848			GBAMemoryScheduleDMA(gba, number, info);
849		}
850		if (GBADMARegisterIsDoIRQ(info->reg)) {
851			GBARaiseIRQ(gba, IRQ_DMA0 + number);
852		}
853	} else {
854		info->nextDest = dest;
855		info->nextCount = wordsRemaining;
856	}
857	info->nextSource = source;
858
859	if (info->nextEvent != INT_MAX) {
860		info->nextEvent += cycles;
861	}
862	cpu->cycles += cycles;
863}
864
865void GBAMemorySerialize(struct GBAMemory* memory, struct GBASerializedState* state) {
866	memcpy(state->wram, memory->wram, SIZE_WORKING_RAM);
867	memcpy(state->iwram, memory->iwram, SIZE_WORKING_IRAM);
868}
869
870void GBAMemoryDeserialize(struct GBAMemory* memory, struct GBASerializedState* state) {
871	memcpy(memory->wram, state->wram, SIZE_WORKING_RAM);
872	memcpy(memory->iwram, state->iwram, SIZE_WORKING_IRAM);
873}