all repos — mgba @ 4b4be372c0ff200e2da2e2855bc942a08e544618

mGBA Game Boy Advance Emulator

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}