6502: delete the cruddy old native one. add a cruddy new native one as attic crap.
This commit is contained in:
parent
8ac0576c54
commit
db681d5948
|
@ -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" />
|
||||
|
|
|
@ -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
|
|
@ -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">
|
|
@ -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
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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
|
|
@ -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"; }
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef INTS_H
|
||||
#define INTS_H
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short ushort;
|
||||
typedef signed char sbyte;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue