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 = 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 struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform;
76 struct LR35902Core* cpu = debugger->cpu;
77 cpu->nextEvent = cpu->cycles;
78}
79
80static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
81 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
82 struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListAppend(&debugger->breakpoints);
83 breakpoint->address = address;
84 breakpoint->segment = -1;
85}
86
87static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address) {
88 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
89 struct LR35902DebugBreakpointList* breakpoints = &debugger->breakpoints;
90 size_t i;
91 for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) {
92 if (LR35902DebugBreakpointListGetPointer(breakpoints, i)->address == address) {
93 LR35902DebugBreakpointListShift(breakpoints, i, 1);
94 }
95 }
96}
97
98static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform* d) {
99 struct LR35902Debugger* debugger = (struct LR35902Debugger*) d;
100 return LR35902DebugBreakpointListSize(&debugger->breakpoints) || LR35902DebugWatchpointListSize(&debugger->watchpoints);
101}