src/lr35902/debugger.c (view raw)
1/* Copyright (c) 2013-2016 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 "debugger.h"
7
8#include "lr35902/lr35902.h"
9#include "core/core.h"
10
11DEFINE_VECTOR(LR35902DebugBreakpointList, struct LR35902DebugBreakpoint);
12DEFINE_VECTOR(LR35902DebugWatchpointList, struct LR35902DebugWatchpoint);
13
14static struct LR35902DebugBreakpoint* _lookupBreakpoint(struct LR35902DebugBreakpointList* breakpoints, uint16_t address) {
15 size_t i;
16 for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) {
17 if (LR35902DebugBreakpointListGetPointer(breakpoints, i)->address == address) {
18 return LR35902DebugBreakpointListGetPointer(breakpoints, i);
19 }
20 }
21 return 0;
22}
23
24static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
25 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
26 struct LR35902DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu->pc - 1);
27 if (!breakpoint) {
28 return;
29 }
30 // TODO: Segments
31 struct mDebuggerEntryInfo info = {
32 .address = breakpoint->address
33 };
34 mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info);
35}
36
37static void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform);
38static void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform);
39
40static void LR35902DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info);
41
42static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address);
43static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address);
44static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*);
45static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*);
46
47struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) {
48 struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct LR35902Debugger));
49 platform->entered = LR35902DebuggerEnter;
50 platform->init = LR35902DebuggerInit;
51 platform->deinit = LR35902DebuggerDeinit;
52 platform->setBreakpoint = LR35902DebuggerSetBreakpoint;
53 platform->clearBreakpoint = LR35902DebuggerClearBreakpoint;
54 platform->setWatchpoint = NULL;
55 platform->clearWatchpoint = NULL;
56 platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints;
57 platform->hasBreakpoints = LR35902DebuggerHasBreakpoints;
58 return platform;
59}
60
61void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) {
62 struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
63 debugger->cpu = cpu;
64 LR35902DebugBreakpointListInit(&debugger->breakpoints, 0);
65 LR35902DebugWatchpointListInit(&debugger->watchpoints, 0);
66}
67
68void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform) {
69 struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
70 LR35902DebugBreakpointListDeinit(&debugger->breakpoints);
71 LR35902DebugWatchpointListDeinit(&debugger->watchpoints);
72}
73
74static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
75 UNUSED(reason);
76 UNUSED(info);
77 struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
78 struct LR35902Core* cpu = debugger->cpu;
79 cpu->nextEvent = cpu->cycles;
80}
81
82static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
83 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
84 struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListAppend(&debugger->breakpoints);
85 breakpoint->address = address;
86 breakpoint->segment = -1;
87}
88
89static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
90 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
91 struct LR35902DebugBreakpointList* breakpoints = &debugger->breakpoints;
92 size_t i;
93 for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) {
94 if (LR35902DebugBreakpointListGetPointer(breakpoints, i)->address == address) {
95 LR35902DebugBreakpointListShift(breakpoints, i, 1);
96 }
97 }
98}
99
100static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform* d) {
101 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
102 return LR35902DebugBreakpointListSize(&debugger->breakpoints) || LR35902DebugWatchpointListSize(&debugger->watchpoints);
103}