all repos — mgba @ 775e417cc6781ceb30520c85c968d198efb87429

mGBA Game Boy Advance Emulator

src/debugger/debugger.c (view raw)

  1#include "debugger.h"
  2
  3#include "arm.h"
  4
  5#include "memory-debugger.h"
  6
  7static void _checkBreakpoints(struct ARMDebugger* debugger) {
  8	struct DebugBreakpoint* breakpoint;
  9	int instructionLength;
 10	enum ExecutionMode mode = debugger->cpu->cpsr.t;
 11	if (mode == MODE_ARM) {
 12		instructionLength = WORD_SIZE_ARM;
 13	} else {
 14		instructionLength = WORD_SIZE_THUMB;
 15	}
 16	for (breakpoint = debugger->breakpoints; breakpoint; breakpoint = breakpoint->next) {
 17		if (breakpoint->address + instructionLength == (uint32_t) debugger->cpu->gprs[ARM_PC]) {
 18			ARMDebuggerEnter(debugger, DEBUGGER_ENTER_BREAKPOINT);
 19			break;
 20		}
 21	}
 22}
 23
 24void ARMDebuggerInit(struct ARMDebugger* debugger, struct ARMCore* cpu) {
 25	debugger->cpu = cpu;
 26	debugger->state = DEBUGGER_RUNNING;
 27	debugger->breakpoints = 0;
 28	debugger->memoryShim.original = cpu->memory;
 29	debugger->memoryShim.p = debugger;
 30	debugger->memoryShim.watchpoints = 0;
 31	if (debugger->init) {
 32		debugger->init(debugger);
 33	}
 34}
 35
 36void ARMDebuggerDeinit(struct ARMDebugger* debugger) {
 37	// TODO: actually call this
 38	debugger->deinit(debugger);
 39}
 40
 41void ARMDebuggerRun(struct ARMDebugger* debugger) {
 42	if (debugger->state == DEBUGGER_EXITING) {
 43		debugger->state = DEBUGGER_RUNNING;
 44	}
 45	while (debugger->state < DEBUGGER_EXITING) {
 46		if (!debugger->breakpoints) {
 47			while (debugger->state == DEBUGGER_RUNNING) {
 48				ARMRun(debugger->cpu);
 49			}
 50		} else {
 51			while (debugger->state == DEBUGGER_RUNNING) {
 52				ARMRun(debugger->cpu);
 53				_checkBreakpoints(debugger);
 54			}
 55		}
 56		switch (debugger->state) {
 57		case DEBUGGER_RUNNING:
 58			break;
 59		case DEBUGGER_PAUSED:
 60			if (debugger->paused) {
 61				debugger->paused(debugger);
 62			} else {
 63				debugger->state = DEBUGGER_RUNNING;
 64			}
 65			break;
 66		case DEBUGGER_EXITING:
 67		case DEBUGGER_SHUTDOWN:
 68			return;
 69		}
 70	}
 71}
 72
 73void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason reason) {
 74	debugger->state = DEBUGGER_PAUSED;
 75	if (debugger->entered) {
 76		debugger->entered(debugger, reason);
 77	}
 78}
 79
 80void ARMDebuggerSetBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
 81	struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint));
 82	breakpoint->address = address;
 83	breakpoint->next = debugger->breakpoints;
 84	debugger->breakpoints = breakpoint;
 85}
 86
 87void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
 88	struct DebugBreakpoint** previous = &debugger->breakpoints;
 89	struct DebugBreakpoint* breakpoint;
 90	for (; (breakpoint = *previous); previous = &breakpoint->next) {
 91		if (breakpoint->address == address) {
 92			*previous = breakpoint->next;
 93			free(breakpoint);
 94		}
 95	}
 96}
 97
 98void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
 99	if (debugger->cpu->memory != &debugger->memoryShim.d) {
100		ARMDebuggerInstallMemoryShim(debugger);
101	}
102	struct DebugBreakpoint* watchpoint = malloc(sizeof(struct DebugBreakpoint));
103	watchpoint->address = address;
104	watchpoint->next = debugger->memoryShim.watchpoints;
105	debugger->memoryShim.watchpoints = watchpoint;
106}