CDL - major refactor complete. muuuuch better.

This commit is contained in:
zeromus 2015-10-28 03:51:53 -05:00
parent 65c2387b0a
commit 70e0954f28
14 changed files with 416 additions and 435 deletions

View File

@ -20,11 +20,8 @@ namespace BizHawk.Client.EmuHawk
{
public partial class CDL : Form, IToolFormAutoConfig
{
[RequiredService]
public IEmulator _emu { get; private set; }
private CodeDataLog _cdl;
private RecentFiles _recent_fld = new RecentFiles();
[ConfigPersist]
private RecentFiles _recent
{
@ -48,6 +45,7 @@ namespace BizHawk.Client.EmuHawk
private ICodeDataLogger CodeDataLogger { get; set; }
private string _currentFileName = string.Empty;
private CodeDataLog _cdl;
public CDL()
{
@ -66,33 +64,11 @@ namespace BizHawk.Client.EmuHawk
public void Restart()
{
//zeromus doesn't like this logic very much. it has to change.
if (_emu.SystemId == "PCE")
{
var pce = _emu as PCEngine;
LoggingActiveCheckbox.Checked = pce.Cpu.CDLLoggingActive;
_cdl = pce.Cpu.CDL;
pce.InitCDLMappings();
}
else if(_emu.SystemId == "GB")
{
var gambatte = _emu as Gameboy;
_cdl = gambatte.CDL;
if (_cdl == null)
LoggingActiveCheckbox.Checked = false;
else
LoggingActiveCheckbox.Checked = _cdl.Active;
}
else if (_emu is GPGX)
{
var gpgx = _emu as GPGX;
_cdl = gpgx.CDL;
if (_cdl == null)
LoggingActiveCheckbox.Checked = false;
else
LoggingActiveCheckbox.Checked = _cdl.Active;
}
//don't try to recover the current CDL!
//even though it seems like it might be nice, it might get mixed up between games. even if we use CheckCDL. Switching games with the same memory map will be bad.
_cdl = null;
_currentFileName = null;
LoggingActiveCheckbox.Checked = false;
UpdateDisplay();
}
@ -146,48 +122,25 @@ namespace BizHawk.Client.EmuHawk
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
var newCDL = CodeDataLog.Load(fs);
var newCDL = new CodeDataLog();
newCDL.Load(fs);
//this check may be inadequate in the future
if(newCDL.SubType != _emu.SystemId)
throw new InvalidDataException("File is a CDL file of the wrong target core (like, a different game console)!");
//have the core create a CodeDataLog to check mapping information against
var testCDL = new CodeDataLog();
CodeDataLogger.NewCDL(testCDL);
if (!newCDL.Check(testCDL))
{
MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return;
}
//ok, it's all good:
_cdl = newCDL;
if (_emu.SystemId == "PCE")
{
var pce = _emu as PCEngine;
var cdl_pce = newCDL as CodeDataLog_PCE;
if (!cdl_pce.CheckConsistency(pce.Cpu.Mappings))
{
MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return;
}
pce.Cpu.CDL = _cdl;
}
else if (_emu.SystemId == "GB")
{
var gambatte = _emu as Gameboy;
var cdl_gb = newCDL as CodeDataLog_GB;
var memd = gambatte.AsMemoryDomains();
if (!cdl_gb.CheckConsistency(memd))
{
MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return;
}
gambatte.CDL = cdl_gb;
}
else if (_emu is GPGX)
{
var gpgx = _emu as GPGX;
var cdl_gb = newCDL as CodeDataLog_GEN;
var memd = gpgx.AsMemoryDomains();
if (!cdl_gb.CheckConsistency(memd))
{
MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return;
}
gpgx.CDL = cdl_gb;
}
CodeDataLogger.SetCDL(null);
if (LoggingActiveCheckbox.Checked)
CodeDataLogger.SetCDL(_cdl);
_currentFileName = path;
}
UpdateDisplay();
@ -213,68 +166,70 @@ namespace BizHawk.Client.EmuHawk
RecentSubMenu.DropDownItems.AddRange(_recent.RecentMenu(LoadFile, true));
}
void NewFileLogic()
{
_cdl = new CodeDataLog();
CodeDataLogger.NewCDL(_cdl);
if (LoggingActiveCheckbox.Checked)
CodeDataLogger.SetCDL(_cdl);
else CodeDataLogger.SetCDL(null);
_currentFileName = null;
UpdateDisplay();
}
private void NewMenuItem_Click(object sender, EventArgs e)
{
var result = MessageBox.Show(this, "OK to create new CDL?", "Query", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
//take care not to clobber an existing CDL
if (_cdl != null)
{
if (_emu.SystemId == "PCE")
{
var pce = _emu as PCEngine;
_cdl = CodeDataLog_PCE.Create(pce.Cpu.Mappings);
pce.Cpu.CDL = _cdl;
}
else if (_emu.SystemId == "GB")
{
var gambatte = _emu as Gameboy;
var memd = gambatte.AsMemoryDomains();
var cdl_gb = CodeDataLog_GB.Create(memd);
gambatte.CDL = cdl_gb;
_cdl = cdl_gb;
}
else if (_emu is GPGX)
{
var gpgx = _emu as GPGX;
var memd = gpgx.AsMemoryDomains();
var cdl_gen = CodeDataLog_GEN.Create(memd);
gpgx.CDL = cdl_gen;
_cdl = cdl_gen;
}
UpdateDisplay();
var result = MessageBox.Show(this, "OK to create new CDL?", "Query", MessageBoxButtons.YesNo);
if (result != DialogResult.Yes)
return;
}
NewFileLogic();
}
private void OpenMenuItem_Click(object sender, EventArgs e)
{
var result = MessageBox.Show(this, "OK to load new CDL?", "Query", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
var file = ToolHelpers.OpenFileDialog(
_currentFileName,
PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null),
"Code Data Logger Files",
"cdl");
var file = ToolHelpers.OpenFileDialog(
_currentFileName,
PathManager.MakeAbsolutePath(Global.Config.PathEntries.LogPathFragment, null),
"Code Data Logger Files",
"cdl");
if (file != null)
{
LoadFile(file.FullName);
}
if (file == null)
return;
//take care not to clobber an existing CDL
if (_cdl != null)
{
var result = MessageBox.Show(this, "OK to load new CDL?", "Query", MessageBoxButtons.YesNo);
if (result != DialogResult.Yes)
return;
}
LoadFile(file.FullName);
}
private void SaveMenuItem_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(_currentFileName))
if (string.IsNullOrWhiteSpace(_currentFileName))
{
using (var fs = new FileStream(_currentFileName, FileMode.Create, FileAccess.Write))
{
_cdl.Save(fs);
}
RunSaveAs();
return;
}
using (var fs = new FileStream(_currentFileName, FileMode.Create, FileAccess.Write))
{
_cdl.Save(fs);
}
}
private void SaveAsMenuItem_Click(object sender, EventArgs e)
void RunSaveAs()
{
if (_cdl == null)
{
@ -300,6 +255,11 @@ namespace BizHawk.Client.EmuHawk
}
}
private void SaveAsMenuItem_Click(object sender, EventArgs e)
{
RunSaveAs();
}
private void AppendMenuItem_Click(object sender, EventArgs e)
{
if (_cdl == null)
@ -318,7 +278,13 @@ namespace BizHawk.Client.EmuHawk
{
using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
var newCDL = CodeDataLog.Load(fs);
var newCDL = new CodeDataLog();
newCDL.Load(fs);
if (!_cdl.Check(newCDL))
{
MessageBox.Show(this, "CDL file does not match emulator's current memory map!");
return;
}
_cdl.LogicalOrFrom(newCDL);
UpdateDisplay();
}
@ -348,17 +314,16 @@ namespace BizHawk.Client.EmuHawk
if (_cdl == null)
{
MessageBox.Show(this, "Cannot disassemble with no CDL loaded!", "Alert");
return;
}
else
var sfd = new SaveFileDialog();
var result = sfd.ShowDialog(this);
if (result == DialogResult.OK)
{
var sfd = new SaveFileDialog();
var result = sfd.ShowDialog(this);
if (result == DialogResult.OK)
using (var fs = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write))
{
using (var fs = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write))
{
_cdl.Disassemble(fs, MemoryDomains);
}
CodeDataLogger.DisassembleCDL(fs, _cdl);
}
}
}
@ -368,6 +333,13 @@ namespace BizHawk.Client.EmuHawk
Close();
}
protected override void OnClosed(EventArgs e)
{
//deactivate logger
if (CodeDataLogger != null) //just in case...
CodeDataLogger.SetCDL(null);
}
#endregion
#region Dialog Events
@ -380,21 +352,14 @@ namespace BizHawk.Client.EmuHawk
{
if (LoggingActiveCheckbox.Checked && _cdl == null)
{
MessageBox.Show(this, "Cannot log with no CDL loaded!", "Alert");
LoggingActiveCheckbox.Checked = false;
//implicitly create a new file
NewFileLogic();
}
if (_emu.SystemId == "PCE")
{
//set a special flag on the CPU to indicate CDL is running, maybe it's faster, who knows
var pce = _emu as PCEngine;
pce.Cpu.CDLLoggingActive = LoggingActiveCheckbox.Checked;
}
//zeromus doesnt like this kind of logic
if (_cdl != null)
_cdl.Active = LoggingActiveCheckbox.Checked;
if (_cdl != null && LoggingActiveCheckbox.Checked)
CodeDataLogger.SetCDL(_cdl);
else
CodeDataLogger.SetCDL(null);
}
private void PCECDL_DragEnter(object sender, DragEventArgs e)

View File

@ -64,6 +64,7 @@
<Compile Include="Base Implementations\NullSound.cs" />
<Compile Include="Base Implementations\TraceBuffer.cs" />
<Compile Include="BinaryQuickSerializer.cs" />
<Compile Include="CodeDataLog.cs" />
<Compile Include="CoreAttributes.cs" />
<Compile Include="CoreComms.cs" />
<Compile Include="Database\CRC32.cs" />

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Common
{
public class CodeDataLog : Dictionary<string, byte[]>
{
public CodeDataLog()
{
}
/// <summary>
/// This is just a hook, if needed, to readily suspend logging, without having to rewire the core
/// </summary>
public bool Active = true;
public string SubType;
public int SubVer;
/// <summary>
/// Tests whether the other CodeDataLog is structurally identical
/// </summary>
public bool Check(CodeDataLog other)
{
if (SubType != other.SubType)
return false;
if (SubVer != other.SubVer)
return false;
if (this.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)
{
if (this.Count != other.Count)
throw new InvalidDataException("Dictionaries must have the same number of keys!");
foreach (var kvp in other)
{
byte[] fromdata = kvp.Value;
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)
{
var w = new BinaryWriter(s);
w.Write("BIZHAWK-CDL-2");
w.Write(SubType.PadRight(15));
w.Write(Count);
foreach (var kvp in this)
{
w.Write(kvp.Key);
w.Write(kvp.Value.Length);
w.Write(kvp.Value);
}
w.Flush();
}
public void Load(Stream s)
{
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++)
{
string key = br.ReadString();
int len = br.ReadInt32();
byte[] data = br.ReadBytes(len);
this[key] = data;
}
}
}
}

View File

@ -1,6 +1,23 @@
namespace BizHawk.Emulation.Common
using System.IO;
namespace BizHawk.Emulation.Common
{
public interface ICodeDataLogger : IEmulatorService
{
{
/// <summary>
/// Sets the CodeDataLog as current (and logging) on the core
/// </summary>
void SetCDL(CodeDataLog cdl);
/// <summary>
/// Fills a new CodeDataLog with memory domain information suitable for the core
/// </summary>
void NewCDL(CodeDataLog cdl);
/// <summary>
/// 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
/// </summary>
void DisassembleCDL(Stream s, CodeDataLog cdl);
}
}

View File

@ -118,7 +118,6 @@
<DependentUpon>TI83.cs</DependentUpon>
</Compile>
<Compile Include="Calculator\TI83LinkPort.cs" />
<Compile Include="CodeDataLog.cs" />
<Compile Include="Computers\AppleII\AppleII.cs" />
<Compile Include="Computers\AppleII\AppleII.IAudioProvider.cs">
<DependentUpon>AppleII.cs</DependentUpon>
@ -347,8 +346,10 @@
</Compile>
<Compile Include="Consoles\Intellivision\PSG.cs" />
<Compile Include="Consoles\Intellivision\STIC.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\CodeDataLog_GB.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.ICodeDataLog.cs">
<DependentUpon>Gambatte.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.IDebuggable.cs">
<DependentUpon>Gambatte.cs</DependentUpon>
</Compile>
@ -758,7 +759,6 @@
<Compile Include="Consoles\PC Engine\PCEngine.Input.cs" />
<Compile Include="Consoles\PC Engine\PCEngine.TurboCD.cs" />
<Compile Include="Consoles\PC Engine\ScsiCDBus.cs" />
<Compile Include="Consoles\Sega\CodeDataLog_GEN.cs" />
<Compile Include="Consoles\Sega\Genesis\Cart\EEPROM.cs" />
<Compile Include="Consoles\Sega\Genesis\Cart\RomHeader.cs" />
<Compile Include="Consoles\Sega\Genesis\Cart\SaveRAM.cs" />
@ -827,7 +827,7 @@
<Compile Include="CoreInventory.cs" />
<Compile Include="CPUs\CP1610\CP1610.Disassembler.cs" />
<Compile Include="CPUs\CP1610\CP1610.Execute.cs" />
<Compile Include="CPUs\HuC6280\CodeDataLog_PCE.cs" />
<Compile Include="CPUs\HuC6280\HuC6280_CDL.cs" />
<Compile Include="CPUs\W65816\Disassembler.cs" />
<Compile Include="CPUs\68000\Diassembler.cs" />
<Compile Include="CPUs\68000\Instructions\BitArithemetic.cs" />

View File

@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Components.H6280
{
public class CodeDataLog_PCE : CodeDataLog
{
public static CodeDataLog_PCE Create(IEnumerable<HuC6280.MemMapping> mm)
{
var t = new CodeDataLog_PCE();
foreach (var kvp in SizesFromHuMap(mm))
{
t[kvp.Key] = new byte[kvp.Value];
}
return t;
}
public override string SubType { get { return "PCE"; } }
public override int SubVer { get { return 0; } }
public override void Disassemble(Stream s, IMemoryDomains mem)
{
var w = new StreamWriter(s);
w.WriteLine("; Bizhawk CDL Disassembly");
w.WriteLine();
foreach (var kvp in this)
{
w.WriteLine(".\"{0}\" size=0x{1:x8}", kvp.Key, kvp.Value.Length);
byte[] cd = kvp.Value;
var md = mem[kvp.Key];
for (int i = 0; i < kvp.Value.Length; i++)
{
if ((kvp.Value[i] & (byte)HuC6280.CDLUsage.Code) != 0)
{
int unused;
string dis = HuC6280.DisassembleExt(
0,
out unused,
delegate(ushort addr)
{
return md.PeekByte(addr + i);
},
delegate(ushort addr)
{
return md.PeekWord(addr + i, false);
}
);
w.WriteLine("0x{0:x8}: {1}", i, dis);
}
}
w.WriteLine();
}
w.WriteLine("; EOF");
w.Flush();
}
public bool CheckConsistency(object arg)
{
var mm = (IEnumerable<HuC6280.MemMapping>)arg;
var sizes = SizesFromHuMap(mm);
if (sizes.Count != Count)
return false;
foreach (var kvp in sizes)
{
if (!ContainsKey(kvp.Key))
return false;
if (this[kvp.Key].Length != kvp.Value)
return false;
}
return true;
}
private static Dictionary<string, int> SizesFromHuMap(IEnumerable<HuC6280.MemMapping> mm)
{
Dictionary<string, int> sizes = new Dictionary<string, int>();
foreach (var m in mm)
{
if (!sizes.ContainsKey(m.Name) || m.MaxOffs >= sizes[m.Name])
sizes[m.Name] = m.MaxOffs;
}
List<string> keys = new List<string>(sizes.Keys);
foreach (var key in keys)
{
// becase we were looking at offsets, and each bank is 8192 big, we need to add that size
sizes[key] += 8192;
}
return sizes;
}
}
}

View File

@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
if (Debug) Logger(State());
MemoryCallbacks.CallExecutes(PC);
if (CDLLoggingActive) CDLOpcode();
if (CDL != null && CDL.Active) CDLOpcode();
byte opcode = ReadMemory(PC++);
switch (opcode)

View File

@ -5,103 +5,65 @@ using System.Text;
using System.IO;
using BizHawk.Emulation.Common;
//needed for being a factory
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Components.H6280;
using BizHawk.Emulation.Cores.Consoles.Sega;
namespace BizHawk.Emulation.Cores.Components.H6280
{
public abstract class CodeDataLog : Dictionary<string, byte[]>
public partial class HuC6280
{
public CodeDataLog()
:base()
{
}
public void DisassembleCDL(Stream s, CodeDataLog cdl, IMemoryDomains mem)
{
var w = new StreamWriter(s);
w.WriteLine("; Bizhawk CDL Disassembly");
w.WriteLine();
foreach (var kvp in cdl)
{
w.WriteLine(".\"{0}\" size=0x{1:x8}", kvp.Key, kvp.Value.Length);
/// <summary>
/// You don't have to use this necessarily, it's just provided for convenience
/// </summary>
public bool Active;
byte[] cd = kvp.Value;
var md = mem[kvp.Key];
public virtual void Disassemble(Stream s, IMemoryDomains mem) { }
for (int i = 0; i < kvp.Value.Length; i++)
{
if ((kvp.Value[i] & (byte)HuC6280.CDLUsage.Code) != 0)
{
int unused;
string dis = HuC6280.DisassembleExt(
0,
out unused,
delegate(ushort addr)
{
return md.PeekByte(addr + i);
},
delegate(ushort addr)
{
return md.PeekWord(addr + i, false);
}
);
w.WriteLine("0x{0:x8}: {1}", i, dis);
}
}
w.WriteLine();
}
w.WriteLine("; EOF");
w.Flush();
}
public abstract string SubType { get; }
public abstract int SubVer { get; }
private static Dictionary<string, int> SizesFromHuMap(IEnumerable<HuC6280.MemMapping> mm)
{
Dictionary<string, int> sizes = new Dictionary<string, int>();
foreach (var m in mm)
{
if (!sizes.ContainsKey(m.Name) || m.MaxOffs >= sizes[m.Name])
sizes[m.Name] = m.MaxOffs;
}
public void LogicalOrFrom(CodeDataLog other)
{
if (this.Count != other.Count)
throw new InvalidDataException("Dictionaries must have the same number of keys!");
foreach (var kvp in other)
{
byte[] fromdata = kvp.Value;
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)
{
var w = new BinaryWriter(s);
w.Write("BIZHAWK-CDL-2");
w.Write(SubType.PadRight(15));
w.Write(Count);
foreach (var kvp in this)
{
w.Write(kvp.Key);
w.Write(kvp.Value.Length);
w.Write(kvp.Value);
}
w.Flush();
}
public static CodeDataLog Load(Stream s)
{
var br = new BinaryReader(s);
string id = br.ReadString();
string FileSubType;
if (id == "BIZHAWK-CDL-1")
FileSubType = "PCE";
else if (id == "BIZHAWK-CDL-2")
FileSubType = br.ReadString().TrimEnd(' ');
else
throw new InvalidDataException("File is not a Bizhawk CDL file!");
if (FileSubType == "PCE")
return new CodeDataLog_PCE().Load(br);
else if(FileSubType == "GB")
return new CodeDataLog_GB().Load(br);
else if (FileSubType == "GEN")
return new CodeDataLog_GEN().Load(br);
else return null;
}
private CodeDataLog Load(BinaryReader br)
{
int count = br.ReadInt32();
for (int i = 0; i < count; i++)
{
string key = br.ReadString();
int len = br.ReadInt32();
byte[] data = br.ReadBytes(len);
this[key] = data;
}
return this;
}
List<string> keys = new List<string>(sizes.Keys);
foreach (var key in keys)
{
// becase we were looking at offsets, and each bank is 8192 big, we need to add that size
sizes[key] += 8192;
}
return sizes;
}
}
public partial class HuC6280
@ -118,8 +80,6 @@ namespace BizHawk.Emulation.Cores.Components.H6280
public CodeDataLog CDL = null;
public bool CDLLoggingActive = false;
[Flags]
public enum CDLUsage : byte
{

View File

@ -1,38 +0,0 @@
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components.H6280;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
public class CodeDataLog_GB : CodeDataLog
{
public static CodeDataLog_GB Create(IMemoryDomains memdomains)
{
var t = new CodeDataLog_GB();
t["ROM"] = new byte[memdomains["ROM"].Size];
//t["HRAM"] = new byte[memdomains["HRAM"].Size]; //this is probably useless, but it's here if someone needs it
t["WRAM"] = new byte[memdomains["WRAM"].Size];
if(memdomains.Has("CartRAM"))
t["CartRAM"] = new byte[memdomains["WRAM"].Size];
return t;
}
public override string SubType { get { return "GB"; } }
public override int SubVer { get { return 0; } }
//todo - this could be base classed
public bool CheckConsistency(IMemoryDomains memdomains)
{
if (memdomains["ROM"].Size != this["ROM"].Length) return false;
if (memdomains["WRAM"].Size != this["WRAM"].Length) return false;
if (memdomains.Has("CartRAM") != this.ContainsKey("CartRAM")) return false;
if(memdomains.Has("CartRAM"))
if (memdomains["CartRAM"].Size != this["CartRAM"].Length)
return false;
return true;
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using System.IO;
using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
partial class Gameboy
{
void ICodeDataLogger.SetCDL(CodeDataLog cdl)
{
CDL = cdl;
if(cdl == null)
LibGambatte.gambatte_setcdcallback(GambatteState, null);
else
LibGambatte.gambatte_setcdcallback(GambatteState, CDCallback);
}
void ICodeDataLogger.NewCDL(CodeDataLog cdl)
{
cdl["ROM"] = new byte[MemoryDomains["ROM"].Size];
//cdl["HRAM"] = new byte[_memoryDomains["HRAM"].Size]; //this is probably useless, but it's here if someone needs it
cdl["WRAM"] = new byte[MemoryDomains["WRAM"].Size];
if (MemoryDomains.Has("CartRAM"))
cdl["CartRAM"] = new byte[MemoryDomains["WRAM"].Size];
cdl.SubType = "GB";
cdl.SubVer = 0;
}
//not supported
void ICodeDataLogger.DisassembleCDL(Stream s, CodeDataLog cdl) { }
CodeDataLog CDL;
LibGambatte.CDCallback CDCallback;
void CDCallbackProc(int addr, LibGambatte.CDLog_AddrType addrtype, LibGambatte.CDLog_Flags flags)
{
if (CDL == null) return;
if (!CDL.Active) return;
string key;
switch (addrtype)
{
case LibGambatte.CDLog_AddrType.ROM: key = "ROM"; break;
case LibGambatte.CDLog_AddrType.HRAM: key = "HRAM"; break;
case LibGambatte.CDLog_AddrType.WRAM: key = "WRAM"; break;
case LibGambatte.CDLog_AddrType.CartRAM: key = "CartRAM"; break;
default: throw new InvalidOperationException("Juniper lightbulb proxy");
}
CDL[key][addr] |= (byte)flags;
}
}
}

View File

@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
portedUrl: "http://gambatte.sourceforge.net/"
)]
[ServiceNotApplicable(typeof(IDriveLight), typeof(IDriveLight))]
public partial class Gameboy : IEmulator, IVideoProvider, ISyncSoundProvider, ISaveRam, IStatable, IInputPollable,
public partial class Gameboy : IEmulator, IVideoProvider, ISyncSoundProvider, ISaveRam, IStatable, IInputPollable, ICodeDataLogger,
IDebuggable, ISettable<Gameboy.GambatteSettings, Gameboy.GambatteSyncSettings>
{
/// <summary>
@ -173,10 +173,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
TimeCallback = new LibGambatte.RTCCallback(GetCurrentTime);
LibGambatte.gambatte_setrtccallback(GambatteState, TimeCallback);
//seems to have near negligable speed impact. lets always use it, for now.
//someone who cares can make it controllable
CDCallback = new LibGambatte.CDCallback(CDCallbackProc);
LibGambatte.gambatte_setcdcallback(GambatteState, CDCallback);
NewSaveCoreSetBuff();
}
@ -187,24 +184,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
}
}
public CodeDataLog_GB CDL;
LibGambatte.CDCallback CDCallback;
void CDCallbackProc(int addr, LibGambatte.CDLog_AddrType addrtype, LibGambatte.CDLog_Flags flags)
{
if (CDL == null) return;
if (!CDL.Active) return;
string key;
switch (addrtype)
{
case LibGambatte.CDLog_AddrType.ROM: key = "ROM"; break;
case LibGambatte.CDLog_AddrType.HRAM: key = "HRAM"; break;
case LibGambatte.CDLog_AddrType.WRAM: key = "WRAM"; break;
case LibGambatte.CDLog_AddrType.CartRAM: key = "CartRAM"; break;
default: throw new InvalidOperationException("Juniper lightbulb proxy");
}
CDL[key][addr] |= (byte)flags;
}
public IEmulatorServiceProvider ServiceProvider { get; private set; }
#region ALL SAVESTATEABLE STATE GOES HERE

View File

@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
isReleased: true
)]
public sealed partial class PCEngine : IEmulator, ISaveRam, IStatable, IInputPollable,
IDebuggable, ISettable<PCEngine.PCESettings, PCEngine.PCESyncSettings>, IDriveLight
IDebuggable, ISettable<PCEngine.PCESettings, PCEngine.PCESyncSettings>, IDriveLight, ICodeDataLogger
{
// ROM
public byte[] RomData;
@ -315,6 +315,47 @@ namespace BizHawk.Emulation.Cores.PCEngine
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } }
void ICodeDataLogger.SetCDL(CodeDataLog cdl)
{
Cpu.CDL = cdl;
}
void ICodeDataLogger.NewCDL(CodeDataLog cdl)
{
InitCDLMappings();
var mm = this.Cpu.Mappings;
foreach (var kvp in SizesFromHuMap(mm))
{
cdl[kvp.Key] = new byte[kvp.Value];
}
cdl.SubType = "PCE";
cdl.SubVer = 0;
}
void ICodeDataLogger.DisassembleCDL(Stream s, CodeDataLog cdl)
{
Cpu.DisassembleCDL(s, cdl, memoryDomains);
}
private static Dictionary<string, int> SizesFromHuMap(IEnumerable<HuC6280.MemMapping> mm)
{
Dictionary<string, int> sizes = new Dictionary<string, int>();
foreach (var m in mm)
{
if (!sizes.ContainsKey(m.Name) || m.MaxOffs >= sizes[m.Name])
sizes[m.Name] = m.MaxOffs;
}
List<string> keys = new List<string>(sizes.Keys);
foreach (var key in keys)
{
// becase we were looking at offsets, and each bank is 8192 big, we need to add that size
sizes[key] += 8192;
}
return sizes;
}
public void ResetCounters()
{
// this should just be a public setter instead of a new method.

View File

@ -1,38 +0,0 @@
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components.H6280;
namespace BizHawk.Emulation.Cores.Consoles.Sega
{
public class CodeDataLog_GEN : CodeDataLog
{
public static CodeDataLog_GEN Create(IMemoryDomains memdomains)
{
var t = new CodeDataLog_GEN();
t["MD CART"] = new byte[memdomains["MD CART"].Size];
t["68K RAM"] = new byte[memdomains["68K RAM"].Size];
t["Z80 RAM"] = new byte[memdomains["Z80 RAM"].Size];
if(memdomains.Has("SRAM"))
t["SRAM"] = new byte[memdomains["SRAM"].Size];
return t;
}
public override string SubType { get { return "GEN"; } }
public override int SubVer { get { return 0; } }
//todo - this could be base classed
public bool CheckConsistency(IMemoryDomains memdomains)
{
if (memdomains["MD CART"].Size != this["MD CART"].Length) return false;
if (memdomains["68K RAM"].Size != this["68K RAM"].Length) return false;
if (memdomains["Z80 RAM"].Size != this["Z80 RAM"].Length) return false;
if (memdomains.Has("SRAM") != this.ContainsKey("SRAM")) return false;
if (memdomains.Has("SRAM"))
if (memdomains["SRAM"].Size != this["SRAM"].Length)
return false;
return true;
}
}
}

View File

@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
singleInstance: true
)]
public class GPGX : IEmulator, ISyncSoundProvider, IVideoProvider, ISaveRam, IStatable, IRegionable,
IInputPollable, IDebuggable, ISettable<GPGX.GPGXSettings, GPGX.GPGXSyncSettings>, IDriveLight
IInputPollable, IDebuggable, ISettable<GPGX.GPGXSettings, GPGX.GPGXSyncSettings>, IDriveLight, ICodeDataLogger
{
static GPGX AttachedCore = null;
@ -172,7 +172,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
//TODO - this hits performance, we need to make it controllable
CDCallback = new LibGPGX.CDCallback(CDCallbackProc);
LibGPGX.gpgx_set_cd_callback(CDCallback);
InitMemCallbacks();
KillMemCallbacks();
@ -184,9 +183,34 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
}
}
public CodeDataLog_GEN CDL;
void ICodeDataLogger.SetCDL(CodeDataLog cdl)
{
CDL = cdl;
if(cdl == null) LibGPGX.gpgx_set_cd_callback(null);
else LibGPGX.gpgx_set_cd_callback(CDCallback);
}
void ICodeDataLogger.NewCDL(CodeDataLog cdl)
{
cdl["MD CART"] = new byte[MemoryDomains["MD CART"].Size];
cdl["68K RAM"] = new byte[MemoryDomains["68K RAM"].Size];
cdl["Z80 RAM"] = new byte[MemoryDomains["Z80 RAM"].Size];
if (MemoryDomains.Has("SRAM"))
cdl["SRAM"] = new byte[MemoryDomains["SRAM"].Size];
cdl.SubType = "GEN";
cdl.SubVer = 0;
}
//not supported
void ICodeDataLogger.DisassembleCDL(Stream s, CodeDataLog cdl) { }
CodeDataLog CDL;
void CDCallbackProc(int addr, LibGPGX.CDLog_AddrType addrtype, LibGPGX.CDLog_Flags flags)
{
//TODO - hard reset makes CDL go nuts.
if (CDL == null) return;
if (!CDL.Active) return;
string key;