split arm7 polling/touch screen polling to a new "alt lag" variable and add a setting for whether to consider these sources (fixes #3278)
add in new disasm system (taken from https://github.com/MAP233224/dthumb), works much better than darm
This commit is contained in:
parent
d3d90eb70d
commit
347fa24820
Binary file not shown.
|
@ -38,6 +38,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
public byte TouchY;
|
||||
public byte MicVolume;
|
||||
public byte GBALightSensor;
|
||||
public bool ConsiderAltLag;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
@ -112,21 +113,24 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
[BizImport(CC)]
|
||||
public abstract void SetMemoryCallback(int which, MemoryCallback callback);
|
||||
|
||||
// bit 0 -> ARM9 or ARM7
|
||||
// bit 1 -> ARM or THUMB mode
|
||||
public enum CpuTypes : uint
|
||||
[Flags]
|
||||
public enum TraceMask : uint
|
||||
{
|
||||
ARM9,
|
||||
ARM7,
|
||||
ARM9_THUMB,
|
||||
ARM7_THUMB,
|
||||
NONE = 0,
|
||||
ARM7_THUMB = 1,
|
||||
ARM7_ARM = 2,
|
||||
ARM9_THUMB = 4,
|
||||
ARM9_ARM = 8,
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CC)]
|
||||
public delegate void TraceCallback(CpuTypes _cpu, IntPtr _regs, uint _opcode);
|
||||
public delegate void TraceCallback(TraceMask type, IntPtr regs, IntPtr disasm, uint cyclesOff);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void SetTraceCallback(TraceCallback callback);
|
||||
public abstract void SetTraceCallback(TraceCallback callback, TraceMask mask);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void GetDisassembly(TraceMask type, uint opcode, byte[] ret);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract IntPtr GetFrameThreadProc();
|
||||
|
|
|
@ -71,6 +71,45 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
[DefaultValue(AudioBitrateType.Auto)]
|
||||
public AudioBitrateType AudioBitrate { get; set; }
|
||||
|
||||
[DisplayName("Alt Lag")]
|
||||
[Description("If true, touch screen polling and ARM7 key polling will be considered for lag frames. Otherwise, only ARM9 key polling will be considered.")]
|
||||
[DefaultValue(false)]
|
||||
public bool ConsiderAltLag { get; set; }
|
||||
|
||||
[DisplayName("Trace ARM7 Thumb")]
|
||||
[Description("")]
|
||||
[DefaultValue(false)]
|
||||
public bool TraceArm7Thumb { get; set; }
|
||||
|
||||
[DisplayName("Trace ARM7 ARM")]
|
||||
[Description("")]
|
||||
[DefaultValue(false)]
|
||||
public bool TraceArm7Arm { get; set; }
|
||||
|
||||
[DisplayName("Trace ARM9 Thumb")]
|
||||
[Description("")]
|
||||
[DefaultValue(false)]
|
||||
public bool TraceArm9Thumb { get; set; }
|
||||
|
||||
[DisplayName("Trace ARM9 ARM")]
|
||||
[Description("")]
|
||||
[DefaultValue(true)]
|
||||
public bool TraceArm9Arm { get; set; }
|
||||
|
||||
public LibMelonDS.TraceMask GetTraceMask()
|
||||
{
|
||||
var ret = LibMelonDS.TraceMask.NONE;
|
||||
if (TraceArm7Thumb)
|
||||
ret |= LibMelonDS.TraceMask.ARM7_THUMB;
|
||||
if (TraceArm7Arm)
|
||||
ret |= LibMelonDS.TraceMask.ARM7_ARM;
|
||||
if (TraceArm9Thumb)
|
||||
ret |= LibMelonDS.TraceMask.ARM9_THUMB;
|
||||
if (TraceArm9Arm)
|
||||
ret |= LibMelonDS.TraceMask.ARM9_ARM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public NDSSettings Clone() => MemberwiseClone() as NDSSettings;
|
||||
|
||||
public static bool NeedsScreenResize(NDSSettings x, NDSSettings y)
|
||||
|
|
|
@ -10,44 +10,43 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
private ITraceable Tracer { get; }
|
||||
private readonly LibMelonDS.TraceCallback _tracecb;
|
||||
|
||||
private void MakeTrace(LibMelonDS.CpuTypes _cpu, IntPtr _regs, uint _opcode)
|
||||
private unsafe void MakeTrace(LibMelonDS.TraceMask type, IntPtr r, IntPtr disasm, uint cyclesOff)
|
||||
{
|
||||
string cpu = _cpu switch
|
||||
{
|
||||
LibMelonDS.CpuTypes.ARM9 => "ARM9",
|
||||
LibMelonDS.CpuTypes.ARM7 => "ARM7",
|
||||
LibMelonDS.CpuTypes.ARM9_THUMB => "ARM9 (Thumb)",
|
||||
LibMelonDS.CpuTypes.ARM7_THUMB => "ARM7 (Thumb)",
|
||||
string cpu = type switch
|
||||
{
|
||||
LibMelonDS.TraceMask.ARM7_THUMB => "ARM7 (Thumb)",
|
||||
LibMelonDS.TraceMask.ARM7_ARM => "ARM7",
|
||||
LibMelonDS.TraceMask.ARM9_THUMB => "ARM9 (Thumb)",
|
||||
LibMelonDS.TraceMask.ARM9_ARM => "ARM9",
|
||||
_ => throw new InvalidOperationException("Invalid CPU Mode???"),
|
||||
};
|
||||
|
||||
int[] regs = new int[16];
|
||||
Marshal.Copy(_regs, regs, 0, 16);
|
||||
uint* regs = (uint*)r;
|
||||
|
||||
bool isthumb = ((uint)_cpu & 2u) == 2u;
|
||||
uint pc = (uint)regs[15] - (isthumb ? 2u : 4u); // handle prefetch
|
||||
bool isthumb = type is LibMelonDS.TraceMask.ARM7_THUMB or LibMelonDS.TraceMask.ARM9_THUMB;
|
||||
uint pc = regs[15] - (isthumb ? 2u : 4u); // handle prefetch
|
||||
|
||||
Tracer.Put(new(
|
||||
disassembly: string.Format("{0:x8}", pc).PadRight(12) + _disassembler.Trace(pc, _opcode, isthumb).PadRight(32),
|
||||
disassembly: string.Format("{0:x8}", pc).PadRight(12) + Marshal.PtrToStringAnsi(disasm).PadRight(64),
|
||||
registerInfo: string.Format(
|
||||
"r0:{0:x8} r1:{1:x8} r2:{2:x8} r3:{3:x8} r4:{4:x8} r5:{5:x8} r6:{6:x8} r7:{7:x8} r8:{8:x8} r9:{9:x8} r10:{10:x8} r11:{11:x8} r12:{12:x8} r13:{13:x8} r14:{14:x8} r15:{15:x8} Cy:{16} {17}",
|
||||
(uint)regs[0],
|
||||
(uint)regs[1],
|
||||
(uint)regs[2],
|
||||
(uint)regs[3],
|
||||
(uint)regs[4],
|
||||
(uint)regs[5],
|
||||
(uint)regs[6],
|
||||
(uint)regs[7],
|
||||
(uint)regs[8],
|
||||
(uint)regs[9],
|
||||
(uint)regs[10],
|
||||
(uint)regs[11],
|
||||
(uint)regs[12],
|
||||
(uint)regs[13],
|
||||
(uint)regs[14],
|
||||
(uint)regs[15],
|
||||
TotalExecutedCycles,
|
||||
regs[0],
|
||||
regs[1],
|
||||
regs[2],
|
||||
regs[3],
|
||||
regs[4],
|
||||
regs[5],
|
||||
regs[6],
|
||||
regs[7],
|
||||
regs[8],
|
||||
regs[9],
|
||||
regs[10],
|
||||
regs[11],
|
||||
regs[12],
|
||||
regs[13],
|
||||
regs[14],
|
||||
regs[15],
|
||||
CycleCount + cyclesOff,
|
||||
cpu)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
_resampler = new SpeexResampler(SpeexResampler.Quality.QUALITY_DEFAULT, 32768, 44100, 32768, 44100, null, this);
|
||||
_serviceProvider.Register<ISoundProvider>(_resampler);
|
||||
|
||||
_disassembler = new NDSDisassembler();
|
||||
_disassembler = new(_core);
|
||||
_serviceProvider.Register<IDisassemblable>(_disassembler);
|
||||
|
||||
const string TRACE_HEADER = "ARM9+ARM7: PC, opcode, registers (r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, Cy, CpuMode)";
|
||||
|
@ -327,7 +327,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_core.SetTraceCallback(Tracer.IsEnabled() ? _tracecb : null);
|
||||
_core.SetTraceCallback(Tracer.IsEnabled() ? _tracecb : null, _settings.GetTraceMask());
|
||||
return new LibMelonDS.FrameInfo
|
||||
{
|
||||
Time = GetRtcTime(!DeterministicEmulation),
|
||||
|
@ -336,6 +336,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
TouchY = (byte)controller.AxisValue("Touch Y"),
|
||||
MicVolume = (byte)controller.AxisValue("Mic Volume"),
|
||||
GBALightSensor = (byte)controller.AxisValue("GBA Light Sensor"),
|
||||
ConsiderAltLag = _settings.ConsiderAltLag,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using BizHawk.BizInvoke;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components.ARM;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||
{
|
||||
public class NDSDisassembler : VerifiedDisassembler
|
||||
{
|
||||
private static readonly Darm _libdarm = BizInvoker.GetInvoker<Darm>(
|
||||
new DynamicLibraryImportResolver(OSTailoredCode.IsUnixHost ? "libdarm.so" : "libdarm.dll", hasLimitedLifetime: false),
|
||||
CallingConventionAdapters.Native
|
||||
);
|
||||
private readonly LibMelonDS _core;
|
||||
|
||||
public NDSDisassembler(LibMelonDS core)
|
||||
=> _core = core;
|
||||
|
||||
public override IEnumerable<string> AvailableCpus => new[]
|
||||
{
|
||||
|
@ -29,52 +28,37 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
if (m is NDS.NDSSystemBus NdsSysBus)
|
||||
{
|
||||
NdsSysBus.UseArm9 = int.Parse(Cpu.Substring(5, 1)) == 5;
|
||||
m = NdsSysBus;
|
||||
}
|
||||
|
||||
var ret = new byte[64];
|
||||
var type = Cpu switch
|
||||
{
|
||||
"ARM v5" => LibMelonDS.TraceMask.ARM9_ARM,
|
||||
"ARM v5 (Thumb)" => LibMelonDS.TraceMask.ARM9_THUMB,
|
||||
"ARM v4" => LibMelonDS.TraceMask.ARM7_ARM,
|
||||
"ARM v4 (Thumb)" => LibMelonDS.TraceMask.ARM7_THUMB,
|
||||
_ => throw new Exception("Invalid CPU mode?"),
|
||||
};
|
||||
|
||||
if (Cpu.Length == 14)
|
||||
{
|
||||
addr &= ~1u;
|
||||
int op = m.PeekByte(addr) | m.PeekByte(addr + 1) << 8;
|
||||
string ret = _libdarm.DisassembleStuff(addr | 1, (uint)op);
|
||||
uint op = m.PeekByte(addr) | (uint)m.PeekByte(addr + 1) << 8;
|
||||
_core.GetDisassembly(type, op, ret);
|
||||
length = 2;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr &= ~3u;
|
||||
int op = m.PeekByte(addr)
|
||||
| m.PeekByte(addr + 1) << 8
|
||||
| m.PeekByte(addr + 2) << 16
|
||||
| m.PeekByte(addr + 3) << 24;
|
||||
string ret = _libdarm.DisassembleStuff(addr, (uint)op);
|
||||
uint op = m.PeekByte(addr)
|
||||
| (uint)m.PeekByte(addr + 1) << 8
|
||||
| (uint)m.PeekByte(addr + 2) << 16
|
||||
| (uint)m.PeekByte(addr + 3) << 24;
|
||||
_core.GetDisassembly(type, op, ret);
|
||||
length = 4;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public string Trace(uint pc, uint op, bool isthumb)
|
||||
{
|
||||
if (isthumb)
|
||||
{
|
||||
pc &= ~1u;
|
||||
string ret = _libdarm.DisassembleStuff(pc | 1, op);
|
||||
if (ret == null)
|
||||
{
|
||||
ret = "Can't disassemble???";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
pc &= ~3u;
|
||||
string ret = _libdarm.DisassembleStuff(pc, op);
|
||||
if (ret == null)
|
||||
{
|
||||
ret = "Can't disassemble???";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return Encoding.ASCII.GetString(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -339,6 +339,7 @@ struct MyFrameInfo : public FrameInfo
|
|||
u8 TouchY;
|
||||
s8 MicVolume;
|
||||
s8 GBALightSensor;
|
||||
bool ConsiderAltLag;
|
||||
};
|
||||
|
||||
static s16 biz_mic_input[735];
|
||||
|
@ -424,6 +425,11 @@ EXPORT void FrameAdvance(MyFrameInfo* f)
|
|||
}
|
||||
f->Cycles = NDS::GetSysClockCycles(2);
|
||||
f->Lagged = NDS::LagFrameFlag;
|
||||
// if we want to consider other lag sources, use that lag flag if we haven't unlagged already
|
||||
if (f->ConsiderAltLag && NDS::LagFrameFlag)
|
||||
{
|
||||
f->Lagged = NDS::AltLagFrameFlag;
|
||||
}
|
||||
|
||||
RunningFrame = false;
|
||||
}
|
||||
|
@ -464,13 +470,52 @@ EXPORT void SetMemoryCallback(u32 which, void (*callback)(u32 addr))
|
|||
}
|
||||
}
|
||||
|
||||
void (*TraceCallback)(u32, u32*, u32) = nullptr;
|
||||
TraceMask_t TraceMask = TRACE_NONE;
|
||||
static void (*TraceCallback)(TraceMask_t, u32*, u8*, u32) = nullptr;
|
||||
#define TRACE_STRING_LENGTH 64
|
||||
typedef enum {
|
||||
ARMv4T, //ARM v4, THUMB v1
|
||||
ARMv5TE, //ARM v5, THUMB v2
|
||||
ARMv6, //ARM v6, THUMB v3
|
||||
} ARMARCH; //only 32-bit legacy architectures with THUMB support
|
||||
extern "C" unsigned int Disassemble_thumb(unsigned int code, unsigned char str[TRACE_STRING_LENGTH], unsigned int it, const unsigned char* cond, ARMARCH tv);
|
||||
extern "C" void Disassemble_arm(unsigned int code, unsigned char str[TRACE_STRING_LENGTH], ARMARCH av);
|
||||
|
||||
EXPORT void SetTraceCallback(void (*callback)(u32 cpu, u32* regs, u32 opcode))
|
||||
void TraceTrampoline(TraceMask_t type, u32* regs, u32 opcode)
|
||||
{
|
||||
static unsigned char disasm[TRACE_STRING_LENGTH];
|
||||
memset(disasm, 0, sizeof disasm);
|
||||
switch (type) {
|
||||
case TRACE_ARM7_THUMB: Disassemble_thumb(opcode, disasm, 0, nullptr, ARMv4T); break;
|
||||
case TRACE_ARM7_ARM: Disassemble_arm(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM9_THUMB: Disassemble_thumb(opcode, disasm, 0, nullptr, ARMv5TE); break;
|
||||
case TRACE_ARM9_ARM: Disassemble_arm(opcode, disasm, ARMv5TE); break;
|
||||
default: __builtin_unreachable();
|
||||
}
|
||||
TraceCallback(type, regs, disasm, NDS::GetSysClockCycles(2));
|
||||
}
|
||||
|
||||
EXPORT void SetTraceCallback(void (*callback)(TraceMask_t mask, u32* regs, u8* disasm, u32 cyclesOff), TraceMask_t mask)
|
||||
{
|
||||
TraceCallback = callback;
|
||||
TraceMask = callback ? mask : TRACE_NONE;
|
||||
}
|
||||
|
||||
EXPORT void GetDisassembly(TraceMask_t type, u32 opcode, char* ret)
|
||||
{
|
||||
static unsigned char disasm[TRACE_STRING_LENGTH];
|
||||
memset(disasm, 0, sizeof disasm);
|
||||
switch (type) {
|
||||
case TRACE_ARM7_THUMB: Disassemble_thumb(opcode, disasm, 0, nullptr, ARMv4T); break;
|
||||
case TRACE_ARM7_ARM: Disassemble_arm(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM9_THUMB: Disassemble_thumb(opcode, disasm, 0, nullptr, ARMv5TE); break;
|
||||
case TRACE_ARM9_ARM: Disassemble_arm(opcode, disasm, ARMv5TE); break;
|
||||
default: __builtin_unreachable();
|
||||
}
|
||||
memcpy(ret, disasm, TRACE_STRING_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
extern uintptr_t FrameThreadProc;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CCFLAGS := -Wno-discarded-qualifiers
|
||||
CCFLAGS := -Wno-discarded-qualifiers -Wno-pointer-sign
|
||||
|
||||
CXXFLAGS := -DMELONDS_VERSION="" \
|
||||
-I./melonDS/src -I./melonDS/src/teakra/include \
|
||||
|
@ -76,6 +76,7 @@ SRCS = \
|
|||
$(addprefix melonDS/src/,$(MISC_SRCS)) \
|
||||
BizConfig.cpp \
|
||||
BizInterface.cpp \
|
||||
BizPlatform.cpp
|
||||
BizPlatform.cpp \
|
||||
dthumb.c
|
||||
|
||||
include ../common.mak
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
|||
Subproject commit d0aff66cf671d9853974d374d39e11fd89d13819
|
||||
Subproject commit c9e835f87408ba9b00708941fc07e541eedcb3ec
|
Loading…
Reference in New Issue