all repos — mgba @ 7a4ca414e5c7f5fc0c28739b1008f0096528aa70

mGBA Game Boy Advance Emulator

src/debugger/memory-debugger.c (view raw)

 1#include "memory-debugger.h"
 2
 3#include "debugger.h"
 4
 5#include <string.h>
 6
 7static void ARMDebuggerShim_store32(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
 8static void ARMDebuggerShim_store16(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
 9static void ARMDebuggerShim_store8(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
10static void ARMDebuggerShim_setActiveRegion(struct ARMCore* cpu, uint32_t address);
11
12#define FIND_DEBUGGER(DEBUGGER, CPU) \
13	{ \
14		DEBUGGER = 0; \
15		int i; \
16		for (i = 0; i < CPU->numComponents; ++i) { \
17			if (CPU->components[i]->id == ARM_DEBUGGER_ID) { \
18				DEBUGGER = (struct ARMDebugger*) cpu->components[i]; \
19				break; \
20			} \
21		} \
22	}
23
24#define CREATE_SHIM(NAME, RETURN, TYPES, ARGS...) \
25	static RETURN ARMDebuggerShim_ ## NAME TYPES { \
26		struct ARMDebugger* debugger; \
27		FIND_DEBUGGER(debugger, cpu); \
28		return debugger->originalMemory.NAME(cpu, ARGS); \
29	}
30
31CREATE_SHIM(load32, int32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
32CREATE_SHIM(load16, int16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
33CREATE_SHIM(loadU16, uint16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
34CREATE_SHIM(load8, int8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
35CREATE_SHIM(loadU8, uint8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
36CREATE_SHIM(waitMultiple, int, (struct ARMCore* cpu, uint32_t startAddress, int count), startAddress, count)
37
38static int _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t address, int width) {
39	width -= 1;
40	for (; watchpoints; watchpoints = watchpoints->next) {
41		if (!((watchpoints->address ^ address) & ~width)) {
42			return 1;
43		}
44	}
45	return 0;
46}
47
48void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
49	debugger->originalMemory = debugger->cpu->memory;
50	debugger->cpu->memory.store32 = ARMDebuggerShim_store32;
51	debugger->cpu->memory.store16 = ARMDebuggerShim_store16;
52	debugger->cpu->memory.store8 = ARMDebuggerShim_store8;
53	debugger->cpu->memory.load32 = ARMDebuggerShim_load32;
54	debugger->cpu->memory.load16 = ARMDebuggerShim_load16;
55	debugger->cpu->memory.loadU16 = ARMDebuggerShim_loadU16;
56	debugger->cpu->memory.load8 = ARMDebuggerShim_load8;
57	debugger->cpu->memory.loadU8 = ARMDebuggerShim_loadU8;
58	debugger->cpu->memory.setActiveRegion = ARMDebuggerShim_setActiveRegion;
59	debugger->cpu->memory.waitMultiple = ARMDebuggerShim_waitMultiple;
60}
61
62void ARMDebuggerShim_store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
63	struct ARMDebugger* debugger;
64	FIND_DEBUGGER(debugger, cpu);
65	if (_checkWatchpoints(debugger->watchpoints, address, 4)) {
66		ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT);
67	}
68	debugger->originalMemory.store32(debugger->cpu, address, value, cycleCounter);
69}
70
71void ARMDebuggerShim_store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
72	struct ARMDebugger* debugger;
73	FIND_DEBUGGER(debugger, cpu);
74	if (_checkWatchpoints(debugger->watchpoints, address, 2)) {
75		ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT);
76	}
77	debugger->originalMemory.store16(debugger->cpu, address, value, cycleCounter);
78}
79
80void ARMDebuggerShim_store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
81	struct ARMDebugger* debugger;
82	FIND_DEBUGGER(debugger, cpu);
83	if (_checkWatchpoints(debugger->watchpoints, address, 1)) {
84		ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT);
85	}
86	debugger->originalMemory.store8(debugger->cpu, address, value, cycleCounter);
87}
88
89void ARMDebuggerShim_setActiveRegion(struct ARMCore* cpu, uint32_t address) {
90	struct ARMDebugger* debugger;
91	FIND_DEBUGGER(debugger, cpu);
92	debugger->originalMemory.setActiveRegion(cpu, address);
93}