diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index e00c027608..25a58fb886 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -877,10 +877,7 @@
       <DependentUpon>GPGX.cs</DependentUpon>
     </Compile>
     <Compile Include="Consoles\Sega\gpgx32\GPGXControlConverter.cs" />
-    <Compile Include="Consoles\Sega\gpgx32\GPGXControlConverterDynamic.cs" />
-    <Compile Include="Consoles\Sega\gpgx32\GPGXDynamic.cs" />
     <Compile Include="Consoles\Sega\gpgx32\LibGPGX.cs" />
-    <Compile Include="Consoles\Sega\gpgx32\LibGPGXDynamic.cs" />
     <Compile Include="Consoles\Sega\gpgx\GenDbgHlp.cs" />
     <Compile Include="Consoles\Sega\gpgx\GPGX.cs" />
     <Compile Include="Consoles\Sega\gpgx\GPGX.ICodeDataLogger.cs">
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXControlConverterDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXControlConverterDynamic.cs
deleted file mode 100644
index f1827c0992..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXControlConverterDynamic.cs
+++ /dev/null
@@ -1,264 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using BizHawk.Common;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
-{
-	public class GPGXControlConverterDynamic
-	{
-		// this isn't all done
-
-		struct CName
-		{
-			public string Name;
-			public LibGPGXDynamic.INPUT_KEYS Key;
-			public CName(string Name, LibGPGXDynamic.INPUT_KEYS Key)
-			{
-				this.Name = Name;
-				this.Key = Key;
-			}
-		}
-
-		static CName[] Genesis3 =
-		{
-			new CName("Up", LibGPGXDynamic.INPUT_KEYS.INPUT_UP),
-			new CName("Down", LibGPGXDynamic.INPUT_KEYS.INPUT_DOWN),
-			new CName("Left", LibGPGXDynamic.INPUT_KEYS.INPUT_LEFT),
-			new CName("Right", LibGPGXDynamic.INPUT_KEYS.INPUT_RIGHT),
-			new CName("A", LibGPGXDynamic.INPUT_KEYS.INPUT_A),
-			new CName("B", LibGPGXDynamic.INPUT_KEYS.INPUT_B),
-			new CName("C", LibGPGXDynamic.INPUT_KEYS.INPUT_C),
-			new CName("Start", LibGPGXDynamic.INPUT_KEYS.INPUT_START),
-		};
-
-		static CName[] Genesis6 = 
-		{
-			new CName("Up", LibGPGXDynamic.INPUT_KEYS.INPUT_UP),
-			new CName("Down", LibGPGXDynamic.INPUT_KEYS.INPUT_DOWN),
-			new CName("Left", LibGPGXDynamic.INPUT_KEYS.INPUT_LEFT),
-			new CName("Right", LibGPGXDynamic.INPUT_KEYS.INPUT_RIGHT),
-			new CName("A", LibGPGXDynamic.INPUT_KEYS.INPUT_A),
-			new CName("B", LibGPGXDynamic.INPUT_KEYS.INPUT_B),
-			new CName("C", LibGPGXDynamic.INPUT_KEYS.INPUT_C),
-			new CName("Start", LibGPGXDynamic.INPUT_KEYS.INPUT_START),
-			new CName("X", LibGPGXDynamic.INPUT_KEYS.INPUT_X),
-			new CName("Y", LibGPGXDynamic.INPUT_KEYS.INPUT_Y),
-			new CName("Z", LibGPGXDynamic.INPUT_KEYS.INPUT_Z),
-			new CName("Mode", LibGPGXDynamic.INPUT_KEYS.INPUT_MODE),
-		};
-
-		static CName[] Mouse =
-		{
-			new CName("Mouse Left", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_LEFT),
-			new CName("Mouse Center", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_CENTER),
-			new CName("Mouse Right", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_RIGHT),
-			new CName("Mouse Start", LibGPGXDynamic.INPUT_KEYS.INPUT_MOUSE_START),
-		};
-
-		static CName[] Lightgun =
-		{
-			new CName("Lightgun Trigger", LibGPGXDynamic.INPUT_KEYS.INPUT_MENACER_TRIGGER),
-			new CName("Lightgun Start", LibGPGXDynamic.INPUT_KEYS.INPUT_MENACER_START),
-		};
-
-		static CName[] Activator = 
-		{
-			new CName("1L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_1L),
-			new CName("1U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_1U),
-			new CName("2L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_2L),
-			new CName("2U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_2U),
-			new CName("3L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_3L),
-			new CName("3U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_3U),
-			new CName("4L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_4L),
-			new CName("4U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_4U),
-			new CName("5L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_5L),
-			new CName("5U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_5U),
-			new CName("6L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_6L),
-			new CName("6U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_6U),
-			new CName("7L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_7L),
-			new CName("7U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_7U),
-			new CName("8L", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_8L),
-			new CName("8U", LibGPGXDynamic.INPUT_KEYS.INPUT_ACTIVATOR_8U),
-		};
-
-		static CName[] XEA1P =
-		{
-			new CName("XE A", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_A),
-			new CName("XE B", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_B),
-			new CName("XE C", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_C),
-			new CName("XE D", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_D),
-			new CName("XE Start", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_START),
-			new CName("XE Select", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_SELECT),
-			new CName("XE E1", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_E1),
-			new CName("XE E2", LibGPGXDynamic.INPUT_KEYS.INPUT_XE_E2),
-		};
-
-		static ControllerDefinition.FloatRange MouseRange = new ControllerDefinition.FloatRange(-256, 0, 255);
-		// lightgun needs to be transformed to match the current screen resolution
-		static ControllerDefinition.FloatRange LightgunRange = new ControllerDefinition.FloatRange(0, 5000, 10000);
-
-		static ControllerDefinition.FloatRange XEA1PRange = new ControllerDefinition.FloatRange(-128, 0, 127);
-
-		LibGPGXDynamic.InputData target = null;
-		IController source = null;
-
-		List<Action> Converts = new List<Action>();
-
-		public ControllerDefinition ControllerDef { get; private set; }
-
-		void AddToController(int idx, int player, IEnumerable<CName> Buttons)
-		{
-			foreach (var Button in Buttons)
-			{
-				string Name = string.Format("P{0} {1}", player, Button.Name);
-				ControllerDef.BoolButtons.Add(Name);
-				var ButtonFlag = Button.Key;
-				Converts.Add(delegate()
-				{
-					if (source.IsPressed(Name))
-						target.pad[idx] |= ButtonFlag;
-				});
-			}
-		}
-
-		void DoMouseAnalog(int idx, int player)
-		{
-			string NX = string.Format("P{0} Mouse X", player);
-			string NY = string.Format("P{0} Mouse Y", player);
-			ControllerDef.FloatControls.Add(NX);
-			ControllerDef.FloatControls.Add(NY);
-			ControllerDef.FloatRanges.Add(MouseRange);
-			ControllerDef.FloatRanges.Add(MouseRange);
-			Converts.Add(delegate()
-			{
-				target.analog[(2 * idx) + 0] = (short)source.GetFloat(NX);
-				target.analog[(2 * idx) + 1] = (short)source.GetFloat(NY);
-			});
-		}
-
-		void DoLightgunAnalog(int idx, int player)
-		{
-			string NX = string.Format("P{0} Lightgun X", player);
-			string NY = string.Format("P{0} Lightgun Y", player);
-			ControllerDef.FloatControls.Add(NX);
-			ControllerDef.FloatControls.Add(NY);
-			ControllerDef.FloatRanges.Add(LightgunRange);
-			ControllerDef.FloatRanges.Add(LightgunRange);
-			Converts.Add(delegate()
-			{
-				target.analog[(2 * idx) + 0] = (short)(source.GetFloat(NX) / 10000.0f * (ScreenWidth - 1));
-				target.analog[(2 * idx) + 1] = (short)(source.GetFloat(NY) / 10000.0f * (ScreenHeight - 1));
-			});
-		}
-
-		void DoXEA1PAnalog(int idx, int player)
-		{
-			string NX = string.Format("P{0} Stick X", player);
-			string NY = string.Format("P{0} Stick Y", player);
-			string NZ = string.Format("P{0} Stick Z", player);
-			ControllerDef.FloatControls.Add(NX);
-			ControllerDef.FloatControls.Add(NY);
-			ControllerDef.FloatControls.Add(NZ);
-			ControllerDef.FloatRanges.Add(XEA1PRange);
-			ControllerDef.FloatRanges.Add(XEA1PRange);
-			ControllerDef.FloatRanges.Add(XEA1PRange);
-			Converts.Add(delegate()
-			{
-				target.analog[(2 * idx) + 0] = (short)(source.GetFloat(NX));
-				target.analog[(2 * idx) + 1] = (short)(source.GetFloat(NY));
-				// +2 is correct in how gpgx internally does this
-				target.analog[(2 * idx) + 2] = (short)(source.GetFloat(NZ));
-			});
-		}
-
-		public GPGXControlConverterDynamic(LibGPGXDynamic.InputData input)
-		{
-			Console.WriteLine("Genesis Controller report:");
-			foreach (var e in input.system)
-				Console.WriteLine("S:{0}", e);
-			foreach (var e in input.dev)
-				Console.WriteLine("D:{0}", e);
-
-			int player = 1;
-
-			ControllerDef = new ControllerDefinition();
-
-			ControllerDef.BoolButtons.Add("Power");
-			ControllerDef.BoolButtons.Add("Reset");
-
-			for (int i = 0; i < LibGPGXDynamic.MAX_DEVICES; i++)
-			{
-				switch (input.dev[i])
-				{
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PAD3B:
-						AddToController(i, player, Genesis3);
-						player++;
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PAD6B:
-						AddToController(i, player, Genesis6);
-						player++;
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_MOUSE:
-						AddToController(i, player, Mouse);
-						DoMouseAnalog(i, player);
-						player++;
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_NONE:
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_LIGHTGUN:
-						// supports menacers and justifiers
-						AddToController(i, player, Lightgun);
-						DoLightgunAnalog(i, player);
-						player++;
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PAD2B:
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PADDLE:
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_SPORTSPAD:
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_TEREBI:
-						throw new Exception("Master System only device?  Something went wrong.");
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_ACTIVATOR:
-						AddToController(i, player, Activator);
-						player++;
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_XE_A1P:
-						AddToController(i, player, XEA1P);
-						DoXEA1PAnalog(i, player);
-						player++;
-						break;
-					case LibGPGXDynamic.INPUT_DEVICE.DEVICE_PICO:
-						// PICO isn't finished on the unmanaged side either
-						throw new Exception("Sega PICO not implemented yet!");
-					default:
-						throw new Exception("Unknown Genesis control device!  Something went wrong.");
-				}
-			}
-
-			ControllerDef.Name = "GPGX Genesis Controller";
-		}
-
-		public void Convert(IController source, LibGPGXDynamic.InputData target)
-		{
-			this.source = source;
-			this.target = target;
-			target.ClearAllBools();
-			foreach (var f in Converts)
-				f();
-			this.source = null;
-			this.target = null;
-		}
-
-		/// <summary>
-		/// must be set for proper lightgun operation
-		/// </summary>
-		public int ScreenWidth { get; set; }
-		/// <summary>
-		/// must be set for proper lightgun operation
-		/// </summary>
-		public int ScreenHeight { get; set; }
-
-	}
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXDynamic.cs
deleted file mode 100644
index ad89e4d6f2..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/GPGXDynamic.cs
+++ /dev/null
@@ -1,900 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-using BizHawk.Common.BufferExtensions;
-using BizHawk.Emulation.Common;
-using BizHawk.Common;
-
-using System.Runtime.InteropServices;
-
-using System.IO;
-
-using System.ComponentModel;
-
-
-namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
-{
-	[CoreAttributes(
-		"Genplus-gx",
-		"",
-		isPorted: true,
-		isReleased: true,
-		portedVersion: "r874",
-		portedUrl: "https://code.google.com/p/genplus-gx/",
-		singleInstance: false
-		)]
-	public class GPGXDynamic : IEmulator, ISyncSoundProvider, IVideoProvider, ISaveRam, IStatable,
-		IInputPollable, IDebuggable, ISettable<GPGXDynamic.GPGXSettings, GPGXDynamic.GPGXSyncSettings>, IDriveLight
-	{
-		DiscSystem.Disc CD;
-		byte[] romfile;
-		bool drivelight;
-
-		bool disposed = false;
-
-		LibGPGXDynamic gpgx;
-		ElfRunner elf;
-
-		LibGPGXDynamic.load_archive_cb LoadCallback = null;
-		LibGPGXDynamic.input_cb InputCallback = null;
-
-		LibGPGXDynamic.InputData input = new LibGPGXDynamic.InputData();
-
-		public enum ControlType
-		{
-			None,
-			OnePlayer,
-			Normal,
-			Xea1p,
-			Activator,
-			Teamplayer,
-			Wayplay,
-			Mouse
-		};
-
-		//[CoreConstructor("GEN")]
-		public GPGXDynamic(CoreComm comm, byte[] file, object Settings, object SyncSettings)
-			: this(comm, file, null, Settings, SyncSettings)
-		{
-		}
-
-		public GPGXDynamic(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
-		{
-			ServiceProvider = new BasicServiceProvider(this);
-			(ServiceProvider as BasicServiceProvider).Register<ITraceable>(_tracer);
-			// this can influence some things internally
-			string romextension = "GEN";
-
-			// three or six button?
-			// http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds
-
-			//hack, don't use
-			//romfile = File.ReadAllBytes(@"D:\encodes\bizhawksrc\output\SANIC CD\PierSolar (E).bin");
-			if (rom != null && rom.Length > 16 * 1024 * 1024)
-			{
-				throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
-			}
-
-			elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"));
-			try
-			{
-				gpgx = new LibGPGXDynamic();
-				elf.PopulateInterface(gpgx);
-
-				_SyncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();
-
-				CoreComm = comm;
-
-				LoadCallback = new LibGPGXDynamic.load_archive_cb(load_archive);
-
-				this.romfile = rom;
-				this.CD = CD;
-
-				LibGPGXDynamic.INPUT_SYSTEM system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_NONE;
-				LibGPGXDynamic.INPUT_SYSTEM system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_NONE;
-
-				switch (this._SyncSettings.ControlType)
-				{
-					case ControlType.None:
-					default:
-						break;
-					case ControlType.Activator:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
-						system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
-						break;
-					case ControlType.Normal:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
-						system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
-						break;
-					case ControlType.OnePlayer:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
-						break;
-					case ControlType.Xea1p:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_XE_A1P;
-						break;
-					case ControlType.Teamplayer:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
-						system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
-						break;
-					case ControlType.Wayplay:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_WAYPLAY;
-						system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_WAYPLAY;
-						break;
-					case ControlType.Mouse:
-						system_a = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
-						// seems like mouse in port 1 would be supported, but not both at the same time
-						system_b = LibGPGXDynamic.INPUT_SYSTEM.SYSTEM_MOUSE;
-						break;
-				}
-
-
-				if (!gpgx.gpgx_init(romextension, LoadCallback, this._SyncSettings.UseSixButton, system_a, system_b, this._SyncSettings.Region))
-					throw new Exception("gpgx_init() failed");
-
-				{
-					int fpsnum = 60;
-					int fpsden = 1;
-					gpgx.gpgx_get_fps(ref fpsnum, ref fpsden);
-					CoreComm.VsyncNum = fpsnum;
-					CoreComm.VsyncDen = fpsden;
-					DisplayType = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
-				}
-
-				// compute state size
-				{
-					byte[] tmp = new byte[gpgx.gpgx_state_max_size()];
-					int size = gpgx.gpgx_state_size(tmp, tmp.Length);
-					if (size <= 0)
-						throw new Exception("Couldn't Determine GPGX internal state size!");
-					savebuff = new byte[size];
-					savebuff2 = new byte[savebuff.Length + 13];
-					Console.WriteLine("GPGX Internal State Size: {0}", size);
-				}
-
-				SetControllerDefinition();
-
-				// pull the default video size from the core
-				update_video_initial();
-
-				SetMemoryDomains();
-
-				InputCallback = new LibGPGXDynamic.input_cb(input_callback);
-				gpgx.gpgx_set_input_callback(InputCallback);
-
-				if (CD != null)
-					DriveLightEnabled = true;
-
-				PutSettings((GPGXSettings)Settings ?? new GPGXSettings());
-
-				InitMemCallbacks();
-				KillMemCallbacks();
-			}
-			catch
-			{
-				Dispose();
-				throw;
-			}
-		}
-
-		public IEmulatorServiceProvider ServiceProvider { get; private set; }
-
-		public bool DriveLightEnabled { get; private set; }
-		public bool DriveLightOn { get; private set; }
-
-		/// <summary>
-		/// core callback for file loading
-		/// </summary>
-		/// <param name="filename">string identifying file to be loaded</param>
-		/// <param name="buffer">buffer to load file to</param>
-		/// <param name="maxsize">maximum length buffer can hold</param>
-		/// <returns>actual size loaded, or 0 on failure</returns>
-		int load_archive(string filename, IntPtr buffer, int maxsize)
-		{
-			byte[] srcdata = null;
-
-			if (buffer == IntPtr.Zero)
-			{
-				Console.WriteLine("Couldn't satisfy firmware request {0} because buffer == NULL", filename);
-				return 0;
-			}
-
-			if (filename == "PRIMARY_ROM")
-			{
-				if (romfile == null)
-				{
-					Console.WriteLine("Couldn't satisfy firmware request PRIMARY_ROM because none was provided.");
-					return 0;
-				}
-				srcdata = romfile;
-			}
-			else if (filename == "PRIMARY_CD" || filename == "SECONDARY_CD")
-			{
-				if (filename == "PRIMARY_CD" && romfile != null)
-				{
-					Console.WriteLine("Declined to satisfy firmware request PRIMARY_CD because PRIMARY_ROM was provided.");
-					return 0;
-				}
-				else
-				{
-					if (CD == null)
-					{
-						Console.WriteLine("Couldn't satisfy firmware request {0} because none was provided.", filename);
-						return 0;
-					}
-					srcdata = GetCDData();
-					if (srcdata.Length != maxsize)
-					{
-						Console.WriteLine("Couldn't satisfy firmware request {0} because of struct size.", filename);
-						return 0;
-					}
-				}
-			}
-			else
-			{
-				// use fromtend firmware interface
-
-				string firmwareID = null;
-				switch (filename)
-				{
-					case "CD_BIOS_EU": firmwareID = "CD_BIOS_EU"; break;
-					case "CD_BIOS_JP": firmwareID = "CD_BIOS_JP"; break;
-					case "CD_BIOS_US": firmwareID = "CD_BIOS_US"; break;
-					default:
-						break;
-				}
-				if (firmwareID != null)
-				{
-					// this path will be the most common PEBKAC error, so be a bit more vocal about the problem
-					srcdata = CoreComm.CoreFileProvider.GetFirmware("GEN", firmwareID, false, "GPGX firmwares are usually required.");
-					if (srcdata == null)
-					{
-						Console.WriteLine("Frontend couldn't satisfy firmware request GEN:{0}", firmwareID);
-						return 0;
-					}
-				}
-				else
-				{
-					Console.WriteLine("Unrecognized firmware request {0}", filename);
-					return 0;
-				}
-			}
-
-			if (srcdata != null)
-			{
-				if (srcdata.Length > maxsize)
-				{
-					Console.WriteLine("Couldn't satisfy firmware request {0} because {1} > {2}", filename, srcdata.Length, maxsize);
-					return 0;
-				}
-				else
-				{
-					Marshal.Copy(srcdata, 0, buffer, srcdata.Length);
-					Console.WriteLine("Firmware request {0} satisfied at size {1}", filename, srcdata.Length);
-					return srcdata.Length;
-				}
-			}
-			else
-			{
-				throw new Exception();
-				//Console.WriteLine("Couldn't satisfy firmware request {0} for unknown reasons", filename);
-				//return 0;
-			}
-
-		}
-
-		void CDRead(int lba, IntPtr dest, bool audio)
-		{
-			if (audio)
-			{
-				byte[] data = new byte[2352];
-				if (lba < CD.LBACount)
-				{
-					CD.ReadLBA_2352(lba, data, 0);
-				}
-				else
-				{
-					// audio seems to read slightly past the end of disks; probably innoculous
-					// just send back 0s.
-					// Console.WriteLine("!!{0} >= {1}", lba, CD.LBACount);
-				}
-				Marshal.Copy(data, 0, dest, 2352);
-			}
-			else
-			{
-				byte[] data = new byte[2048];
-				CD.ReadLBA_2048(lba, data, 0);
-				Marshal.Copy(data, 0, dest, 2048);
-				drivelight = true;
-			}
-		}
-
-		LibGPGXDynamic.cd_read_cb cd_callback_handle;
-
-		unsafe byte[] GetCDData()
-		{
-			LibGPGXDynamic.CDData ret = new LibGPGXDynamic.CDData();
-			int size = Marshal.SizeOf(ret);
-
-			ret.readcallback = cd_callback_handle = new LibGPGXDynamic.cd_read_cb(CDRead);
-
-			var ses = CD.Structure.Sessions[0];
-			int ntrack = ses.Tracks.Count;
-
-			// bet you a dollar this is all wrong
-			for (int i = 0; i < LibGPGXDynamic.CD_MAX_TRACKS; i++)
-			{
-				if (i < ntrack)
-				{
-					ret.tracks[i].start = ses.Tracks[i].Indexes[1].aba - 150;
-					ret.tracks[i].end = ses.Tracks[i].LengthInSectors + ret.tracks[i].start;
-					if (i == ntrack - 1)
-					{
-						ret.end = ret.tracks[i].end;
-						ret.last = ntrack;
-					}
-				}
-				else
-				{
-					ret.tracks[i].start = 0;
-					ret.tracks[i].end = 0;
-				}
-			}
-
-			byte[] retdata = new byte[size];
-
-			fixed (byte* p = &retdata[0])
-			{
-				Marshal.StructureToPtr(ret, (IntPtr)p, false);
-			}
-			return retdata;
-		}
-
-
-		#region controller
-
-		/// <summary>
-		/// size of native input struct
-		/// </summary>
-		int inputsize;
-
-		GPGXControlConverterDynamic ControlConverter;
-
-		public ControllerDefinition ControllerDefinition { get; private set; }
-		public IController Controller { get; set; }
-
-		void SetControllerDefinition()
-		{
-			inputsize = Marshal.SizeOf(typeof(LibGPGXDynamic.InputData));
-			if (!gpgx.gpgx_get_control(input, inputsize))
-				throw new Exception("gpgx_get_control() failed");
-
-			ControlConverter = new GPGXControlConverterDynamic(input);
-			ControllerDefinition = ControlConverter.ControllerDef;
-		}
-
-		public LibGPGXDynamic.INPUT_DEVICE[] GetDevices()
-		{
-			return (LibGPGXDynamic.INPUT_DEVICE[])input.dev.Clone();
-		}
-
-		// core callback for input
-		void input_callback()
-		{
-			InputCallbacks.Call();
-			IsLagFrame = false;
-		}
-
-		private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
-
-		public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } }
-
-		private readonly TraceBuffer _tracer = new TraceBuffer();
-
-		#endregion
-
-		// TODO: use render and rendersound
-		public void FrameAdvance(bool render, bool rendersound = true)
-		{
-			if (Controller["Reset"])
-				gpgx.gpgx_reset(false);
-			if (Controller["Power"])
-				gpgx.gpgx_reset(true);
-
-			// do we really have to get each time?  nothing has changed
-			if (!gpgx.gpgx_get_control(input, inputsize))
-				throw new Exception("gpgx_get_control() failed!");
-
-			ControlConverter.ScreenWidth = vwidth;
-			ControlConverter.ScreenHeight = vheight;
-			ControlConverter.Convert(Controller, input);
-
-			if (!gpgx.gpgx_put_control(input, inputsize))
-				throw new Exception("gpgx_put_control() failed!");
-
-			IsLagFrame = true;
-			Frame++;
-			drivelight = false;
-
-			gpgx.gpgx_advance();
-			update_video();
-			update_audio();
-
-			if (IsLagFrame)
-				LagCount++;
-
-			if (CD != null)
-				DriveLightOn = drivelight;
-		}
-
-		public int Frame { get; private set; }
-		public int LagCount { get; set; }
-		public bool IsLagFrame { get; private set; }
-
-		public string SystemId { get { return "GEN"; } }
-		public bool DeterministicEmulation { get { return true; } }
-		public string BoardName { get { return null; } }
-
-		public CoreComm CoreComm { get; private set; }
-
-		#region saveram
-
-		byte[] DisposedSaveRam = null;
-
-		public byte[] CloneSaveRam()
-		{
-			if (disposed)
-			{
-				if (DisposedSaveRam != null)
-				{
-					return (byte[])DisposedSaveRam.Clone();
-				}
-				else
-				{
-					return new byte[0];
-				}
-			}
-			else
-			{
-				int size = 0;
-				IntPtr area = IntPtr.Zero;
-				gpgx.gpgx_get_sram(ref area, ref size);
-				if (size <= 0 || area == IntPtr.Zero)
-					return new byte[0];
-				gpgx.gpgx_sram_prepread();
-
-				byte[] ret = new byte[size];
-				Marshal.Copy(area, ret, 0, size);
-				return ret;
-			}
-		}
-
-		public void StoreSaveRam(byte[] data)
-		{
-			if (disposed)
-			{
-				throw new ObjectDisposedException(typeof(GPGX).ToString());
-			}
-			else
-			{
-				int size = 0;
-				IntPtr area = IntPtr.Zero;
-				gpgx.gpgx_get_sram(ref area, ref size);
-				if (size <= 0 || area == IntPtr.Zero)
-					return;
-				if (size != data.Length)
-					throw new Exception("Unexpected saveram size");
-
-				Marshal.Copy(data, 0, area, size);
-				gpgx.gpgx_sram_commitwrite();
-			}
-		}
-
-		public bool SaveRamModified
-		{
-			get
-			{
-				if (disposed)
-				{
-					return DisposedSaveRam != null;
-				}
-				else
-				{
-					int size = 0;
-					IntPtr area = IntPtr.Zero;
-					gpgx.gpgx_get_sram(ref area, ref size);
-					return size > 0 && area != IntPtr.Zero;
-				}
-			}
-		}
-
-		#endregion
-
-		public void ResetCounters()
-		{
-			Frame = 0;
-			IsLagFrame = false;
-			LagCount = 0;
-		}
-
-		#region savestates
-
-		private byte[] savebuff;
-		private byte[] savebuff2;
-
-		public void SaveStateText(System.IO.TextWriter writer)
-		{
-			var temp = SaveStateBinary();
-			temp.SaveAsHexFast(writer);
-			// write extra copy of stuff we don't use
-			writer.WriteLine("Frame {0}", Frame);
-		}
-
-		public void LoadStateText(System.IO.TextReader reader)
-		{
-			string hex = reader.ReadLine();
-			byte[] state = new byte[hex.Length / 2];
-			state.ReadFromHexFast(hex);
-			LoadStateBinary(new System.IO.BinaryReader(new System.IO.MemoryStream(state)));
-		}
-
-		public void SaveStateBinary(System.IO.BinaryWriter writer)
-		{
-			if (!gpgx.gpgx_state_save(savebuff, savebuff.Length))
-				throw new Exception("gpgx_state_save() returned false");
-
-			writer.Write(savebuff.Length);
-			writer.Write(savebuff);
-			// other variables
-			writer.Write(Frame);
-			writer.Write(LagCount);
-			writer.Write(IsLagFrame);
-		}
-
-		public void LoadStateBinary(System.IO.BinaryReader reader)
-		{
-			int newlen = reader.ReadInt32();
-			if (newlen != savebuff.Length)
-				throw new Exception("Unexpected state size");
-			reader.Read(savebuff, 0, savebuff.Length);
-			if (!gpgx.gpgx_state_load(savebuff, savebuff.Length))
-				throw new Exception("gpgx_state_load() returned false");
-			// other variables
-			Frame = reader.ReadInt32();
-			LagCount = reader.ReadInt32();
-			IsLagFrame = reader.ReadBoolean();
-			update_video();
-		}
-
-		public byte[] SaveStateBinary()
-		{
-			var ms = new System.IO.MemoryStream(savebuff2, true);
-			var bw = new System.IO.BinaryWriter(ms);
-			SaveStateBinary(bw);
-			bw.Flush();
-			ms.Close();
-			return savebuff2;
-		}
-
-		public bool BinarySaveStatesPreferred { get { return true; } }
-
-		#endregion
-
-		#region debugging tools
-
-		private IMemoryDomains MemoryDomains;
-
-		unsafe void SetMemoryDomains()
-		{
-			var mm = new List<MemoryDomain>();
-			for (int i = LibGPGXDynamic.MIN_MEM_DOMAIN; i <= LibGPGXDynamic.MAX_MEM_DOMAIN; i++)
-			{
-				IntPtr area = IntPtr.Zero;
-				int size = 0;
-				IntPtr pname = gpgx.gpgx_get_memdom(i, ref area, ref size);
-				if (area == IntPtr.Zero || pname == IntPtr.Zero || size == 0)
-					continue;
-				string name = Marshal.PtrToStringAnsi(pname);
-				if (name == "VRAM")
-				{
-					// vram pokes need to go through hook which invalidates cached tiles
-					byte* p = (byte*)area;
-					mm.Add(new MemoryDomain(name, size, MemoryDomain.Endian.Unknown,
-						delegate(long addr)
-						{
-							if (addr < 0 || addr >= 65536)
-								throw new ArgumentOutOfRangeException();
-							return p[addr ^ 1];
-						},
-						delegate(long addr, byte val)
-						{
-							if (addr < 0 || addr >= 65536)
-								throw new ArgumentOutOfRangeException();
-							gpgx.gpgx_poke_vram(((int)addr) ^ 1, val);
-						},
-						byteSize: 2));
-				}
-
-				else
-				{
-					var byteSize = name.Contains("Z80") ? 1 : 2;
-					mm.Add(MemoryDomain.FromIntPtrSwap16(name, size, MemoryDomain.Endian.Big, area, writable: true, byteSize: byteSize));
-				}
-			}
-			MemoryDomains = new MemoryDomainList(mm);
-			(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
-		}
-
-		public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
-		{
-			LibGPGXDynamic.RegisterInfo[] regs = new LibGPGXDynamic.RegisterInfo[gpgx.gpgx_getmaxnumregs()];
-
-			int n = gpgx.gpgx_getregs(regs);
-			if (n > regs.Length)
-				throw new InvalidOperationException("A buffer overrun has occured!");
-			var ret = new Dictionary<string, RegisterValue>();
-			for (int i = 0; i < n; i++)
-			{
-				// el hacko
-				string name = Marshal.PtrToStringAnsi(regs[i].Name);
-				byte size = 32;
-				if (name.Contains("68K SR") || name.StartsWith("Z80"))
-					size = 16;
-				ret[Marshal.PtrToStringAnsi(regs[i].Name)] =
-					new RegisterValue { BitSize = size, Value = (ulong)regs[i].Value };
-			}
-			return ret;
-		}
-
-		public bool CanStep(StepType type) { return false; }
-
-		[FeatureNotImplemented]
-		public void Step(StepType type) { throw new NotImplementedException(); }
-
-		[FeatureNotImplemented]
-		public void SetCpuRegister(string register, int value)
-		{
-			throw new NotImplementedException();
-		}
-
-		public void UpdateVDPViewContext(LibGPGXDynamic.VDPView view)
-		{
-			gpgx.gpgx_get_vdp_view(view);
-			gpgx.gpgx_flush_vram(); // fully regenerate internal caches as needed
-		}
-
-		private readonly MemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem();
-		public IMemoryCallbackSystem MemoryCallbacks { get { return _memoryCallbacks; } }
-
-		LibGPGXDynamic.mem_cb ExecCallback;
-		LibGPGXDynamic.mem_cb ReadCallback;
-		LibGPGXDynamic.mem_cb WriteCallback;
-
-		void InitMemCallbacks()
-		{
-			ExecCallback = new LibGPGXDynamic.mem_cb(a => MemoryCallbacks.CallExecutes(a));
-			ReadCallback = new LibGPGXDynamic.mem_cb(a => MemoryCallbacks.CallReads(a));
-			WriteCallback = new LibGPGXDynamic.mem_cb(a => MemoryCallbacks.CallWrites(a));
-			_memoryCallbacks.ActiveChanged += RefreshMemCallbacks;
-		}
-
-		void RefreshMemCallbacks()
-		{
-			gpgx.gpgx_set_mem_callback(
-				MemoryCallbacks.HasReads ? ReadCallback : null,
-				MemoryCallbacks.HasWrites ? WriteCallback : null,
-				MemoryCallbacks.HasExecutes ? ExecCallback : null);
-		}
-
-		void KillMemCallbacks()
-		{
-			gpgx.gpgx_set_mem_callback(null, null, null);
-		}
-
-		#endregion
-
-		public void Dispose()
-		{
-			if (!disposed)
-			{
-				// if (SaveRamModified)
-				//	DisposedSaveRam = CloneSaveRam();
-				// KillMemCallbacks();
-				if (CD != null)
-				{
-					CD.Dispose();
-				}
-				if (elf != null)
-				{
-					elf.Dispose();
-					elf = null;
-					gpgx = null;
-				}
-
-				disposed = true;
-			}
-		}
-
-		#region SoundProvider
-
-		short[] samples = new short[4096];
-		int nsamp = 0;
-
-		public ISoundProvider SoundProvider { get { return null; } }
-		public ISyncSoundProvider SyncSoundProvider { get { return this; } }
-		public bool StartAsyncSound() { return false; }
-		public void EndAsyncSound() { }
-
-		public void GetSamples(out short[] samples, out int nsamp)
-		{
-			nsamp = this.nsamp;
-			samples = this.samples;
-			this.nsamp = 0;
-		}
-
-		public void DiscardSamples()
-		{
-			this.nsamp = 0;
-		}
-
-		void update_audio()
-		{
-			IntPtr src = IntPtr.Zero;
-			gpgx.gpgx_get_audio(ref nsamp, ref src);
-			if (src != IntPtr.Zero)
-			{
-				Marshal.Copy(src, samples, 0, nsamp * 2);
-			}
-		}
-
-		#endregion
-
-		#region VideoProvider
-
-		public DisplayType DisplayType { get; private set; }
-
-		int[] vidbuff = new int[0];
-		int vwidth;
-		int vheight;
-		public int[] GetVideoBuffer() { return vidbuff; }
-		public int VirtualWidth { get { return BufferWidth; } } // TODO
-		public int VirtualHeight { get { return BufferHeight; } } // TODO
-		public int BufferWidth { get { return vwidth; } }
-		public int BufferHeight { get { return vheight; } }
-		public int BackgroundColor { get { return unchecked((int)0xff000000); } }
-
-		void update_video_initial()
-		{
-			// hack: you should call update_video() here, but that gives you 256x192 on frame 0
-			// and we know that we only use GPGX to emulate genesis games that will always be 320x224 immediately afterwards
-
-			// so instead, just assume a 320x224 size now; if that happens to be wrong, it'll be fixed soon enough.
-
-			vwidth = 320;
-			vheight = 224;
-			vidbuff = new int[vwidth * vheight];
-			for (int i = 0; i < vidbuff.Length; i++)
-				vidbuff[i] = unchecked((int)0xff000000);
-		}
-
-		unsafe void update_video()
-		{
-			int pitch = 0;
-			IntPtr src = IntPtr.Zero;
-
-			gpgx.gpgx_get_video(ref vwidth, ref vheight, ref pitch, ref src);
-
-			if (vidbuff.Length < vwidth * vheight)
-				vidbuff = new int[vwidth * vheight];
-
-			int rinc = (pitch / 4) - vwidth;
-			fixed (int* pdst_ = &vidbuff[0])
-			{
-				int* pdst = pdst_;
-				int* psrc = (int*)src;
-
-				for (int j = 0; j < vheight; j++)
-				{
-					for (int i = 0; i < vwidth; i++)
-						*pdst++ = *psrc++;// | unchecked((int)0xff000000);
-					psrc += rinc;
-				}
-			}
-		}
-
-		#endregion
-
-		#region Settings
-
-		GPGXSyncSettings _SyncSettings;
-		GPGXSettings _Settings;
-
-		public GPGXSettings GetSettings() { return _Settings.Clone(); }
-		public GPGXSyncSettings GetSyncSettings() { return _SyncSettings.Clone(); }
-		public bool PutSettings(GPGXSettings o)
-		{
-			_Settings = o;
-			gpgx.gpgx_set_draw_mask(_Settings.GetDrawMask());
-			return false;
-		}
-		public bool PutSyncSettings(GPGXSyncSettings o)
-		{
-			bool ret = GPGXSyncSettings.NeedsReboot(_SyncSettings, o);
-			_SyncSettings = o;
-			return ret;
-		}
-
-		public class GPGXSettings
-		{
-			[DisplayName("Background Layer A")]
-			[Description("True to draw BG layer A")]
-			[DefaultValue(true)]
-			public bool DrawBGA { get; set; }
-
-			[DisplayName("Background Layer B")]
-			[Description("True to draw BG layer B")]
-			[DefaultValue(true)]
-			public bool DrawBGB { get; set; }
-
-			[DisplayName("Background Layer W")]
-			[Description("True to draw BG layer W")]
-			[DefaultValue(true)]
-			public bool DrawBGW { get; set; }
-
-			public GPGXSettings()
-			{
-				SettingsUtil.SetDefaultValues(this);
-			}
-
-			public GPGXSettings Clone()
-			{
-				return (GPGXSettings)MemberwiseClone();
-			}
-
-			public LibGPGXDynamic.DrawMask GetDrawMask()
-			{
-				LibGPGXDynamic.DrawMask ret = 0;
-				if (DrawBGA) ret |= LibGPGXDynamic.DrawMask.BGA;
-				if (DrawBGB) ret |= LibGPGXDynamic.DrawMask.BGB;
-				if (DrawBGW) ret |= LibGPGXDynamic.DrawMask.BGW;
-				return ret;
-			}
-		}
-
-		public class GPGXSyncSettings
-		{
-			[DisplayName("Use Six Button Controllers")]
-			[Description("Controls the type of any attached normal controllers; six button controllers are used if true, otherwise three button controllers.  Some games don't work correctly with six button controllers.  Not relevant if other controller types are connected.")]
-			[DefaultValue(true)]
-			public bool UseSixButton { get; set; }
-
-			[DisplayName("Control Type")]
-			[Description("Sets the type of controls that are plugged into the console.  Some games will automatically load with a different control type.")]
-			[DefaultValue(ControlType.Normal)]
-			public ControlType ControlType { get; set; }
-
-			[DisplayName("Autodetect Region")]
-			[Description("Sets the region of the emulated console.  Many games can run on multiple regions and will behave differently on different ones.  Some games may require a particular region.")]
-			[DefaultValue(LibGPGXDynamic.Region.Autodetect)]
-			public LibGPGXDynamic.Region Region { get; set; }
-
-			public GPGXSyncSettings()
-			{
-				SettingsUtil.SetDefaultValues(this);
-			}
-
-			public GPGXSyncSettings Clone()
-			{
-				return (GPGXSyncSettings)MemberwiseClone();
-			}
-
-			public static bool NeedsReboot(GPGXSyncSettings x, GPGXSyncSettings y)
-			{
-				return !DeepEquality.DeepEquals(x, y);
-			}
-		}
-
-		#endregion
-	}
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/LibGPGXDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/LibGPGXDynamic.cs
deleted file mode 100644
index f538c6f6aa..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx32/LibGPGXDynamic.cs
+++ /dev/null
@@ -1,323 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Runtime.InteropServices;
-
-namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx32
-{
-	public class LibGPGXDynamic
-	{
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_get_video_t(ref int w, ref int h, ref int pitch, ref IntPtr buffer);
-		public gpgx_get_video_t gpgx_get_video;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_get_audio_t(ref int n, ref IntPtr buffer);
-		public gpgx_get_audio_t gpgx_get_audio;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate int load_archive_cb(string filename, IntPtr buffer, int maxsize);
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_advance_t();
-		public gpgx_advance_t gpgx_advance;
-
-		public enum Region : int
-		{
-			Autodetect = 0,
-			USA = 1,
-			Europe = 2,
-			Japan_NTSC = 3,
-			Japan_PAL = 4
-		}
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate bool gpgx_init_t(string feromextension, load_archive_cb feload_archive_cb, bool sixbutton, INPUT_SYSTEM system_a, INPUT_SYSTEM system_b, Region region);
-		public gpgx_init_t gpgx_init;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_get_fps_t(ref int num, ref int den);
-		public gpgx_get_fps_t gpgx_get_fps;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate int gpgx_state_max_size_t();
-		public gpgx_state_max_size_t gpgx_state_max_size;
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate int gpgx_state_size_t(byte[] dest, int size);
-		public gpgx_state_size_t gpgx_state_size;
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate bool gpgx_state_save_t(byte[] dest, int size);
-		public gpgx_state_save_t gpgx_state_save;
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate bool gpgx_state_load_t(byte[] src, int size);
-		public gpgx_state_load_t gpgx_state_load;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate bool gpgx_get_control_t([Out]InputData dest, int bytes);
-		public gpgx_get_control_t gpgx_get_control;
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate bool gpgx_put_control_t([In]InputData src, int bytes);
-		public gpgx_put_control_t gpgx_put_control;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_get_sram_t(ref IntPtr area, ref int size);
-		public gpgx_get_sram_t gpgx_get_sram;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_clear_sram_t();
-		public gpgx_clear_sram_t gpgx_clear_sram;
-
-		public const int MIN_MEM_DOMAIN = 0;
-		public const int MAX_MEM_DOMAIN = 13;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		// apparently, if you use built in string marshalling, the interop will assume that
-		// the unmanaged char pointer was allocated in hglobal and try to free it that way
-		public delegate IntPtr gpgx_get_memdom_t(int which, ref IntPtr area, ref int size);
-		public gpgx_get_memdom_t gpgx_get_memdom;
-
-		// call this before reading sram returned by gpgx_get_sram()
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_sram_prepread_t();
-		public gpgx_sram_prepread_t gpgx_sram_prepread;
-
-		// call this after writing sram returned by gpgx_get_sram()
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_sram_commitwrite_t();
-		public gpgx_sram_commitwrite_t gpgx_sram_commitwrite;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_reset_t(bool hard);
-		public gpgx_reset_t gpgx_reset;
-
-		public const int MAX_DEVICES = 8;
-
-		public enum INPUT_SYSTEM : byte
-		{
-			SYSTEM_NONE = 0,		// unconnected port	
-			SYSTEM_MD_GAMEPAD = 1,	// single 3-buttons or 6-buttons Control Pad 	
-			SYSTEM_MOUSE = 2,		// Sega Mouse 	
-			SYSTEM_MENACER = 3,		// Sega Menacer -- port B only
-			SYSTEM_JUSTIFIER = 4,	// Konami Justifiers -- port B only
-			SYSTEM_XE_A1P = 5,		// XE-A1P analog controller -- port A only
-			SYSTEM_ACTIVATOR = 6,	// Sega Activator 	
-			SYSTEM_MS_GAMEPAD = 7,	// single 2-buttons Control Pad -- Master System
-			SYSTEM_LIGHTPHASER = 8,	// Sega Light Phaser -- Master System
-			SYSTEM_PADDLE = 9,		// Sega Paddle Control -- Master System
-			SYSTEM_SPORTSPAD = 10,	// Sega Sports Pad -- Master System
-			SYSTEM_TEAMPLAYER = 11,	// Multi Tap -- Sega TeamPlayer 	
-			SYSTEM_WAYPLAY = 12,	// Multi Tap -- EA 4-Way Play -- use both ports
-		};
-
-		public enum INPUT_DEVICE : byte
-		{
-			DEVICE_NONE = 0xff,		// unconnected device = fixed ID for Team Player)
-			DEVICE_PAD3B = 0x00,	// 3-buttons Control Pad = fixed ID for Team Player)
-			DEVICE_PAD6B = 0x01,	// 6-buttons Control Pad = fixed ID for Team Player)
-			DEVICE_PAD2B = 0x02,	// 2-buttons Control Pad
-			DEVICE_MOUSE = 0x03,	// Sega Mouse
-			DEVICE_LIGHTGUN = 0x04, // Sega Light Phaser, Menacer or Konami Justifiers
-			DEVICE_PADDLE = 0x05,	// Sega Paddle Control
-			DEVICE_SPORTSPAD = 0x06,// Sega Sports Pad
-			DEVICE_PICO = 0x07,		// PICO tablet
-			DEVICE_TEREBI = 0x08,	// Terebi Oekaki tablet
-			DEVICE_XE_A1P = 0x09,	// XE-A1P analog controller
-			DEVICE_ACTIVATOR = 0x0a,// Activator
-		};
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void input_cb();
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_set_input_callback_t(input_cb cb);
-		public gpgx_set_input_callback_t gpgx_set_input_callback;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void mem_cb(uint addr);
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_set_mem_callback_t(mem_cb read, mem_cb write, mem_cb exec);
-		public gpgx_set_mem_callback_t gpgx_set_mem_callback;
-
-		/// <summary>
-		/// not every flag is valid for every device!
-		/// </summary>
-		[Flags]
-		public enum INPUT_KEYS : ushort
-		{
-			/* Default Input bitmasks */
-			INPUT_MODE = 0x0800,
-			INPUT_X = 0x0400,
-			INPUT_Y = 0x0200,
-			INPUT_Z = 0x0100,
-			INPUT_START = 0x0080,
-			INPUT_A = 0x0040,
-			INPUT_C = 0x0020,
-			INPUT_B = 0x0010,
-			INPUT_RIGHT = 0x0008,
-			INPUT_LEFT = 0x0004,
-			INPUT_DOWN = 0x0002,
-			INPUT_UP = 0x0001,
-
-			/* Master System specific bitmasks */
-			INPUT_BUTTON2 = 0x0020,
-			INPUT_BUTTON1 = 0x0010,
-
-			/* Mega Mouse specific bitmask */
-			INPUT_MOUSE_START = 0x0080,
-			INPUT_MOUSE_CENTER = 0x0040,
-			INPUT_MOUSE_RIGHT = 0x0020,
-			INPUT_MOUSE_LEFT = 0x0010,
-
-			/* Pico hardware specific bitmask */
-			INPUT_PICO_PEN = 0x0080,
-			INPUT_PICO_RED = 0x0010,
-
-			/* XE-1AP specific bitmask */
-			INPUT_XE_E1 = 0x0800,
-			INPUT_XE_E2 = 0x0400,
-			INPUT_XE_START = 0x0200,
-			INPUT_XE_SELECT = 0x0100,
-			INPUT_XE_A = 0x0080,
-			INPUT_XE_B = 0x0040,
-			INPUT_XE_C = 0x0020,
-			INPUT_XE_D = 0x0010,
-
-			/* Activator specific bitmasks */
-			INPUT_ACTIVATOR_8U = 0x8000,
-			INPUT_ACTIVATOR_8L = 0x4000,
-			INPUT_ACTIVATOR_7U = 0x2000,
-			INPUT_ACTIVATOR_7L = 0x1000,
-			INPUT_ACTIVATOR_6U = 0x0800,
-			INPUT_ACTIVATOR_6L = 0x0400,
-			INPUT_ACTIVATOR_5U = 0x0200,
-			INPUT_ACTIVATOR_5L = 0x0100,
-			INPUT_ACTIVATOR_4U = 0x0080,
-			INPUT_ACTIVATOR_4L = 0x0040,
-			INPUT_ACTIVATOR_3U = 0x0020,
-			INPUT_ACTIVATOR_3L = 0x0010,
-			INPUT_ACTIVATOR_2U = 0x0008,
-			INPUT_ACTIVATOR_2L = 0x0004,
-			INPUT_ACTIVATOR_1U = 0x0002,
-			INPUT_ACTIVATOR_1L = 0x0001,
-
-			/* Menacer */
-			INPUT_MENACER_TRIGGER = 0x0040,
-			INPUT_MENACER_START = 0x0080,
-		};
-
-		[StructLayout(LayoutKind.Sequential)]
-		public class InputData
-		{
-			[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
-			public readonly INPUT_SYSTEM[] system = new INPUT_SYSTEM[2];
-			[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICES)]
-			public readonly INPUT_DEVICE[] dev = new INPUT_DEVICE[MAX_DEVICES];
-			/// <summary>
-			/// digital inputs
-			/// </summary>
-			[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICES)]
-			public readonly INPUT_KEYS[] pad = new INPUT_KEYS[MAX_DEVICES];
-			/// <summary>
-			/// analog (x/y)
-			/// </summary>
-			[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DEVICES * 2)]
-			public readonly short[] analog = new short[MAX_DEVICES * 2];
-			/// <summary>
-			/// gun horizontal offset
-			/// </summary>
-			public int x_offset;
-			/// <summary>
-			/// gun vertical offset
-			/// </summary>
-			public int y_offset;
-
-			public void ClearAllBools()
-			{
-				for (int i = 0; i < pad.Length; i++)
-					pad[i] = 0;
-			}
-		}
-
-		public const int CD_MAX_TRACKS = 100;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void cd_read_cb(int lba, IntPtr dest, bool audio);
-
-		[StructLayout(LayoutKind.Sequential)]
-		public struct CDTrack
-		{
-			public int start;
-			public int end;
-		}
-
-		[StructLayout(LayoutKind.Sequential)]
-		public class CDData
-		{
-			public int end;
-			public int last;
-			[MarshalAs(UnmanagedType.ByValArray, SizeConst = CD_MAX_TRACKS)]
-			public readonly CDTrack[] tracks = new CDTrack[CD_MAX_TRACKS];
-			public cd_read_cb readcallback;
-		}
-
-		[StructLayout(LayoutKind.Sequential)]
-		public struct VDPNameTable
-		{
-			public int Width; // in cells
-			public int Height; // in cells
-			public int Baseaddr;
-		}
-
-		[StructLayout(LayoutKind.Sequential)]
-		public class VDPView
-		{
-			public IntPtr VRAM;
-			public IntPtr PatternCache;
-			public IntPtr ColorCache;
-			public VDPNameTable NTA;
-			public VDPNameTable NTB;
-			public VDPNameTable NTW;
-		}
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_get_vdp_view_t([Out] VDPView view);
-		public gpgx_get_vdp_view_t gpgx_get_vdp_view;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_poke_vram_t(int addr, byte value);
-		public gpgx_poke_vram_t gpgx_poke_vram;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_flush_vram_t();
-		public gpgx_flush_vram_t gpgx_flush_vram;
-
-		[StructLayout(LayoutKind.Sequential)]
-		public struct RegisterInfo
-		{
-			public int Value;
-			public IntPtr Name;
-		}
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate int gpgx_getmaxnumregs_t();
-		public gpgx_getmaxnumregs_t gpgx_getmaxnumregs;
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate int gpgx_getregs_t([Out] RegisterInfo[] regs);
-		public gpgx_getregs_t gpgx_getregs;
-
-		[Flags]
-		public enum DrawMask : int
-		{
-			BGA = 1,
-			BGB = 2,
-			BGW = 4
-		}
-
-		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void gpgx_set_draw_mask_t(DrawMask mask);
-		public gpgx_set_draw_mask_t gpgx_set_draw_mask;
-	}
-}