2014-11-23 16:10:46 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Emulation.Common
|
|
|
|
|
{
|
2016-03-02 02:10:09 +00:00
|
|
|
|
/// <summary>
|
2017-04-19 14:41:26 +00:00
|
|
|
|
/// This service manages debugging capabilities from the core to the client. Tools such as the debugger make use of this, as well as LUA scripting
|
|
|
|
|
/// This service specifically manages getting/setting CPU registers, managing breakpoints, and stepping through CPU instructions
|
2016-03-02 02:10:09 +00:00
|
|
|
|
/// Providing a disassembly is managed by another service, these are aspects outside of the disassembler that are essential to debugging tools
|
|
|
|
|
/// Tools like the debugger will gracefully degrade based on the availability of each component of this service,
|
|
|
|
|
/// it is expected that any of these features will throw a NotImplementedException if not implemented, and the client will manage accordingly
|
|
|
|
|
/// </summary>
|
2014-12-15 22:25:06 +00:00
|
|
|
|
public interface IDebuggable : IEmulatorService
|
2014-11-23 16:10:46 +00:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2017-04-19 14:41:26 +00:00
|
|
|
|
/// Returns a list of CPU registers and their current state
|
2014-11-23 16:10:46 +00:00
|
|
|
|
/// </summary>
|
2014-12-20 13:16:15 +00:00
|
|
|
|
IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters();
|
2014-11-23 16:10:46 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2017-04-19 14:41:26 +00:00
|
|
|
|
/// Sets a given CPU register to the given value
|
2014-11-23 16:10:46 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
void SetCpuRegister(string register, int value);
|
2014-12-05 00:05:40 +00:00
|
|
|
|
|
2016-12-13 21:56:20 +00:00
|
|
|
|
/// <summary>
|
2017-04-19 14:41:26 +00:00
|
|
|
|
/// Gets a memory callback implementation that manages memory callback functionality
|
2016-12-13 21:56:20 +00:00
|
|
|
|
/// </summary>
|
2014-12-05 01:56:45 +00:00
|
|
|
|
IMemoryCallbackSystem MemoryCallbacks { get; }
|
2014-12-14 18:58:16 +00:00
|
|
|
|
|
2014-12-20 13:29:57 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Informs the calling code whether or not the given step type is implemented,
|
|
|
|
|
/// if false, a NotImplementedException will be thrown if Step is called with the given value
|
|
|
|
|
/// </summary>
|
|
|
|
|
bool CanStep(StepType type);
|
2014-12-15 22:19:10 +00:00
|
|
|
|
|
2014-12-20 13:29:57 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Advances the core based on the given Step type
|
|
|
|
|
/// </summary>
|
2014-12-15 22:19:10 +00:00
|
|
|
|
void Step(StepType type);
|
2017-01-10 01:23:05 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2017-04-19 14:41:26 +00:00
|
|
|
|
/// Gets the total number of CPU cycles since the beginning of the core's lifecycle
|
|
|
|
|
/// Note that the CPU in this case is the "main" CPU, for some cores that may be somewhat subjective
|
2017-01-10 01:23:05 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
int TotalExecutedCycles { get; } // TODO: this should probably be a long, but most cores were using int, oh well
|
2014-11-23 16:10:46 +00:00
|
|
|
|
}
|
2014-12-20 03:19:33 +00:00
|
|
|
|
|
2014-12-20 13:16:15 +00:00
|
|
|
|
public class RegisterValue
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
public ulong Value { get; private set; }
|
|
|
|
|
public byte BitSize { get; private set; }
|
|
|
|
|
|
|
|
|
|
public RegisterValue(ulong val, byte bitSize)
|
|
|
|
|
{
|
|
|
|
|
if (bitSize == 64)
|
2016-02-29 00:03:01 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
Value = val;
|
2016-02-29 00:03:01 +00:00
|
|
|
|
}
|
2016-02-21 19:00:11 +00:00
|
|
|
|
else if (bitSize > 64 || bitSize == 0)
|
2016-02-29 00:03:01 +00:00
|
|
|
|
{
|
2017-04-10 12:36:42 +00:00
|
|
|
|
throw new System.ArgumentOutOfRangeException(nameof(bitSize), "BitSize must be in 1..64");
|
2016-02-29 00:03:01 +00:00
|
|
|
|
}
|
2016-02-21 19:00:11 +00:00
|
|
|
|
else
|
2016-02-29 00:03:01 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
Value = val & (1UL << bitSize) - 1;
|
2016-02-29 00:03:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-21 19:00:11 +00:00
|
|
|
|
BitSize = bitSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(bool val)
|
|
|
|
|
{
|
|
|
|
|
Value = val ? 1UL : 0UL;
|
|
|
|
|
BitSize = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(byte val)
|
|
|
|
|
{
|
|
|
|
|
Value = val;
|
|
|
|
|
BitSize = 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(sbyte val)
|
|
|
|
|
{
|
|
|
|
|
Value = (byte)val;
|
|
|
|
|
BitSize = 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(ushort val)
|
|
|
|
|
{
|
|
|
|
|
Value = val;
|
|
|
|
|
BitSize = 16;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(short val)
|
|
|
|
|
{
|
|
|
|
|
Value = (ushort)val;
|
|
|
|
|
BitSize = 16;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(uint val)
|
|
|
|
|
{
|
|
|
|
|
Value = val;
|
|
|
|
|
BitSize = 32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(int val)
|
|
|
|
|
{
|
|
|
|
|
Value = (uint)val;
|
|
|
|
|
BitSize = 32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(ulong val)
|
|
|
|
|
{
|
|
|
|
|
Value = val;
|
|
|
|
|
BitSize = 64;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RegisterValue(long val)
|
|
|
|
|
{
|
|
|
|
|
Value = (ulong)val;
|
|
|
|
|
BitSize = 64;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:16:15 +00:00
|
|
|
|
public static implicit operator RegisterValue(bool val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:16:15 +00:00
|
|
|
|
public static implicit operator RegisterValue(byte val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static implicit operator RegisterValue(sbyte val)
|
|
|
|
|
{
|
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:16:15 +00:00
|
|
|
|
public static implicit operator RegisterValue(ushort val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-21 19:00:11 +00:00
|
|
|
|
public static implicit operator RegisterValue(short val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:16:15 +00:00
|
|
|
|
public static implicit operator RegisterValue(uint val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-21 19:00:11 +00:00
|
|
|
|
public static implicit operator RegisterValue(int val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:16:15 +00:00
|
|
|
|
public static implicit operator RegisterValue(ulong val)
|
2014-12-20 03:19:33 +00:00
|
|
|
|
{
|
2016-02-21 19:00:11 +00:00
|
|
|
|
return new RegisterValue(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static implicit operator RegisterValue(long val)
|
|
|
|
|
{
|
|
|
|
|
return new RegisterValue(val);
|
2014-12-20 03:19:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-11-23 16:10:46 +00:00
|
|
|
|
}
|