diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs
index 45fcafe4c3..f6a5dfd511 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs
@@ -18,11 +18,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 		[CoreConstructor(VSystemID.Raw.GEN)]
 		public GPGX(CoreLoadParameters<GPGXSettings, GPGXSyncSettings> lp)
 		{
-			LoadCallback = new LibGPGX.load_archive_cb(load_archive);
-			_inputCallback = new LibGPGX.input_cb(input_callback);
+			LoadCallback = load_archive;
+			_inputCallback = input_callback;
 			InitMemCallbacks(); // ExecCallback, ReadCallback, WriteCallback
-			CDCallback = new LibGPGX.CDCallback(CDCallbackProc);
-			cd_callback_handle = new LibGPGX.cd_read_cb(CDRead);
+			CDCallback = CDCallbackProc;
+			cd_callback_handle = CDRead;
 
 			ServiceProvider = new BasicServiceProvider(this);
 			// this can influence some things internally (autodetect romtype, etc)
@@ -68,6 +68,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 
 				if (lp.Discs.Count > 0)
 				{
+					if (lp.Discs.Count > 128)
+					{
+						throw new("Too many discs loaded at once!");
+					}
+
 					_cds = lp.Discs.Select(d => d.DiscData).ToArray();
 					_cdReaders = _cds.Select(c => new DiscSectorReader(c)).ToArray();
 					Core.gpgx_set_cdd_callback(cd_callback_handle);
@@ -197,7 +202,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 				}
 				srcdata = _romfile;
 			}
-			else if (filename == "PRIMARY_CD" || filename == "SECONDARY_CD")
+			else if (filename is "PRIMARY_CD" or "SECONDARY_CD")
 			{
 				if (filename == "PRIMARY_CD" && _romfile != null)
 				{
@@ -272,30 +277,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 
 		private CoreComm CoreComm { get; }
 
-		private void CDRead(int lba, IntPtr dest, bool audio)
+		private readonly byte[] _sectorBuffer = new byte[2448];
+
+		private void CDRead(int lba, IntPtr dest, bool subcode)
 		{
 			if ((uint)_discIndex < _cds.Length)
 			{
-				if (audio)
+				if (subcode)
 				{
-					byte[] data = new byte[2352];
-					if (lba < _cds[_discIndex].Session1.LeadoutLBA)
-					{
-						_cdReaders[_discIndex].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);
+					_cdReaders[_discIndex].ReadLBA_2448(lba, _sectorBuffer, 0);
+					Marshal.Copy(_sectorBuffer, 2352, dest, 96);
 				}
 				else
 				{
-					byte[] data = new byte[2048];
-					_cdReaders[_discIndex].ReadLBA_2048(lba, data, 0);
-					Marshal.Copy(data, 0, dest, 2048);
+					_cdReaders[_discIndex].ReadLBA_2352(lba, _sectorBuffer, 0);
+					Marshal.Copy(_sectorBuffer, 0, dest, 2352);
 					_driveLight = true;
 				}
 			}
@@ -314,9 +310,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 			//zero 07-jul-2015 - throws a dollar in the pile, since he probably messed it up worse
 			for (int i = 0; i < LibGPGX.CD_MAX_TRACKS; i++)
 			{
-				ret.tracks[i].loopEnabled = 0;
-				ret.tracks[i].loopOffset = 0;
-				
 				if (i < ntrack)
 				{
 					ret.tracks[i].mode = ses.Tracks[i].Mode;
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs
index 5471226769..aa355da0eb 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/LibGPGX.cs
@@ -277,7 +277,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 		public const int CD_MAX_TRACKS = 100;
 
 		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-		public delegate void cd_read_cb(int lba, IntPtr dest, bool audio);
+		public delegate void cd_read_cb(int lba, IntPtr dest, [MarshalAs(UnmanagedType.Bool)] bool subcode);
 
 		[StructLayout(LayoutKind.Sequential)]
 		public struct CDTrack
@@ -285,8 +285,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
 			public int start;
 			public int end;
 			public int mode;
-			public int loopEnabled;
-			public int loopOffset;
 		}
 
 		[StructLayout(LayoutKind.Sequential)]