diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index b99f89985a..9d15932567 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -467,6 +467,12 @@ GBGPUView.cs + + Form + + + GenDbgWind.cs + Form @@ -932,6 +938,9 @@ GBGPUView.cs + + GenDbgWind.cs + GenGameGenie.cs diff --git a/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.Designer.cs b/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.Designer.cs new file mode 100644 index 0000000000..2746610f3c --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.Designer.cs @@ -0,0 +1,109 @@ +namespace BizHawk.Client.EmuHawk.tools.Genesis +{ + partial class GenDbgWind + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.FormattingEnabled = true; + this.listBox1.Location = new System.Drawing.Point(12, 12); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(114, 264); + this.listBox1.TabIndex = 0; + // + // listBox2 + // + this.listBox2.FormattingEnabled = true; + this.listBox2.Location = new System.Drawing.Point(132, 12); + this.listBox2.Name = "listBox2"; + this.listBox2.Size = new System.Drawing.Size(120, 264); + this.listBox2.TabIndex = 1; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(12, 282); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 2; + this.button1.Text = "Save"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // button2 + // + this.button2.Location = new System.Drawing.Point(132, 282); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(75, 23); + this.button2.TabIndex = 3; + this.button2.Text = "Save"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // button3 + // + this.button3.Location = new System.Drawing.Point(70, 311); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(75, 23); + this.button3.TabIndex = 4; + this.button3.Text = "Compare"; + this.button3.UseVisualStyleBackColor = true; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // GenDbgWind + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(404, 365); + this.Controls.Add(this.button3); + this.Controls.Add(this.button2); + this.Controls.Add(this.button1); + this.Controls.Add(this.listBox2); + this.Controls.Add(this.listBox1); + this.Name = "GenDbgWind"; + this.Text = "GenDbgWind"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GenDbgWind_FormClosed); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.ListBox listBox2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button3; + } +} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.cs b/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.cs new file mode 100644 index 0000000000..46a2ffbfa3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; + +namespace BizHawk.Client.EmuHawk.tools.Genesis +{ + public partial class GenDbgWind : Form + { + GenDbgHlp dbg; + + public GenDbgWind() + { + InitializeComponent(); + for (int i = 0; i < 10; i++) + { + listBox1.Items.Add(i.ToString()); + listBox2.Items.Add(i.ToString()); + } + + dbg = new GenDbgHlp(); + } + + private void button1_Click(object sender, EventArgs e) + { + if (listBox1.SelectedIndex != -1) + dbg.SaveState(int.Parse((string)listBox1.SelectedItem)); + } + + private void button2_Click(object sender, EventArgs e) + { + if (listBox2.SelectedIndex != -1) + dbg.SaveState(int.Parse((string)listBox2.SelectedItem)); + } + + private void button3_Click(object sender, EventArgs e) + { + if (listBox1.SelectedIndex != -1 && listBox2.SelectedIndex != -1) + dbg.Cmp(int.Parse((string)listBox1.SelectedItem), int.Parse((string)listBox2.SelectedItem)); + } + + private void GenDbgWind_FormClosed(object sender, FormClosedEventArgs e) + { + dbg.Dispose(); + dbg = null; + } + } +} diff --git a/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.resx b/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.resx new file mode 100644 index 0000000000..29dcb1b3a3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/Genesis/GenDbgWind.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 314d7ada18..8ab3f5fff3 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -408,6 +408,7 @@ + diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GenDbgHlp.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GenDbgHlp.cs new file mode 100644 index 0000000000..294831ff86 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GenDbgHlp.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using System.IO; + +namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx +{ + public class GenDbgHlp : IDisposable + { + private static class Win32 + { + [DllImport("kernel32.dll")] + public static extern IntPtr LoadLibrary(string dllToLoad); + [DllImport("kernel32.dll")] + public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); + [DllImport("kernel32.dll")] + public static extern bool FreeLibrary(IntPtr hModule); + } + + // config + const string modulename = "libgenplusgx.dll"; + const string symbolname = @"D:\encodes\bizhawksrc\genplus-gx\libretro\msvc\Debug\vars.txt"; + const int start = 0x0c7d8000 - 0x0c540000; + const int length = 0x01082000; + + bool disposed = false; + + public void Dispose() + { + if (!disposed) + { + Win32.FreeLibrary(DllBase); + DllBase = IntPtr.Zero; + disposed = true; + } + } + + IntPtr DllBase; + + List SymbolsByAddr = new List(); + Dictionary SymbolsByName = new Dictionary(); + + byte[][] data = new byte[10][]; + + public void SaveState(int statenum) + { + if (disposed) throw new ObjectDisposedException(this.GetType().ToString()); + + if (data[statenum] == null) + data[statenum] = new byte[length]; + + Marshal.Copy(DllBase + start, data[statenum], 0, length); + Console.WriteLine("State {0} saved", statenum); + } + + + unsafe public void Cmp(int statex, int statey) + { + if (disposed) throw new ObjectDisposedException(this.GetType().ToString()); + List> bads = new List>(); + + byte[] x = data[statex]; + byte[] y = data[statey]; + + if (x == null || y == null) + { + Console.WriteLine("Missing State!"); + return; + } + + bool inrange = false; + int startsec = 0; + + fixed (byte* p0 = &x[0]) + fixed (byte* p1 = &y[0]) + { + for (int i = 0; i < length; i++) + { + if (!inrange) + { + if (p0[i] != p1[i]) + { + startsec = i; + inrange = true; + } + } + else + { + if (p0[i] == p1[i]) + { + bads.Add(new Tuple(startsec, i)); + inrange = false; + } + } + } + } + if (inrange) + bads.Add(new Tuple(startsec, length)); + + for (int i = 0; i < bads.Count; i++) + { + IntPtr addr = (IntPtr)(bads[i].Item1 + start); + int len = bads[i].Item2 - bads[i].Item1; + + var ss = Find(addr, len); + Console.WriteLine("0x{0:X8}[0x{1}]", (int)addr, len); + foreach (var sym in ss) + Console.WriteLine(sym); + Console.WriteLine(); + } + if (bads.Count == 0) + Console.WriteLine("Clean!"); + } + + + + public GenDbgHlp() + { + using (StreamReader sr = new StreamReader(symbolname)) + { + string line; + while ((line = sr.ReadLine()) != null) + { + Symbol sym = Symbol.FromString(line); + SymbolsByAddr.Add(sym); + SymbolsByName.Add(sym.name, sym); + } + SymbolsByAddr.Sort(); + } + + DllBase = Win32.LoadLibrary(modulename); + if (DllBase == IntPtr.Zero) + throw new Exception(); + } + + public List Find(IntPtr addr, int length) + { + if (disposed) throw new ObjectDisposedException(this.GetType().ToString()); + Symbol min = new Symbol { addr = addr }; + Symbol max = new Symbol { addr = addr + length }; + + int minidx = SymbolsByAddr.BinarySearch(min); + if (minidx < 0) + { + minidx = ~minidx; + // inexact matches return the first larger value, so find the next smallset one + if (minidx > 0) + minidx--; + } + int maxidx = SymbolsByAddr.BinarySearch(max); + if (maxidx < 0) + { + maxidx = ~maxidx; + if (maxidx > 0) + maxidx--; + } + return SymbolsByAddr.GetRange(minidx, maxidx - minidx + 1); + } + + + public struct Symbol : IComparable + { + public IntPtr addr; + public string section; + public string name; + + public static Symbol FromString(string s) + { + string[] ss = s.Split(','); + if (ss.Length != 4) + throw new Exception(); + if (!ss[1].StartsWith("0x")) + throw new Exception(); + Symbol ret = new Symbol + { + addr = (IntPtr)int.Parse(ss[1].Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier), + section = ss[3], + name = ss[0] + }; + return ret; + } + + public int CompareTo(Symbol other) + { + return (int)this.addr - (int)other.addr; + } + + public override string ToString() + { + return string.Format("0x{0:X8} {1} ({2})", (int)addr, name, section); + } + } + + + } +} diff --git a/genplus-gx/core/genesis.c b/genplus-gx/core/genesis.c index 70d88003ab..880bc96ed2 100644 --- a/genplus-gx/core/genesis.c +++ b/genplus-gx/core/genesis.c @@ -240,7 +240,7 @@ void gen_reset(int hard_reset) } /* 68k & Z80 could be anywhere in VDP frame (Bonkers, Eternal Champions, X-Men 2) */ - m68k.cycles = Z80.cycles = (uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX)); + m68k.cycles = Z80.cycles = 0; //(uint32)((MCYCLES_PER_LINE * lines_per_frame) * ((double)rand() / (double)RAND_MAX)); /* 68k cycles should be a multiple of 7 */ m68k.cycles = (m68k.cycles / 7) * 7; diff --git a/genplus-gx/core/m68k/m68k.h b/genplus-gx/core/m68k/m68k.h index f93b3fc0e3..c938b3e289 100644 --- a/genplus-gx/core/m68k/m68k.h +++ b/genplus-gx/core/m68k/m68k.h @@ -231,7 +231,7 @@ typedef struct { cpu_memory_map memory_map[256]; /* memory mapping */ - cpu_idle_t poll; /* polling detection */ + cpu_idle_t poll; /* polling detection */ // 0x1400 uint cycles; /* current master cycle count */ uint cycle_end; /* aimed master cycle count for current execution frame */ diff --git a/genplus-gx/core/z80/z80.h b/genplus-gx/core/z80/z80.h index d505775162..d48d59db55 100644 --- a/genplus-gx/core/z80/z80.h +++ b/genplus-gx/core/z80/z80.h @@ -36,14 +36,14 @@ enum { /****************************************************************************/ typedef struct { - PAIR pc,sp,af,bc,de,hl,ix,iy,wz; - PAIR af2,bc2,de2,hl2; - UINT8 r,r2,iff1,iff2,halt,im,i; - UINT8 nmi_state; /* nmi line state */ - UINT8 nmi_pending; /* nmi pending */ - UINT8 irq_state; /* irq line state */ - UINT8 after_ei; /* are we in the EI shadow? */ - UINT32 cycles; /* master clock cycles global counter */ + PAIR pc,sp,af,bc,de,hl,ix,iy,wz; // 0x00 + PAIR af2,bc2,de2,hl2; // 0x24 + UINT8 r,r2,iff1,iff2,halt,im,i; // 0x34 + UINT8 nmi_state; // 0x3b /* nmi line state */ + UINT8 nmi_pending; // 0x3c /* nmi pending */ + UINT8 irq_state; // 0x3d /* irq line state */ + UINT8 after_ei; // 0x3e /* are we in the EI shadow? */ + UINT32 cycles; // 0x40 /* master clock cycles global counter */ const struct z80_irq_daisy_chain *daisy; int (*irq_callback)(int irqline); } Z80_Regs; diff --git a/output/dll/libgenplusgx.dll b/output/dll/libgenplusgx.dll index 01ce571c5c..dc2f4fe098 100644 Binary files a/output/dll/libgenplusgx.dll and b/output/dll/libgenplusgx.dll differ