clean things up and make gpgx fully (?) multi-instance correct

This commit is contained in:
nattthebear 2017-05-28 13:46:08 -04:00
parent 7d0330bb9e
commit 7f2e06b0b5
9 changed files with 226 additions and 147 deletions

View File

@ -7,9 +7,10 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
using System.Drawing.Imaging;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx64;
using BizHawk.Common;
namespace BizHawk.Client.EmuHawk
{
@ -18,7 +19,8 @@ namespace BizHawk.Client.EmuHawk
[RequiredService]
private GPGX Emu { get; set; }
private LibGPGX.VDPView View = new LibGPGX.VDPView();
private GPGX.VDPView View;
int palindex = 0;
protected override System.Drawing.Point ScrollToControl(System.Windows.Forms.Control activeControl)
@ -121,12 +123,12 @@ namespace BizHawk.Client.EmuHawk
public void NewUpdate(ToolFormUpdateType type) { }
public void UpdateValues()
public unsafe void UpdateValues()
{
if (Emu == null)
return;
Emu.UpdateVDPViewContext(View);
unsafe
using ((View = Emu.UpdateVDPViewContext()).EnterExit())
{
int* pal = (int*)View.ColorCache;
//for (int i = 0; i < 0x40; i++)
@ -138,6 +140,7 @@ namespace BizHawk.Client.EmuHawk
DrawNameTable(View.NTA, VRAMNT, tiles, pal, bmpViewNTA);
DrawNameTable(View.NTB, VRAMNT, tiles, pal, bmpViewNTB);
DrawNameTable(View.NTW, VRAMNT, tiles, pal, bmpViewNTW);
View = null;
}
}

View File

@ -10,7 +10,8 @@ namespace BizHawk.Emulation.Common
public Func<long, byte> Peek
{
get { return _peek; } set { _peek = value; }
get { return _peek; }
set { _peek = value; }
}
public Action<long, byte> Poke
@ -228,4 +229,53 @@ namespace BizHawk.Emulation.Common
WordSize = 2;
}
}
public unsafe class MemoryDomainIntPtrSwap16Monitor : MemoryDomain
{
public IntPtr Data { get; set; }
private readonly IMonitor _monitor;
public override byte PeekByte(long addr)
{
if ((ulong)addr < (ulong)Size)
{
using (_monitor.EnterExit())
{
return ((byte*)Data)[addr ^ 1];
}
}
throw new ArgumentOutOfRangeException(nameof(addr));
}
public override void PokeByte(long addr, byte val)
{
if (Writable)
{
if ((ulong)addr < (ulong)Size)
{
using (_monitor.EnterExit())
{
((byte*)Data)[addr ^ 1] = val;
}
}
else
{
throw new ArgumentOutOfRangeException(nameof(addr));
}
}
}
public MemoryDomainIntPtrSwap16Monitor(string name, Endian endian, IntPtr data, long size, bool writable,
IMonitor monitor)
{
Name = name;
EndianType = endian;
Data = data;
Size = size;
Writable = writable;
WordSize = 2;
_monitor = monitor;
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
@ -11,6 +12,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
private IMemoryDomains MemoryDomains;
private unsafe void SetMemoryDomains()
{
using (_elf.EnterExit())
{
var mm = new List<MemoryDomain>();
for (int i = LibGPGX.MIN_MEM_DOMAIN; i <= LibGPGX.MAX_MEM_DOMAIN; i++)
@ -30,6 +33,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
if (addr < 0 || addr >= 65536)
throw new ArgumentOutOfRangeException();
using (_elf.EnterExit())
return p[addr ^ 1];
},
delegate (long addr, byte val)
@ -40,11 +44,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
},
wordSize: 2));
}
else
{
// TODO: are the Z80 domains really Swap16 in the core? Check this
mm.Add(new MemoryDomainIntPtrSwap16(name, MemoryDomain.Endian.Big, area, size, name != "MD CART" && name != "CD BOOT ROM"));
mm.Add(new MemoryDomainIntPtrSwap16Monitor(name, MemoryDomain.Endian.Big, area, size, name != "MD CART" && name != "CD BOOT ROM", _elf));
}
}
var m68Bus = new MemoryDomainDelegate("M68K BUS", 0x1000000, MemoryDomain.Endian.Big,
@ -65,6 +68,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
mm.Add(m68Bus);
if (IsMegaCD)
{
var s68Bus = new MemoryDomainDelegate("S68K BUS", 0x1000000, MemoryDomain.Endian.Big,
delegate (long addr)
{
@ -81,8 +86,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
Core.gpgx_write_s68k_bus(a, val);
}, 2);
if (IsMegaCD)
{
mm.Add(s68Bus);
}
@ -93,3 +97,4 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
}
}
}
}

View File

@ -4,6 +4,7 @@ using System.IO;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using System.Runtime.InteropServices;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
@ -17,6 +18,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
return new byte[0];
byte[] ret = new byte[size];
using (_elf.EnterExit())
Marshal.Copy(area, ret, 0, size);
return ret;
}

View File

@ -1,6 +1,7 @@
using System;
using BizHawk.Emulation.Common;
using System.Runtime.InteropServices;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
@ -50,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
Core.gpgx_get_audio(ref nsamp, ref src);
if (src != IntPtr.Zero)
{
using (_elf.EnterExit())
Marshal.Copy(src, samples, 0, nsamp * 2);
}
}

View File

@ -62,9 +62,5 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
ms.Close();
return ms.ToArray();
}
private void InitStateBuffers()
{
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using BizHawk.Emulation.Common;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
@ -47,6 +48,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
return;
}
using (_elf.EnterExit())
{
int gppitch, gpwidth, gpheight;
IntPtr src = IntPtr.Zero;
@ -82,6 +85,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
}
}
}
}
}
}

View File

@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using BizHawk.Common.BizInvoke;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Waterbox;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
{
@ -40,8 +41,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
throw new InvalidOperationException("ROM too big! Did you try to load a CD as a ROM?");
}
try
{
_elf = new PeRunner(new PeRunnerOptions
{
Path = comm.CoreFileProvider.DllPath(),
@ -52,11 +51,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
SpecialHeapSizeKB = 64
});
if (_elf.ShouldMonitor)
Core = BizInvoker.GetInvoker<LibGPGX>(_elf, _elf);
else
Core = BizInvoker.GetInvoker<LibGPGX>(_elf);
using (_elf.EnterExit())
{
_syncSettings = (GPGXSyncSettings)syncSettings ?? new GPGXSyncSettings();
_settings = (GPGXSettings)settings ?? new GPGXSettings();
@ -110,7 +107,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
break;
}
if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
throw new Exception("gpgx_init() failed");
@ -131,10 +127,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
_elf.Seal();
Core.gpgx_set_cdd_callback(cd_callback_handle);
// compute state size
InitStateBuffers();
SetControllerDefinition();
// pull the default video size from the core
@ -160,11 +152,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
}
catch
{
Dispose();
throw;
}
}
private LibGPGX Core;
@ -382,10 +369,46 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
public bool IsMegaCD { get { return CD != null; } }
public void UpdateVDPViewContext(LibGPGX.VDPView view)
public class VDPView : IMonitor
{
Core.gpgx_get_vdp_view(view);
private readonly IMonitor _m;
public VDPView(LibGPGX.VDPView v, IMonitor m)
{
_m = m;
VRAM = v.VRAM;
PatternCache = v.PatternCache;
ColorCache = v.ColorCache;
NTA = v.NTA;
NTB = v.NTB;
NTW = v.NTW;
}
public IntPtr VRAM;
public IntPtr PatternCache;
public IntPtr ColorCache;
public LibGPGX.VDPNameTable NTA;
public LibGPGX.VDPNameTable NTB;
public LibGPGX.VDPNameTable NTW;
public void Enter()
{
_m.Enter();
}
public void Exit()
{
_m.Exit();
}
}
public VDPView UpdateVDPViewContext()
{
var v = new LibGPGX.VDPView();
Core.gpgx_get_vdp_view(v);
Core.gpgx_flush_vram(); // fully regenerate internal caches as needed
return new VDPView(v, _elf);
}
public DisplayType Region { get; private set; }

View File

@ -15,9 +15,9 @@ namespace BizHawk.Emulation.Cores.Waterbox
public abstract class Swappable : IMonitor, IDisposable
{
/// <summary>
/// start address, or 0 if we don't need to be swapped
/// start address
/// </summary>
private ulong _lockkey = 0;
private ulong _lockkey;
/// <summary>
/// the the relevant lockinfo for this core
@ -42,16 +42,10 @@ namespace BizHawk.Emulation.Cores.Waterbox
protected void Initialize(ulong lockkey)
{
_lockkey = lockkey;
if (lockkey != 0)
{
if (lockkey == 0)
throw new NullReferenceException();
_currentLockInfo = LockInfos.GetOrAdd(_lockkey, new LockInfo { Sync = new object() });
}
}
/// <summary>
/// true if the IMonitor should be used for native calls
/// </summary>
public bool ShouldMonitor { get { return _lockkey != 0; } }
// any Swappable is assumed to conflict with any other Swappable at the same base address,
// but not any other starting address. so don't put them too close together!