BizHawk/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs

142 lines
3.6 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("REG" + i + "_lo", (int)(reg));
ret.Add("REG" + 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;
}
[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) { return false; }
[FeatureNotImplemented]
public void Step(StepType type) { throw new NotImplementedException(); }
private mupen64plusApi.MemoryCallback _readcb;
private mupen64plusApi.MemoryCallback _writecb;
private mupen64plusApi.MemoryCallback _executecb;
private void RefreshMemoryCallbacks()
{
var mcs = MemoryCallbacks;
// we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point
if (mcs.HasReads)
{
_readcb = delegate(uint addr)
{
api.OnBreakpoint(new mupen64plusApi.BreakParams
{
_type = mupen64plusApi.BreakType.Read,
_addr = addr,
_mcs = mcs
});
};
}
else
{
_readcb = null;
}
if (mcs.HasWrites)
{
_writecb = delegate(uint addr)
{
api.OnBreakpoint(new mupen64plusApi.BreakParams
{
_type = mupen64plusApi.BreakType.Write,
_addr = addr,
_mcs = mcs
});
};
}
else
{
_writecb = null;
}
if (mcs.HasExecutes)
{
_executecb = delegate(uint addr)
{
api.OnBreakpoint(new mupen64plusApi.BreakParams
{
_type = mupen64plusApi.BreakType.Execute,
_addr = addr,
_mcs = mcs
});
};
}
else
{
_executecb = null;
}
api.setReadCallback(_readcb);
api.setWriteCallback(_writecb);
api.setExecuteCallback(_executecb);
}
}
}