all repos — mgba @ 1541e6e0b060637cff5ff882fa24956f88dc3a35

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