6502: delete the cruddy old native one. add a cruddy new native one as attic crap.

This commit is contained in:
goyuken 2014-10-19 22:18:25 +00:00
parent 8ac0576c54
commit db681d5948
18 changed files with 5905 additions and 1818 deletions

View File

@ -472,8 +472,6 @@
<Compile Include="CPUs\MOS 6502X\Disassembler.cs" />
<Compile Include="CPUs\MOS 6502X\Execute.cs" />
<Compile Include="CPUs\MOS 6502X\MOS6502X.cs" />
<Compile Include="CPUs\MOS 6502X\MOS6502XDouble.cs" />
<Compile Include="CPUs\MOS 6502X\MOS6502XNative.cs" />
<Compile Include="CPUs\x86\Disassembler.cs" />
<Compile Include="CPUs\x86\Execute.cs" />
<Compile Include="CPUs\x86\Timing.cs" />

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MOS6502XNative", "MOS6502XNative.vcxproj", "{3F8F3D38-25DB-45C9-84C9-943D0368BF47}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "6502XXX", "6502XXX.vcxproj", "{0EF7FBBC-3CA9-4121-AF6C-C46CD02354B4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -9,10 +9,10 @@ Global
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3F8F3D38-25DB-45C9-84C9-943D0368BF47}.Debug|Win32.ActiveCfg = Debug|Win32
{3F8F3D38-25DB-45C9-84C9-943D0368BF47}.Debug|Win32.Build.0 = Debug|Win32
{3F8F3D38-25DB-45C9-84C9-943D0368BF47}.Release|Win32.ActiveCfg = Release|Win32
{3F8F3D38-25DB-45C9-84C9-943D0368BF47}.Release|Win32.Build.0 = Release|Win32
{0EF7FBBC-3CA9-4121-AF6C-C46CD02354B4}.Debug|Win32.ActiveCfg = Debug|Win32
{0EF7FBBC-3CA9-4121-AF6C-C46CD02354B4}.Debug|Win32.Build.0 = Debug|Win32
{0EF7FBBC-3CA9-4121-AF6C-C46CD02354B4}.Release|Win32.ActiveCfg = Release|Win32
{0EF7FBBC-3CA9-4121-AF6C-C46CD02354B4}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -11,9 +11,9 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3F8F3D38-25DB-45C9-84C9-943D0368BF47}</ProjectGuid>
<ProjectGuid>{0EF7FBBC-3CA9-4121-AF6C-C46CD02354B4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>MOS6502XNative</RootNamespace>
<RootNamespace>My6502XXX</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -39,37 +39,35 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<CustomBuildAfterTargets>
</CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<CustomBuildAfterTargets>
</CustomBuildAfterTargets>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOS6502XNATIVE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MY6502XXX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)..\..\..\..\BizHawk.MultiClient\output\dll\$(TargetName).dll"</Command>
<Command>copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\..\..\output\dll\$(TargetFileName)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOS6502XNATIVE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MY6502XXX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -78,18 +76,15 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>copy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)..\..\..\..\BizHawk.MultiClient\output\dll\$(TargetName).dll"</Command>
<Command>copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\..\..\output\dll\$(TargetFileName)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ints.h" />
<ClInclude Include="MOS6502X.h" />
<ClInclude Include="UopEnum.h" />
<ClCompile Include="Execute.cpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Execute.cpp" />
<ClCompile Include="MOS6502X.cpp" />
<ClCompile Include="UopTable.cpp" />
<ClInclude Include="TableNZ.h" />
<ClInclude Include="UopEnum.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -15,25 +15,16 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="UopEnum.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MOS6502X.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ints.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="UopTable.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Execute.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MOS6502X.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="UopEnum.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TableNZ.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,327 @@
using System;
using BizHawk.Common;
using System.Runtime.InteropServices;
using System.Security;
using System.Reflection;
using System.Reflection.Emit;
namespace BizHawk.Emulation.Cores.Components.M6502
{
[StructLayout(LayoutKind.Explicit)] // LayoutKind.Sequential doesn't work right on the managed form of non-blittable structs
public sealed partial class MOS6502X
{
[FieldOffset(0)]
private int _anchor;
[SuppressUnmanagedCodeSecurity]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate byte ReadDel(ushort addr);
[SuppressUnmanagedCodeSecurity]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void WriteDel(ushort addr, byte val);
[SuppressUnmanagedCodeSecurity]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void AddrDel(ushort addr);
// interface
[FieldOffset(16)]private ReadDel _ReadMemory;
[FieldOffset(20)]private ReadDel _DummyReadMemory;
[FieldOffset(24)]private ReadDel _PeekMemory;
[FieldOffset(28)]private WriteDel _WriteMemory;
[FieldOffset(32)]private AddrDel _OnExecFetch; // this only calls when the first byte of an instruction is fetched.
public ReadDel ReadMemory
{
set { _rmp = Marshal.GetFunctionPointerForDelegate(value); _ReadMemory = value; }
get { return _ReadMemory; }
}
public ReadDel DummyReadMemory
{
set { _dmp = Marshal.GetFunctionPointerForDelegate(value); _DummyReadMemory = value; }
get { return _DummyReadMemory; }
}
public ReadDel PeekMemory
{
set { _pmp = Marshal.GetFunctionPointerForDelegate(value); _PeekMemory = value; }
get { return _PeekMemory; }
}
public WriteDel WriteMemory
{
set { _wmp = Marshal.GetFunctionPointerForDelegate(value); _WriteMemory = value; }
get { return _WriteMemory; }
}
public AddrDel OnExecFetch
{
set { _exp = IntPtr.Zero; /* Marshal.GetFunctionPointerForDelegate(value); */ _OnExecFetch = value; }
get { return _OnExecFetch; }
}
[FieldOffset(36)]public Action<string> TraceCallback; // TODOOO
[FieldOffset(40)]private IntPtr _rmp;
[FieldOffset(44)]private IntPtr _dmp;
[FieldOffset(48)]private IntPtr _pmp;
[FieldOffset(52)]private IntPtr _wmp;
[FieldOffset(56)]private IntPtr _exp;
// config
[FieldOffset(60)]public bool BCD_Enabled = true;
[FieldOffset(61)]public bool debug = false;
// state
[FieldOffset(62)]public byte A;
[FieldOffset(63)]public byte X;
[FieldOffset(64)]public byte Y;
//public byte P;
/// <summary>Carry Flag</summary>
[FieldOffset(65)]public bool FlagC;
/// <summary>Zero Flag</summary>
[FieldOffset(66)]public bool FlagZ;
/// <summary>Interrupt Disable Flag</summary>
[FieldOffset(67)]public bool FlagI;
/// <summary>Decimal Mode Flag</summary>
[FieldOffset(68)]public bool FlagD;
/// <summary>Break Flag</summary>
[FieldOffset(69)]public bool FlagB;
/// <summary>T... Flag</summary>
[FieldOffset(70)]public bool FlagT;
/// <summary>Overflow Flag</summary>
[FieldOffset(71)]public bool FlagV;
/// <summary>Negative Flag</summary>
[FieldOffset(72)]public bool FlagN;
[FieldOffset(74)]public ushort PC;
[FieldOffset(76)]public byte S;
[FieldOffset(77)]public bool IRQ;
[FieldOffset(78)]public bool NMI;
[FieldOffset(79)]public bool RDY;
[FieldOffset(80)]public int TotalExecutedCycles;
//opcode bytes.. theoretically redundant with the temp variables? who knows.
[FieldOffset(84)]int opcode;
[FieldOffset(88)]byte opcode2;
[FieldOffset(89)]byte opcode3;
[FieldOffset(92)]int ea;
[FieldOffset(96)]int alu_temp; //cpu internal temp variables
[FieldOffset(100)]int mi; //microcode index
[FieldOffset(104)]bool iflag_pending; //iflag must be stored after it is checked in some cases (CLI and SEI).
[FieldOffset(105)]bool rdy_freeze; //true if the CPU must be frozen
//tracks whether an interrupt condition has popped up recently.
//not sure if this is real or not but it helps with the branch_irq_hack
[FieldOffset(106)]bool interrupt_pending;
[FieldOffset(107)]bool branch_irq_hack; //see Uop.RelBranch_Stage3 for more details
// transient state
[FieldOffset(108)]byte value8;
[FieldOffset(109)]byte temp8;
[FieldOffset(110)]ushort value16;
[FieldOffset(112)]bool branch_taken = false;
[FieldOffset(113)]bool my_iflag;
[FieldOffset(114)]bool booltemp;
[FieldOffset(116)]int tempint;
[FieldOffset(120)]int lo;
[FieldOffset(124)]int hi;
public byte P
{
// NVTB DIZC
get
{
byte ret = 0;
if (FlagC) ret |= 1;
if (FlagZ) ret |= 2;
if (FlagI) ret |= 4;
if (FlagD) ret |= 8;
if (FlagB) ret |= 16;
if (FlagT) ret |= 32;
if (FlagV) ret |= 64;
if (FlagN) ret |= 128;
return ret;
}
set
{
FlagC = (value & 1) != 0;
FlagZ = (value & 2) != 0;
FlagI = (value & 4) != 0;
FlagD = (value & 8) != 0;
FlagB = (value & 16) != 0;
FlagT = (value & 32) != 0;
FlagV = (value & 64) != 0;
FlagN = (value & 128) != 0;
}
}
public MOS6502X()
{
InitOpcodeHandlers();
InitNative();
Reset();
}
public void SyncState(Serializer ser)
{
ser.BeginSection("MOS6502X");
ser.Sync("A", ref A);
ser.Sync("X", ref X);
ser.Sync("Y", ref Y);
{
byte tmp = P;
ser.Sync("P", ref tmp);
P = tmp;
}
ser.Sync("PC", ref PC);
ser.Sync("S", ref S);
ser.Sync("NMI", ref NMI);
ser.Sync("IRQ", ref IRQ);
ser.Sync("RDY", ref RDY);
ser.Sync("TotalExecutedCycles", ref TotalExecutedCycles);
ser.Sync("opcode", ref opcode);
ser.Sync("opcode2", ref opcode2);
ser.Sync("opcode3", ref opcode3);
ser.Sync("ea", ref ea);
ser.Sync("alu_temp", ref alu_temp);
ser.Sync("mi", ref mi);
ser.Sync("iflag_pending", ref iflag_pending);
ser.Sync("rdy_freeze", ref rdy_freeze);
ser.Sync("interrupt_pending", ref interrupt_pending);
ser.Sync("branch_irq_hack", ref branch_irq_hack);
ser.EndSection();
}
public void Reset()
{
A = 0;
X = 0;
Y = 0;
P = 0;
S = 0;
PC = 0;
TotalExecutedCycles = 0;
mi = 0;
opcode = 256;
iflag_pending = true;
RDY = true;
}
public void NESSoftReset()
{
opcode = VOP_RESET;
mi = 0;
iflag_pending = true;
FlagI = true;
}
public string State(bool disassemble = true)
{
int notused;
string a = string.Format("{0:X4} {1:X2} {2} ", PC, _PeekMemory(PC), disassemble ? Disassemble(PC, out notused) : "---").PadRight(30);
string b = string.Format("A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}", A, X, Y, P, S, TotalExecutedCycles);
string val = a + b + " ";
if (FlagN) val = val + "N";
if (FlagV) val = val + "V";
if (FlagT) val = val + "T";
if (FlagB) val = val + "B";
if (FlagD) val = val + "D";
if (FlagI) val = val + "I";
if (FlagZ) val = val + "Z";
if (FlagC) val = val + "C";
return val;
}
public string TraceState()
{
// only disassemble when we're at the beginning of an opcode
return State(opcode == VOP_Fetch1 || Microcode[opcode][mi] >= Uop.End);
}
public const ushort NMIVector = 0xFFFA;
public const ushort ResetVector = 0xFFFC;
public const ushort BRKVector = 0xFFFE;
public const ushort IRQVector = 0xFFFE;
enum ExceptionType
{
BRK, NMI, IRQ
}
#region native interop
private void InitNative()
{
}
[SuppressUnmanagedCodeSecurity]
[DllImport("6502XXX.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint="_ZN3CPU10ExecuteOneEv")]
//[DllImport("6502XXX.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint="?ExecuteOne@CPU@@QAEXXZ")]
private static extern void ExecuteOneNativeInternal(IntPtr o);
public unsafe void ExecuteOneNative()
{
fixed (int* p = &_anchor)
{
ExecuteOneNativeInternal((IntPtr)p);
}
}
#endregion
public void SetCallbacks
(
ReadDel ReadMemory,
ReadDel DummyReadMemory,
ReadDel PeekMemory,
WriteDel WriteMemory
)
{
this.ReadMemory = ReadMemory;
this.DummyReadMemory = DummyReadMemory;
this.PeekMemory = PeekMemory;
this.WriteMemory = WriteMemory;
}
public ushort ReadWord(ushort address)
{
byte l = _ReadMemory(address);
byte h = _ReadMemory(++address);
return (ushort)((h << 8) | l);
}
public ushort PeekWord(ushort address)
{
byte l = _PeekMemory(address);
byte h = _PeekMemory(++address);
return (ushort)((h << 8) | l);
}
private static readonly byte[] TableNZ =
{
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
};
}
}

View File

@ -0,0 +1,19 @@
const byte TableNZ[] =
{
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
};

View File

@ -139,7 +139,6 @@ enum Uop {
Uop_DecS,
Uop_PushPCL,
Uop_PushPCH,
Uop_PushPCH_B,
Uop_PushP,
Uop_PullP,
Uop_PullPCL,
@ -250,5 +249,4 @@ enum Uop {
Uop_End_BranchSpecial,
Uop_End_SuppressInterrupt,
};
extern const Uop Microcode[264][8];
#endif // UOPENUM_H

View File

@ -0,0 +1,26 @@
CXX = g++
CXXFLAGS = -Wall -I.. -O3 -fno-exceptions -fomit-frame-pointer -std=c++11
TARGET = 6502XXX.dll
LDFLAGS = -shared -static-libgcc -static-libstdc++ $(CXXFLAGS)
RM = rm
CP = cp
SRCS = \
../execute.cpp
OBJS = $(SRCS:.cpp=.o)
all: $(TARGET)
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS)
$(TARGET) : $(OBJS)
$(CXX) -o $@ $(LDFLAGS) $(OBJS)
clean:
$(RM) $(OBJS)
$(RM) $(TARGET)
install:
$(CP) $(TARGET) ../../../../../output/dll

View File

@ -1,242 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Components.M6502
{
/// <summary>
/// maintains a managed 6502X and an unmanaged 6502X, running them alongside and ensuring consistency
/// by taking savestates every cycle (!). slow.
/// </summary>
/*
public class MOS6502XDouble
{
readonly MOS6502X m;
readonly MOS6502X_CPP n;
public MOS6502XDouble()
{
m = new MOS6502X(DisposeBuilder);
n = new MOS6502X_CPP(DisposeBuilder);
BCD_Enabled = true;
m.SetCallbacks(
delegate(ushort addr)
{
byte ret = ReadMemory(addr);
reads.Enqueue(ret);
return ret;
},
delegate(ushort addr)
{
byte ret = DummyReadMemory(addr);
reads.Enqueue(ret);
return ret;
},
delegate(ushort addr)
{
byte ret = PeekMemory(addr);
reads.Enqueue(ret);
return ret;
},
delegate(ushort addr, byte value)
{
writes.Enqueue(value);
WriteMemory(addr, value);
});
n.SetCallbacks(
delegate(ushort addr)
{
if (reads.Count > 0)
return reads.Dequeue();
else
{
PreCrash();
throw new Exception("native did extra read!");
}
},
delegate(ushort addr)
{
if (reads.Count > 0)
return reads.Dequeue();
else
{
PreCrash();
throw new Exception("native did extra read!");
}
},
delegate(ushort addr, byte value)
{
if (writes.Count > 0)
{
byte test = writes.Dequeue();
if (test != value)
{
PreCrash();
throw new Exception(string.Format("writes were different! managed {0} native {1}", test, value));
}
// ignore because the write already happened
}
else
{
PreCrash();
throw new Exception("native did extra write!");
}
}, DisposeBuilder);
SyncUp();
}
Queue<byte> reads = new Queue<byte>();
Queue<byte> writes = new Queue<byte>();
private bool _BCD_Enabled;
public bool BCD_Enabled { get { return _BCD_Enabled; } set { _BCD_Enabled = value; m.BCD_Enabled = value; n.BCD_Enabled = value; } }
public bool debug { get; private set; }
public bool throw_unhandled { get; private set; }
public byte A { get; private set; }
public byte X { get; private set; }
public byte Y { get; private set; }
byte _P;
public byte P { get { return _P; } set { _P = value; m.P = value; n.P = value; SyncUp(); } }
ushort _PC;
public ushort PC { get { return _PC; } set { _PC = value; m.PC = value; n.PC = value; SyncUp(); } }
byte _S;
public byte S { get { return _S; } set { _S = value; m.S = value; n.S = value; SyncUp(); } }
bool _IRQ;
public bool IRQ { get { return _IRQ; } set { _IRQ = value; m.IRQ = value; n.IRQ = value; } }
bool _NMI;
public bool NMI { get { return _NMI; } set { _NMI = value; m.NMI = value; n.NMI = value; } }
public int TotalExecutedCycles { get; private set; }
public Func<ushort, byte> ReadMemory; //{ set { m.ReadMemory = value; n.ReadMemory = value; } }
public Func<ushort, byte> DummyReadMemory; //{ set { m.DummyReadMemory = value; n.DummyReadMemory = value; } }
public Func<ushort, byte> PeekMemory; //{ set { m.ReadMemory = value; n.ReadMemory = value; } }
public Action<ushort, byte> WriteMemory; //{ set { m.WriteMemory = value; n.WriteMemory = value; } }
public void SetCallbacks
(
Func<ushort, byte> ReadMemory,
Func<ushort, byte> DummyReadMemory,
Func<ushort, byte> PeekMemory,
Action<ushort, byte> WriteMemory,
Action<System.Runtime.InteropServices.GCHandle> DisposeBuilder
)
{
this.ReadMemory = ReadMemory;
this.DummyReadMemory = DummyReadMemory;
this.PeekMemory = PeekMemory;
this.WriteMemory = WriteMemory;
}
string oldleft = "";
string oldright = "";
void PreCrash()
{
Console.WriteLine(String.Format("about to crash! cached:\n==managed==\n{0}\n==native==\n{1}\n", oldleft, oldright));
}
void TestQueue()
{
if (reads.Count > 0)
{
PreCrash();
throw new Exception("managed did extra read!");
}
if (writes.Count > 0)
{
PreCrash();
throw new Exception("managed did extra write!");
}
}
void SyncUp()
{
TestQueue();
StringWriter sm = new StringWriter();
Serializer ssm = new Serializer(sm);
m.SyncState(ssm);
sm.Flush();
StringWriter sn = new StringWriter();
Serializer ssn = new Serializer(sn);
n.SyncState(ssn);
sn.Flush();
string sssm = sm.ToString();
string sssn = sn.ToString();
if (sssm != sssn)
{
PreCrash();
throw new Exception(string.Format("save mismatch!\n==managed==\n{0}\n==native==\n{1}\n", sssm, sssn));
}
A = m.A;
X = m.X;
Y = m.Y;
_P = m.P;
_PC = m.PC;
_S = m.S;
_IRQ = m.IRQ;
_NMI = m.NMI;
oldleft = sssm;
oldright = sssn;
}
void MtoN()
{
StringWriter sm = new StringWriter();
Serializer ssm = new Serializer(sm);
m.SyncState(ssm);
sm.Flush();
StringReader sn = new StringReader(sm.ToString());
Serializer ssn = new Serializer(sn);
n.SyncState(ssn);
}
public string State()
{
SyncUp();
return m.State();
}
public void NESSoftReset()
{
m.NESSoftReset();
n.NESSoftReset();
SyncUp();
}
public void ExecuteOne()
{
m.ExecuteOne();
n.ExecuteOne();
SyncUp();
}
public void SyncState(Serializer ser)
{
// doesn't work quite as expected because you can't rewind a ser
SyncUp();
if (ser.IsWriter)
{
// since SyncUp() guarantees that states are the same, we only need write one
m.SyncState(ser);
}
else
{
// daisy chain the state
m.SyncState(ser);
MtoN();
}
SyncUp();
}
public string Disassemble(ushort pc, out int bytesToAdvance) { bytesToAdvance = 1; return "FOOBAR"; }
}
*/
}

View File

@ -1,218 +0,0 @@
using System;
using System.Runtime.InteropServices;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Components.M6502
{
public static class MOS6502X_DLL
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate byte ReadMemoryD(ushort addr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void WriteMemoryD(ushort addr, byte value);
[DllImport("MOS6502XNative.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr Create();
[DllImport("MOS6502XNative.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void Destroy(IntPtr ptr);
[DllImport("MOS6502XNative.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint = "?Reset@MOS6502X@@QAEXXZ")]
internal static extern void Reset(IntPtr ptr);
[DllImport("MOS6502XNative.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint = "?NESSoftReset@MOS6502X@@QAEXXZ")]
internal static extern void NESSoftReset(IntPtr ptr);
[DllImport("MOS6502XNative.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint = "?ExecuteOne@MOS6502X@@QAEXXZ")]
internal static extern void ExecuteOne(IntPtr ptr);
[DllImport("MOS6502XNative.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint = "?SetTrampolines@MOS6502X@@QAEXP6AEG@Z0P6AXGE@Z@Z")]
internal static extern void SetTrampolines(IntPtr ptr, ReadMemoryD Read, ReadMemoryD DummyRead, WriteMemoryD Write);
}
/// <summary>
/// MOS6502X core in unmanaged code
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public class MOS6502X_CPP
{
/*
* In order to get anywhere near usable performance, the class is cleared of all unblittable types,
* set up with identical memory order to a C++ class, and then GC pinned for the duration. A
* naive pinvoke attempt will produce 1/7th the performance of this.
*/
// these are aliased to a C++ class, so don't move them
#region c++ alias
// C# bool is not blittable!
[FieldOffset(0x00), MarshalAs(UnmanagedType.U1)]
byte _BCD_Enabled;
[FieldOffset(0x01), MarshalAs(UnmanagedType.U1)]
public byte debug;
[FieldOffset(0x02), MarshalAs(UnmanagedType.U1)]
public byte throw_unhandled;
[FieldOffset(0x03)]
public byte A;
[FieldOffset(0x04)]
public byte X;
[FieldOffset(0x05)]
public byte Y;
[FieldOffset(0x06)]
public byte P;
[FieldOffset(0x08)]
public ushort PC;
[FieldOffset(0x0a)]
public byte S;
[FieldOffset(0x0b), MarshalAs(UnmanagedType.U1)]
byte _IRQ;
[FieldOffset(0x0c), MarshalAs(UnmanagedType.U1)]
byte _NMI;
[FieldOffset(0x10)]
public int TotalExecutedCycles;
// delegates are not blittable, so pretend they aren't there
[FieldOffset(0x14)]
IntPtr ZZZ000;
//public MOS6502X_DLL.ReadMemoryD ReadMemory;
[FieldOffset(0x18)]
IntPtr ZZZ001;
//public MOS6502X_DLL.ReadMemoryD DummyReadMemory;
[FieldOffset(0x1c)]
IntPtr ZZZ002;
//public MOS6502X_DLL.WriteMemoryD WriteMemory;
//opcode bytes.. theoretically redundant with the temp variables? who knows.
[FieldOffset(0x20)]
public int opcode;
[FieldOffset(0x24)]
public byte opcode2;
[FieldOffset(0x25)]
public byte opcode3;
[FieldOffset(0x28)]
public int ea;
[FieldOffset(0x2c)]
public int alu_temp; //cpu internal temp variables
[FieldOffset(0x30)]
public int mi; //microcode index
[FieldOffset(0x34), MarshalAs(UnmanagedType.U1)]
public byte iflag_pending; //iflag must be stored after it is checked in some cases (CLI and SEI).
//tracks whether an interrupt condition has popped up recently.
//not sure if this is real or not but it helps with the branch_irq_hack
[FieldOffset(0x35), MarshalAs(UnmanagedType.U1)]
public byte interrupt_pending;
[FieldOffset(0x36), MarshalAs(UnmanagedType.U1)]
public byte branch_irq_hack; //see Uop.RelBranch_Stage3 for more details
#endregion
[FieldOffset(0x48)]
IntPtr pthis;
// for fields which were converted from bool to byte, use props for backwards compatibility
public bool IRQ { get { return _IRQ != 0; } set { _IRQ = (byte)(value ? 1 : 0); } }
public bool NMI { get { return _NMI != 0; } set { _NMI = (byte)(value ? 1 : 0); } }
public bool BCD_Enabled { get { return _BCD_Enabled != 0; } set { _BCD_Enabled = (byte)(value ? 1 : 0); } }
public MOS6502X_CPP(Action<GCHandle> DisposeBuilder)
{
// this bit of foolery is only needed if you actually need to run the native-side constructor
//IntPtr native = MOS6502X_DLL.Create();
//if (native == null)
// throw new Exception("Native constructor returned null!");
var h = GCHandle.Alloc(this, GCHandleType.Pinned);
pthis = h.AddrOfPinnedObject();
// bad - use memcpy instead
//Marshal.PtrToStructure(native, this);
//MOS6502X_DLL.Destroy(native);
BCD_Enabled = true;
MOS6502X_DLL.Reset(pthis);
DisposeBuilder(h);
}
public void Reset() { MOS6502X_DLL.Reset(pthis); }
public void NESSoftReset() { MOS6502X_DLL.NESSoftReset(pthis); }
public void ExecuteOne() { MOS6502X_DLL.ExecuteOne(pthis); }
public string State() { return "FOOBAR"; } /*
{
int notused;
string a = string.Format("{0:X4} {1:X2} {2} ", PC, ReadMemory(PC), Disassemble(PC, out notused)).PadRight(30);
string b = string.Format("A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}", A, X, Y, P, S, TotalExecutedCycles);
string val = a + b + " ";
if (FlagN) val = val + "N";
if (FlagV) val = val + "V";
if (FlagT) val = val + "T";
if (FlagB) val = val + "B";
if (FlagD) val = val + "D";
if (FlagI) val = val + "I";
if (FlagZ) val = val + "Z";
if (FlagC) val = val + "C";
return val;
}*/
// to maintain savestate compatibility, we have bytes that we serialize as bool
static void SyncByteFakeBool(Serializer ser, string name, ref byte loc)
{
bool tmp = loc != 0;
ser.Sync(name, ref tmp);
loc = (byte)(tmp ? 1 : 0);
}
public void SyncState(Serializer ser)
{
ser.BeginSection("MOS6502X");
ser.Sync("A", ref A);
ser.Sync("X", ref X);
ser.Sync("Y", ref Y);
ser.Sync("P", ref P);
ser.Sync("PC", ref PC);
ser.Sync("S", ref S);
SyncByteFakeBool(ser, "NMI", ref _NMI);//ser.Sync("NMI", ref _NMI);
SyncByteFakeBool(ser, "IRQ", ref _IRQ);//ser.Sync("IRQ", ref _IRQ);
ser.Sync("TotalExecutedCycles", ref TotalExecutedCycles);
ser.Sync("opcode", ref opcode);
ser.Sync("opcode2", ref opcode2);
ser.Sync("opcode3", ref opcode3);
ser.Sync("ea", ref ea);
ser.Sync("alu_temp", ref alu_temp);
ser.Sync("mi", ref mi);
SyncByteFakeBool(ser, "iflag_pending", ref iflag_pending); //ser.Sync("iflag_pending", ref iflag_pending);
SyncByteFakeBool(ser, "interrupt_pending", ref interrupt_pending); //ser.Sync("interrupt_pending", ref interrupt_pending);
SyncByteFakeBool(ser, "branch_irq_hack", ref branch_irq_hack); //ser.Sync("branch_irq_hack", ref branch_irq_hack);
ser.EndSection();
}
public string Disassemble(ushort pc, out int bytesToAdvance) { bytesToAdvance = 1; return "FOOBAR"; }
public void SetCallbacks
(Func<ushort, byte> ReadMemory,
Func<ushort, byte> DummyReadMemory,
Action<ushort, byte> WriteMemory, Action<GCHandle> DisposeBuilder)
{
var d1 = new MOS6502X_DLL.ReadMemoryD(ReadMemory);
var h1 = GCHandle.Alloc(d1);
var d2 = new MOS6502X_DLL.ReadMemoryD(DummyReadMemory);
var h2 = GCHandle.Alloc(d2);
var d3 = new MOS6502X_DLL.WriteMemoryD(WriteMemory);
var h3 = GCHandle.Alloc(d3);
MOS6502X_DLL.SetTrampolines(pthis, d1, d2, d3);
DisposeBuilder(h1);
DisposeBuilder(h2);
DisposeBuilder(h3);
}
}
}

View File

@ -1,80 +0,0 @@
#include "MOS6502X.h"
void MOS6502X::FetchDummy()
{
DummyReadMemory(PC);
}
void MOS6502X::Reset()
{
A = 0;
X = 0;
Y = 0;
P = 0;
S = 0;
PC = 0;
TotalExecutedCycles = 0;
mi = 0;
opcode = 256;
//MessageBox(NULL,L"Opcode set to 256", NULL, 0);
iflag_pending = true;
}
void MOS6502X::SetTrampolines(byte (__cdecl *ReadMemory)(ushort), byte (__cdecl *DummyReadMemory)(ushort), void (__cdecl *WriteMemory)(ushort, byte))
{
this->ReadMemory = ReadMemory;
this->DummyReadMemory = DummyReadMemory;
this->WriteMemory = WriteMemory;
}
/*
#include <string>
#define SHOWRA(a) SHOWGA((int)(void *)(a) - ((int)(void *)cpu), #a)
void SHOWGA(int diff, const char *nom)
{
char buffra[24];
std::sprintf(buffra, "%08xi", diff);
MessageBoxA(NULL, buffra, nom, 0);
}*/
void* Create()
{
MOS6502X* cpu = new MOS6502X();
/*
SHOWRA(&cpu->BCD_Enabled);
SHOWRA(&cpu->debug);
SHOWRA(&cpu->throw_unhandled);
SHOWRA(&cpu->A);
SHOWRA(&cpu->X);
SHOWRA(&cpu->Y);
SHOWRA(&cpu->P);
SHOWRA(&cpu->PC);
SHOWRA(&cpu->S);
SHOWRA(&cpu->IRQ);
SHOWRA(&cpu->NMI);
SHOWRA(&cpu->TotalExecutedCycles);
SHOWRA(&cpu->ReadMemory);
SHOWRA(&cpu->DummyReadMemory);
SHOWRA(&cpu->WriteMemory);
SHOWRA(&cpu->opcode);
SHOWRA(&cpu->opcode2);
SHOWRA(&cpu->opcode3);
SHOWRA(&cpu->ea);
SHOWRA(&cpu->alu_temp);
SHOWRA(&cpu->mi);
SHOWRA(&cpu->iflag_pending);
SHOWRA(&cpu->interrupt_pending);
SHOWRA(&cpu->branch_irq_hack);
*/
return (void *)cpu;
}
void Destroy(void *ptr)
{
MOS6502X* cpu = (MOS6502X*) ptr;
delete cpu;
}

View File

@ -1,53 +0,0 @@
#ifndef MOS6502X_H
#define MOS6502X_H
#include "ints.h"
class MOS6502X
{
public:
bool BCD_Enabled;
bool debug;
bool throw_unhandled;
byte A;
byte X;
byte Y;
byte P;
ushort PC;
byte S;
bool IRQ;
bool NMI;
int TotalExecutedCycles;
byte (__cdecl *ReadMemory)(ushort);
byte (__cdecl *DummyReadMemory)(ushort);
void (__cdecl *WriteMemory)(ushort, byte);
//opcode bytes.. theoretically redundant with the temp variables? who knows.
int opcode;
byte opcode2, opcode3;
int ea, alu_temp; //cpu internal temp variables
int mi; //microcode index
bool iflag_pending; //iflag must be stored after it is checked in some cases (CLI and SEI).
//tracks whether an interrupt condition has popped up recently.
//not sure if this is real or not but it helps with the branch_irq_hack
bool interrupt_pending;
bool branch_irq_hack; //see Uop.RelBranch_Stage3 for more details
__declspec(dllexport) void ExecuteOne();
void FetchDummy();
__declspec(dllexport) void Reset();
__declspec(dllexport) void NESSoftReset();
__declspec(dllexport) void SetTrampolines(byte (__cdecl *ReadMemory)(ushort), byte (__cdecl *DummyReadMemory)(ushort), void (__cdecl *WriteMemory)(ushort, byte));
};
extern "C" __declspec(dllexport) void* __cdecl Create();
extern "C" __declspec(dllexport) void __cdecl Destroy(void *);
#endif // MOS6502X_H

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

View File

@ -1,8 +0,0 @@
#ifndef INTS_H
#define INTS_H
typedef unsigned char byte;
typedef unsigned short ushort;
typedef signed char sbyte;
#endif