all repos — mgba @ d5da0ff31b21574291b3fcf716d3015e96e5cfda

mGBA Game Boy Advance Emulator

src/gba/gba.c (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "gba.h"
  7
  8#include "arm/decoder.h"
  9#include "arm/isa-inlines.h"
 10
 11#include "gba/bios.h"
 12#include "gba/cheats.h"
 13#include "gba/io.h"
 14#include "gba/rr/rr.h"
 15#include "gba/supervisor/thread.h"
 16#include "gba/serialize.h"
 17#include "gba/sio.h"
 18
 19#include "util/crc32.h"
 20#include "util/memory.h"
 21#include "util/math.h"
 22#include "util/patch.h"
 23#include "util/vfs.h"
 24
 25const uint32_t GBA_ARM7TDMI_FREQUENCY = 0x1000000;
 26const uint32_t GBA_COMPONENT_MAGIC = 0x1000000;
 27
 28static const size_t GBA_ROM_MAGIC_OFFSET = 3;
 29static const uint8_t GBA_ROM_MAGIC[] = { 0xEA };
 30
 31static const size_t GBA_MB_MAGIC_OFFSET = 0xC0;
 32
 33static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component);
 34static void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh);
 35static void GBAProcessEvents(struct ARMCore* cpu);
 36static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles);
 37static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode);
 38static void GBAIllegal(struct ARMCore* cpu, uint32_t opcode);
 39static void GBABreakpoint(struct ARMCore* cpu, int immediate);
 40
 41static bool _setSoftwareBreakpoint(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode);
 42static bool _clearSoftwareBreakpoint(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t opcode);
 43
 44
 45#ifdef _3DS
 46extern uint32_t* romBuffer;
 47extern size_t romBufferSize;
 48#endif
 49
 50void GBACreate(struct GBA* gba) {
 51	gba->d.id = GBA_COMPONENT_MAGIC;
 52	gba->d.init = GBAInit;
 53	gba->d.deinit = 0;
 54}
 55
 56static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
 57	struct GBA* gba = (struct GBA*) component;
 58	gba->cpu = cpu;
 59	gba->debugger = 0;
 60	gba->sync = 0;
 61
 62	GBAInterruptHandlerInit(&cpu->irqh);
 63	GBAMemoryInit(gba);
 64	GBASavedataInit(&gba->memory.savedata, 0);
 65
 66	gba->video.p = gba;
 67	GBAVideoInit(&gba->video);
 68
 69	gba->audio.p = gba;
 70	GBAAudioInit(&gba->audio, GBA_AUDIO_SAMPLES);
 71
 72	GBAIOInit(gba);
 73
 74	gba->sio.p = gba;
 75	GBASIOInit(&gba->sio);
 76
 77	gba->timersEnabled = 0;
 78	memset(gba->timers, 0, sizeof(gba->timers));
 79
 80	gba->springIRQ = 0;
 81	gba->keySource = 0;
 82	gba->rotationSource = 0;
 83	gba->luminanceSource = 0;
 84	gba->rtcSource = 0;
 85	gba->rumble = 0;
 86	gba->rr = 0;
 87
 88	gba->romVf = 0;
 89	gba->biosVf = 0;
 90
 91	gba->logHandler = 0;
 92	gba->logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL;
 93	gba->stream = 0;
 94	gba->keyCallback = 0;
 95	gba->stopCallback = 0;
 96
 97	gba->biosChecksum = GBAChecksum(gba->memory.bios, SIZE_BIOS);
 98
 99	gba->idleOptimization = IDLE_LOOP_REMOVE;
100	gba->idleLoop = IDLE_LOOP_NONE;
101
102	gba->realisticTiming = true;
103	gba->hardCrash = true;
104
105	gba->performingDMA = false;
106
107	gba->pristineRom = 0;
108	gba->pristineRomSize = 0;
109	gba->yankedRomSize = 0;
110}
111
112void GBAUnloadROM(struct GBA* gba) {
113	if (gba->memory.rom && gba->pristineRom != gba->memory.rom) {
114		if (gba->yankedRomSize) {
115			gba->yankedRomSize = 0;
116		}
117		mappedMemoryFree(gba->memory.rom, SIZE_CART0);
118	}
119	gba->memory.rom = 0;
120
121	if (gba->romVf) {
122#ifndef _3DS
123		gba->romVf->unmap(gba->romVf, gba->pristineRom, gba->pristineRomSize);
124#endif
125		gba->pristineRom = 0;
126		gba->romVf = 0;
127	}
128
129	GBASavedataDeinit(&gba->memory.savedata);
130	gba->idleLoop = IDLE_LOOP_NONE;
131}
132
133void GBADestroy(struct GBA* gba) {
134	GBAUnloadROM(gba);
135
136	if (gba->biosVf) {
137		gba->biosVf->unmap(gba->biosVf, gba->memory.bios, SIZE_BIOS);
138	}
139
140	GBAMemoryDeinit(gba);
141	GBAVideoDeinit(&gba->video);
142	GBAAudioDeinit(&gba->audio);
143	GBASIODeinit(&gba->sio);
144	gba->rr = 0;
145}
146
147void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) {
148	irqh->reset = GBAReset;
149	irqh->processEvents = GBAProcessEvents;
150	irqh->swi16 = GBASwi16;
151	irqh->swi32 = GBASwi32;
152	irqh->hitIllegal = GBAIllegal;
153	irqh->readCPSR = GBATestIRQ;
154	irqh->hitStub = GBAHitStub;
155	irqh->bkpt16 = GBABreakpoint;
156	irqh->bkpt32 = GBABreakpoint;
157}
158
159void GBAReset(struct ARMCore* cpu) {
160	ARMSetPrivilegeMode(cpu, MODE_IRQ);
161	cpu->gprs[ARM_SP] = SP_BASE_IRQ;
162	ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
163	cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR;
164	ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
165	cpu->gprs[ARM_SP] = SP_BASE_SYSTEM;
166
167	struct GBA* gba = (struct GBA*) cpu->master;
168	if (!gba->rr || (!gba->rr->isPlaying(gba->rr) && !gba->rr->isRecording(gba->rr))) {
169		GBASavedataUnmask(&gba->memory.savedata);
170	}
171
172	if (gba->yankedRomSize) {
173		gba->memory.romSize = gba->yankedRomSize;
174		gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
175		gba->yankedRomSize = 0;
176	}
177	GBAMemoryReset(gba);
178	GBAVideoReset(&gba->video);
179	GBAAudioReset(&gba->audio);
180	GBAIOInit(gba);
181
182	GBASIOReset(&gba->sio);
183
184	gba->timersEnabled = 0;
185	memset(gba->timers, 0, sizeof(gba->timers));
186
187	gba->lastJump = 0;
188	gba->haltPending = false;
189	gba->idleDetectionStep = 0;
190	gba->idleDetectionFailures = 0;
191}
192
193void GBASkipBIOS(struct GBA* gba) {
194	struct ARMCore* cpu = gba->cpu;
195	if (cpu->gprs[ARM_PC] == BASE_RESET + WORD_SIZE_ARM) {
196		if (gba->memory.rom) {
197			cpu->gprs[ARM_PC] = BASE_CART0;
198		} else {
199			cpu->gprs[ARM_PC] = BASE_WORKING_RAM;
200		}
201		int currentCycles = 0;
202		ARM_WRITE_PC;
203	}
204}
205
206static void GBAProcessEvents(struct ARMCore* cpu) {
207	do {
208		struct GBA* gba = (struct GBA*) cpu->master;
209		int32_t cycles = cpu->nextEvent;
210		int32_t nextEvent = INT_MAX;
211		int32_t testEvent;
212#ifndef NDEBUG
213		if (cycles < 0) {
214			GBALog(gba, GBA_LOG_FATAL, "Negative cycles passed: %i", cycles);
215		}
216#endif
217
218		gba->bus = cpu->prefetch[1];
219		if (cpu->executionMode == MODE_THUMB) {
220			gba->bus |= cpu->prefetch[1] << 16;
221		}
222
223		if (gba->springIRQ) {
224			ARMRaiseIRQ(cpu);
225			gba->springIRQ = 0;
226		}
227
228		testEvent = GBAVideoProcessEvents(&gba->video, cycles);
229		if (testEvent < nextEvent) {
230			nextEvent = testEvent;
231		}
232
233		testEvent = GBAAudioProcessEvents(&gba->audio, cycles);
234		if (testEvent < nextEvent) {
235			nextEvent = testEvent;
236		}
237
238		testEvent = GBATimersProcessEvents(gba, cycles);
239		if (testEvent < nextEvent) {
240			nextEvent = testEvent;
241		}
242
243		testEvent = GBAMemoryRunDMAs(gba, cycles);
244		if (testEvent < nextEvent) {
245			nextEvent = testEvent;
246		}
247
248		testEvent = GBASIOProcessEvents(&gba->sio, cycles);
249		if (testEvent < nextEvent) {
250			nextEvent = testEvent;
251		}
252
253		cpu->cycles -= cycles;
254		cpu->nextEvent = nextEvent;
255
256		if (cpu->halted) {
257			cpu->cycles = cpu->nextEvent;
258		}
259	} while (cpu->cycles >= cpu->nextEvent);
260}
261
262static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles) {
263	int32_t nextEvent = INT_MAX;
264	if (gba->timersEnabled) {
265		struct GBATimer* timer;
266		struct GBATimer* nextTimer;
267
268		timer = &gba->timers[0];
269		if (GBATimerFlagsIsEnable(timer->flags)) {
270			timer->nextEvent -= cycles;
271			timer->lastEvent -= cycles;
272			while (timer->nextEvent <= 0) {
273				timer->lastEvent = timer->nextEvent;
274				timer->nextEvent += timer->overflowInterval;
275				gba->memory.io[REG_TM0CNT_LO >> 1] = timer->reload;
276				timer->oldReload = timer->reload;
277
278				if (GBATimerFlagsIsDoIrq(timer->flags)) {
279					GBARaiseIRQ(gba, IRQ_TIMER0);
280				}
281
282				if (gba->audio.enable) {
283					if ((gba->audio.chALeft || gba->audio.chARight) && gba->audio.chATimer == 0) {
284						GBAAudioSampleFIFO(&gba->audio, 0, timer->lastEvent);
285					}
286
287					if ((gba->audio.chBLeft || gba->audio.chBRight) && gba->audio.chBTimer == 0) {
288						GBAAudioSampleFIFO(&gba->audio, 1, timer->lastEvent);
289					}
290				}
291
292				nextTimer = &gba->timers[1];
293				if (GBATimerFlagsIsCountUp(nextTimer->flags)) {
294					++gba->memory.io[REG_TM1CNT_LO >> 1];
295					if (!gba->memory.io[REG_TM1CNT_LO >> 1]) {
296						nextTimer->nextEvent = 0;
297					}
298				}
299			}
300			nextEvent = timer->nextEvent;
301		}
302
303		timer = &gba->timers[1];
304		if (GBATimerFlagsIsEnable(timer->flags)) {
305			timer->nextEvent -= cycles;
306			timer->lastEvent -= cycles;
307			if (timer->nextEvent <= 0) {
308				timer->lastEvent = timer->nextEvent;
309				timer->nextEvent += timer->overflowInterval;
310				gba->memory.io[REG_TM1CNT_LO >> 1] = timer->reload;
311				timer->oldReload = timer->reload;
312
313				if (GBATimerFlagsIsDoIrq(timer->flags)) {
314					GBARaiseIRQ(gba, IRQ_TIMER1);
315				}
316
317				if (gba->audio.enable) {
318					if ((gba->audio.chALeft || gba->audio.chARight) && gba->audio.chATimer == 1) {
319						GBAAudioSampleFIFO(&gba->audio, 0, timer->lastEvent);
320					}
321
322					if ((gba->audio.chBLeft || gba->audio.chBRight) && gba->audio.chBTimer == 1) {
323						GBAAudioSampleFIFO(&gba->audio, 1, timer->lastEvent);
324					}
325				}
326
327				if (GBATimerFlagsIsCountUp(timer->flags)) {
328					timer->nextEvent = INT_MAX;
329				}
330
331				nextTimer = &gba->timers[2];
332				if (GBATimerFlagsIsCountUp(nextTimer->flags)) {
333					++gba->memory.io[REG_TM2CNT_LO >> 1];
334					if (!gba->memory.io[REG_TM2CNT_LO >> 1]) {
335						nextTimer->nextEvent = 0;
336					}
337				}
338			}
339			if (timer->nextEvent < nextEvent) {
340				nextEvent = timer->nextEvent;
341			}
342		}
343
344		timer = &gba->timers[2];
345		if (GBATimerFlagsIsEnable(timer->flags)) {
346			timer->nextEvent -= cycles;
347			timer->lastEvent -= cycles;
348			if (timer->nextEvent <= 0) {
349				timer->lastEvent = timer->nextEvent;
350				timer->nextEvent += timer->overflowInterval;
351				gba->memory.io[REG_TM2CNT_LO >> 1] = timer->reload;
352				timer->oldReload = timer->reload;
353
354				if (GBATimerFlagsIsDoIrq(timer->flags)) {
355					GBARaiseIRQ(gba, IRQ_TIMER2);
356				}
357
358				if (GBATimerFlagsIsCountUp(timer->flags)) {
359					timer->nextEvent = INT_MAX;
360				}
361
362				nextTimer = &gba->timers[3];
363				if (GBATimerFlagsIsCountUp(nextTimer->flags)) {
364					++gba->memory.io[REG_TM3CNT_LO >> 1];
365					if (!gba->memory.io[REG_TM3CNT_LO >> 1]) {
366						nextTimer->nextEvent = 0;
367					}
368				}
369			}
370			if (timer->nextEvent < nextEvent) {
371				nextEvent = timer->nextEvent;
372			}
373		}
374
375		timer = &gba->timers[3];
376		if (GBATimerFlagsIsEnable(timer->flags)) {
377			timer->nextEvent -= cycles;
378			timer->lastEvent -= cycles;
379			if (timer->nextEvent <= 0) {
380				timer->lastEvent = timer->nextEvent;
381				timer->nextEvent += timer->overflowInterval;
382				gba->memory.io[REG_TM3CNT_LO >> 1] = timer->reload;
383				timer->oldReload = timer->reload;
384
385				if (GBATimerFlagsIsDoIrq(timer->flags)) {
386					GBARaiseIRQ(gba, IRQ_TIMER3);
387				}
388
389				if (GBATimerFlagsIsCountUp(timer->flags)) {
390					timer->nextEvent = INT_MAX;
391				}
392			}
393			if (timer->nextEvent < nextEvent) {
394				nextEvent = timer->nextEvent;
395			}
396		}
397	}
398	return nextEvent;
399}
400
401void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger) {
402	debugger->setSoftwareBreakpoint = _setSoftwareBreakpoint;
403	debugger->clearSoftwareBreakpoint = _clearSoftwareBreakpoint;
404	gba->debugger = debugger;
405	gba->cpu->components[GBA_COMPONENT_DEBUGGER] = &debugger->d;
406	ARMHotplugAttach(gba->cpu, GBA_COMPONENT_DEBUGGER);
407}
408
409void GBADetachDebugger(struct GBA* gba) {
410	gba->debugger = 0;
411	ARMHotplugDetach(gba->cpu, GBA_COMPONENT_DEBUGGER);
412	gba->cpu->components[GBA_COMPONENT_DEBUGGER] = 0;
413}
414
415bool GBALoadMB(struct GBA* gba, struct VFile* vf, const char* fname) {
416	GBAUnloadROM(gba);
417	gba->romVf = vf;
418	gba->pristineRomSize = vf->size(vf);
419	vf->seek(vf, 0, SEEK_SET);
420	if (gba->pristineRomSize > SIZE_WORKING_RAM) {
421		gba->pristineRomSize = SIZE_WORKING_RAM;
422	}
423#ifdef _3DS
424	gba->pristineRom = 0;
425	if (gba->pristineRomSize <= romBufferSize) {
426		gba->pristineRom = romBuffer;
427		vf->read(vf, romBuffer, gba->pristineRomSize);
428	}
429#else
430	gba->pristineRom = vf->map(vf, gba->pristineRomSize, MAP_READ);
431#endif
432	if (!gba->pristineRom) {
433		GBALog(gba, GBA_LOG_WARN, "Couldn't map ROM");
434		return false;
435	}
436	gba->yankedRomSize = 0;
437	gba->activeFile = fname;
438	gba->memory.romSize = 0;
439	gba->memory.romMask = 0;
440	gba->romCrc32 = doCrc32(gba->pristineRom, gba->pristineRomSize);
441	return true;
442}
443
444bool GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname) {
445	GBAUnloadROM(gba);
446	gba->romVf = vf;
447	gba->pristineRomSize = vf->size(vf);
448	vf->seek(vf, 0, SEEK_SET);
449	if (gba->pristineRomSize > SIZE_CART0) {
450		gba->pristineRomSize = SIZE_CART0;
451	}
452#ifdef _3DS
453	gba->pristineRom = 0;
454	if (gba->pristineRomSize <= romBufferSize) {
455		gba->pristineRom = romBuffer;
456		vf->read(vf, romBuffer, gba->pristineRomSize);
457	}
458#else
459	gba->pristineRom = vf->map(vf, gba->pristineRomSize, MAP_READ);
460#endif
461	if (!gba->pristineRom) {
462		GBALog(gba, GBA_LOG_WARN, "Couldn't map ROM");
463		return false;
464	}
465	gba->yankedRomSize = 0;
466	gba->memory.rom = gba->pristineRom;
467	gba->activeFile = fname;
468	gba->memory.romSize = gba->pristineRomSize;
469	gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
470	gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize);
471	GBASavedataInit(&gba->memory.savedata, sav);
472	GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]);
473	return true;
474	// TODO: error check
475}
476
477void GBAYankROM(struct GBA* gba) {
478	gba->yankedRomSize = gba->memory.romSize;
479	gba->memory.romSize = 0;
480	gba->memory.romMask = 0;
481	GBARaiseIRQ(gba, IRQ_GAMEPAK);
482}
483
484void GBALoadBIOS(struct GBA* gba, struct VFile* vf) {
485	gba->biosVf = vf;
486	uint32_t* bios = vf->map(vf, SIZE_BIOS, MAP_READ);
487	if (!bios) {
488		GBALog(gba, GBA_LOG_WARN, "Couldn't map BIOS");
489		return;
490	}
491	gba->memory.bios = bios;
492	gba->memory.fullBios = 1;
493	uint32_t checksum = GBAChecksum(gba->memory.bios, SIZE_BIOS);
494	GBALog(gba, GBA_LOG_DEBUG, "BIOS Checksum: 0x%X", checksum);
495	if (checksum == GBA_BIOS_CHECKSUM) {
496		GBALog(gba, GBA_LOG_INFO, "Official GBA BIOS detected");
497	} else if (checksum == GBA_DS_BIOS_CHECKSUM) {
498		GBALog(gba, GBA_LOG_INFO, "Official GBA (DS) BIOS detected");
499	} else {
500		GBALog(gba, GBA_LOG_WARN, "BIOS checksum incorrect");
501	}
502	gba->biosChecksum = checksum;
503	if (gba->memory.activeRegion == REGION_BIOS) {
504		gba->cpu->memory.activeRegion = gba->memory.bios;
505	}
506	// TODO: error check
507}
508
509void GBAApplyPatch(struct GBA* gba, struct Patch* patch) {
510	size_t patchedSize = patch->outputSize(patch, gba->memory.romSize);
511	if (!patchedSize || patchedSize > SIZE_CART0) {
512		return;
513	}
514	gba->memory.rom = anonymousMemoryMap(SIZE_CART0);
515	if (!patch->applyPatch(patch, gba->pristineRom, gba->pristineRomSize, gba->memory.rom, patchedSize)) {
516		mappedMemoryFree(gba->memory.rom, patchedSize);
517		gba->memory.rom = gba->pristineRom;
518		return;
519	}
520	gba->memory.romSize = patchedSize;
521	gba->memory.romMask = SIZE_CART0 - 1;
522	gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize);
523}
524
525void GBATimerUpdateRegister(struct GBA* gba, int timer) {
526	struct GBATimer* currentTimer = &gba->timers[timer];
527	if (GBATimerFlagsIsEnable(currentTimer->flags) && !GBATimerFlagsIsCountUp(currentTimer->flags)) {
528		int32_t prefetchSkew = 0;
529		if (gba->memory.lastPrefetchedPc - gba->memory.lastPrefetchedLoads * WORD_SIZE_THUMB >= (uint32_t) gba->cpu->gprs[ARM_PC]) {
530			prefetchSkew = (gba->memory.lastPrefetchedPc - gba->cpu->gprs[ARM_PC]) * (gba->cpu->memory.activeSeqCycles16 + 1) / WORD_SIZE_THUMB;
531		}
532		// Reading this takes two cycles (1N+1I), so let's remove them preemptively
533		gba->memory.io[(REG_TM0CNT_LO + (timer << 2)) >> 1] = currentTimer->oldReload + ((gba->cpu->cycles - currentTimer->lastEvent - 2 + prefetchSkew) >> GBATimerFlagsGetPrescaleBits(currentTimer->flags));
534	}
535}
536
537void GBATimerWriteTMCNT_LO(struct GBA* gba, int timer, uint16_t reload) {
538	gba->timers[timer].reload = reload;
539	gba->timers[timer].overflowInterval = (0x10000 - gba->timers[timer].reload) << GBATimerFlagsGetPrescaleBits(gba->timers[timer].flags);
540}
541
542void GBATimerWriteTMCNT_HI(struct GBA* gba, int timer, uint16_t control) {
543	struct GBATimer* currentTimer = &gba->timers[timer];
544	GBATimerUpdateRegister(gba, timer);
545
546	unsigned oldPrescale = GBATimerFlagsGetPrescaleBits(currentTimer->flags);
547	switch (control & 0x0003) {
548	case 0x0000:
549		currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 0);
550		break;
551	case 0x0001:
552		currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 6);
553		break;
554	case 0x0002:
555		currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 8);
556		break;
557	case 0x0003:
558		currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 10);
559		break;
560	}
561	currentTimer->flags = GBATimerFlagsTestFillCountUp(currentTimer->flags, control & 0x0004);
562	currentTimer->flags = GBATimerFlagsTestFillDoIrq(currentTimer->flags, control & 0x0040);
563	currentTimer->overflowInterval = (0x10000 - currentTimer->reload) << GBATimerFlagsGetPrescaleBits(currentTimer->flags);
564	bool wasEnabled = GBATimerFlagsIsEnable(currentTimer->flags);
565	currentTimer->flags = GBATimerFlagsTestFillEnable(currentTimer->flags, control & 0x0080);
566	if (!wasEnabled && GBATimerFlagsIsEnable(currentTimer->flags)) {
567		if (!GBATimerFlagsIsCountUp(currentTimer->flags)) {
568			currentTimer->nextEvent = gba->cpu->cycles + currentTimer->overflowInterval;
569		} else {
570			currentTimer->nextEvent = INT_MAX;
571		}
572		gba->memory.io[(REG_TM0CNT_LO + (timer << 2)) >> 1] = currentTimer->reload;
573		currentTimer->oldReload = currentTimer->reload;
574		currentTimer->lastEvent = gba->cpu->cycles;
575		gba->timersEnabled |= 1 << timer;
576	} else if (wasEnabled && !GBATimerFlagsIsEnable(currentTimer->flags)) {
577		if (!GBATimerFlagsIsCountUp(currentTimer->flags)) {
578			gba->memory.io[(REG_TM0CNT_LO + (timer << 2)) >> 1] = currentTimer->oldReload + ((gba->cpu->cycles - currentTimer->lastEvent) >> oldPrescale);
579		}
580		gba->timersEnabled &= ~(1 << timer);
581	} else if (GBATimerFlagsGetPrescaleBits(currentTimer->flags) != oldPrescale && !GBATimerFlagsIsCountUp(currentTimer->flags)) {
582		// FIXME: this might be before present
583		currentTimer->nextEvent = currentTimer->lastEvent + currentTimer->overflowInterval;
584	}
585
586	if (currentTimer->nextEvent < gba->cpu->nextEvent) {
587		gba->cpu->nextEvent = currentTimer->nextEvent;
588	}
589};
590
591void GBAWriteIE(struct GBA* gba, uint16_t value) {
592	if (value & (1 << IRQ_KEYPAD)) {
593		GBALog(gba, GBA_LOG_STUB, "Keypad interrupts not implemented");
594	}
595
596	if (gba->memory.io[REG_IME >> 1] && value & gba->memory.io[REG_IF >> 1]) {
597		ARMRaiseIRQ(gba->cpu);
598	}
599}
600
601void GBAWriteIME(struct GBA* gba, uint16_t value) {
602	if (value && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
603		ARMRaiseIRQ(gba->cpu);
604	}
605}
606
607void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq) {
608	gba->memory.io[REG_IF >> 1] |= 1 << irq;
609	gba->cpu->halted = 0;
610
611	if (gba->memory.io[REG_IME >> 1] && (gba->memory.io[REG_IE >> 1] & 1 << irq)) {
612		ARMRaiseIRQ(gba->cpu);
613	}
614}
615
616void GBATestIRQ(struct ARMCore* cpu) {
617	struct GBA* gba = (struct GBA*) cpu->master;
618	if (gba->memory.io[REG_IME >> 1] && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
619		gba->springIRQ = 1;
620		gba->cpu->nextEvent = gba->cpu->cycles;
621	}
622}
623
624void GBAHalt(struct GBA* gba) {
625	gba->cpu->nextEvent = gba->cpu->cycles;
626	gba->cpu->halted = 1;
627}
628
629void GBAStop(struct GBA* gba) {
630	if (!gba->stopCallback) {
631		return;
632	}
633	gba->cpu->nextEvent = gba->cpu->cycles;
634	gba->stopCallback->stop(gba->stopCallback);
635}
636
637static void _GBAVLog(struct GBA* gba, enum GBALogLevel level, const char* format, va_list args) {
638	struct GBAThread* threadContext = GBAThreadGetContext();
639	enum GBALogLevel logLevel = GBA_LOG_ALL;
640
641	if (gba) {
642		logLevel = gba->logLevel;
643	}
644
645	if (threadContext) {
646		logLevel = threadContext->logLevel;
647		gba = threadContext->gba;
648	}
649
650	if (!(level & logLevel) && level != GBA_LOG_FATAL) {
651		return;
652	}
653
654	if (level == GBA_LOG_FATAL && gba) {
655		gba->cpu->nextEvent = 0;
656	}
657
658	if (threadContext) {
659		if (level == GBA_LOG_FATAL) {
660			MutexLock(&threadContext->stateMutex);
661			threadContext->state = THREAD_CRASHED;
662			MutexUnlock(&threadContext->stateMutex);
663		}
664	}
665	if (gba && gba->logHandler) {
666		gba->logHandler(threadContext, level, format, args);
667		return;
668	}
669
670	vprintf(format, args);
671	printf("\n");
672
673	if (level == GBA_LOG_FATAL && !threadContext) {
674		abort();
675	}
676}
677
678void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {
679	va_list args;
680	va_start(args, format);
681	_GBAVLog(gba, level, format, args);
682	va_end(args);
683}
684
685void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel level, const char* format, ...) {
686	struct GBA* gba = 0;
687	if (debugger->cpu) {
688		gba = (struct GBA*) debugger->cpu->master;
689	}
690
691	enum GBALogLevel gbaLevel;
692	switch (level) {
693	default: // Avoids compiler warning
694	case DEBUGGER_LOG_DEBUG:
695		gbaLevel = GBA_LOG_DEBUG;
696		break;
697	case DEBUGGER_LOG_INFO:
698		gbaLevel = GBA_LOG_INFO;
699		break;
700	case DEBUGGER_LOG_WARN:
701		gbaLevel = GBA_LOG_WARN;
702		break;
703	case DEBUGGER_LOG_ERROR:
704		gbaLevel = GBA_LOG_ERROR;
705		break;
706	}
707	va_list args;
708	va_start(args, format);
709	_GBAVLog(gba, gbaLevel, format, args);
710	va_end(args);
711}
712
713bool GBAIsROM(struct VFile* vf) {
714	if (vf->seek(vf, GBA_ROM_MAGIC_OFFSET, SEEK_SET) < 0) {
715		return false;
716	}
717	uint8_t signature[sizeof(GBA_ROM_MAGIC)];
718	if (vf->read(vf, &signature, sizeof(signature)) != sizeof(signature)) {
719		return false;
720	}
721	if (GBAIsBIOS(vf)) {
722		return false;
723	}
724	return memcmp(signature, GBA_ROM_MAGIC, sizeof(signature)) == 0;
725}
726
727bool GBAIsMB(struct VFile* vf) {
728	if (!GBAIsROM(vf)) {
729		return false;
730	}
731	if (vf->size(vf) > SIZE_WORKING_RAM) {
732		return false;
733	}
734	if (vf->seek(vf, GBA_MB_MAGIC_OFFSET, SEEK_SET) < 0) {
735		return false;
736	}
737	uint32_t signature;
738	if (vf->read(vf, &signature, sizeof(signature)) != sizeof(signature)) {
739		return false;
740	}
741	uint32_t opcode;
742	LOAD_32(opcode, 0, &signature);
743	struct ARMInstructionInfo info;
744	ARMDecodeARM(opcode, &info);
745	if (info.branchType != ARM_BRANCH) {
746		return false;
747	}
748	if (info.op1.immediate <= 0) {
749		return false;
750	} else if (info.op1.immediate == 28) {
751		// Ancient toolchain that is known to throw MB detection for a loop
752		return false;
753	} else if (info.op1.immediate != 24) {
754		return true;
755	}
756	// Found a libgba-linked cart...these are a bit harder to detect.
757	return false;
758}
759
760bool GBAIsBIOS(struct VFile* vf) {
761	if (vf->seek(vf, 0, SEEK_SET) < 0) {
762		return false;
763	}
764	uint8_t interruptTable[7 * 4];
765	if (vf->read(vf, &interruptTable, sizeof(interruptTable)) != sizeof(interruptTable)) {
766		return false;
767	}
768	int i;
769	for (i = 0; i < 7; ++i) {
770		if (interruptTable[4 * i + 3] != 0xEA || interruptTable[4 * i + 2]) {
771			return false;
772		}
773	}
774	return true;
775}
776
777void GBAGetGameCode(struct GBA* gba, char* out) {
778	if (!gba->memory.rom) {
779		out[0] = '\0';
780		return;
781	}
782	memcpy(out, &((struct GBACartridge*) gba->memory.rom)->id, 4);
783}
784
785void GBAGetGameTitle(struct GBA* gba, char* out) {
786	if (gba->memory.rom) {
787		memcpy(out, &((struct GBACartridge*) gba->memory.rom)->title, 12);
788		return;
789	}
790	if (gba->pristineRom) {
791		memcpy(out, &((struct GBACartridge*) gba->pristineRom)->title, 12);
792		return;
793	}
794	strncpy(out, "(BIOS)", 12);
795}
796
797void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) {
798	struct GBA* gba = (struct GBA*) cpu->master;
799	enum GBALogLevel level = GBA_LOG_ERROR;
800	if (gba->debugger) {
801		level = GBA_LOG_STUB;
802		struct DebuggerEntryInfo info = {
803			.address = _ARMPCAddress(cpu),
804			.opcode = opcode
805		};
806		ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP, &info);
807	}
808	GBALog(gba, level, "Stub opcode: %08x", opcode);
809}
810
811void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) {
812	struct GBA* gba = (struct GBA*) cpu->master;
813	if (!gba->yankedRomSize) {
814		GBALog(gba, GBA_LOG_WARN, "Illegal opcode: %08x", opcode);
815	}
816	if (gba->debugger) {
817		struct DebuggerEntryInfo info = {
818			.address = _ARMPCAddress(cpu),
819			.opcode = opcode
820		};
821		ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP, &info);
822	} else {
823		ARMRaiseUndefined(cpu);
824	}
825}
826
827void GBABreakpoint(struct ARMCore* cpu, int immediate) {
828	struct GBA* gba = (struct GBA*) cpu->master;
829	if (immediate >= GBA_COMPONENT_MAX) {
830		return;
831	}
832	switch (immediate) {
833	case GBA_COMPONENT_DEBUGGER:
834		if (gba->debugger) {
835			struct DebuggerEntryInfo info = {
836				.address = _ARMPCAddress(cpu)
837			};
838			ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_BREAKPOINT, &info);
839		}
840		break;
841	case GBA_COMPONENT_CHEAT_DEVICE:
842		if (gba->cpu->components[GBA_COMPONENT_CHEAT_DEVICE]) {
843			struct GBACheatDevice* device = (struct GBACheatDevice*) gba->cpu->components[GBA_COMPONENT_CHEAT_DEVICE];
844			struct GBACheatHook* hook = 0;
845			size_t i;
846			for (i = 0; i < GBACheatSetsSize(&device->cheats); ++i) {
847				struct GBACheatSet* cheats = *GBACheatSetsGetPointer(&device->cheats, i);
848				if (cheats->hook && cheats->hook->address == _ARMPCAddress(cpu)) {
849					GBACheatRefresh(device, cheats);
850					hook = cheats->hook;
851				}
852			}
853			if (hook) {
854				ARMRunFake(cpu, hook->patchedOpcode);
855			}
856		}
857		break;
858	default:
859		break;
860	}
861}
862
863void GBAFrameStarted(struct GBA* gba) {
864	UNUSED(gba);
865
866	struct GBAThread* thread = GBAThreadGetContext();
867	if (!thread) {
868		return;
869	}
870
871	if (thread->rewindBuffer) {
872		--thread->rewindBufferNext;
873		if (thread->rewindBufferNext <= 0) {
874			thread->rewindBufferNext = thread->rewindBufferInterval;
875			GBARecordFrame(thread);
876		}
877	}
878}
879
880void GBAFrameEnded(struct GBA* gba) {
881	GBASavedataClean(&gba->memory.savedata, gba->video.frameCounter);
882
883	if (gba->rr) {
884		gba->rr->nextFrame(gba->rr);
885	}
886
887	if (gba->cpu->components && gba->cpu->components[GBA_COMPONENT_CHEAT_DEVICE]) {
888		struct GBACheatDevice* device = (struct GBACheatDevice*) gba->cpu->components[GBA_COMPONENT_CHEAT_DEVICE];
889		size_t i;
890		for (i = 0; i < GBACheatSetsSize(&device->cheats); ++i) {
891			struct GBACheatSet* cheats = *GBACheatSetsGetPointer(&device->cheats, i);
892			if (!cheats->hook) {
893				GBACheatRefresh(device, cheats);
894			}
895		}
896	}
897
898	if (gba->stream && gba->stream->postVideoFrame) {
899		gba->stream->postVideoFrame(gba->stream, gba->video.renderer);
900	}
901
902	if (gba->memory.hw.devices & (HW_GB_PLAYER | HW_GB_PLAYER_DETECTION)) {
903		GBAHardwarePlayerUpdate(gba);
904	}
905
906	struct GBAThread* thread = GBAThreadGetContext();
907	if (!thread) {
908		return;
909	}
910
911	if (thread->frameCallback) {
912		thread->frameCallback(thread);
913	}
914}
915
916void GBASetBreakpoint(struct GBA* gba, struct ARMComponent* component, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) {
917	size_t immediate;
918	for (immediate = 0; immediate < gba->cpu->numComponents; ++immediate) {
919		if (gba->cpu->components[immediate] == component) {
920			break;
921		}
922	}
923	if (immediate == gba->cpu->numComponents) {
924		return;
925	}
926	if (mode == MODE_ARM) {
927		int32_t value;
928		int32_t old;
929		value = 0xE1200070;
930		value |= immediate & 0xF;
931		value |= (immediate & 0xFFF0) << 4;
932		GBAPatch32(gba->cpu, address, value, &old);
933		*opcode = old;
934	} else {
935		int16_t value;
936		int16_t old;
937		value = 0xBE00;
938		value |= immediate & 0xFF;
939		GBAPatch16(gba->cpu, address, value, &old);
940		*opcode = (uint16_t) old;
941	}
942}
943
944void GBAClearBreakpoint(struct GBA* gba, uint32_t address, enum ExecutionMode mode, uint32_t opcode) {
945	if (mode == MODE_ARM) {
946		GBAPatch32(gba->cpu, address, opcode, 0);
947	} else {
948		GBAPatch16(gba->cpu, address, opcode, 0);
949	}
950}
951
952#if (!defined(USE_PTHREADS) && !defined(_WIN32)) || defined(DISABLE_THREADING)
953struct GBAThread* GBAThreadGetContext(void) {
954	return 0;
955}
956#endif
957
958static bool _setSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) {
959	GBASetBreakpoint((struct GBA*) debugger->cpu->master, &debugger->d, address, mode, opcode);
960	return true;
961}
962
963static bool _clearSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode, uint32_t opcode) {
964	GBAClearBreakpoint((struct GBA*) debugger->cpu->master, address, mode, opcode);
965	return true;
966}