Support null (any) address for N64 breakpoints. (#2833)

* Support null (any) address for N64 breakpoints.

Fixes #2808

* Move null check for better readability.

* Replace debugger mutex with semaphore that counts debug steps.

This is taken directly from upstream m64p. If breakpoints are being hit fast enough and in large enough quantity, m64p always ends up getting into a deadlock. The semaphore seems to resist this problem.

* Remove tabs
This commit is contained in:
Zach 2021-07-14 10:49:31 -07:00 committed by GitHub
parent 488fd2c6af
commit 58293dde9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 22 deletions

Binary file not shown.

View File

@ -35,8 +35,8 @@
int g_DebuggerActive = 0; // whether the debugger is enabled or not
int run;
static SDL_cond *debugger_done_cond;
static SDL_mutex *mutex;
// Holds the number of pending steps the debugger needs to perform.
static SDL_sem* sem_pending_steps;
uint32 previousPC;
@ -51,16 +51,13 @@ void init_debugger()
init_host_disassembler();
mutex = SDL_CreateMutex();
debugger_done_cond = SDL_CreateCond();
sem_pending_steps = SDL_CreateSemaphore(0);
}
void destroy_debugger()
{
SDL_DestroyMutex(mutex);
mutex = NULL;
SDL_DestroyCond(debugger_done_cond);
debugger_done_cond = NULL;
SDL_DestroySemaphore(sem_pending_steps);
sem_pending_steps = NULL;
g_DebuggerActive = 0;
}
@ -86,9 +83,7 @@ void update_debugger(uint32 pc, int bpt)
}
if(run==0) {
// Emulation thread is blocked until a button is clicked.
SDL_mutexP(mutex);
SDL_CondWait(debugger_done_cond, mutex);
SDL_mutexV(mutex);
SDL_SemWait(sem_pending_steps);
}
previousPC = pc;
@ -96,7 +91,7 @@ void update_debugger(uint32 pc, int bpt)
void debugger_step()
{
SDL_CondSignal(debugger_done_cond);
SDL_SemPost(sem_pending_steps);
}

View File

@ -904,15 +904,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
m64pload_saveram(src);
}
/* TODO: Support address masks and null address */
/* TODO: Support address masks */
public void SetBreakpoint(BreakType type, uint? address)
{
m64p_breakpoint breakpoint = new m64p_breakpoint
{
address = address.Value,
endaddr = address.Value + 0x03,
flags = (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_ENABLED
};
m64p_breakpoint breakpoint = address is null
? new m64p_breakpoint()
{
// For null address, specify max address range to match any address
address = 0x0,
endaddr = uint.MaxValue,
flags = (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_ENABLED
}
: new m64p_breakpoint()
{
address = address.Value,
endaddr = address.Value + 0x03,
flags = (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_ENABLED
};
switch(type)
{
@ -936,18 +944,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
{
int index = 0;
// Convert null (any) address to breakpoint with max range
uint size = address != null ? 4 : uint.MaxValue;
address ??= 0x0;
switch(type)
{
case BreakType.Read:
index = m64pDebugBreakpointLookup(address.Value, 4, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_READ);
index = m64pDebugBreakpointLookup(address.Value, size, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_READ);
break;
case BreakType.Write:
index = m64pDebugBreakpointLookup(address.Value, 4, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_WRITE);
index = m64pDebugBreakpointLookup(address.Value, size, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_WRITE);
break;
case BreakType.Execute:
index = m64pDebugBreakpointLookup(address.Value, 4, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_EXEC);
index = m64pDebugBreakpointLookup(address.Value, size, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_EXEC);
break;
}