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