diff --git a/BizHawk.Emulation/Consoles/Sega/Saturn/LibYabause.cs b/BizHawk.Emulation/Consoles/Sega/Saturn/LibYabause.cs index 05e98c4cc2..c05e5f1601 100644 --- a/BizHawk.Emulation/Consoles/Sega/Saturn/LibYabause.cs +++ b/BizHawk.Emulation/Consoles/Sega/Saturn/LibYabause.cs @@ -102,11 +102,37 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn public static extern void libyabause_deinit(); [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_savesaveram(string fn); - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern bool libyabause_savesaveram(string fn); + [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] public static extern bool libyabause_loadsaveram(string fn); [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void libyabause_clearsaveram(); + [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern bool libyabause_saveramodified(); + + public struct NativeMemoryDomain + { + public IntPtr data; + public string name; + public int length; + } + + [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr libyabause_getmemoryareas(); + + public static IEnumerable libyabause_getmemoryareas_ex() + { + var ret = new List(); + IntPtr start = libyabause_getmemoryareas(); + while (true) + { + var nmd = (NativeMemoryDomain)Marshal.PtrToStructure(start, typeof(NativeMemoryDomain)); + if (nmd.data == IntPtr.Zero || nmd.name == null) + return ret.AsReadOnly(); + ret.Add(nmd); + start += Marshal.SizeOf(typeof(NativeMemoryDomain)); + } + } /// /// diff --git a/BizHawk.Emulation/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation/Consoles/Sega/Saturn/Yabause.cs index 8ed69f0939..d696496f66 100644 --- a/BizHawk.Emulation/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation/Consoles/Sega/Saturn/Yabause.cs @@ -78,6 +78,8 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn BufferWidth = 320; BufferHeight = 224; + + InitMemoryDomains(); } public ControllerDefinition ControllerDefinition @@ -214,8 +216,8 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn public bool SaveRamModified { - get { return true; } - set { if (!value) throw new InvalidOperationException(); } + get { return LibYabause.libyabause_saveramodified(); } + set { throw new InvalidOperationException("No you may not!"); } } #endregion @@ -353,15 +355,53 @@ namespace BizHawk.Emulation.Consoles.Sega.Saturn public CoreComm CoreComm { get; private set; } - public IList MemoryDomains + #region memorydomains + + void InitMemoryDomains() { - get { throw new NotImplementedException(); } + var ret = new List(); + var nmds = LibYabause.libyabause_getmemoryareas_ex(); + foreach (var nmd in nmds) + { + int l = nmd.length; + IntPtr d = nmd.data; + ret.Add(new MemoryDomain( + nmd.name, + nmd.length, + Endian.Little, + delegate(int addr) + { + if (addr < 0 || addr >= l) + throw new ArgumentOutOfRangeException(); + unsafe + { + byte* p = (byte*)d; + return p[addr]; + } + }, + delegate(int addr, byte val) + { + if (addr < 0 || addr >= l) + throw new ArgumentOutOfRangeException(); + unsafe + { + byte* p = (byte*)d; + //p[addr] = val; + } + } + )); + } + // fulfill the prophecy of MainMemory always being MemoryDomains[0] + var tmp = ret[2]; + ret[2] = ret[0]; + ret[0] = tmp; + MemoryDomains = ret.AsReadOnly(); } - public MemoryDomain MainMemory - { - get { throw new NotImplementedException(); } - } + public IList MemoryDomains { get; private set; } + public MemoryDomain MainMemory { get { return MemoryDomains[0]; } } + + #endregion public void Dispose() { diff --git a/BizHawk.MultiClient/output/dll/libyabause.dll b/BizHawk.MultiClient/output/dll/libyabause.dll index dee0a20f0e..0911a812d6 100644 Binary files a/BizHawk.MultiClient/output/dll/libyabause.dll and b/BizHawk.MultiClient/output/dll/libyabause.dll differ diff --git a/yabause/src/libyabause/yui.cpp b/yabause/src/libyabause/yui.cpp index 2796e59819..b16aa32ee7 100644 --- a/yabause/src/libyabause/yui.cpp +++ b/yabause/src/libyabause/yui.cpp @@ -202,11 +202,51 @@ extern "C" __declspec(dllexport) int libyabause_loadsaveram(const char *fn) return !T123Load(BupRam, 0x10000, 1, fn); } +extern "C" __declspec(dllexport) int libyabause_saveramodified() +{ + return BupRamWritten; +} + extern "C" __declspec(dllexport) void libyabause_clearsaveram() { FormatBackupRam(BupRam, 0x10000); } +typedef struct +{ + void *data; + const char *name; + int length; +} memoryarea; + +memoryarea normmemareas[] = +{ + {NULL, "Boot Rom", 512 * 1024}, + {NULL, "Backup Ram", 64 * 1024}, + {NULL, "Work Ram Low", 1024 * 1024}, + {NULL, "Sound Ram", 512 * 1024}, + {NULL, "VDP1 Ram", 512 * 1024}, + {NULL, "VDP1 Framebuffer", 512 * 1024}, + {NULL, "VDP2 Ram", 512 * 1024}, + {NULL, "VDP2 CRam", 4 * 1024}, + {NULL, "Work Ram High", 1024 * 1024}, + {NULL, NULL, 0} +}; + +extern "C" __declspec(dllexport) memoryarea *libyabause_getmemoryareas() +{ + normmemareas[0].data = BiosRom; + normmemareas[1].data = BupRam; + normmemareas[2].data = LowWram; + normmemareas[3].data = SoundRam; + normmemareas[4].data = Vdp1Ram; + normmemareas[5].data = Vdp1FrameBuffer; + normmemareas[6].data = Vdp2Ram; + normmemareas[7].data = Vdp2ColorRam; + normmemareas[8].data = HighWram; + return &normmemareas[0]; +} + extern "C" __declspec(dllexport) int libyabause_frameadvance(int *w, int *h, int *nsamp) { LagFrameFlag = 1; diff --git a/yabause/src/vdp1.h b/yabause/src/vdp1.h index 5f82e0c691..4e30d01ef4 100644 --- a/yabause/src/vdp1.h +++ b/yabause/src/vdp1.h @@ -66,6 +66,8 @@ extern VideoInterface_struct *VIDCore; extern VideoInterface_struct VIDDummy; extern u8 * Vdp1Ram; +// purely for debugging purposes +extern u8 *Vdp1FrameBuffer; u8 FASTCALL Vdp1RamReadByte(u32); u16 FASTCALL Vdp1RamReadWord(u32);