all repos — mgba @ 0f68dbc832db31915d31a6e13438e566083dfb42

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
 24static void ARMDebuggerInit(struct ARMCore*, struct ARMComponent*);
 25static void ARMDebuggerDeinit(struct ARMComponent*);
 26
 27void ARMDebuggerCreate(struct ARMDebugger* debugger) {
 28	debugger->d.init = ARMDebuggerInit;
 29	debugger->d.deinit = ARMDebuggerDeinit;
 30}
 31
 32void ARMDebuggerInit(struct ARMCore* cpu, struct ARMComponent* component) {
 33	struct ARMDebugger* debugger = (struct ARMDebugger*) component;
 34	debugger->cpu = cpu;
 35	debugger->state = DEBUGGER_RUNNING;
 36	debugger->breakpoints = 0;
 37	debugger->memoryShim.original = cpu->memory;
 38	debugger->memoryShim.p = debugger;
 39	debugger->memoryShim.watchpoints = 0;
 40	if (debugger->init) {
 41		debugger->init(debugger);
 42	}
 43}
 44
 45void ARMDebuggerDeinit(struct ARMComponent* component) {
 46	struct ARMDebugger* debugger = (struct ARMDebugger*) component;
 47	debugger->deinit(debugger);
 48}
 49
 50void ARMDebuggerRun(struct ARMDebugger* debugger) {
 51	if (debugger->state == DEBUGGER_EXITING) {
 52		debugger->state = DEBUGGER_RUNNING;
 53	}
 54	while (debugger->state < DEBUGGER_EXITING) {
 55		if (!debugger->breakpoints) {
 56			while (debugger->state == DEBUGGER_RUNNING) {
 57				ARMRun(debugger->cpu);
 58			}
 59		} else {
 60			while (debugger->state == DEBUGGER_RUNNING) {
 61				ARMRun(debugger->cpu);
 62				_checkBreakpoints(debugger);
 63			}
 64		}
 65		switch (debugger->state) {
 66		case DEBUGGER_RUNNING:
 67			break;
 68		case DEBUGGER_PAUSED:
 69			if (debugger->paused) {
 70				debugger->paused(debugger);
 71			} else {
 72				debugger->state = DEBUGGER_RUNNING;
 73			}
 74			break;
 75		case DEBUGGER_EXITING:
 76		case DEBUGGER_SHUTDOWN:
 77			return;
 78		}
 79	}
 80}
 81
 82void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason reason) {
 83	debugger->state = DEBUGGER_PAUSED;
 84	if (debugger->entered) {
 85		debugger->entered(debugger, reason);
 86	}
 87}
 88
 89void ARMDebuggerSetBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
 90	struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint));
 91	breakpoint->address = address;
 92	breakpoint->next = debugger->breakpoints;
 93	debugger->breakpoints = breakpoint;
 94}
 95
 96void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
 97	struct DebugBreakpoint** previous = &debugger->breakpoints;
 98	struct DebugBreakpoint* breakpoint;
 99	for (; (breakpoint = *previous); previous = &breakpoint->next) {
100		if (breakpoint->address == address) {
101			*previous = breakpoint->next;
102			free(breakpoint);
103		}
104	}
105}
106
107void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
108	// FIXME: Make watchpoints work again
109	struct DebugBreakpoint* watchpoint = malloc(sizeof(struct DebugBreakpoint));
110	watchpoint->address = address;
111	watchpoint->next = debugger->memoryShim.watchpoints;
112	debugger->memoryShim.watchpoints = watchpoint;
113}