diff --git a/BizHawk.Emulation.Common/CodeDataLog.cs b/BizHawk.Emulation.Common/Base Implementations/CodeDataLog.cs similarity index 79% rename from BizHawk.Emulation.Common/CodeDataLog.cs rename to BizHawk.Emulation.Common/Base Implementations/CodeDataLog.cs index 972ff199a1..260c48b3e0 100644 --- a/BizHawk.Emulation.Common/CodeDataLog.cs +++ b/BizHawk.Emulation.Common/Base Implementations/CodeDataLog.cs @@ -1,17 +1,20 @@ using System; -using System.Runtime.InteropServices; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.IO; -using BizHawk.Emulation.Common; +using System.Runtime.InteropServices; namespace BizHawk.Emulation.Common { - public class CodeDataLog : Dictionary + /// + /// The base implementation of ICodeDataLog + /// + /// + /// + public class CodeDataLog : Dictionary, ICodeDataLog { public CodeDataLog() { + Active = true; } /// @@ -20,9 +23,14 @@ namespace BizHawk.Emulation.Common public void Pin() { if (Pins.Count != 0) + { throw new InvalidOperationException("incremental astrological examination"); + } + foreach (var kvp in this) + { Pins[kvp.Key] = GCHandle.Alloc(kvp.Value, GCHandleType.Pinned); + } } /// @@ -31,7 +39,10 @@ namespace BizHawk.Emulation.Common public void Unpin() { foreach (var pin in Pins.Values) + { pin.Free(); + } + Pins.Clear(); } @@ -46,49 +57,67 @@ namespace BizHawk.Emulation.Common /// /// Pinned managed arrays /// - Dictionary Pins = new Dictionary(); + private readonly Dictionary Pins = new Dictionary(); /// /// Whether the CDL is tracking a block with the given name /// - public bool Has(string blockname) { return ContainsKey(blockname); } + public bool Has(string blockname) + { + return ContainsKey(blockname); + } /// /// This is just a hook, if needed, to readily suspend logging, without having to rewire the core /// - public bool Active = true; + public bool Active { get; set; } - public string SubType; - public int SubVer; + public string SubType { get; set; } + public int SubVer { get; set; } /// /// Tests whether the other CodeDataLog is structurally identical /// - public bool Check(CodeDataLog other) + public bool Check(ICodeDataLog other) { if (SubType != other.SubType) + { return false; - if (SubVer != other.SubVer) - return false; + } - if (this.Count != other.Count) + if (SubVer != other.SubVer) + { return false; + } + + if (Count != other.Count) + { + return false; + } + foreach (var kvp in this) { if (!other.ContainsKey(kvp.Key)) + { return false; + } + var oval = other[kvp.Key]; if (oval.Length != kvp.Value.Length) + { return false; + } } return true; } - public void LogicalOrFrom(CodeDataLog other) + public void LogicalOrFrom(ICodeDataLog other) { - if (this.Count != other.Count) + if (Count != other.Count) + { throw new InvalidDataException("Dictionaries must have the same number of keys!"); + } foreach (var kvp in other) { @@ -96,17 +125,23 @@ namespace BizHawk.Emulation.Common byte[] todata = this[kvp.Key]; if (fromdata.Length != todata.Length) + { throw new InvalidDataException("Memory regions must be the same size!"); + } for (int i = 0; i < todata.Length; i++) + { todata[i] |= fromdata[i]; + } } } public void ClearData() { foreach (byte[] data in Values) + { Array.Clear(data, 0, data.Length); + } } public void Save(Stream s) @@ -114,7 +149,7 @@ namespace BizHawk.Emulation.Common _Save(s, true); } - Dictionary _Save(Stream s, bool forReal) + private Dictionary _Save(Stream s, bool forReal) { var ret = new Dictionary(); var w = new BinaryWriter(s); @@ -142,6 +177,7 @@ namespace BizHawk.Emulation.Common addr += kvp.Value.Length; } } + w.Flush(); return ret; } @@ -156,11 +192,17 @@ namespace BizHawk.Emulation.Common var br = new BinaryReader(s); string id = br.ReadString(); if (id == "BIZHAWK-CDL-1") + { SubType = "PCE"; + } else if (id == "BIZHAWK-CDL-2") + { SubType = br.ReadString().TrimEnd(' '); + } else + { throw new InvalidDataException("File is not a Bizhawk CDL file!"); + } int count = br.ReadInt32(); for (int i = 0; i < count; i++) diff --git a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj index fd5a2c2852..5c5b3ade3e 100644 --- a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj +++ b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj @@ -107,7 +107,7 @@ - + diff --git a/BizHawk.Emulation.Common/Interfaces/Services/ICodeDataLogger.cs b/BizHawk.Emulation.Common/Interfaces/Services/ICodeDataLogger.cs index 6fcd634156..a2d064c923 100644 --- a/BizHawk.Emulation.Common/Interfaces/Services/ICodeDataLogger.cs +++ b/BizHawk.Emulation.Common/Interfaces/Services/ICodeDataLogger.cs @@ -1,4 +1,6 @@ -using System.IO; +using System; +using System.IO; +using System.Collections.Generic; namespace BizHawk.Emulation.Common { @@ -11,17 +13,64 @@ namespace BizHawk.Emulation.Common /// /// Sets the CodeDataLog as current (and logging) on the core /// - void SetCDL(CodeDataLog cdl); + void SetCDL(ICodeDataLog cdl); /// /// Fills a new CodeDataLog with memory domain information suitable for the core /// - void NewCDL(CodeDataLog cdl); + void NewCDL(ICodeDataLog cdl); /// /// Disassembles the CodeDataLog to an output Stream. Can't be done without a core because there's no code to disassemble otherwise! /// This could be extended later to produce richer multi-file disassembly /// - void DisassembleCDL(Stream s, CodeDataLog cdl); + void DisassembleCDL(Stream s, ICodeDataLog cdl); + } + + /// + /// Defines a code/data log to be used with the code/data logger + /// + /// + public interface ICodeDataLog : IDictionary + { + /// + /// Pins the managed arrays. Not that we expect them to be allocated, but in case we do, seeing thish ere will remind us to check for the pin condition and abort + /// + void Pin(); + + /// + /// Unpins the managed arrays, to be paired with calls to Pin() + /// + void Unpin(); + + /// + /// Retrieves the pointer to a managed array + /// + IntPtr GetPin(string key); + + /// + /// Whether the CDL is tracking a block with the given name + /// + bool Has(string blockname); + + /// + /// This is just a hook, if needed, to readily suspend logging, without having to rewire the core + /// + bool Active { get; set; } + + string SubType { get; set; } + + int SubVer { get; set; } + + /// + /// Tests whether the other CodeDataLog is structurally identical + /// + bool Check(ICodeDataLog other); + + void LogicalOrFrom(ICodeDataLog other); + + void ClearData(); + + void Save(Stream s); } } diff --git a/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280_CDL.cs b/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280_CDL.cs index def9ecc065..9438733ba7 100644 --- a/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280_CDL.cs +++ b/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280_CDL.cs @@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280 { public partial class HuC6280 { - public void DisassembleCDL(Stream s, CodeDataLog cdl, IMemoryDomains mem) + public void DisassembleCDL(Stream s, ICodeDataLog cdl, IMemoryDomains mem) { var w = new StreamWriter(s); w.WriteLine("; Bizhawk CDL Disassembly"); @@ -78,7 +78,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280 public MemMapping[] Mappings; // = new MemMapping[256]; - public CodeDataLog CDL = null; + public ICodeDataLog CDL = null; [Flags] public enum CDLUsage : byte diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ICodeDataLog.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ICodeDataLog.cs index 1eaf4cbaf9..8625c95d3b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ICodeDataLog.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ICodeDataLog.cs @@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { partial class Gameboy { - void ICodeDataLogger.SetCDL(CodeDataLog cdl) + void ICodeDataLogger.SetCDL(ICodeDataLog cdl) { CDL = cdl; if(cdl == null) @@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy LibGambatte.gambatte_setcdcallback(GambatteState, CDCallback); } - void ICodeDataLogger.NewCDL(CodeDataLog cdl) + void ICodeDataLogger.NewCDL(ICodeDataLog cdl) { cdl["ROM"] = new byte[MemoryDomains["ROM"].Size]; @@ -32,9 +32,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy } //not supported - void ICodeDataLogger.DisassembleCDL(Stream s, CodeDataLog cdl) { } + void ICodeDataLogger.DisassembleCDL(Stream s, ICodeDataLog cdl) { } - CodeDataLog CDL; + ICodeDataLog CDL; LibGambatte.CDCallback CDCallback; void CDCallbackProc(int addr, LibGambatte.CDLog_AddrType addrtype, LibGambatte.CDLog_Flags flags) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.ICodeDataLog.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.ICodeDataLog.cs index 0348165c76..7585653826 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.ICodeDataLog.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.ICodeDataLog.cs @@ -1,24 +1,24 @@ -using System; -using System.IO; -using System.Collections.Generic; - -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.Gameboy +using System; +using System.IO; +using System.Collections.Generic; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { - partial class GambatteLink - { - void ICodeDataLogger.SetCDL(CodeDataLog cdl) + partial class GambatteLink + { + void ICodeDataLogger.SetCDL(ICodeDataLog cdl) { - ((ICodeDataLogger)L).SetCDL(cdl); - } - - void ICodeDataLogger.NewCDL(CodeDataLog cdl) - { - ((ICodeDataLogger)L).NewCDL(cdl); + ((ICodeDataLogger)L).SetCDL(cdl); } - void ICodeDataLogger.DisassembleCDL(Stream s, CodeDataLog cdl) { ((ICodeDataLogger)L).DisassembleCDL(s, cdl); } - - } + void ICodeDataLogger.NewCDL(ICodeDataLog cdl) + { + ((ICodeDataLogger)L).NewCDL(cdl); + } + + void ICodeDataLogger.DisassembleCDL(Stream s, ICodeDataLog cdl) { ((ICodeDataLogger)L).DisassembleCDL(s, cdl); } + + } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs index bc92dbf1dd..f08f29b57e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs @@ -204,7 +204,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES Marshal.Copy(temp, 0, new IntPtr(ptr), CpuRegs.SIZEOF); } - public void QUERY_set_cdl(CodeDataLog cdl) + public void QUERY_set_cdl(ICodeDataLog cdl) { WritePipeMessage(eMessage.eMessage_QUERY_set_cdl); if (cdl == null) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index a2b3c47ff4..127ef65e68 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -174,9 +174,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES } } - CodeDataLog currCdl; + ICodeDataLog currCdl; - public void SetCDL(CodeDataLog cdl) + public void SetCDL(ICodeDataLog cdl) { if(currCdl != null) currCdl.Unpin(); currCdl = cdl; @@ -186,7 +186,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES api.QUERY_set_cdl(currCdl); } - public void NewCDL(CodeDataLog cdl) + public void NewCDL(ICodeDataLog cdl) { cdl["CARTROM"] = new byte[MemoryDomains["CARTROM"].Size]; @@ -200,7 +200,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES cdl.SubVer = 0; } - public void DisassembleCDL(Stream s, CodeDataLog cdl) + public void DisassembleCDL(Stream s, ICodeDataLog cdl) { //not supported yet } diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.ICodeDataLogger.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.ICodeDataLogger.cs index e46911343a..8161881024 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.ICodeDataLogger.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.ICodeDataLogger.cs @@ -8,12 +8,12 @@ namespace BizHawk.Emulation.Cores.PCEngine { public sealed partial class PCEngine : ICodeDataLogger { - public void SetCDL(CodeDataLog cdl) + public void SetCDL(ICodeDataLog cdl) { Cpu.CDL = cdl; } - public void NewCDL(CodeDataLog cdl) + public void NewCDL(ICodeDataLog cdl) { InitCDLMappings(); var mm = this.Cpu.Mappings; @@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.PCEngine cdl.SubVer = 0; } - public void DisassembleCDL(Stream s, CodeDataLog cdl) + public void DisassembleCDL(Stream s, ICodeDataLog cdl) { Cpu.DisassembleCDL(s, cdl, _memoryDomains); } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs index 1b00f989e1..3c5d438faf 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ICodeDataLogger.cs @@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem { public sealed partial class SMS : ICodeDataLogger { - public void SetCDL(CodeDataLog cdl) + public void SetCDL(ICodeDataLog cdl) { CDL = cdl; if (cdl == null) @@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem } } - public void NewCDL(CodeDataLog cdl) + public void NewCDL(ICodeDataLog cdl) { cdl["ROM"] = new byte[MemoryDomains["ROM"].Size]; cdl["Main RAM"] = new byte[MemoryDomains["Main RAM"].Size]; @@ -43,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem } [FeatureNotImplemented] - public void DisassembleCDL(Stream s, CodeDataLog cdl) + public void DisassembleCDL(Stream s, ICodeDataLog cdl) { } @@ -73,7 +73,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem private delegate CDLog_MapResults MapMemoryDelegate(ushort addr, bool write); private MapMemoryDelegate MapMemory; - private CodeDataLog CDL; + private ICodeDataLog CDL; private void RunCDL(ushort address, CDLog_Flags flags) { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ICodeDataLogger.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ICodeDataLogger.cs index 63d4cfe903..0c154bece0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ICodeDataLogger.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ICodeDataLogger.cs @@ -7,14 +7,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx { public partial class GPGX : ICodeDataLogger { - public void SetCDL(CodeDataLog cdl) + public void SetCDL(ICodeDataLog cdl) { CDL = cdl; if (cdl == null) LibGPGX.gpgx_set_cd_callback(null); else LibGPGX.gpgx_set_cd_callback(CDCallback); } - public void NewCDL(CodeDataLog cdl) + public void NewCDL(ICodeDataLog cdl) { cdl["MD CART"] = new byte[MemoryDomains["MD CART"].Size]; cdl["68K RAM"] = new byte[MemoryDomains["68K RAM"].Size]; @@ -29,9 +29,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx // TODO: we have Disassembling now // not supported - public void DisassembleCDL(Stream s, CodeDataLog cdl) { } + public void DisassembleCDL(Stream s, ICodeDataLog cdl) { } - private CodeDataLog CDL; + private ICodeDataLog CDL; private void CDCallbackProc(int addr, LibGPGX.CDLog_AddrType addrtype, LibGPGX.CDLog_Flags flags) { //TODO - hard reset makes CDL go nuts. diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ICodeDataLogger.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ICodeDataLogger.cs index 0d144b94cd..445a11ea62 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ICodeDataLogger.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ICodeDataLogger.cs @@ -7,14 +7,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 { public partial class GPGX : ICodeDataLogger { - public void SetCDL(CodeDataLog cdl) + public void SetCDL(ICodeDataLog cdl) { CDL = cdl; if (cdl == null) Core.gpgx_set_cd_callback(null); else Core.gpgx_set_cd_callback(CDCallback); } - public void NewCDL(CodeDataLog cdl) + public void NewCDL(ICodeDataLog cdl) { cdl["MD CART"] = new byte[MemoryDomains["MD CART"].Size]; cdl["68K RAM"] = new byte[MemoryDomains["68K RAM"].Size]; @@ -29,9 +29,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 // TODO: we have Disassembling now // not supported - public void DisassembleCDL(Stream s, CodeDataLog cdl) { } + public void DisassembleCDL(Stream s, ICodeDataLog cdl) { } - private CodeDataLog CDL; + private ICodeDataLog CDL; private void CDCallbackProc(int addr, LibGPGX.CDLog_AddrType addrtype, LibGPGX.CDLog_Flags flags) { //TODO - hard reset makes CDL go nuts.