all repos — mgba @ 6616ca9111785abada65142442c51a84dc0c804d

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 ARMMemory*, uint32_t address, int32_t value, int* cycleCounter);
  8static void ARMDebuggerShim_store16(struct ARMMemory*, uint32_t address, int16_t value, int* cycleCounter);
  9static void ARMDebuggerShim_store8(struct ARMMemory*, uint32_t address, int8_t value, int* cycleCounter);
 10static void ARMDebuggerShim_setActiveRegion(struct ARMMemory* memory, uint32_t address);
 11
 12#define CREATE_SHIM(NAME, RETURN, TYPES, ARGS...) \
 13	static RETURN ARMDebuggerShim_ ## NAME TYPES { \
 14		struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory; \
 15		return debugMemory->original->NAME(debugMemory->original, ARGS); \
 16	}
 17
 18CREATE_SHIM(load32, int32_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
 19CREATE_SHIM(load16, int16_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
 20CREATE_SHIM(loadU16, uint16_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
 21CREATE_SHIM(load8, int8_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
 22CREATE_SHIM(loadU8, uint8_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
 23CREATE_SHIM(waitMultiple, int, (struct ARMMemory* memory, uint32_t startAddress, int count), startAddress, count)
 24
 25static int _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t address, int width) {
 26	width -= 1;
 27	for (; watchpoints; watchpoints = watchpoints->next) {
 28		if (!((watchpoints->address ^ address) & ~width)) {
 29			return 1;
 30		}
 31	}
 32	return 0;
 33}
 34
 35void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
 36	debugger->memoryShim.original = debugger->cpu->memory;
 37	memcpy(&debugger->memoryShim.d, debugger->cpu->memory, sizeof(struct ARMMemory));
 38	debugger->memoryShim.d.store32 = ARMDebuggerShim_store32;
 39	debugger->memoryShim.d.store16 = ARMDebuggerShim_store16;
 40	debugger->memoryShim.d.store8 = ARMDebuggerShim_store8;
 41	debugger->memoryShim.d.load32 = ARMDebuggerShim_load32;
 42	debugger->memoryShim.d.load16 = ARMDebuggerShim_load16;
 43	debugger->memoryShim.d.loadU16 = ARMDebuggerShim_loadU16;
 44	debugger->memoryShim.d.load8 = ARMDebuggerShim_load8;
 45	debugger->memoryShim.d.loadU8 = ARMDebuggerShim_loadU8;
 46	debugger->memoryShim.d.setActiveRegion = ARMDebuggerShim_setActiveRegion;
 47	debugger->memoryShim.d.waitMultiple = ARMDebuggerShim_waitMultiple;
 48	debugger->cpu->memory = &debugger->memoryShim.d;
 49}
 50
 51int32_t ARMDebuggerLoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
 52	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 53	return debugMemory->original->load32(debugMemory->original, address, cycleCounter);
 54}
 55
 56int16_t ARMDebuggerLoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
 57	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 58	return debugMemory->original->load16(debugMemory->original, address, cycleCounter);
 59}
 60
 61uint16_t ARMDebuggerLoadU16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
 62	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 63	return debugMemory->original->loadU16(debugMemory->original, address, cycleCounter);
 64}
 65
 66int8_t ARMDebuggerLoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
 67	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 68	return debugMemory->original->load8(debugMemory->original, address, cycleCounter);
 69}
 70
 71uint8_t ARMDebuggerLoadU8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
 72	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 73	return debugMemory->original->loadU8(debugMemory->original, address, cycleCounter);
 74}
 75
 76void ARMDebuggerShim_store32(struct ARMMemory* memory, uint32_t address, int32_t value, int* cycleCounter) {
 77	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 78	if (_checkWatchpoints(debugMemory->watchpoints, address, 4)) {
 79		ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
 80	}
 81	debugMemory->original->store32(debugMemory->original, address, value, cycleCounter);
 82}
 83
 84void ARMDebuggerShim_store16(struct ARMMemory* memory, uint32_t address, int16_t value, int* cycleCounter) {
 85	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 86	if (_checkWatchpoints(debugMemory->watchpoints, address, 2)) {
 87		ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
 88	}
 89	debugMemory->original->store16(debugMemory->original, address, value, cycleCounter);
 90}
 91
 92void ARMDebuggerShim_store8(struct ARMMemory* memory, uint32_t address, int8_t value, int* cycleCounter) {
 93	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
 94	if (_checkWatchpoints(debugMemory->watchpoints, address, 1)) {
 95		ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
 96	}
 97	debugMemory->original->store8(debugMemory->original, address, value, cycleCounter);
 98}
 99
100void ARMDebuggerShim_setActiveRegion(struct ARMMemory* memory, uint32_t address) {
101	struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
102	debugMemory->original->setActiveRegion(debugMemory->original, address);
103	memory->activeRegion = debugMemory->original->activeRegion;
104	memory->activeMask = debugMemory->original->activeMask;
105	memory->activePrefetchCycles32 = debugMemory->original->activePrefetchCycles32;
106	memory->activePrefetchCycles16 = debugMemory->original->activePrefetchCycles16;
107	memory->activeNonseqCycles32 = debugMemory->original->activeNonseqCycles32;
108	memory->activeNonseqCycles16 = debugMemory->original->activeNonseqCycles16;
109}