From 88467d2fbf068ab3393c7e487e2974359106f0c0 Mon Sep 17 00:00:00 2001
From: nattthebear <goyuken@gmail.com>
Date: Sun, 21 Feb 2016 08:54:00 -0500
Subject: [PATCH 1/3] mgba layer toggle

---
 .../Consoles/Nintendo/GBA/LibmGBA.cs          |  13 +++++
 .../Consoles/Nintendo/GBA/MGBAHawk.cs         |  54 ++++++++++++++----
 output/dll/mgba.dll                           | Bin 768000 -> 768000 bytes
 3 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs
index ace3823951..5de892aa57 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs
@@ -60,5 +60,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 		public static extern void BizGetState(IntPtr ctx, byte[] dest);
 		[DllImport(dll, CallingConvention = cc)]
 		public static extern bool BizPutState(IntPtr ctx, byte[] src);
+
+		[Flags]
+		public enum Layers : int
+		{
+			BG0 = 1,
+			BG1 = 2,
+			BG2 = 4,
+			BG3 = 8,
+			OBJ = 16
+		}
+
+		[DllImport(dll, CallingConvention = cc)]
+		public static extern void BizSetLayerMask(IntPtr ctx, Layers mask);
 	}
 }
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
index 20e5874766..e1f7f6ac95 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
@@ -12,14 +12,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 {
 	[CoreAttributes("mGBA", "endrift", true, true, "0.4.0", "https://mgba.io/", false)]
 	[ServiceNotApplicable(typeof(IDriveLight), typeof(IRegionable))]
-	public class MGBAHawk : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable, ISaveRam, IStatable, IInputPollable, ISettable<object, MGBAHawk.SyncSettings>
+	public class MGBAHawk : IEmulator, IVideoProvider, ISyncSoundProvider, IGBAGPUViewable, ISaveRam, IStatable, IInputPollable, ISettable<MGBAHawk.Settings, MGBAHawk.SyncSettings>
 	{
 		IntPtr core;
 
 		[CoreConstructor("GBA")]
-		public MGBAHawk(byte[] file, CoreComm comm, SyncSettings syncSettings, bool deterministic)
+		public MGBAHawk(byte[] file, CoreComm comm, SyncSettings syncSettings, Settings settings, bool deterministic)
 		{
 			_syncSettings = syncSettings ?? new SyncSettings();
+			_settings = settings ?? new Settings();
 			DeterministicEmulation = deterministic;
 
 			byte[] bios = comm.CoreFileProvider.GetFirmware("GBA", "Bios", false);
@@ -150,7 +151,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 		{
 			nsamp = this.nsamp;
 			samples = soundbuff;
-			Console.WriteLine(nsamp);
 			DiscardSamples();
 		}
 		public void DiscardSamples()
@@ -391,9 +391,48 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 			return basetime + increment;
 		}
 
-		public object GetSettings()
+		public Settings GetSettings()
 		{
-			return null;
+			return _settings.Clone();
+		}
+
+		public bool PutSettings(Settings o)
+		{
+			LibmGBA.Layers mask = 0;
+			if (o.DisplayBG0) mask |= LibmGBA.Layers.BG0;
+			if (o.DisplayBG1) mask |= LibmGBA.Layers.BG1;
+			if (o.DisplayBG2) mask |= LibmGBA.Layers.BG2;
+			if (o.DisplayBG3) mask |= LibmGBA.Layers.BG3;
+			if (o.DisplayOBJ) mask |= LibmGBA.Layers.OBJ;
+			LibmGBA.BizSetLayerMask(core, mask);
+			_settings = o;
+			return false;
+		}
+
+		private Settings _settings;
+
+		public class Settings
+		{
+			[DefaultValue(true)]
+			public bool DisplayBG0 { get; set; }
+			[DefaultValue(true)]
+			public bool DisplayBG1 { get; set; }
+			[DefaultValue(true)]
+			public bool DisplayBG2 { get; set; }
+			[DefaultValue(true)]
+			public bool DisplayBG3 { get; set; }
+			[DefaultValue(true)]
+			public bool DisplayOBJ { get; set; }
+
+			public Settings Clone()
+			{
+				return (Settings)MemberwiseClone();
+			}
+
+			public Settings()
+			{
+				SettingsUtil.SetDefaultValues(this);
+			}
 		}
 
 		public SyncSettings GetSyncSettings()
@@ -401,11 +440,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 			return _syncSettings.Clone();
 		}
 
-		public bool PutSettings(object o)
-		{
-			return false;
-		}
-
 		public bool PutSyncSettings(SyncSettings o)
 		{
 			bool ret = SyncSettings.NeedsReboot(o, _syncSettings);
diff --git a/output/dll/mgba.dll b/output/dll/mgba.dll
index 32883749a7866b15722c5776ca9fc03aa1266088..eef8de93b2c8ee746a2e7813ded4fabc1409c321 100644
GIT binary patch
delta 5405
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

delta 5382
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
Yg{zmxr(*L}z~H=GDOZWkl4_^@3;3$aFaQ7m


From a1f3b3d73539dd9bde57898e38308025473b7306 Mon Sep 17 00:00:00 2001
From: nattthebear <goyuken@gmail.com>
Date: Sun, 21 Feb 2016 10:11:38 -0500
Subject: [PATCH 2/3] Issue 441 - mgba - store saveram in savestates.  No
 compatibility is kept with existing savestates

---
 .../Consoles/Nintendo/GBA/MGBAHawk.cs         | 62 ++++++++++++++-----
 1 file changed, 46 insertions(+), 16 deletions(-)

diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
index e1f7f6ac95..494bcd7694 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
@@ -254,6 +254,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 			}
 		}
 
+		/// <summary>
+		/// takes a legacy saveram format that we used to use for vbanext-hawk and extracts the saveram from it.  works most of the time
+		/// </summary>
 		private static byte[] LegacyFix(byte[] saveram)
 		{
 			// at one point vbanext-hawk had a special saveram format which we want to load.
@@ -281,19 +284,39 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 				data = LegacyFix(data);
 			}
 
-			int len = LibmGBA.BizGetSaveRamSize(core);
-			if (len > data.Length)
+			StoreSaveRamInternal(data, data.Length);
+		}
+
+		/// <summary>
+		/// like StoreSaveRam, but only uses up to length bytes of source
+		/// </summary>
+		private void StoreSaveRamInternal(byte[] data, int length)
+		{
+			int expectedlen = LibmGBA.BizGetSaveRamSize(core);
+			
+			if (expectedlen > length)
 			{
-				byte[] _tmp = new byte[len];
-				Array.Copy(data, _tmp, data.Length);
-				for (int i = data.Length; i < len; i++)
-					_tmp[i] = 0xff;
-				data = _tmp;
+				// scenario:
+				// game has no savetype override, but autodetects to < 128K.
+				// saveram is snapshotted after autodetect and then loaded into a fresh core before autodetect
+
+				// resolution:
+				// provide fake extra bytes that won't be used anyway
+				Array.Copy(data, tempsaveram2, length);
+
+				for (int i = length; i < expectedlen; i++)
+					tempsaveram2[i] = 0xff;
+				data = tempsaveram2;
 			}
-			else if (len < data.Length)
+			else if (expectedlen < data.Length)
 			{
-				// we could continue from this, but we don't expect it
-				throw new InvalidOperationException("Saveram will be truncated!");
+				// scenario:
+				// game has no savetype override, but autodetects to < 128K
+				// saveram is snapshotted before autodetect and then loaded into a core after autodetect
+				// we'd never expect this to happen with just saveram, because we only Store when the core
+				// is first created.  but the saveram interface is used for savestates as well, where it can happen
+
+				// resolution: do nothing and hope the extra bytes weren't important
 			}
 			LibmGBA.BizPutSaveRam(core, data);
 		}
@@ -308,11 +331,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 		private void InitStates()
 		{
 			savebuff = new byte[LibmGBA.BizGetStateSize()];
-			savebuff2 = new byte[savebuff.Length + 13];
 		}
 
 		private byte[] savebuff;
-		private byte[] savebuff2;
+		private byte[] tempsaveram = new byte[1024 * 128]; // largest possible size
+		private byte[] tempsaveram2 = new byte[1024 * 128]; // largest possible size
 
 		public bool BinarySaveStatesPreferred
 		{
@@ -342,6 +365,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 			writer.Write(IsLagFrame);
 			writer.Write(LagCount);
 			writer.Write(Frame);
+
+			LibmGBA.BizGetSaveRam(core, tempsaveram);
+			int saveramsize = LibmGBA.BizGetSaveRamSize(core);
+			writer.Write(saveramsize);
+			writer.Write(tempsaveram, 0, saveramsize);
 		}
 
 		public void LoadStateBinary(BinaryReader reader)
@@ -357,18 +385,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
 			IsLagFrame = reader.ReadBoolean();
 			LagCount = reader.ReadInt32();
 			Frame = reader.ReadInt32();
+
+			int saveramsize = reader.ReadInt32();
+			reader.Read(tempsaveram, 0, saveramsize);
+			StoreSaveRamInternal(tempsaveram, saveramsize);
 		}
 
 		public byte[] SaveStateBinary()
 		{
-			var ms = new MemoryStream(savebuff2, true);
+			var ms = new MemoryStream();
 			var bw = new BinaryWriter(ms);
 			SaveStateBinary(bw);
 			bw.Flush();
-			if (ms.Position != savebuff2.Length)
-				throw new InvalidOperationException();
 			ms.Close();
-			return savebuff2;
+			return ms.ToArray(); // eww, slow
 		}
 
 		public int LagCount { get; set; }

From 78f20510e514abceb4a11a9741c41cf9fedd4f89 Mon Sep 17 00:00:00 2001
From: feos <feos-theos@yandex.ru>
Date: Sun, 21 Feb 2016 18:13:45 +0300
Subject: [PATCH 3/3] lua: emu.disassemble(uint pc, string name = "")

---
 .../lua/EmuLuaLibrary.Emu.cs                  | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.Emu.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.Emu.cs
index 93f55f608f..40430ffee2 100644
--- a/BizHawk.Client.Common/lua/EmuLuaLibrary.Emu.cs
+++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.Emu.cs
@@ -25,6 +25,12 @@ namespace BizHawk.Client.Common
 		[OptionalService]
 		public IDebuggable DebuggableCore { get; set; }
 
+		[OptionalService]
+		public IDisassemblable DisassemblableCore { get; set; }
+
+		[OptionalService]
+		private IMemoryDomains MemoryDomains { get; set; }
+
 		[OptionalService]
 		public IInputPollable InputPollableCore { get; set; }
 
@@ -66,6 +72,37 @@ namespace BizHawk.Client.Common
 			return Emulator.Frame;
 		}
 
+		[LuaMethodAttributes(
+			"disassemble",
+			"Returns the disassembly object (disasm string and length int) for the given PC address. Uses System Bus domain if no domain name provided"
+		)]
+		public object Disassemble(uint pc, string name = "")
+		{
+			try
+			{
+				if (DisassemblableCore == null)
+				{
+					throw new NotImplementedException();
+				}
+
+				int l;
+				MemoryDomain domain = MemoryDomains.SystemBus;
+
+				if (!string.IsNullOrEmpty(name))
+					domain = MemoryDomains[name];
+
+				var d = DisassemblableCore.Disassemble(domain, pc, out l);
+				return new { disasm = d, length = l };
+			}
+			catch (NotImplementedException)
+			{
+				Log(string.Format(
+					"Error: {0} does not yet implement disassemble()",
+					Emulator.Attributes().CoreName));
+				return null;
+			}
+		}
+
 		// TODO: what about 64 bit registers?
 		[LuaMethodAttributes(
 			"getregister",