170 lines
4.2 KiB
C#
170 lines
4.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using BizHawk.Emulation.Common;
|
|
using BizHawk.Emulation.Cores.Nintendo.N64.NativeApi;
|
|
|
|
namespace BizHawk.Emulation.Cores.Nintendo.N64
|
|
{
|
|
public partial class N64 : IDebuggable
|
|
{
|
|
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
|
|
{
|
|
// note: the approach this code takes is highly bug-prone
|
|
// warning: tracer magically relies on these register names!
|
|
var ret = new Dictionary<string, RegisterValue>();
|
|
var data = new byte[32 * 8 + 4 + 4 + 8 + 8 + 4 + 4 + 32 * 4 + 32 * 8];
|
|
api.getRegisters(data);
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
var reg = BitConverter.ToInt64(data, i * 8);
|
|
ret.Add(GPRnames[i] + "_lo", (int)(reg));
|
|
ret.Add(GPRnames[i] + "_hi", (int)(reg >> 32));
|
|
}
|
|
|
|
var PC = BitConverter.ToUInt32(data, 32 * 8);
|
|
ret.Add("PC", (int)PC);
|
|
|
|
ret.Add("LL", BitConverter.ToInt32(data, 32 * 8 + 4));
|
|
|
|
var Lo = BitConverter.ToInt64(data, 32 * 8 + 4 + 4);
|
|
ret.Add("LO_lo", (int)Lo);
|
|
ret.Add("LO_hi", (int)(Lo >> 32));
|
|
|
|
var Hi = BitConverter.ToInt64(data, 32 * 8 + 4 + 4 + 8);
|
|
ret.Add("HI_lo", (int)Hi);
|
|
ret.Add("HI_hi", (int)(Hi >> 32));
|
|
|
|
ret.Add("FCR0", BitConverter.ToInt32(data, 32 * 8 + 4 + 4 + 8 + 8));
|
|
ret.Add("FCR31", BitConverter.ToInt32(data, 32 * 8 + 4 + 4 + 8 + 8 + 4));
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
var reg_cop0 = BitConverter.ToUInt32(data, 32 * 8 + 4 + 4 + 8 + 8 + 4 + 4 + i * 4);
|
|
ret.Add("CP0 REG" + i, (int)reg_cop0);
|
|
}
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
var reg_cop1_fgr_64 = BitConverter.ToInt64(data, 32 * 8 + 4 + 4 + 8 + 8 + 4 + 4 + 32 * 4 + i * 8);
|
|
ret.Add("CP1 FGR REG" + i + "_lo", (int)reg_cop1_fgr_64);
|
|
ret.Add("CP1 FGR REG" + i + "_hi", (int)(reg_cop1_fgr_64 >> 32));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public string[] GPRnames = new string[32]
|
|
{
|
|
"r0",
|
|
"at",
|
|
"v0", "v1",
|
|
"a0", "a1", "a2", "a3",
|
|
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
|
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
|
"t8", "t9",
|
|
"k0", "k1",
|
|
"gp",
|
|
"sp",
|
|
"s8",
|
|
"ra"
|
|
};
|
|
|
|
[FeatureNotImplemented]
|
|
public void SetCpuRegister(string register, int value)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public IMemoryCallbackSystem MemoryCallbacks
|
|
{
|
|
get { return _memorycallbacks; }
|
|
}
|
|
|
|
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem();
|
|
|
|
public bool CanStep(StepType type)
|
|
{
|
|
switch(type)
|
|
{
|
|
case StepType.Into:
|
|
return false; // Implemented but disabled for now. Should be re-enabled once BizHawk supports mid-frame pausing.
|
|
case StepType.Out:
|
|
return false;
|
|
case StepType.Over:
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
[FeatureNotImplemented]
|
|
public int TotalExecutedCycles
|
|
{
|
|
get { throw new NotImplementedException(); }
|
|
}
|
|
|
|
public void Step(StepType type)
|
|
{
|
|
switch(type)
|
|
{
|
|
case StepType.Into:
|
|
api.Step();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void SetBreakpointHandler()
|
|
{
|
|
var mcs = MemoryCallbacks;
|
|
|
|
api.BreakpointHit += delegate(uint address, mupen64plusApi.BreakType type)
|
|
{
|
|
api.OnBreakpoint(new mupen64plusApi.BreakParams
|
|
{
|
|
_type = type,
|
|
_addr = address,
|
|
_mcs = mcs
|
|
});
|
|
};
|
|
}
|
|
|
|
private void AddBreakpoint(IMemoryCallback callback)
|
|
{
|
|
switch(callback.Type)
|
|
{
|
|
case MemoryCallbackType.Read:
|
|
api.SetBreakpoint(mupen64plusApi.BreakType.Read, callback.Address);
|
|
break;
|
|
|
|
case MemoryCallbackType.Write:
|
|
api.SetBreakpoint(mupen64plusApi.BreakType.Write, callback.Address);
|
|
break;
|
|
|
|
case MemoryCallbackType.Execute:
|
|
api.SetBreakpoint(mupen64plusApi.BreakType.Execute, callback.Address);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void RemoveBreakpoint(IMemoryCallback callback)
|
|
{
|
|
switch(callback.Type)
|
|
{
|
|
case MemoryCallbackType.Read:
|
|
api.RemoveBreakpoint(mupen64plusApi.BreakType.Read, callback.Address);
|
|
break;
|
|
|
|
case MemoryCallbackType.Write:
|
|
api.RemoveBreakpoint(mupen64plusApi.BreakType.Write, callback.Address);
|
|
break;
|
|
|
|
case MemoryCallbackType.Execute:
|
|
api.RemoveBreakpoint(mupen64plusApi.BreakType.Execute, callback.Address);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|