diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/LibQuickNES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/LibQuickNES.cs index 24a76a5e43..6eab122a15 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/LibQuickNES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/LibQuickNES.cs @@ -180,6 +180,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES /// 0 to hide, 8 for normal, 64 for all [DllImport(dllname, CallingConvention = CallingConvention.Cdecl)] public static extern void qn_set_sprite_limit(IntPtr e, int n); + /// + /// get memory area for debugging + /// + /// Context + /// + /// + /// + /// + /// + /// + [DllImport(dllname, CallingConvention = CallingConvention.Cdecl)] + public static extern bool qn_get_memory_area(IntPtr e, int which, ref IntPtr data, ref int size, ref bool writable, ref IntPtr name); /// /// handle "string error" as returned by some quicknes functions diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index 1ff94aca08..d7377adce5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -9,6 +9,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES { public class QuickNES : IEmulator, IVideoProvider, ISyncSoundProvider { + #region FPU precision + private class FPCtrl : IDisposable { [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] @@ -36,6 +38,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES FPCtrl FP = new FPCtrl(); + #endregion + static QuickNES() { LibQuickNES.qn_setup_mappers(); @@ -58,6 +62,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES InitSaveStateBuff(); InitVideo(); InitAudio(); + InitMemoryDomains(); } catch { @@ -266,16 +271,58 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES private set; } - public MemoryDomainList MemoryDomains + #region debugging + + unsafe void InitMemoryDomains() { - get { return MemoryDomainList.GetDummyList(); } + List mm = new List(); + for (int i = 0; ; i++) + { + IntPtr data = IntPtr.Zero; + int size = 0; + bool writable = false; + IntPtr name = IntPtr.Zero; + + if (!LibQuickNES.qn_get_memory_area(Context, i, ref data, ref size, ref writable, ref name)) + break; + + if (data != IntPtr.Zero && size > 0 && name != IntPtr.Zero) + { + byte* p = (byte*)data; + + mm.Add(new MemoryDomain + ( + Marshal.PtrToStringAnsi(name), + size, + MemoryDomain.Endian.Unknown, + delegate(int addr) + { + if (addr < 0 || addr >= size) + throw new ArgumentOutOfRangeException(); + return p[addr]; + }, + delegate(int addr, byte val) + { + if (!writable) + return; + if (addr < 0 || addr >= size) + throw new ArgumentOutOfRangeException(); + p[addr] = val; + })); + } + } + MemoryDomains = new MemoryDomainList(mm, 0); } + public MemoryDomainList MemoryDomains { get; private set; } + public List> GetCpuFlagsAndRegisters() { return new List>(); } + #endregion + #region settings public object GetSettings() diff --git a/output/dll/libquicknes.dll b/output/dll/libquicknes.dll index 05a9485860..8b713d283a 100644 Binary files a/output/dll/libquicknes.dll and b/output/dll/libquicknes.dll differ diff --git a/quicknes/bizinterface.cpp b/quicknes/bizinterface.cpp index 5cfa683fcd..c35d70e8b0 100644 --- a/quicknes/bizinterface.cpp +++ b/quicknes/bizinterface.cpp @@ -193,3 +193,38 @@ EXPORT void qn_set_sprite_limit(Nes_Emu *e, int n) { e->set_sprite_mode((Nes_Emu::sprite_mode_t)n); } + +EXPORT int qn_get_memory_area(Nes_Emu *e, int which, const void **data, int *size, int *writable, const char **name) +{ + if (!data || !size || !writable || !name) + return 0; + switch (which) + { + default: + return 0; + case 0: + *data = e->low_mem(); + *size = e->low_mem_size; + *writable = 1; + *name = "RAM"; + return 1; + case 1: + *data = e->high_mem(); + *size = e->high_mem_size; + *writable = 1; + *name = "WRAM"; + return 1; + case 2: + *data = e->chr_mem(); + *size = e->chr_size(); + *writable = 0; + *name = "CHR"; + return 1; + case 3: + *data = e->nametable_mem(); + *size = e->nametable_size(); + *writable = 0; + *name = "CIRAM (nametables)"; + return 1; + } +}