From 6284c98d72e9d39ccd5de8d72d1d8b945ff889ce Mon Sep 17 00:00:00 2001 From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Fri, 31 Mar 2023 06:22:11 -0700 Subject: [PATCH] hook up clear NAND flag and dsiware saveram support do various cleanups enforce clear NAND flag for movie recording and retroachievements hardcore mode --- .../RetroAchievements.Hardcore.cs | 10 +++ .../Consoles/Nintendo/NDS/LibMelonDS.cs | 11 ++- .../Nintendo/NDS/MelonDS.IDebuggable.cs | 20 +++--- .../Consoles/Nintendo/NDS/MelonDS.ISaveRam.cs | 52 ++++++++++++-- .../Nintendo/NDS/MelonDS.ISettable.cs | 11 ++- .../Nintendo/NDS/MelonDS.ITraceable.cs | 35 +++------- .../Consoles/Nintendo/NDS/MelonDS.cs | 67 +++++++++---------- .../Consoles/Nintendo/NDS/NDSDisassembler.cs | 4 +- .../Consoles/Nintendo/NDS/NDSFirmware.cs | 59 ++++++++-------- 9 files changed, 157 insertions(+), 112 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.Hardcore.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.Hardcore.cs index f743b1b19e..d4633a69b4 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.Hardcore.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.Hardcore.cs @@ -5,6 +5,7 @@ using System.Linq; using BizHawk.Client.Common; using BizHawk.Emulation.Cores.Atari.Atari2600; using BizHawk.Emulation.Cores.Computers.MSX; +using BizHawk.Emulation.Cores.Consoles.Nintendo.NDS; using BizHawk.Emulation.Cores.Consoles.O2Hawk; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using BizHawk.Emulation.Cores.Nintendo.BSNES; @@ -136,6 +137,15 @@ namespace BizHawk.Client.EmuHawk } break; } + case NDS { IsDSi: true } nds: + { + var ss = nds.GetSyncSettings(); + if (!ss.ClearNAND) + { + HandleHardcoreModeDisable("Disabling DSi NAND clear in hardcore mode is not allowed."); + } + break; + } default: if (CoreGraphicsLayers.TryGetValue(Emu.GetType(), out var layers)) { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs index 1365640610..666cb8d8c5 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs @@ -48,7 +48,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS USE_REAL_BIOS = 0x01, SKIP_FIRMWARE = 0x02, GBA_CART_PRESENT = 0x04, - RESERVED_FLAG = 0x08, + CLEAR_NAND = 0x08, FIRMWARE_OVERRIDE = 0x10, IS_DSI = 0x20, LOAD_DSIWARE = 0x40, @@ -98,6 +98,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS [BizImport(CC)] public abstract bool SaveRamIsDirty(); + [BizImport(CC)] + public abstract void ImportDSiWareSavs(uint titleId); + + [BizImport(CC)] + public abstract void ExportDSiWareSavs(uint titleId); + + [BizImport(CC)] + public abstract void DSiWareSavsLength(uint titleId, out int publicSavSize, out int privateSavSize, out int bannerSavSize); + [BizImport(CC)] public abstract void GetRegs(uint[] regs); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs index 183fa02e9e..f186b20fbb 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs @@ -5,18 +5,18 @@ using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { - partial class NDS : IDebuggable + public partial class NDS : IDebuggable { public IDictionary GetCpuFlagsAndRegisters() { - uint[] regs = new uint[2 * 16]; + var regs = new uint[2 * 16]; _core.GetRegs(regs); var ret = new Dictionary(); - for (int i = 0; i < 2; i++) + for (var i = 0; i < 2; i++) { - int ncpu = i == 0 ? 9 : 7; - for (int j = 0; j < 16; j++) + var ncpu = i == 0 ? 9 : 7; + for (var j = 0; j < 16; j++) { ret["ARM" + ncpu + " r" + j] = regs[i * 16 + j]; } @@ -30,13 +30,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { throw new InvalidOperationException("Wrong String Length???"); } - int ncpu = int.Parse(register.Substring(3, 1)); - if (ncpu != 9 && ncpu != 7) + var ncpu = int.Parse(register.Substring(3, 1)); + if (ncpu is not (9 or 7)) { throw new InvalidOperationException("Invalid CPU???"); } - int index = int.Parse(register.Substring(6, register.Length - 6)); - if (index < 0 || index > 15) + var index = int.Parse(register.Substring(6, register.Length - 6)); + if (index is < 0 or > 15) { throw new InvalidOperationException("Invalid Reg Index???"); } @@ -63,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS LibMelonDS.MemoryCallback CreateCallback(MemoryCallbackFlags flags, Func getHasCBOfType) { var rawFlags = (uint)flags; - return (address) => + return address => { if (getHasCBOfType()) { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISaveRam.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISaveRam.cs index f711a37ad4..d5c0270603 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISaveRam.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISaveRam.cs @@ -1,28 +1,68 @@ +using System; +using System.IO; +using BizHawk.Common; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { - partial class NDS : ISaveRam + public partial class NDS : ISaveRam { - public new bool SaveRamModified => _core.SaveRamIsDirty(); + public new bool SaveRamModified => IsDSiWare || _core.SaveRamIsDirty(); public new byte[] CloneSaveRam() { - int length = _core.GetSaveRamLength(); + if (IsDSiWare) + { + _core.DSiWareSavsLength(DSiTitleId.Lower, out var publicSavSize, out var privateSavSize, out var bannerSavSize); + if (publicSavSize + privateSavSize + bannerSavSize == 0) return null; + _exe.AddTransientFile(Array.Empty(), "public.sav"); + _exe.AddTransientFile(Array.Empty(), "private.sav"); + _exe.AddTransientFile(Array.Empty(), "banner.sav"); + _core.ExportDSiWareSavs(DSiTitleId.Lower); + var publicSav = _exe.RemoveTransientFile("public.sav"); + var privateSav = _exe.RemoveTransientFile("private.sav"); + var bannerSav = _exe.RemoveTransientFile("banner.sav"); + if (publicSav.Length != publicSavSize || privateSav.Length != privateSavSize || + bannerSav.Length != bannerSavSize) + { + throw new InvalidOperationException("Unexpected size difference in DSiWare sav files!"); + } + var ret = new byte[publicSavSize + privateSavSize + bannerSavSize]; + publicSav.AsSpan().CopyTo(ret.AsSpan().Slice(0, publicSavSize)); + privateSav.AsSpan().CopyTo(ret.AsSpan().Slice(publicSavSize, privateSavSize)); + bannerSav.AsSpan().CopyTo(ret.AsSpan().Slice(publicSavSize + privateSavSize, bannerSavSize)); + return ret; + } + + var length = _core.GetSaveRamLength(); if (length > 0) { - byte[] ret = new byte[length]; + var ret = new byte[length]; _core.GetSaveRam(ret); return ret; } - return new byte[0]; + return null; } public new void StoreSaveRam(byte[] data) { - if (data.Length > 0) + if (IsDSiWare) + { + _core.DSiWareSavsLength(DSiTitleId.Lower, out var publicSavSize, out var privateSavSize, out var bannerSavSize); + if (data.Length == publicSavSize + privateSavSize + bannerSavSize) + { + if (publicSavSize > 0) _exe.AddReadonlyFile(data.AsSpan().Slice(0, publicSavSize).ToArray(), "public.sav"); + if (privateSavSize > 0) _exe.AddReadonlyFile(data.AsSpan().Slice(publicSavSize, privateSavSize).ToArray(), "private.sav"); + if (bannerSavSize > 0) _exe.AddReadonlyFile(data.AsSpan().Slice(publicSavSize + privateSavSize, bannerSavSize).ToArray(), "banner.sav"); + _core.ImportDSiWareSavs(DSiTitleId.Lower); + if (publicSavSize > 0) _exe.RemoveReadonlyFile("public.sav"); + if (privateSavSize > 0) _exe.RemoveReadonlyFile("private.sav"); + if (bannerSavSize > 0) _exe.RemoveReadonlyFile("banner.sav"); + } + } + else if (data.Length > 0) { _core.PutSaveRam(data, (uint)data.Length); } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISettable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISettable.cs index 7eead0132d..74dc095f1f 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISettable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ISettable.cs @@ -9,7 +9,7 @@ using Newtonsoft.Json; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { - partial class NDS : ISettable + public partial class NDS : ISettable { private NDSSettings _settings; private NDSSyncSettings _syncSettings; @@ -153,7 +153,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS public bool UseRealTime { get; set; } [DisplayName("DSi Mode")] - [Description("If true, DSi mode will be used.")] + [Description("If true, DSi mode will be used. Forced true if a DSiWare rom is detected.")] [DefaultValue(false)] public bool UseDSi { get; set; } @@ -169,9 +169,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS [DisplayName("Firmware Override")] [Description("If true, the firmware settings will be overriden by provided settings. Forced true when recording a movie.")] - [DefaultValue(false)] + [DefaultValue(true)] public bool FirmwareOverride { get; set; } + [DisplayName("Clear NAND")] + [Description("If true, the DSi NAND will have all its titles cleared. Forced true when recording a movie.")] + [DefaultValue(true)] + public bool ClearNAND { get; set; } + public enum StartUp : int { [Display(Name = "Auto Boot")] diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs index d08de8f798..d0a0f1f40c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs @@ -5,14 +5,14 @@ using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { - partial class NDS + public partial class NDS { private ITraceable Tracer { get; } private readonly LibMelonDS.TraceCallback _tracecb; private unsafe void MakeTrace(LibMelonDS.TraceMask type, uint opcode, IntPtr r, IntPtr disasm, uint cyclesOff) { - string cpu = type switch + var cpu = type switch { LibMelonDS.TraceMask.ARM7_THUMB => "ARM7 (Thumb)", LibMelonDS.TraceMask.ARM7_ARM => "ARM7", @@ -21,33 +21,16 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS _ => throw new InvalidOperationException("Invalid CPU Mode???"), }; - uint* regs = (uint*)r; + var regs = (uint*)r; - bool isthumb = type is LibMelonDS.TraceMask.ARM7_THUMB or LibMelonDS.TraceMask.ARM9_THUMB; - uint opaddr = regs[15] - (isthumb ? 4u : 8u); // handle prefetch + var isthumb = type is LibMelonDS.TraceMask.ARM7_THUMB or LibMelonDS.TraceMask.ARM9_THUMB; + var opaddr = regs![15] - (isthumb ? 4u : 8u); // handle prefetch Tracer.Put(new( - disassembly: string.Format("{0:x8}: {1:x8} ", opaddr, opcode).PadRight(12) + Marshal.PtrToStringAnsi(disasm).PadRight(36), - registerInfo: string.Format( - "r0:{0:x8} r1:{1:x8} r2:{2:x8} r3:{3:x8} r4:{4:x8} r5:{5:x8} r6:{6:x8} r7:{7:x8} r8:{8:x8} r9:{9:x8} r10:{10:x8} r11:{11:x8} r12:{12:x8} SP:{13:x8} LR:{14:x8} PC:{15:x8} Cy:{16} {17}", - regs[0], - regs[1], - regs[2], - regs[3], - regs[4], - regs[5], - regs[6], - regs[7], - regs[8], - regs[9], - regs[10], - regs[11], - regs[12], - regs[13], - regs[14], - regs[15], - CycleCount + cyclesOff, - cpu))); + disassembly: $"{opaddr:x8}: {opcode:x8} ".PadRight(12) + Marshal.PtrToStringAnsi(disasm)!.PadRight(36), + registerInfo: $"r0:{regs[0]:x8} r1:{regs[1]:x8} r2:{regs[2]:x8} r3:{regs[3]:x8} r4:{regs[4]:x8} r5:{regs[5]:x8} " + + $"r6:{regs[6]:x8} r7:{regs[7]:x8} r8:{regs[8]:x8} r9:{regs[9]:x8} r10:{regs[10]:x8} r11:{regs[11]:x8} " + + $"r12:{regs[12]:x8} SP:{regs[13]:x8} LR:{regs[14]:x8} PC:{regs[15]:x8} Cy:{CycleCount + cyclesOff} {cpu}")); } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs index d319b61de7..30c58bfd04 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs @@ -13,7 +13,7 @@ using BizHawk.Emulation.Cores.Waterbox; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { - [PortedCore(CoreNames.MelonDS, "Arisotura", "0.9.4", "http://melonds.kuribo64.net/")] + [PortedCore(CoreNames.MelonDS, "Arisotura", "0.9.5", "https://melonds.kuribo64.net/")] [ServiceNotApplicable(new[] { typeof(IDriveLight), typeof(IRegionable) })] public partial class NDS : WaterboxCore { @@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS [CoreConstructor(VSystemID.Raw.NDS)] public NDS(CoreLoadParameters lp) - : base(lp.Comm, new Configuration + : base(lp.Comm, new() { DefaultWidth = 256, DefaultHeight = 384, @@ -34,28 +34,29 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS SystemId = VSystemID.Raw.NDS, }) { - _syncSettings = lp.SyncSettings ?? new NDSSyncSettings(); - _settings = lp.Settings ?? new NDSSettings(); + _syncSettings = lp.SyncSettings ?? new(); + _settings = lp.Settings ?? new(); IsDSi = _syncSettings.UseDSi; var roms = lp.Roms.Select(r => r.RomData).ToList(); + + DSiTitleId = GetDSiTitleId(roms[0]); + IsDSi |= IsDSiWare; if (roms.Count > (IsDSi ? 1 : 3)) { throw new InvalidOperationException("Wrong number of ROMs!"); } - IsDSiWare = IsDSi && RomIsWare(roms[0]); - - bool gbacartpresent = roms.Count > 1; - bool gbasrampresent = roms.Count == 3; + var gbacartpresent = roms.Count > 1; + var gbasrampresent = roms.Count == 3; InitMemoryCallbacks(); _tracecb = MakeTrace; _threadstartcb = ThreadStartCallback; - _core = PreInit(new WaterboxOptions + _core = PreInit(new() { Filename = "melonDS.wbx", SbrkHeapSizeKB = 2 * 1024, @@ -91,13 +92,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS ? CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("NDS", "firmwarei")) : CoreComm.CoreFileProvider.GetFirmware(new("NDS", "firmware")); - var tmd = IsDSi && IsDSiWare - ? GetTMDData(roms[0]) + var tmd = IsDSiWare + ? GetTMDData(DSiTitleId.Full) : null; - bool skipfw = _syncSettings.SkipFirmware || !_syncSettings.UseRealBIOS || fw == null; + var skipfw = _syncSettings.SkipFirmware || !_syncSettings.UseRealBIOS || fw == null; - LibMelonDS.LoadFlags loadFlags = LibMelonDS.LoadFlags.NONE; + var loadFlags = LibMelonDS.LoadFlags.NONE; if (_syncSettings.UseRealBIOS || IsDSi) loadFlags |= LibMelonDS.LoadFlags.USE_REAL_BIOS; @@ -105,11 +106,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS loadFlags |= LibMelonDS.LoadFlags.SKIP_FIRMWARE; if (gbacartpresent) loadFlags |= LibMelonDS.LoadFlags.GBA_CART_PRESENT; + if (IsDSi && (_syncSettings.ClearNAND || lp.DeterministicEmulationRequested)) + loadFlags |= LibMelonDS.LoadFlags.CLEAR_NAND; // TODO: need a way to send through multiple DSiWare titles at once for this approach if (fw is null || _syncSettings.FirmwareOverride || lp.DeterministicEmulationRequested) loadFlags |= LibMelonDS.LoadFlags.FIRMWARE_OVERRIDE; if (IsDSi) loadFlags |= LibMelonDS.LoadFlags.IS_DSI; - if (IsDSi && IsDSiWare) + if (IsDSiWare) loadFlags |= LibMelonDS.LoadFlags.LOAD_DSIWARE; if (_syncSettings.ThreadedRendering) loadFlags |= LibMelonDS.LoadFlags.THREADED_RENDERING; @@ -122,7 +125,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS fwSettings.FirmwareBirthdayMonth = _syncSettings.FirmwareBirthdayMonth; fwSettings.FirmwareBirthdayDay = _syncSettings.FirmwareBirthdayDay; fwSettings.FirmwareFavouriteColour = _syncSettings.FirmwareFavouriteColour; - var message = _syncSettings.FirmwareMessage.Length != 0 ? Encoding.UTF8.GetBytes(_syncSettings.FirmwareMessage) : new byte[1] { 0 }; + var message = _syncSettings.FirmwareMessage.Length != 0 ? Encoding.UTF8.GetBytes(_syncSettings.FirmwareMessage) : new byte[1]; fwSettings.FirmwareMessageLength = message.Length; var loadData = new LibMelonDS.LoadData @@ -217,27 +220,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS _serviceProvider.Register(Tracer); } - private static bool RomIsWare(byte[] file) - { - uint lowerWareTitleId = 0; - for (int i = 0; i < 4; i++) - { - lowerWareTitleId <<= 8; - lowerWareTitleId |= file[0x237 - i]; - } - return lowerWareTitleId == 0x00030004; - } - - private static byte[] GetTMDData(byte[] ware) + private static (ulong Full, uint Upper, uint Lower) GetDSiTitleId(byte[] file) { ulong titleId = 0; - for (int i = 0; i < 8; i++) + for (var i = 0; i < 8; i++) { titleId <<= 8; - titleId |= ware[0x237 - i]; + titleId |= file[0x237 - i]; } + return (titleId, (uint)(titleId >> 32), (uint)(titleId & 0xFFFFFFFFU)); + } + + private static byte[] GetTMDData(ulong titleId) + { using var zip = new ZipArchive(Zstd.DecompressZstdStream(new MemoryStream(Resources.TMDS.Value)), ZipArchiveMode.Read, false); - using var tmd = zip.GetEntry($"{titleId:x16}.tmd")?.Open() ?? throw new Exception($"Cannot find TMD for title ID {titleId:x16}, please report"); + using var tmd = zip.GetEntry($"{titleId:x16}.tmd")?.Open() ?? throw new($"Cannot find TMD for title ID {titleId:x16}, please report"); var ret = new byte[tmd.Length]; tmd.Read(ret, 0, (int)tmd.Length); return ret; @@ -246,7 +243,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS // todo: wire this up w/ frontend public byte[] GetNAND() { - int length = _core.GetNANDSize(); + var length = _core.GetNANDSize(); if (length > 0) { @@ -255,12 +252,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS return ret; } - return new byte[0]; + return null; } public bool IsDSi { get; } - public bool IsDSiWare { get; } + public bool IsDSiWare => DSiTitleId.Upper == 0x00030004; + + private (ulong Full, uint Upper, uint Lower) DSiTitleId { get; } public override ControllerDefinition ControllerDefinition => NDSController; @@ -275,7 +274,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS .AddAxis("GBA Light Sensor", 0.RangeTo(10), 0) .MakeImmutable(); - private LibMelonDS.Buttons GetButtons(IController c) + private static LibMelonDS.Buttons GetButtons(IController c) { LibMelonDS.Buttons b = 0; if (c.IsPressed("Up")) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs index d0342ad94d..111f26932c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs @@ -43,14 +43,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS if (Cpu.Length == 14) { addr &= ~1u; - uint op = m.PeekByte(addr) | (uint)m.PeekByte(addr + 1) << 8; + var op = m.PeekByte(addr) | (uint)m.PeekByte(addr + 1) << 8; _core.GetDisassembly(type, op, ret); length = 2; } else { addr &= ~3u; - uint op = m.PeekByte(addr) + var op = m.PeekByte(addr) | (uint)m.PeekByte(addr + 1) << 8 | (uint)m.PeekByte(addr + 2) << 16 | (uint)m.PeekByte(addr + 3) << 24; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs index 903cb024bd..c3fe952c57 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs @@ -21,8 +21,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS comm.ShowMessage("Hacked firmware detected! Firmware might not work!"); return false; } - int fwMask = fw.Length - 1; - string badCrc16s = ""; + var fwMask = fw.Length - 1; + var badCrc16s = string.Empty; if (!VerifyCrc16(fw, 0x2C, (fw[0x2C + 1] << 8) | fw[0x2C], 0x0000, 0x2A)) { badCrc16s += " Wifi "; @@ -58,12 +58,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS public static void SanitizeFw(byte[] fw) { - int fwMask = fw.Length - 1; - int[] apstart = new int[3] { 0x07FA00 & fwMask, 0x07FB00 & fwMask, 0x07FC00 & fwMask }; + var fwMask = fw.Length - 1; + var apstart = new int[3] { 0x07FA00 & fwMask, 0x07FB00 & fwMask, 0x07FC00 & fwMask }; - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { - for (int j = 0; j < 0x100; j++) + for (var j = 0; j < 0x100; j++) { fw[apstart[i] + j] = 0; } @@ -78,21 +78,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS // F8 98 C1 E6 CC 5D 92 E1 85 8C 96 // different mac address // 18 90 15 E9 7C 1D F1 E1 85 74 02 - byte[] macdependentbytes = new byte[11] { 0xF8, 0x98, 0xC1, 0xE6, 0xCC, 0x9D, 0xBE, 0xE1, 0x85, 0x71, 0x5F }; + var macdependentbytes = new byte[11] { 0xF8, 0x98, 0xC1, 0xE6, 0xCC, 0x9D, 0xBE, 0xE1, 0x85, 0x71, 0x5F }; - int apoffset = 0xF5; + var apoffset = 0xF5; - for (int i = 0; i < 2; i++) + for (var i = 0; i < 2; i++) { - for (int j = 0; j < 11; j++) + for (var j = 0; j < 11; j++) { fw[apstart[i] + apoffset + j] = macdependentbytes[j]; } } - int ffoffset = 0xE7; + var ffoffset = 0xE7; - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { fw[apstart[i] + ffoffset] = 0xFF; } @@ -101,9 +101,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS fw[apstart[2] + 0xFE] = 0x0A; fw[apstart[2] + 0xFF] = 0xF0; - int[] usersettings = new int[2] { 0x7FE00 & fwMask, 0x7FF00 & fwMask }; + var usersettings = new int[2] { 0x7FE00 & fwMask, 0x7FF00 & fwMask }; - for (int i = 0; i < 2; i++) + for (var i = 0; i < 2; i++) { unsafe { @@ -136,11 +136,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { var poly = new ushort[8] { 0xC0C1, 0xC181, 0xC301, 0xC601, 0xCC01, 0xD801, 0xF001, 0xA001 }; - for (int i = 0; i < len; i++) + for (var i = 0; i < len; i++) { seed ^= data[i]; - for (int j = 0; j < 8; j++) + for (var j = 0; j < 8; j++) { if ((seed & 0x1) != 0) { @@ -159,10 +159,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS private static unsafe bool VerifyCrc16(byte[] fw, int startaddr, int len, int seed, int crcaddr) { - ushort storedCrc16 = (ushort)((fw[crcaddr + 1] << 8) | fw[crcaddr]); + var storedCrc16 = (ushort)((fw[crcaddr + 1] << 8) | fw[crcaddr]); fixed (byte* start = &fw[startaddr]) { - ushort actualCrc16 = Crc16(start, len, seed); + var actualCrc16 = Crc16(start, len, seed); return storedCrc16 == actualCrc16; } } @@ -173,7 +173,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS [DllImport("libfwunpack", CallingConvention = CallingConvention.Cdecl)] private static extern void FreeDecryptedFirmware(IntPtr decryptedFw); - private static string[] goodhashes = new string[] + private static readonly string[] goodhashes = { "D83861C66796665A9777B4E9078E9CC8EB13D880", // MACP nds (one of v1-v4), supposedly the most common "F87038265D24677419FE0AF9EED63B4CE1378CC9", // MACg nds (v5) @@ -182,23 +182,22 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS private static bool CheckDecryptedCodeChecksum(byte[] fw, CoreComm comm) { - if (!GetDecryptedFirmware(fw, fw.Length, out IntPtr decryptedfw, out int decrypedfwlen)) + if (!GetDecryptedFirmware(fw, fw.Length, out var decryptedfw, out var decrypedfwlen)) { comm.ShowMessage("Firmware could not be decryped for verification! This firmware might be not work!"); return false; } - else + + var DecryptedFirmware = new byte[decrypedfwlen]; + Marshal.Copy(decryptedfw, DecryptedFirmware, 0, decrypedfwlen); + FreeDecryptedFirmware(decryptedfw); + var hash = SHA1Checksum.ComputeDigestHex(DecryptedFirmware); + if (hash != goodhashes[0] && hash != goodhashes[1] && hash != goodhashes[2]) { - byte[] DecryptedFirmware = new byte[decrypedfwlen]; - Marshal.Copy(decryptedfw, DecryptedFirmware, 0, decrypedfwlen); - FreeDecryptedFirmware(decryptedfw); - var hash = SHA1Checksum.ComputeDigestHex(DecryptedFirmware); - if (hash != goodhashes[0] && hash != goodhashes[1] && hash != goodhashes[2]) - { - comm.ShowMessage("Potentially bad firmware dump! Decrypted hash " + hash + " does not match known good dumps."); - return false; - } + comm.ShowMessage("Potentially bad firmware dump! Decrypted hash " + hash + " does not match known good dumps."); + return false; } + return true; } }