diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs
index a8dbda771d..2bc0cf27dd 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs
@@ -1,5 +1,6 @@
 using System;
 using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Nintendo.GBHawk;
 
 namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
 {
@@ -36,7 +37,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
 
 			linkSettings = (GBLinkSettings)lp.Settings ?? new GBLinkSettings();
 			linkSyncSettings = (GBLinkSyncSettings)lp.SyncSettings ?? new GBLinkSyncSettings();
-			_controllerDeck = new GBHawkLinkControllerDeck(GBHawkLinkControllerDeck.DefaultControllerName, GBHawkLinkControllerDeck.DefaultControllerName);
+			_controllerDeck = new(
+				GBHawkControllerDeck.DefaultControllerName,
+				GBHawkControllerDeck.DefaultControllerName);
 
 			var temp_set_L = new GBHawk.GBHawk.GBSettings();
 			var temp_set_R = new GBHawk.GBHawk.GBSettings();
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs
index 74085bf775..f271887cfc 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllerDeck.cs
@@ -1,10 +1,9 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
 
 using BizHawk.Common;
-using BizHawk.Common.ReflectionExtensions;
 using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Nintendo.GBHawk;
 
 namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
 {
@@ -12,10 +11,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
 	{
 		public GBHawkLinkControllerDeck(string controller1Name, string controller2Name)
 		{
-			Port1 = ControllerCtors.TryGetValue(controller1Name, out var ctor1)
+			Port1 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller1Name, out var ctor1)
 				? ctor1(1)
 				: throw new InvalidOperationException($"Invalid controller type: {controller1Name}");
-			Port2 = ControllerCtors.TryGetValue(controller2Name, out var ctor2)
+			Port2 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller2Name, out var ctor2)
 				? ctor2(2)
 				: throw new InvalidOperationException($"Invalid controller type: {controller2Name}");
 
@@ -54,15 +53,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
 
 		private readonly IPort Port1;
 		private readonly IPort Port2;
-
-		private static IReadOnlyDictionary<string, Func<int, IPort>> _controllerCtors;
-
-		public static IReadOnlyDictionary<string, Func<int, IPort>> ControllerCtors => _controllerCtors
-			??= new Dictionary<string, Func<int, IPort>>
-			{
-				[typeof(StandardControls).DisplayName()] = portNum => new StandardControls(portNum)
-			};
-
-		public static string DefaultControllerName => typeof(StandardControls).DisplayName();
 	}
 }
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllers.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllers.cs
deleted file mode 100644
index 1fe269ddbc..0000000000
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLinkControllers.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using System.ComponentModel;
-using System.Linq;
-
-using BizHawk.Common;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
-{
-	/// <summary>
-	/// Represents a GB add on
-	/// </summary>
-	public interface IPort
-	{
-		byte Read(IController c);
-
-		ControllerDefinition Definition { get; }
-
-		void SyncState(Serializer ser);
-
-		int PortNum { get; }
-	}
-
-	[DisplayName("Gameboy Controller")]
-	public class StandardControls : IPort
-	{
-		public StandardControls(int portNum)
-		{
-			PortNum = portNum;
-			Definition = new ControllerDefinition
-			{
-				Name = "Gameboy Controller H",
-				BoolButtons = BaseDefinition
-				.Select(b => "P" + PortNum + " " + b)
-				.ToList()
-			};
-		}
-
-		public int PortNum { get; }
-
-		public ControllerDefinition Definition { get; }
-
-		public byte Read(IController c)
-		{
-			byte result = 0xFF;
-
-			if (c.IsPressed(Definition.BoolButtons[0]))
-			{
-				result -= 4;
-			}
-			if (c.IsPressed(Definition.BoolButtons[1]))
-			{
-				result -= 8;
-			}
-			if (c.IsPressed(Definition.BoolButtons[2]))
-			{
-				result -= 2;
-			}
-			if (c.IsPressed(Definition.BoolButtons[3]))
-			{
-				result -= 1;
-			}
-			if (c.IsPressed(Definition.BoolButtons[4]))
-			{
-				result -= 128;
-			}
-			if (c.IsPressed(Definition.BoolButtons[5]))
-			{
-				result -= 64;
-			}
-			if (c.IsPressed(Definition.BoolButtons[6]))
-			{
-				result -= 32;
-			}
-			if (c.IsPressed(Definition.BoolButtons[7]))
-			{
-				result -= 16;
-			}
-
-			return result;
-		}
-
-		private static readonly string[] BaseDefinition =
-		{
-			"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
-		};
-
-		public void SyncState(Serializer ser)
-		{
-			//nothing
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.cs
index da58be8893..1aed68ef50 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3x.cs
@@ -1,5 +1,6 @@
 using System;
 using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Nintendo.GBHawk;
 
 namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
 {
@@ -36,7 +37,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
 
 			Link3xSettings = (GBLink3xSettings)lp.Settings ?? new GBLink3xSettings();
 			Link3xSyncSettings = (GBLink3xSyncSettings)lp.SyncSettings ?? new GBLink3xSyncSettings();
-			_controllerDeck = new GBHawkLink3xControllerDeck(GBHawkLink3xControllerDeck.DefaultControllerName, GBHawkLink3xControllerDeck.DefaultControllerName, GBHawkLink3xControllerDeck.DefaultControllerName);
+			_controllerDeck = new(
+				GBHawkControllerDeck.DefaultControllerName,
+				GBHawkControllerDeck.DefaultControllerName,
+				GBHawkControllerDeck.DefaultControllerName);
 
 			var tempSetL = new GBHawk.GBHawk.GBSettings();
 			var tempSetC = new GBHawk.GBHawk.GBSettings();
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs
index e477022c6f..d9d3ebbf58 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllerDeck.cs
@@ -1,10 +1,9 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
 
 using BizHawk.Common;
-using BizHawk.Common.ReflectionExtensions;
 using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Nintendo.GBHawk;
 
 namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
 {
@@ -12,13 +11,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
 	{
 		public GBHawkLink3xControllerDeck(string controller1Name, string controller2Name, string controller3Name)
 		{
-			Port1 = ControllerCtors.TryGetValue(controller1Name, out var ctor1)
+			Port1 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller1Name, out var ctor1)
 				? ctor1(1)
 				: throw new InvalidOperationException($"Invalid controller type: {controller1Name}");
-			Port2 = ControllerCtors.TryGetValue(controller2Name, out var ctor2)
+			Port2 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller2Name, out var ctor2)
 				? ctor2(2)
 				: throw new InvalidOperationException($"Invalid controller type: {controller2Name}");
-			Port3 = ControllerCtors.TryGetValue(controller3Name, out var ctor3)
+			Port3 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller3Name, out var ctor3)
 				? ctor3(3)
 				: throw new InvalidOperationException($"Invalid controller type: {controller3Name}");
 
@@ -70,15 +69,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
 		private readonly IPort Port1;
 		private readonly IPort Port2;
 		private readonly IPort Port3;
-
-		private static IReadOnlyDictionary<string, Func<int, IPort>> _controllerCtors;
-
-		public static IReadOnlyDictionary<string, Func<int, IPort>> ControllerCtors => _controllerCtors
-			??= new Dictionary<string, Func<int, IPort>>
-			{
-				[typeof(StandardControls).DisplayName()] = portNum => new StandardControls(portNum)
-			};
-
-		public static string DefaultControllerName => typeof(StandardControls).DisplayName();
 	}
 }
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllers.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllers.cs
deleted file mode 100644
index 35542a3525..0000000000
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink3x/GBHawkLink3xControllers.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using System.ComponentModel;
-using System.Linq;
-
-using BizHawk.Common;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
-{
-	/// <summary>
-	/// Represents a GB add on
-	/// </summary>
-	public interface IPort
-	{
-		byte Read(IController c);
-
-		ControllerDefinition Definition { get; }
-
-		void SyncState(Serializer ser);
-
-		int PortNum { get; }
-	}
-
-	[DisplayName("Gameboy Controller")]
-	public class StandardControls : IPort
-	{
-		public StandardControls(int portNum)
-		{
-			PortNum = portNum;
-			Definition = new ControllerDefinition
-			{
-				Name = "Gameboy Controller H",
-				BoolButtons = BaseDefinition
-				.Select(b => "P" + PortNum + " " + b)
-				.ToList()
-			};
-		}
-
-		public int PortNum { get; }
-
-		public ControllerDefinition Definition { get; }
-
-		public byte Read(IController c)
-		{
-			byte result = 0xFF;
-
-			if (c.IsPressed(Definition.BoolButtons[0]))
-			{
-				result -= 4;
-			}
-			if (c.IsPressed(Definition.BoolButtons[1]))
-			{
-				result -= 8;
-			}
-			if (c.IsPressed(Definition.BoolButtons[2]))
-			{
-				result -= 2;
-			}
-			if (c.IsPressed(Definition.BoolButtons[3]))
-			{
-				result -= 1;
-			}
-			if (c.IsPressed(Definition.BoolButtons[4]))
-			{
-				result -= 128;
-			}
-			if (c.IsPressed(Definition.BoolButtons[5]))
-			{
-				result -= 64;
-			}
-			if (c.IsPressed(Definition.BoolButtons[6]))
-			{
-				result -= 32;
-			}
-			if (c.IsPressed(Definition.BoolButtons[7]))
-			{
-				result -= 16;
-			}
-
-			return result;
-		}
-
-		private static readonly string[] BaseDefinition =
-		{
-			"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
-		};
-
-		public void SyncState(Serializer ser)
-		{
-			//nothing
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4x.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4x.cs
index ab0f3833e2..7db986c1e4 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4x.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4x.cs
@@ -1,5 +1,6 @@
 using System;
 using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Nintendo.GBHawk;
 
 namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
 {
@@ -56,8 +57,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
 
 			Link4xSettings = (GBLink4xSettings)lp.Settings ?? new GBLink4xSettings();
 			Link4xSyncSettings = (GBLink4xSyncSettings)lp.SyncSettings ?? new GBLink4xSyncSettings();
-			_controllerDeck = new GBHawkLink4xControllerDeck(GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName, 
-															 GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName);
+			_controllerDeck = new(
+				GBHawkControllerDeck.DefaultControllerName,
+				GBHawkControllerDeck.DefaultControllerName,
+				GBHawkControllerDeck.DefaultControllerName,
+				GBHawkControllerDeck.DefaultControllerName);
 
 			var tempSetA = new GBHawk.GBHawk.GBSettings();
 			var tempSetB = new GBHawk.GBHawk.GBSettings();
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs
index 35b5f1609b..8a7370140e 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllerDeck.cs
@@ -1,10 +1,9 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
 
 using BizHawk.Common;
-using BizHawk.Common.ReflectionExtensions;
 using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Nintendo.GBHawk;
 
 namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
 {
@@ -12,16 +11,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
 	{
 		public GBHawkLink4xControllerDeck(string controller1Name, string controller2Name, string controller3Name, string controller4Name)
 		{
-			Port1 = ControllerCtors.TryGetValue(controller1Name, out var ctor1)
+			Port1 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller1Name, out var ctor1)
 				? ctor1(1)
 				: throw new InvalidOperationException($"Invalid controller type: {controller1Name}");
-			Port2 = ControllerCtors.TryGetValue(controller2Name, out var ctor2)
+			Port2 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller2Name, out var ctor2)
 				? ctor2(2)
 				: throw new InvalidOperationException($"Invalid controller type: {controller2Name}");
-			Port3 = ControllerCtors.TryGetValue(controller3Name, out var ctor3)
+			Port3 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller3Name, out var ctor3)
 				? ctor3(3)
 				: throw new InvalidOperationException($"Invalid controller type: {controller3Name}");
-			Port4 = ControllerCtors.TryGetValue(controller4Name, out var ctor4)
+			Port4 = GBHawkControllerDeck.ControllerCtors.TryGetValue(controller4Name, out var ctor4)
 				? ctor4(4)
 				: throw new InvalidOperationException($"Invalid controller type: {controller4Name}");
 
@@ -85,15 +84,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
 		private readonly IPort Port2;
 		private readonly IPort Port3;
 		private readonly IPort Port4;
-
-		private static IReadOnlyDictionary<string, Func<int, IPort>> _controllerCtors;
-
-		public static IReadOnlyDictionary<string, Func<int, IPort>> ControllerCtors => _controllerCtors
-			??= new Dictionary<string, Func<int, IPort>>
-			{
-				[typeof(StandardControls).DisplayName()] = portNum => new StandardControls(portNum)
-			};
-
-		public static string DefaultControllerName => typeof(StandardControls).DisplayName();
 	}
 }
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllers.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllers.cs
deleted file mode 100644
index bfb5f79867..0000000000
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink4x/GBHawkLink4xControllers.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using System.ComponentModel;
-using System.Linq;
-
-using BizHawk.Common;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
-{
-	/// <summary>
-	/// Represents a GB add on
-	/// </summary>
-	public interface IPort
-	{
-		byte Read(IController c);
-
-		ControllerDefinition Definition { get; }
-
-		void SyncState(Serializer ser);
-
-		int PortNum { get; }
-	}
-
-	[DisplayName("Gameboy Controller")]
-	public class StandardControls : IPort
-	{
-		public StandardControls(int portNum)
-		{
-			PortNum = portNum;
-			Definition = new ControllerDefinition
-			{
-				Name = "Gameboy Controller H",
-				BoolButtons = BaseDefinition
-				.Select(b => "P" + PortNum + " " + b)
-				.ToList()
-			};
-		}
-
-		public int PortNum { get; }
-
-		public ControllerDefinition Definition { get; }
-
-		public byte Read(IController c)
-		{
-			byte result = 0xFF;
-
-			if (c.IsPressed(Definition.BoolButtons[0]))
-			{
-				result -= 4;
-			}
-			if (c.IsPressed(Definition.BoolButtons[1]))
-			{
-				result -= 8;
-			}
-			if (c.IsPressed(Definition.BoolButtons[2]))
-			{
-				result -= 2;
-			}
-			if (c.IsPressed(Definition.BoolButtons[3]))
-			{
-				result -= 1;
-			}
-			if (c.IsPressed(Definition.BoolButtons[4]))
-			{
-				result -= 128;
-			}
-			if (c.IsPressed(Definition.BoolButtons[5]))
-			{
-				result -= 64;
-			}
-			if (c.IsPressed(Definition.BoolButtons[6]))
-			{
-				result -= 32;
-			}
-			if (c.IsPressed(Definition.BoolButtons[7]))
-			{
-				result -= 16;
-			}
-
-			return result;
-		}
-
-		private static readonly string[] BaseDefinition =
-		{
-			"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
-		};
-
-		public void SyncState(Serializer ser)
-		{
-			//nothing
-		}
-	}
-}
\ No newline at end of file