c# side to jag debugging improvements
This commit is contained in:
parent
740cd1f8d4
commit
c9618b3f92
|
@ -8,20 +8,167 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
{
|
||||
public partial class JaguarDisassembler : VerifiedDisassembler
|
||||
{
|
||||
private readonly MC68000 _disassembler = new();
|
||||
private readonly MC68000 _m68kDisassembler = new();
|
||||
|
||||
public override string PCRegisterName => "PC";
|
||||
|
||||
public override IEnumerable<string> AvailableCpus => new[] { "M68000" };
|
||||
|
||||
public override string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
public string DisassembleM68K(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
_disassembler.ReadByte = a => (sbyte)m.PeekByte(a);
|
||||
_disassembler.ReadWord = a => (short)m.PeekUshort(a, true);
|
||||
_disassembler.ReadLong = a => (int)m.PeekUint(a, true);
|
||||
var info = _disassembler.Disassemble((int)addr);
|
||||
_m68kDisassembler.ReadByte = a => (sbyte)m.PeekByte(a);
|
||||
_m68kDisassembler.ReadWord = a => (short)m.PeekUshort(a, true);
|
||||
_m68kDisassembler.ReadLong = a => (int)m.PeekUint(a, true);
|
||||
var info = _m68kDisassembler.Disassemble((int)addr);
|
||||
length = info.Length;
|
||||
return $"{info.RawBytes.Substring(0, 4):X4} {info.Mnemonic,-7} {info.Args}";
|
||||
}
|
||||
|
||||
// TOM and JERRY RISC processors are mostly similar, only 6 instructions differ
|
||||
// most of this is taken from virtualjaguar's dasmjag function
|
||||
public string DisassembleRISC(bool gpu, MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
var opcode = m.PeekUshort(addr, true);
|
||||
var arg1 = (opcode >> 5) & 0x1F;
|
||||
var arg2 = opcode & 0x1F;
|
||||
length = (opcode >> 10) == 0x26 ? 6 : 2;
|
||||
|
||||
string argRR() => $"r{arg1:d02}, r{arg2:d02}";
|
||||
string argCZIR() => $"${(arg1 == 0 ? 32 : arg1):X02}, r{arg2:d02}";
|
||||
string argIR() => $"${arg1:X02}, r{arg2:d02}";
|
||||
string argR2() => $"r{arg2:d02}";
|
||||
string argSR()
|
||||
{
|
||||
var s1 = (short)(arg1 << 11) >> 11;
|
||||
if (s1 < 0)
|
||||
{
|
||||
return $"-${-s1:X02}, r{arg2:d02}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"${s1:X02}, r{arg2:d02}";
|
||||
}
|
||||
}
|
||||
string argDRR() => $"(r{arg1:d02}), r{arg2:d02}";
|
||||
string argRDR() => $"r{arg2:d02}, (r{arg1:d02})";
|
||||
string argDROR(int r) => $"(r{r:d02} + ${(arg1 == 0 ? 128 : arg1 * 4):X02}), r{arg2:d02}";
|
||||
string argRDRO(int r) => $"r{arg2:d02}, (r{r:d02} + ${(arg1 == 0 ? 128 : arg1 * 4):X02})";
|
||||
string argDRORR(int r) => $"(r{r:d02} + r{arg1:d02}), r{arg2:d02}";
|
||||
string argRDROR(int r) => $"r{arg1:d02}, (r{r:d02} + r{arg2:d02})";
|
||||
string argCC()
|
||||
{
|
||||
return arg2 switch
|
||||
{
|
||||
0x00 => "",
|
||||
0x01 => "nz, ",
|
||||
0x02 => "z, ",
|
||||
0x04 => "nc, ",
|
||||
0x05 => "nc nz, ",
|
||||
0x06 => "nc z, ",
|
||||
0x08 => "c, ",
|
||||
0x09 => "c nz, ",
|
||||
0x0A => "c z, ",
|
||||
0x14 => "nn, ",
|
||||
0x15 => "nn nz, ",
|
||||
0x16 => "nn z, ",
|
||||
0x18 => "n, ",
|
||||
0x19 => "n nz, ",
|
||||
0x1A => "n z, ",
|
||||
0x1F => "never, ",
|
||||
_ => "???, ",
|
||||
};
|
||||
}
|
||||
|
||||
return (opcode >> 10) switch
|
||||
{
|
||||
0x00 => $"add {argRR()}",
|
||||
0x01 => $"addc {argRR()}",
|
||||
0x02 => $"addq {argCZIR()}",
|
||||
0x03 => $"addqt {argCZIR()}",
|
||||
0x04 => $"sub {argRR()}",
|
||||
0x05 => $"subc {argRR()}",
|
||||
0x06 => $"subq {argCZIR()}",
|
||||
0x07 => $"subqt {argCZIR()}",
|
||||
0x08 => $"neg {argR2()}",
|
||||
0x09 => $"and {argRR()}",
|
||||
0x0A => $"or {argRR()}",
|
||||
0x0B => $"xor {argRR()}",
|
||||
0x0C => $"not {argR2()}",
|
||||
0x0D => $"btet {argIR()}",
|
||||
0x0E => $"bset {argIR()}",
|
||||
0x0F => $"bclr {argIR()}",
|
||||
0x10 => $"mult {argRR()}",
|
||||
0x11 => $"imult {argRR()}",
|
||||
0x12 => $"imultn {argRR()}",
|
||||
0x13 => $"resmac {argR2()}",
|
||||
0x14 => $"imacn {argRR()}",
|
||||
0x15 => $"div {argRR()}",
|
||||
0x16 => $"abs {argR2()}",
|
||||
0x17 => $"sh {argRR()}",
|
||||
0x18 => $"shlq ${32 - arg1:X02}, {argR2()}",
|
||||
0x19 => $"shrq {argCZIR()}",
|
||||
0x1A => $"sha {argRR()}",
|
||||
0x1B => $"sharq {argCZIR()}",
|
||||
0x1C => $"ror {argRR()}",
|
||||
0x1D => $"rorq {argCZIR()}",
|
||||
0x1E => $"cmp {argRR()}",
|
||||
0x1F => $"cmpq {argSR()}",
|
||||
0x20 => gpu ? $"sat8 {argR2()}" : $"subqmod {argCZIR()}",
|
||||
0x21 => $"{(gpu ? "sat16" : "sub16s")} {argR2()}",
|
||||
0x22 => $"move {argRR()}",
|
||||
0x23 => $"moveq {argIR()}",
|
||||
0x24 => $"moveta {argRR()}",
|
||||
0x25 => $"movefa {argRR()}",
|
||||
0x26 => $"movei ${m.PeekUshort(addr + 2, true) | (m.PeekUshort(addr + 4, true) << 16):X04} {argR2()}",
|
||||
0x27 => $"loadb {argDRR()}",
|
||||
0x28 => $"loadw {argDRR()}",
|
||||
0x29 => $"load {argDRR()}",
|
||||
0x2A => gpu ? $"loadp {argDRR()}" : $"sat32s {argR2()}",
|
||||
0x2B => $"load {argDROR(14)}",
|
||||
0x2C => $"load {argDROR(15)}",
|
||||
0x2D => $"storeb {argRDR()}",
|
||||
0x2E => $"storew {argRDR()}",
|
||||
0x2F => $"store {argRDR()}",
|
||||
0x30 => gpu ? $"storep {argRDR()}" : $"mirror {argR2()}",
|
||||
0x31 => $"store {argRDRO(14)}",
|
||||
0x32 => $"store {argRDRO(15)}",
|
||||
0x33 => $"move pc, {argR2()}",
|
||||
0x34 => $"jump {argCC()}(r{arg1:d02})",
|
||||
0x35 => $"jr {argCC()}${addr + 2 + ((sbyte)(arg1 << 3) >> 2):X02}",
|
||||
0x36 => $"mmult {argRR()}",
|
||||
0x37 => $"mtoi {argRR()}",
|
||||
0x38 => $"normi {argRR()}",
|
||||
0x39 => $"nop",
|
||||
0x3A => $"load {argDRORR(14)}",
|
||||
0x3B => $"load {argDRORR(15)}",
|
||||
0x3C => $"store {argRDROR(14)}",
|
||||
0x3D => $"store {argRDROR(15)}",
|
||||
0x3E => gpu ? $"sat24 {argR2()}" : $"illegal [{arg1:d02}, {arg2:d02}]",
|
||||
0x3F => gpu ? $"{(arg1 == 0 ? "pack" : "unpack")} {argR2()}" : $"addqmod {argCZIR()}",
|
||||
_ => throw new InvalidOperationException(),
|
||||
};
|
||||
}
|
||||
|
||||
public override string PCRegisterName => Cpu switch
|
||||
{
|
||||
"M68000" => "M68K PC",
|
||||
"TOM" => "GPU PC",
|
||||
"JERRY" => "DSP PC",
|
||||
_ => throw new InvalidOperationException(),
|
||||
};
|
||||
|
||||
public override IEnumerable<string> AvailableCpus => new[]
|
||||
{
|
||||
"M68000",
|
||||
"TOM",
|
||||
"JERRY",
|
||||
};
|
||||
|
||||
public override string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
return Cpu switch
|
||||
{
|
||||
"M68000" => DisassembleM68K(m, addr, out length),
|
||||
"TOM" => DisassembleRISC(true, m, addr, out length),
|
||||
"JERRY" => DisassembleRISC(false, m, addr, out length),
|
||||
_ => throw new InvalidOperationException(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,15 +110,18 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
public abstract void SetMemoryCallback(int which, MemoryCallback callback);
|
||||
|
||||
[UnmanagedFunctionPointer(CC)]
|
||||
public delegate void TraceCallback(IntPtr regs);
|
||||
public delegate void M68KTraceCallback(IntPtr regs);
|
||||
|
||||
[UnmanagedFunctionPointer(CC)]
|
||||
public delegate void RISCTraceCallback(uint pc, IntPtr regs);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void SetTraceCallback(TraceCallback callback);
|
||||
public abstract void SetTraceCallbacks(M68KTraceCallback cpuTraceCallback, RISCTraceCallback gpuTraceCallback, RISCTraceCallback dspTraceCallback);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void GetRegisters(uint[] regs);
|
||||
public abstract void GetRegisters(IntPtr regs);
|
||||
|
||||
public enum M68KRegisters : uint
|
||||
public enum M68KRegisters : int
|
||||
{
|
||||
D0, D1, D2, D3, D4, D5, D6, D7,
|
||||
A0, A1, A2, A3, A4, A5, A6, A7,
|
||||
|
@ -126,6 +129,6 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
}
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void SetRegister(M68KRegisters which, int val);
|
||||
public abstract void SetRegister(int which, int val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,24 +7,69 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
{
|
||||
partial class VirtualJaguar : IDebuggable
|
||||
{
|
||||
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
|
||||
public unsafe IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
|
||||
{
|
||||
uint[] regs = new uint[18];
|
||||
_core.GetRegisters(regs);
|
||||
// 148 registers, oh my
|
||||
uint* regs = stackalloc uint[18 + 32 + 32 + 32 + 32 + 2];
|
||||
_core.GetRegisters((IntPtr)regs);
|
||||
|
||||
var ret = new Dictionary<string, RegisterValue>();
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
ret[$"D{i}"] = regs[i];
|
||||
ret[$"A{i}"] = regs[8 + i];
|
||||
ret[$"M68K D{i}"] = regs[i];
|
||||
ret[$"M68K A{i}"] = regs[8 + i];
|
||||
}
|
||||
ret["PC"] = regs[16];
|
||||
ret["SR"] = regs[17];
|
||||
ret["M68K PC"] = regs[16];
|
||||
ret["M68K SR"] = regs[17];
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
// registers aren't really 0-63, but it's two banks of 32 registers
|
||||
ret[$"GPU R{i}"] = regs[18 + i];
|
||||
ret[$"DSP R{i}"] = regs[82 + i];
|
||||
}
|
||||
ret["GPU PC"] = regs[146];
|
||||
ret["DSP PC"] = regs[147];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void SetCpuRegister(string register, int value)
|
||||
=> _core.SetRegister((LibVirtualJaguar.M68KRegisters)Enum.Parse(typeof(LibVirtualJaguar.M68KRegisters), register.ToUpperInvariant()), value);
|
||||
{
|
||||
register = register.ToUpperInvariant();
|
||||
if (register.StartsWith("M68K "))
|
||||
{
|
||||
var reg = Enum.Parse(typeof(LibVirtualJaguar.M68KRegisters), register.Remove(0, 5));
|
||||
_core.SetRegister((int)reg, value);
|
||||
}
|
||||
else if (register.StartsWith("GPU ") || register.StartsWith("DSP "))
|
||||
{
|
||||
bool gpu = register.StartsWith("GPU ");
|
||||
var regName = register.Remove(0, 4);
|
||||
|
||||
if (regName == "PC")
|
||||
{
|
||||
_core.SetRegister(gpu ? 146 : 147, value);
|
||||
}
|
||||
else if (regName.StartsWith("R"))
|
||||
{
|
||||
var offset = gpu ? 18 : 82;
|
||||
var reg = int.Parse(regName.Remove(0, 1));
|
||||
if (reg > 63)
|
||||
{
|
||||
throw new ArgumentException("Invalid register", nameof(register));
|
||||
}
|
||||
_core.SetRegister(offset + reg, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Invalid register", nameof(register));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Invalid register", nameof(register));
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanStep(StepType type)
|
||||
=> false;
|
||||
|
|
|
@ -5,15 +5,19 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
||||
{
|
||||
public partial class VirtualJaguar : ISettable<object, VirtualJaguar.VirtualJaguarSyncSettings>
|
||||
public partial class VirtualJaguar : ISettable<VirtualJaguar.VirtualJaguarSettings, VirtualJaguar.VirtualJaguarSyncSettings>
|
||||
{
|
||||
private VirtualJaguarSettings _settings;
|
||||
private VirtualJaguarSyncSettings _syncSettings;
|
||||
|
||||
public object GetSettings()
|
||||
=> null;
|
||||
public VirtualJaguarSettings GetSettings()
|
||||
=> _settings.Clone();
|
||||
|
||||
public PutSettingsDirtyBits PutSettings(object o)
|
||||
=> PutSettingsDirtyBits.None;
|
||||
public PutSettingsDirtyBits PutSettings(VirtualJaguarSettings o)
|
||||
{
|
||||
_settings = o;
|
||||
return PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
public VirtualJaguarSyncSettings GetSyncSettings()
|
||||
=> _syncSettings.Clone();
|
||||
|
@ -25,6 +29,30 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
public class VirtualJaguarSettings
|
||||
{
|
||||
[DisplayName("Trace M68K (CPU)")]
|
||||
[Description("")]
|
||||
[DefaultValue(true)]
|
||||
public bool TraceCPU { get; set; }
|
||||
|
||||
[DisplayName("Trace TOM (GPU)")]
|
||||
[Description("")]
|
||||
[DefaultValue(false)]
|
||||
public bool TraceGPU { get; set; }
|
||||
|
||||
[DisplayName("Trace JERRY (DSP)")]
|
||||
[Description("")]
|
||||
[DefaultValue(false)]
|
||||
public bool TraceDSP { get; set; }
|
||||
|
||||
public VirtualJaguarSettings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
|
||||
public VirtualJaguarSettings Clone()
|
||||
=> (VirtualJaguarSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public class VirtualJaguarSyncSettings
|
||||
{
|
||||
[DisplayName("Player 1 Controller Connected")]
|
||||
|
@ -43,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
public bool NTSC { get; set; }
|
||||
|
||||
[DisplayName("Skip BIOS")]
|
||||
[Description("BIOS file must still be present")]
|
||||
[Description("BIOS file must still be present. Ignored (set to true) for Jaguar CD")]
|
||||
[DefaultValue(true)]
|
||||
public bool SkipBIOS { get; set; }
|
||||
|
||||
|
|
|
@ -7,13 +7,15 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
public partial class VirtualJaguar
|
||||
{
|
||||
private ITraceable Tracer { get; }
|
||||
private readonly LibVirtualJaguar.TraceCallback _traceCallback;
|
||||
private readonly LibVirtualJaguar.M68KTraceCallback _cpuTraceCallback;
|
||||
private readonly LibVirtualJaguar.RISCTraceCallback _gpuTraceCallback;
|
||||
private readonly LibVirtualJaguar.RISCTraceCallback _dspTraceCallback;
|
||||
|
||||
private unsafe void MakeTrace(IntPtr r)
|
||||
private unsafe void MakeCPUTrace(IntPtr r)
|
||||
{
|
||||
uint* regs = (uint*)r;
|
||||
var pc = regs[16] & 0xFFFFFF;
|
||||
var disasm = _disassembler.Disassemble(this.AsMemoryDomains().SystemBus, pc, out _);
|
||||
var disasm = _disassembler.DisassembleM68K(this.AsMemoryDomains().SystemBus, pc, out _);
|
||||
var regInfo = string.Empty;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
|
@ -31,6 +33,37 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
(sr & 4) > 0 ? "Z" : "z",
|
||||
(sr & 2) > 0 ? "V" : "v",
|
||||
(sr & 1) > 0 ? "C" : "c");
|
||||
regInfo += " (M68K)";
|
||||
|
||||
Tracer.Put(new(disassembly: $"{pc:X6}: {disasm}".PadRight(50), registerInfo: regInfo));
|
||||
}
|
||||
|
||||
private unsafe void MakeGPUTrace(uint pc, IntPtr r)
|
||||
{
|
||||
uint* regs = (uint*)r;
|
||||
pc &= 0xFFFFFF;
|
||||
var disasm = _disassembler.DisassembleRISC(true, this.AsMemoryDomains().SystemBus, pc, out _);
|
||||
var regInfo = string.Empty;
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
regInfo += $"r{i}:{regs[i]:X8} ";
|
||||
}
|
||||
regInfo += "(GPU)";
|
||||
|
||||
Tracer.Put(new(disassembly: $"{pc:X6}: {disasm}".PadRight(50), registerInfo: regInfo));
|
||||
}
|
||||
|
||||
private unsafe void MakeDSPTrace(uint pc, IntPtr r)
|
||||
{
|
||||
uint* regs = (uint*)r;
|
||||
pc &= 0xFFFFFF;
|
||||
var disasm = _disassembler.DisassembleRISC(false, this.AsMemoryDomains().SystemBus, pc, out _);
|
||||
var regInfo = string.Empty;
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
regInfo += $"r{i}:{regs[i]:X8} ";
|
||||
}
|
||||
regInfo += "(DSP)";
|
||||
|
||||
Tracer.Put(new(disassembly: $"{pc:X6}: {disasm}".PadRight(50), registerInfo: regInfo));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
private readonly JaguarDisassembler _disassembler;
|
||||
|
||||
[CoreConstructor(VSystemID.Raw.JAG)]
|
||||
public VirtualJaguar(CoreLoadParameters<object, VirtualJaguarSyncSettings> lp)
|
||||
public VirtualJaguar(CoreLoadParameters<VirtualJaguarSettings, VirtualJaguarSyncSettings> lp)
|
||||
: base(lp.Comm, new Configuration
|
||||
{
|
||||
DefaultWidth = 326,
|
||||
|
@ -31,6 +31,7 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
SystemId = VSystemID.Raw.JAG,
|
||||
})
|
||||
{
|
||||
_settings = lp.Settings ?? new();
|
||||
_syncSettings = lp.SyncSettings ?? new();
|
||||
|
||||
ControllerDefinition = CreateControllerDefinition(_syncSettings.P1Active, _syncSettings.P2Active);
|
||||
|
@ -38,7 +39,9 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
VsyncNumerator = _syncSettings.NTSC ? 60 : 50;
|
||||
|
||||
InitMemoryCallbacks();
|
||||
_traceCallback = MakeTrace;
|
||||
_cpuTraceCallback = MakeCPUTrace;
|
||||
_gpuTraceCallback = MakeGPUTrace;
|
||||
_dspTraceCallback = MakeDSPTrace;
|
||||
_cdTocCallback = CDTOCCallback;
|
||||
_cdReadCallback = CDReadCallback;
|
||||
|
||||
|
@ -52,7 +55,7 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
MmapHeapSizeKB = 64 * 1024,
|
||||
SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
|
||||
SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
|
||||
}, new Delegate[] { _readCallback, _writeCallback, _execCallback, _traceCallback, _cdTocCallback, _cdReadCallback, });
|
||||
}, new Delegate[] { _readCallback, _writeCallback, _execCallback, _cpuTraceCallback, _gpuTraceCallback, _dspTraceCallback, _cdTocCallback, _cdReadCallback, });
|
||||
|
||||
var bios = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("Jaguar", "Bios"));
|
||||
if (bios.Length != 0x20000)
|
||||
|
@ -117,7 +120,9 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
_disassembler = new();
|
||||
_serviceProvider.Register<IDisassemblable>(_disassembler);
|
||||
|
||||
const string TRACE_HEADER = "M68K: PC, machine code, mnemonic, operands, registers (D0-D7, A0-A7, SR), flags (XNZVC)";
|
||||
// bleh
|
||||
const string TRACE_HEADER = "M68K: PC, machine code, mnemonic, operands, registers (D0-D7, A0-A7, SR), flags (XNZVC)\r\n"
|
||||
+ "GPU/DSP: PC, machine code, mnemonic, operands, registers (r0-r32)";
|
||||
Tracer = new TraceBuffer(TRACE_HEADER);
|
||||
_serviceProvider.Register(Tracer);
|
||||
}
|
||||
|
@ -198,7 +203,18 @@ namespace BizHawk.Emulation.Cores.Atari.Jaguar
|
|||
|
||||
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_core.SetTraceCallback(Tracer.IsEnabled() ? _traceCallback : null);
|
||||
if (Tracer.IsEnabled())
|
||||
{
|
||||
_core.SetTraceCallbacks(
|
||||
_settings.TraceCPU ? _cpuTraceCallback : null,
|
||||
_settings.TraceGPU ? _gpuTraceCallback : null,
|
||||
_settings.TraceDSP ? _dspTraceCallback : null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_core.SetTraceCallbacks(null, null, null);
|
||||
}
|
||||
|
||||
DriveLightOn = false;
|
||||
|
||||
return new LibVirtualJaguar.FrameInfo()
|
||||
|
|
Loading…
Reference in New Issue