Update驱动
This commit is contained in:
parent
aa984889d9
commit
c1f23ea66f
Binary file not shown.
@ -1,33 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03ba7721c0d6ddf48bb3d6575497a990
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/AxiReplay.meta
Normal file
8
MAME.Unity/Assets/Plugins/AxiReplay.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 302b2980355568a4c807b1ba31964637
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
MAME.Unity/Assets/Plugins/AxiReplay/AxiReplay.asmdef
Normal file
3
MAME.Unity/Assets/Plugins/AxiReplay/AxiReplay.asmdef
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "AxiReplay"
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a45db2096af23647aaafe5b70ccb4d7
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
11
MAME.Unity/Assets/Plugins/AxiReplay/IReplayReader.cs
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/IReplayReader.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
internal interface IReplayReader : IDisposable
|
||||
{
|
||||
bool NextFrame(out ReplayStep data);
|
||||
bool TakeFrame(int addFrame, out ReplayStep data);
|
||||
bool NextFramebyFrameIdx(int FrameID, out ReplayStep data);
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/AxiReplay/IReplayReader.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/IReplayReader.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 896ff07370157db46b612575616020ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
MAME.Unity/Assets/Plugins/AxiReplay/IReplayWriter.cs
Normal file
12
MAME.Unity/Assets/Plugins/AxiReplay/IReplayWriter.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
internal interface IReplayWriter : IDisposable
|
||||
{
|
||||
void NextFrame(UInt64 frameInput);
|
||||
void NextFramebyFrameIdx(int FrameID, UInt64 frameInput);
|
||||
void TakeFrame(int addFrame, UInt64 frameInput);
|
||||
void SaveData(string path, bool bNeedDump = false, string dumpFilePath = null);
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/AxiReplay/IReplayWriter.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/IReplayWriter.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a8fcda365e5a7f428f88bc130eb913b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
147
MAME.Unity/Assets/Plugins/AxiReplay/NetReplay.cs
Normal file
147
MAME.Unity/Assets/Plugins/AxiReplay/NetReplay.cs
Normal file
@ -0,0 +1,147 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
public class NetReplay
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户端当前帧
|
||||
/// </summary>
|
||||
public int mCurrClientFrameIdx = 0;
|
||||
/// <summary>
|
||||
/// 服务器远端当前帧
|
||||
/// </summary>
|
||||
public int mRemoteFrameIdx { get; private set; }
|
||||
/// <summary>
|
||||
/// 服务器远端当前提前量
|
||||
/// </summary>
|
||||
public int mRemoteForwardCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Remote 2 Client Frame Gap
|
||||
/// </summary>
|
||||
public int mDiffFrameCount => mRemoteFrameIdx - mCurrClientFrameIdx;
|
||||
/// <summary>
|
||||
/// 网络数据队列
|
||||
/// </summary>
|
||||
Queue<ReplayStep> mNetReplayQueue = new Queue<ReplayStep>();
|
||||
/// <summary>
|
||||
/// 当前数据
|
||||
/// </summary>
|
||||
ReplayStep mCurrReplay;
|
||||
/// <summary>
|
||||
/// 下一个数据数据
|
||||
/// </summary>
|
||||
ReplayStep mNextReplay;
|
||||
|
||||
bool bNetInit = false;
|
||||
public NetReplay()
|
||||
{
|
||||
ResetData();
|
||||
}
|
||||
public void ResetData()
|
||||
{
|
||||
mNetReplayQueue.Clear();
|
||||
mCurrReplay = default(ReplayStep);
|
||||
mCurrReplay.FrameStartID = int.MinValue;
|
||||
bNetInit = false;
|
||||
}
|
||||
public void InData(ReplayStep inputData, int ServerFrameIdx)
|
||||
{
|
||||
mNetReplayQueue.Enqueue(inputData);
|
||||
mRemoteFrameIdx = inputData.FrameStartID;
|
||||
if (!bNetInit)
|
||||
{
|
||||
bNetInit = true;
|
||||
mNextReplay = mNetReplayQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
public bool TryGetNextFrame(out ReplayStep data, out int frameDiff, out bool inputDiff)
|
||||
{
|
||||
if (!bNetInit)
|
||||
{
|
||||
data = default(ReplayStep);
|
||||
frameDiff = default(int);
|
||||
inputDiff = false;
|
||||
return false;
|
||||
}
|
||||
TakeFrame(1, out data, out frameDiff, out inputDiff);
|
||||
return frameDiff > 0;
|
||||
}
|
||||
|
||||
public bool TryGetNextFrame(int targetFrame, out ReplayStep data, out int frameDiff, out bool inputDiff)
|
||||
{
|
||||
if (!bNetInit)
|
||||
{
|
||||
data = default(ReplayStep);
|
||||
frameDiff = default(int);
|
||||
inputDiff = false;
|
||||
return false;
|
||||
}
|
||||
return TakeFrameToTargetFrame(targetFrame, out data, out frameDiff, out inputDiff);
|
||||
}
|
||||
|
||||
void TakeFrame(int addFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff)
|
||||
{
|
||||
int targetFrame = mCurrClientFrameIdx + addFrame;
|
||||
TakeFrameToTargetFrame(targetFrame, out data, out bFrameDiff, out inputDiff);
|
||||
}
|
||||
|
||||
bool TakeFrameToTargetFrame(int targetFrame, out ReplayStep data, out int bFrameDiff, out bool inputDiff)
|
||||
{
|
||||
bool result;
|
||||
inputDiff = false;
|
||||
if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0)
|
||||
{
|
||||
//当前帧追加
|
||||
mCurrClientFrameIdx = targetFrame;
|
||||
ulong oldInput = mCurrReplay.InPut;
|
||||
mCurrReplay = mNextReplay;
|
||||
if (oldInput != mCurrReplay.InPut)
|
||||
inputDiff = true;
|
||||
mNextReplay = mNetReplayQueue.Dequeue();
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
||||
bFrameDiff = mRemoteFrameIdx - mCurrClientFrameIdx;
|
||||
data = mCurrReplay;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int GetSkipFrameCount()
|
||||
{
|
||||
if(!bNetInit)
|
||||
return 0;
|
||||
//本地队列差异高于服务器提前量的值
|
||||
int moreNum = mDiffFrameCount - mRemoteForwardCount;
|
||||
//if (mDiffFrameCount < 0 || mDiffFrameCount > 10000)
|
||||
// return 0;
|
||||
|
||||
////游戏刚开始的一小段时间,直接追满
|
||||
//if (mCurrClientFrameIdx < 60)
|
||||
// return moreNum;
|
||||
|
||||
int skip = 0;
|
||||
if (mDiffFrameCount > short.MaxValue) skip = 0;
|
||||
else if (moreNum <= 1) skip = 0;
|
||||
else if (moreNum <= 3) skip = 2;
|
||||
else if (moreNum <= 6) skip = 2;
|
||||
else if (moreNum <= 20) skip = moreNum / 2; //20帧以内,平滑跳帧数
|
||||
else skip = moreNum;//完全追上
|
||||
return skip;
|
||||
|
||||
//var frameGap = mDiffFrameCount;
|
||||
//if (frameGap > 10000) return 0;
|
||||
//if (frameGap <= 2) skip = 0;
|
||||
//if (frameGap > 2 && frameGap < 6) skip = 1 + 1;
|
||||
//else if (frameGap > 7 && frameGap < 12) skip = 2 + 1;
|
||||
//else if (frameGap > 13 && frameGap < 20) skip = 3 + 1;
|
||||
//else skip = frameGap - 2;
|
||||
|
||||
|
||||
//return skip;
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/AxiReplay/NetReplay.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/NetReplay.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 452b58ff73a0853449845fd9e1134cc2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
101
MAME.Unity/Assets/Plugins/AxiReplay/ReplayData.cs
Normal file
101
MAME.Unity/Assets/Plugins/AxiReplay/ReplayData.cs
Normal file
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = 44)]
|
||||
public struct ReplayHandler
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int Format;
|
||||
[FieldOffset(sizeof(int) * 1)]
|
||||
public int RomID;
|
||||
[FieldOffset(sizeof(int) * 2)]
|
||||
public int RomType;
|
||||
[FieldOffset(sizeof(int) * 3)]
|
||||
public int DataOffset;
|
||||
[FieldOffset(sizeof(int) * 4)]
|
||||
public int TitleOffset;
|
||||
[FieldOffset(sizeof(int) * 5)]
|
||||
public int NoteOffset;
|
||||
[FieldOffset(sizeof(int) * 6)]
|
||||
public int AllFrame;
|
||||
[FieldOffset(sizeof(int) * 7)]
|
||||
public int AllTime;
|
||||
[FieldOffset(sizeof(int) * 8)]
|
||||
public int SingleLenght;
|
||||
[FieldOffset(sizeof(int) * 9)]
|
||||
public long CreateTime;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct ReplayStep
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public UInt64 All64Data;
|
||||
[FieldOffset(0)]
|
||||
public Int32 FrameStartID;
|
||||
[FieldOffset(4)]
|
||||
public UInt64 InPut;
|
||||
}
|
||||
|
||||
public static class ReplayData
|
||||
{
|
||||
public static int HandlerLenght = sizeof(int) * 9 + sizeof(long);
|
||||
public enum ReplayFormat : byte
|
||||
{
|
||||
None = 0,
|
||||
FM32IPBYTE,
|
||||
FM32IP16,
|
||||
FM32IP32,
|
||||
FM32IP64,
|
||||
}
|
||||
public static void GetStringByteData(string str, out byte[] data, out int lenghtWithEnd, Encoding encoding)
|
||||
{
|
||||
data = encoding.GetBytes(str);
|
||||
lenghtWithEnd = data.Length + 1;
|
||||
}
|
||||
|
||||
public static byte[] GetHandlerData(ReplayHandler replayhandler)
|
||||
{
|
||||
int size = Marshal.SizeOf(typeof(ReplayHandler));
|
||||
byte[] arr = new byte[size];
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||
try
|
||||
{
|
||||
Marshal.StructureToPtr(replayhandler, ptr, false);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static ReplayHandler GetReplayHandlerFromData(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length < ReplayData.HandlerLenght)
|
||||
{
|
||||
throw new ArgumentException("Invalid data length or null data.");
|
||||
}
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(ReplayData.HandlerLenght);
|
||||
try
|
||||
{
|
||||
// 将byte数组的内容复制到非托管内存中
|
||||
Marshal.Copy(data, 0, ptr, ReplayData.HandlerLenght);
|
||||
// 从非托管内存将内容转换回ReplayHandler结构体
|
||||
return (ReplayHandler)Marshal.PtrToStructure(ptr, typeof(ReplayHandler));
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 释放非托管内存
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/AxiReplay/ReplayData.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/ReplayData.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42df5a138f4f4ae488815f35d8e748da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
179
MAME.Unity/Assets/Plugins/AxiReplay/ReplayReader.cs
Normal file
179
MAME.Unity/Assets/Plugins/AxiReplay/ReplayReader.cs
Normal file
@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using static AxiReplay.ReplayData;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
public class ReplayReader : IReplayReader
|
||||
{
|
||||
public ReplayData.ReplayFormat mFormat { get; private set; }
|
||||
public Encoding TexEncoding { get; private set; }
|
||||
ReplayHandler handler;
|
||||
string mTitle;
|
||||
string mNote;
|
||||
int mAllFrame;
|
||||
int mAllTime;
|
||||
long mData;
|
||||
int mSingleInputLenght;
|
||||
int mSingleDataLenght;
|
||||
FileStream mStream;
|
||||
BinaryReader mBinaryReader;
|
||||
|
||||
int mCurrFrame = 0;
|
||||
byte[] mNextOutbytes;
|
||||
public ReplayStep currStep;
|
||||
public ReplayStep nextStep;
|
||||
bool bEnd;
|
||||
|
||||
List<string> dbgList = new List<string>();
|
||||
bool bdbg = false;
|
||||
string dumpPath;
|
||||
|
||||
public ReplayReader(string path, bool bWithDump = false, string dumppath = null)
|
||||
{
|
||||
dbgList.Clear();
|
||||
bdbg = bWithDump;
|
||||
dumpPath = dumppath;
|
||||
mStream = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
mBinaryReader = new BinaryReader(mStream);
|
||||
byte[] Outbytes;
|
||||
Outbytes = mBinaryReader.ReadBytes(ReplayData.HandlerLenght);
|
||||
handler = ReplayData.GetReplayHandlerFromData(Outbytes);
|
||||
mFormat = (ReplayFormat)handler.Format;
|
||||
switch (mFormat)
|
||||
{
|
||||
case ReplayData.ReplayFormat.FM32IP64: mSingleInputLenght = sizeof(UInt64); break;
|
||||
case ReplayData.ReplayFormat.FM32IP32: mSingleInputLenght = sizeof(UInt32); break;
|
||||
case ReplayData.ReplayFormat.FM32IP16: mSingleInputLenght = sizeof(UInt16); break;
|
||||
case ReplayData.ReplayFormat.FM32IPBYTE: mSingleInputLenght = sizeof(byte); break;
|
||||
}
|
||||
//Frame+Lenght
|
||||
mSingleDataLenght = (sizeof(UInt32)) + mSingleInputLenght;
|
||||
nextStep = new ReplayStep();
|
||||
nextStep.FrameStartID = -1;
|
||||
bEnd = false;
|
||||
|
||||
dbgList.Add($"Format => {handler.Format}");
|
||||
dbgList.Add($"DataOffset => {handler.DataOffset}");
|
||||
dbgList.Add($"CreateTime => {handler.CreateTime}");
|
||||
dbgList.Add($"AllFrame => {handler.AllFrame}");
|
||||
dbgList.Add($"SingleLenght => {handler.SingleLenght}");
|
||||
|
||||
|
||||
mNextOutbytes = new byte[mSingleDataLenght];
|
||||
|
||||
if (bWithDump)
|
||||
{
|
||||
int TestFrameIdx = -1;
|
||||
while (!bEnd)
|
||||
{
|
||||
UpdateNextFrame(TestFrameIdx++);
|
||||
}
|
||||
File.WriteAllLines(dumppath, dbgList);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateNextFrame(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UpdateNextFrame(int targetFrame)
|
||||
{
|
||||
//如果已经超过
|
||||
while (targetFrame >= nextStep.FrameStartID)
|
||||
{
|
||||
if (nextStep.FrameStartID >= handler.AllFrame)
|
||||
{
|
||||
bEnd = true;
|
||||
break;
|
||||
}
|
||||
mBinaryReader.Read(mNextOutbytes, 0, mSingleDataLenght);
|
||||
switch (mFormat)
|
||||
{
|
||||
case ReplayFormat.FM32IP64:
|
||||
{
|
||||
nextStep.FrameStartID = BitConverter.ToInt32(mNextOutbytes, 0);
|
||||
nextStep.InPut = BitConverter.ToUInt64(mNextOutbytes, sizeof(UInt32));
|
||||
}
|
||||
break;
|
||||
case ReplayFormat.FM32IP32:
|
||||
{
|
||||
nextStep.All64Data = BitConverter.ToUInt64(mNextOutbytes, 0);
|
||||
}
|
||||
break;
|
||||
case ReplayFormat.FM32IP16:
|
||||
{
|
||||
nextStep.All64Data = BitConverter.ToUInt64(mNextOutbytes, 0);
|
||||
}
|
||||
break;
|
||||
case ReplayFormat.FM32IPBYTE:
|
||||
{
|
||||
nextStep.All64Data = BitConverter.ToUInt64(mNextOutbytes, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
dbgList.Add($"{nextStep.FrameStartID} | {nextStep.InPut}");
|
||||
|
||||
targetFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
int byFrameIdx = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 往前推进1帧的Input(返回是否变化)
|
||||
/// </summary>
|
||||
public bool NextFrame(out ReplayStep data)
|
||||
{
|
||||
return TakeFrame(1, out data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 往前推进指定帧数量的Input (返回是否变化)
|
||||
/// </summary>
|
||||
/// <param name="addFrame"></param>
|
||||
public bool TakeFrame(int addFrame, out ReplayStep data)
|
||||
{
|
||||
bool Changed = false;
|
||||
mCurrFrame += addFrame;
|
||||
if (mCurrFrame >= nextStep.FrameStartID)
|
||||
{
|
||||
Changed = currStep.InPut != nextStep.InPut;
|
||||
currStep = nextStep;
|
||||
data = currStep;
|
||||
UpdateNextFrame(mCurrFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = currStep;
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
||||
int lastTest = 0;
|
||||
/// <summary>
|
||||
/// 往前推进帧的,指定帧下标
|
||||
/// </summary>
|
||||
public bool NextFramebyFrameIdx(int FrameID, out ReplayStep data)
|
||||
{
|
||||
if (FrameID - lastTest != 1)
|
||||
{
|
||||
}
|
||||
lastTest = FrameID;
|
||||
bool res = TakeFrame(FrameID - byFrameIdx, out data);
|
||||
byFrameIdx = FrameID;
|
||||
return res;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
mStream.Dispose();
|
||||
mBinaryReader.Dispose();
|
||||
//TODO
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/AxiReplay/ReplayReader.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/ReplayReader.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66e0e18d1f5981745a3078e8460cb0e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
159
MAME.Unity/Assets/Plugins/AxiReplay/ReplayWriter.cs
Normal file
159
MAME.Unity/Assets/Plugins/AxiReplay/ReplayWriter.cs
Normal file
@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
public class ReplayWriter : IReplayWriter
|
||||
{
|
||||
public ReplayData.ReplayFormat mFormat { get; private set; }
|
||||
public Encoding TexEncoding { get; private set; }
|
||||
ReplayHandler handler;
|
||||
string mTitle;
|
||||
string mNote;
|
||||
int mAllFrame;
|
||||
int mAllTime;
|
||||
long mData;
|
||||
int mSingleInputLenght;
|
||||
int mSingleDataLenght;
|
||||
MemoryStream mStream;
|
||||
BinaryWriter mBinaryWriter;
|
||||
|
||||
int mCurrFrame;
|
||||
UInt64 mCurrInput;
|
||||
ReplayStep wirteStep;
|
||||
|
||||
List<string> dbgList = new List<string>();
|
||||
|
||||
public ReplayWriter(string Title, string Note, ReplayData.ReplayFormat format, Encoding encoding)
|
||||
{
|
||||
mTitle = Title;
|
||||
mNote = Note;
|
||||
TexEncoding = encoding;
|
||||
mFormat = format;
|
||||
switch (mFormat)
|
||||
{
|
||||
case ReplayData.ReplayFormat.FM32IP64: mSingleInputLenght = sizeof(UInt64); break;
|
||||
case ReplayData.ReplayFormat.FM32IP32: mSingleInputLenght = sizeof(UInt32); break;
|
||||
case ReplayData.ReplayFormat.FM32IP16: mSingleInputLenght = sizeof(UInt16); break;
|
||||
case ReplayData.ReplayFormat.FM32IPBYTE: mSingleInputLenght = sizeof(byte); break;
|
||||
}
|
||||
mSingleDataLenght = (sizeof(UInt32)) + mSingleInputLenght;
|
||||
|
||||
mStream = new MemoryStream();
|
||||
mBinaryWriter = new BinaryWriter(mStream);
|
||||
|
||||
//mCurrFrame = -1;
|
||||
mCurrFrame = 0;
|
||||
mCurrInput = int.MaxValue;
|
||||
wirteStep = new ReplayStep();
|
||||
|
||||
dbgList.Clear();
|
||||
|
||||
}
|
||||
|
||||
int byFrameIdx = 0;
|
||||
/// <summary>
|
||||
/// 往前推进帧的,指定帧下标
|
||||
/// </summary>
|
||||
/// <param name="frameInput"></param>
|
||||
public void NextFramebyFrameIdx(int FrameID, UInt64 frameInput)
|
||||
{
|
||||
TakeFrame(FrameID - byFrameIdx, frameInput);
|
||||
byFrameIdx = FrameID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 往前推进1帧的Input
|
||||
/// </summary>
|
||||
/// <param name="frameInput"></param>
|
||||
public void NextFrame(UInt64 frameInput)
|
||||
{
|
||||
TakeFrame(1, frameInput);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 往前推进指定帧数量的Input
|
||||
/// </summary>
|
||||
/// <param name="frameInput"></param>
|
||||
public void TakeFrame(int addFrame, UInt64 frameInput)
|
||||
{
|
||||
if (addFrame < 0)
|
||||
{
|
||||
|
||||
}
|
||||
mCurrFrame += addFrame;
|
||||
if (mCurrInput == frameInput)
|
||||
return;
|
||||
mCurrInput = frameInput;
|
||||
|
||||
wirteStep.FrameStartID = mCurrFrame;
|
||||
wirteStep.InPut = mCurrInput;
|
||||
dbgList.Add($"{mCurrFrame} | {mCurrInput}");
|
||||
|
||||
switch (mFormat)
|
||||
{
|
||||
case ReplayData.ReplayFormat.FM32IP64:
|
||||
mBinaryWriter.Write(wirteStep.FrameStartID);
|
||||
mBinaryWriter.Write(wirteStep.InPut);
|
||||
break;
|
||||
case ReplayData.ReplayFormat.FM32IP32:
|
||||
mBinaryWriter.Write(BitConverter.GetBytes(wirteStep.All64Data), 0, 4 + 4);
|
||||
break;
|
||||
case ReplayData.ReplayFormat.FM32IP16:
|
||||
mBinaryWriter.Write(BitConverter.GetBytes(wirteStep.All64Data), 0, 4 + 2);
|
||||
break;
|
||||
case ReplayData.ReplayFormat.FM32IPBYTE:
|
||||
mBinaryWriter.Write(BitConverter.GetBytes(wirteStep.All64Data), 0, 4 + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveData(string path, bool bWithDump = false, string dumppath = null)
|
||||
{
|
||||
byte[] titleData; int titleLenghtWithEnd;
|
||||
ReplayData.GetStringByteData(mTitle, out titleData, out titleLenghtWithEnd, TexEncoding);
|
||||
byte[] noteData; int noteLenghtWithEnd;
|
||||
ReplayData.GetStringByteData(mNote, out noteData, out noteLenghtWithEnd, TexEncoding);
|
||||
|
||||
ReplayHandler handler = new ReplayHandler();
|
||||
handler.Format = (int)this.mFormat;
|
||||
handler.DataOffset = ReplayData.HandlerLenght;
|
||||
handler.CreateTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
handler.AllFrame = wirteStep.FrameStartID;
|
||||
handler.SingleLenght = mSingleDataLenght;
|
||||
|
||||
using (FileStream fs = new FileStream(path, FileMode.Create))
|
||||
{
|
||||
using (BinaryWriter bw = new BinaryWriter(fs))
|
||||
{
|
||||
//写入Handler
|
||||
bw.Write(ReplayData.GetHandlerData(handler));
|
||||
//写入Data
|
||||
bw.Write(mStream.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
if (bWithDump)
|
||||
{
|
||||
List<string> temp = new List<string>();
|
||||
temp.Add($"Format => {handler.Format}");
|
||||
temp.Add($"DataOffset => {handler.DataOffset}");
|
||||
temp.Add($"CreateTime => {handler.CreateTime}");
|
||||
temp.Add($"AllFrame => {handler.AllFrame}");
|
||||
temp.Add($"SingleLenght => {handler.SingleLenght}");
|
||||
dbgList.InsertRange(0, temp);
|
||||
File.WriteAllLines(dumppath, dbgList);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
mStream.Dispose();
|
||||
mBinaryWriter.Dispose();
|
||||
//TODO
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/AxiReplay/ReplayWriter.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/AxiReplay/ReplayWriter.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc53a3d9a3e1749438b6ad1cef7b39bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -1,33 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 111763684b017184c8de7d0d4efbfeb1
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a84f6259c44984045a42bd9e64c43b0a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/AxiBitmap.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/AxiBitmap.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f996a7038b3e4a04bbc4722c030e7c0e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
263
MAME.Unity/Assets/Plugins/UMAME/AxiBitmap/AxiBitmap.cs
Normal file
263
MAME.Unity/Assets/Plugins/UMAME/AxiBitmap/AxiBitmap.cs
Normal file
@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MAME.Core.AxiBitmap
|
||||
{
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct AxiColor
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int sdColor;
|
||||
[FieldOffset(0)]
|
||||
public byte r;
|
||||
[FieldOffset(1)]
|
||||
public byte g;
|
||||
[FieldOffset(2)]
|
||||
public byte b;
|
||||
[FieldOffset(3)]
|
||||
public byte a;
|
||||
|
||||
public AxiColor(byte _r, byte _g, byte _b)
|
||||
{
|
||||
r = g = b = a = 0;
|
||||
sdColor = 0;
|
||||
r = _r;
|
||||
g = _g;
|
||||
b = _b;
|
||||
a = byte.MaxValue;
|
||||
}
|
||||
public AxiColor(byte _r, byte _g, byte _b, byte _a)
|
||||
{
|
||||
r = g = b = a = 0;
|
||||
sdColor = 0;
|
||||
r = _r;
|
||||
g = _g;
|
||||
b = _b;
|
||||
a = _a;
|
||||
}
|
||||
public static AxiColor FromArgb(int argb)
|
||||
{
|
||||
return new AxiColor { sdColor = argb };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0:X8}", sdColor);
|
||||
}
|
||||
|
||||
public static int ToArgb(AxiColor color)
|
||||
{
|
||||
return color.sdColor;
|
||||
}
|
||||
|
||||
#region 颜色定义
|
||||
public static AxiColor Transparent => new AxiColor(0, 0, 0, 0);
|
||||
public static AxiColor AliceBlue => new AxiColor(240, 248, 255);
|
||||
public static AxiColor AntiqueWhite => new AxiColor(250, 235, 215);
|
||||
public static AxiColor Aqua => new AxiColor(0, 255, 255);
|
||||
public static AxiColor Aquamarine => new AxiColor(127, 255, 212);
|
||||
public static AxiColor Azure => new AxiColor(240, 255, 255);
|
||||
public static AxiColor Beige => new AxiColor(245, 245, 220);
|
||||
public static AxiColor Bisque => new AxiColor(255, 228, 196);
|
||||
public static AxiColor Black => new AxiColor(0, 0, 0);
|
||||
public static AxiColor BlanchedAlmond => new AxiColor(255, 235, 205);
|
||||
public static AxiColor Blue => new AxiColor(0, 0, 255);
|
||||
public static AxiColor BlueViolet => new AxiColor(138, 43, 226);
|
||||
public static AxiColor Brown => new AxiColor(165, 42, 42);
|
||||
public static AxiColor BurlyWood => new AxiColor(222, 184, 135);
|
||||
public static AxiColor CadetBlue => new AxiColor(95, 158, 160);
|
||||
public static AxiColor Chartreuse => new AxiColor(127, 255, 0);
|
||||
public static AxiColor Chocolate => new AxiColor(210, 105, 30);
|
||||
public static AxiColor Coral => new AxiColor(255, 127, 80);
|
||||
public static AxiColor CornflowerBlue => new AxiColor(100, 149, 237);
|
||||
public static AxiColor Cornsilk => new AxiColor(255, 248, 220);
|
||||
public static AxiColor Crimson => new AxiColor(220, 20, 60);
|
||||
public static AxiColor Cyan => new AxiColor(0, 255, 255);
|
||||
public static AxiColor DarkBlue => new AxiColor(0, 0, 139);
|
||||
public static AxiColor DarkCyan => new AxiColor(0, 139, 139);
|
||||
public static AxiColor DarkGoldenrod => new AxiColor(184, 134, 11);
|
||||
public static AxiColor DarkGray => new AxiColor(169, 169, 169);
|
||||
public static AxiColor DarkGreen => new AxiColor(0, 100, 0);
|
||||
public static AxiColor DarkKhaki => new AxiColor(189, 183, 107);
|
||||
public static AxiColor DarkMagenta => new AxiColor(139, 0, 139);
|
||||
public static AxiColor DarkOliveGreen => new AxiColor(85, 107, 47);
|
||||
public static AxiColor DarkOrange => new AxiColor(255, 140, 0);
|
||||
public static AxiColor DarkOrchid => new AxiColor(153, 50, 204);
|
||||
public static AxiColor DarkRed => new AxiColor(139, 0, 0);
|
||||
public static AxiColor DarkSalmon => new AxiColor(233, 150, 122);
|
||||
public static AxiColor DarkSeaGreen => new AxiColor(143, 188, 143);
|
||||
public static AxiColor DarkSlateBlue => new AxiColor(72, 61, 139);
|
||||
public static AxiColor DarkSlateGray => new AxiColor(47, 79, 79);
|
||||
public static AxiColor DarkViolet => new AxiColor(148, 0, 211);
|
||||
public static AxiColor DeepPink => new AxiColor(255, 20, 147);
|
||||
public static AxiColor DeepSkyBlue => new AxiColor(0, 191, 255);
|
||||
public static AxiColor DimGray => new AxiColor(105, 105, 105);
|
||||
public static AxiColor DodgerBlue => new AxiColor(30, 144, 255);
|
||||
public static AxiColor FireBrick => new AxiColor(178, 34, 34);
|
||||
public static AxiColor FloralWhite => new AxiColor(255, 250, 240);
|
||||
public static AxiColor ForestGreen => new AxiColor(34, 139, 34);
|
||||
public static AxiColor Fuchsia => new AxiColor(255, 0, 255);
|
||||
public static AxiColor Gainsboro => new AxiColor(220, 220, 220);
|
||||
public static AxiColor GhostWhite => new AxiColor(248, 248, 255);
|
||||
public static AxiColor Gold => new AxiColor(255, 215, 0);
|
||||
public static AxiColor Goldenrod => new AxiColor(218, 165, 32);
|
||||
public static AxiColor Gray => new AxiColor(128, 128, 128);
|
||||
public static AxiColor Green => new AxiColor(0, 128, 0);
|
||||
public static AxiColor GreenYellow => new AxiColor(173, 255, 47);
|
||||
public static AxiColor Honeydew => new AxiColor(240, 255, 240);
|
||||
public static AxiColor HotPink => new AxiColor(255, 105, 180);
|
||||
public static AxiColor IndianRed => new AxiColor(205, 92, 92);
|
||||
public static AxiColor Indigo => new AxiColor(75, 0, 130);
|
||||
public static AxiColor Ivory => new AxiColor(255, 255, 240);
|
||||
public static AxiColor Khaki => new AxiColor(240, 230, 140);
|
||||
public static AxiColor Lavender => new AxiColor(230, 230, 250);
|
||||
public static AxiColor LavenderBlush => new AxiColor(255, 240, 245);
|
||||
public static AxiColor LawnGreen => new AxiColor(124, 252, 0);
|
||||
public static AxiColor LemonChiffon => new AxiColor(255, 250, 205);
|
||||
public static AxiColor LightBlue => new AxiColor(173, 216, 230);
|
||||
public static AxiColor LightCoral => new AxiColor(240, 128, 128);
|
||||
public static AxiColor LightCyan => new AxiColor(224, 255, 255);
|
||||
public static AxiColor LightGoldenrodYellow => new AxiColor(250, 250, 210);
|
||||
public static AxiColor LightGray => new AxiColor(211, 211, 211);
|
||||
public static AxiColor LightGreen => new AxiColor(144, 238, 144);
|
||||
public static AxiColor LightPink => new AxiColor(255, 182, 193);
|
||||
public static AxiColor LightSalmon => new AxiColor(255, 160, 122);
|
||||
public static AxiColor LightSeaGreen => new AxiColor(32, 178, 170);
|
||||
public static AxiColor LightSkyBlue => new AxiColor(135, 206, 250);
|
||||
public static AxiColor LightSlateGray => new AxiColor(119, 136, 153);
|
||||
public static AxiColor LightYellow => new AxiColor(255, 255, 224);
|
||||
public static AxiColor Lime => new AxiColor(0, 255, 0);
|
||||
public static AxiColor LimeGreen => new AxiColor(50, 205, 50);
|
||||
public static AxiColor Linen => new AxiColor(250, 240, 230);
|
||||
public static AxiColor Magenta => new AxiColor(255, 0, 255);
|
||||
public static AxiColor Maroon => new AxiColor(176, 48, 96);
|
||||
public static AxiColor MediumAquamarine => new AxiColor(102, 205, 170);
|
||||
public static AxiColor MediumBlue => new AxiColor(0, 0, 205);
|
||||
public static AxiColor MediumOrchid => new AxiColor(186, 85, 211);
|
||||
public static AxiColor MediumPurple => new AxiColor(147, 112, 219);
|
||||
public static AxiColor MediumSeaGreen => new AxiColor(60, 179, 113);
|
||||
public static AxiColor MediumSlateBlue => new AxiColor(123, 104, 238);
|
||||
public static AxiColor MediumSpringGreen => new AxiColor(0, 250, 154);
|
||||
public static AxiColor MediumTurquoise => new AxiColor(72, 209, 204);
|
||||
public static AxiColor MediumVioletRed => new AxiColor(199, 21, 133);
|
||||
public static AxiColor MidnightBlue => new AxiColor(25, 25, 112);
|
||||
public static AxiColor MintCream => new AxiColor(245, 255, 250);
|
||||
public static AxiColor MistyRose => new AxiColor(255, 228, 225);
|
||||
public static AxiColor Moccasin => new AxiColor(255, 228, 181);
|
||||
public static AxiColor NavajoWhite => new AxiColor(255, 222, 173);
|
||||
public static AxiColor Navy => new AxiColor(0, 0, 128);
|
||||
public static AxiColor OldLace => new AxiColor(253, 245, 230);
|
||||
public static AxiColor Olive => new AxiColor(128, 128, 0);
|
||||
public static AxiColor OliveDrab => new AxiColor(107, 142, 35);
|
||||
public static AxiColor Orange => new AxiColor(255, 165, 0);
|
||||
public static AxiColor OrangeRed => new AxiColor(255, 69, 0);
|
||||
public static AxiColor Orchid => new AxiColor(218, 112, 214);
|
||||
public static AxiColor PaleGoldenrod => new AxiColor(238, 232, 170);
|
||||
public static AxiColor PaleGreen => new AxiColor(152, 251, 152);
|
||||
public static AxiColor PaleTurquoise => new AxiColor(175, 238, 238);
|
||||
public static AxiColor PaleVioletRed => new AxiColor(219, 112, 147);
|
||||
public static AxiColor PapayaWhip => new AxiColor(255, 239, 213);
|
||||
public static AxiColor PeachPuff => new AxiColor(255, 218, 185);
|
||||
public static AxiColor Peru => new AxiColor(205, 133, 63);
|
||||
public static AxiColor Pink => new AxiColor(255, 192, 203);
|
||||
public static AxiColor Plum => new AxiColor(221, 160, 221);
|
||||
public static AxiColor PowderBlue => new AxiColor(176, 224, 230);
|
||||
public static AxiColor Purple => new AxiColor(160, 32, 240);
|
||||
public static AxiColor Red => new AxiColor(255, 0, 0);
|
||||
public static AxiColor RosyBrown => new AxiColor(188, 143, 143);
|
||||
public static AxiColor RoyalBlue => new AxiColor(65, 105, 225);
|
||||
public static AxiColor SaddleBrown => new AxiColor(139, 69, 19);
|
||||
public static AxiColor Salmon => new AxiColor(250, 128, 114);
|
||||
public static AxiColor SandyBrown => new AxiColor(244, 164, 96);
|
||||
public static AxiColor SeaGreen => new AxiColor(46, 139, 87);
|
||||
public static AxiColor SeaShell => new AxiColor(255, 245, 238);
|
||||
public static AxiColor Sienna => new AxiColor(160, 82, 45);
|
||||
public static AxiColor Silver => new AxiColor(192, 192, 192);
|
||||
public static AxiColor SkyBlue => new AxiColor(135, 206, 235);
|
||||
public static AxiColor SlateBlue => new AxiColor(106, 90, 205);
|
||||
public static AxiColor SlateGray => new AxiColor(112, 128, 144);
|
||||
public static AxiColor Snow => new AxiColor(255, 250, 250);
|
||||
public static AxiColor SpringGreen => new AxiColor(0, 255, 127);
|
||||
public static AxiColor SteelBlue => new AxiColor(70, 130, 180);
|
||||
public static AxiColor Tan => new AxiColor(210, 180, 140);
|
||||
public static AxiColor Teal => new AxiColor(0, 128, 128);
|
||||
public static AxiColor Thistle => new AxiColor(216, 191, 216);
|
||||
public static AxiColor Tomato => new AxiColor(255, 99, 71);
|
||||
public static AxiColor Turquoise => new AxiColor(64, 224, 208);
|
||||
public static AxiColor Violet => new AxiColor(238, 130, 238);
|
||||
public static AxiColor Wheat => new AxiColor(245, 222, 179);
|
||||
public static AxiColor White => new AxiColor(255, 255, 255);
|
||||
public static AxiColor WhiteSmoke => new AxiColor(245, 245, 245);
|
||||
public static AxiColor Yellow => new AxiColor(255, 255, 0);
|
||||
public static AxiColor YellowGreen => new AxiColor(154, 205, 50);
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class AxiBitmapEx
|
||||
{
|
||||
public static int ToArgb(this AxiColor color)
|
||||
{
|
||||
return (color.a << 24) | (color.r << 16) | (color.g << 8) | color.b;
|
||||
}
|
||||
|
||||
|
||||
//public static void CloneIntColorArr(int[] baseBitmap, int[] targetBitmap, int baseWidth, int baseHeight, Rectangle rect)
|
||||
//{
|
||||
// // 检查矩形是否超出位图边界
|
||||
// if (rect.X < 0 || rect.X + rect.Width > baseWidth || rect.Y < 0 || rect.Y + rect.Height > baseHeight)
|
||||
// {
|
||||
// throw new ArgumentException("Rectangle is out of bitmap bounds.");
|
||||
// }
|
||||
|
||||
// int baseStartIndex = rect.Y * baseWidth + rect.X;
|
||||
// int targetStartIndex = rect.Y * rect.Width;
|
||||
|
||||
// for (int y = 0; y < rect.Height; y++)
|
||||
// {
|
||||
// // 注意这里使用了rect.Width作为要拷贝的元素数量,而不是baseWidth
|
||||
// Buffer.BlockCopy(baseBitmap, baseStartIndex + y * baseWidth, targetBitmap, targetStartIndex + y * rect.Width, rect.Width * sizeof(int));
|
||||
// // 或者使用Array.Copy,但要注意类型的大小(在这里是int)
|
||||
// // Array.Copy(baseBitmap, baseStartIndex + y * baseWidth, targetBitmap, targetStartIndex + y * rect.Width, rect.Width);
|
||||
// }
|
||||
//}
|
||||
|
||||
public static void CloneIntColorArr(int[] baseBitmap, int[] targetBitmap, int Width, int Height, Rectangle rect)
|
||||
{
|
||||
// 检查矩形是否超出位图边界
|
||||
if (rect.X < 0 || rect.Right > Width || rect.Y < 0 || rect.Bottom > Height)
|
||||
{
|
||||
throw new ArgumentException("out of");
|
||||
}
|
||||
|
||||
int srcStartIndex = rect.Y * Width + rect.X;
|
||||
|
||||
for (int y = 0; y < rect.Height; y++)
|
||||
{
|
||||
Array.Copy(baseBitmap, srcStartIndex + y * Width, targetBitmap, y * rect.Width, rect.Width);
|
||||
}
|
||||
}
|
||||
|
||||
public struct Rectangle
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
public int Width;
|
||||
public int Height;
|
||||
public Rectangle(int x, int y, int width, int height)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
public int Right => X + Width;
|
||||
public int Bottom => Y + Height;
|
||||
public int Area { get { return Width * Height; } }
|
||||
public bool Contains(int pointX, int pointY) { return pointX >= X && pointX < X + Width && pointY >= Y && pointY < Y + Height; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/AxiBitmap/AxiBitmap.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/AxiBitmap/AxiBitmap.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b94fc4b46eb73b541b66a64f2831e49c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/Log.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/Log.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19fb05683c89f9d438ce6cb7e65de2ec
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
25
MAME.Unity/Assets/Plugins/UMAME/Log/EmuLogger.cs
Normal file
25
MAME.Unity/Assets/Plugins/UMAME/Log/EmuLogger.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public static class EmuLogger
|
||||
{
|
||||
|
||||
#region 抽象出去
|
||||
static Action<string> Act_Log;
|
||||
|
||||
public static void BindFunc(ILog ilog)
|
||||
{
|
||||
Act_Log -= Act_Log;
|
||||
|
||||
Act_Log += ilog.Log;
|
||||
}
|
||||
|
||||
public static void Log(string msg)
|
||||
{
|
||||
Act_Log?.Invoke(msg);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Log/EmuLogger.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Log/EmuLogger.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 152466b6f17e41244be3f9dd18aee4e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
66
MAME.Unity/Assets/Plugins/UMAME/MAMEEmu.cs
Normal file
66
MAME.Unity/Assets/Plugins/UMAME/MAMEEmu.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public class MAMEEmu : IDisposable
|
||||
{
|
||||
MameMainMotion mameMainMotion;
|
||||
//byte[] mGameTileData;
|
||||
//byte[] mtileListData;
|
||||
public MAMEEmu()
|
||||
{
|
||||
mameMainMotion = new MameMainMotion();
|
||||
}
|
||||
|
||||
public bool bRom => mameMainMotion.bRom;
|
||||
|
||||
public void Init(
|
||||
string RomDir,
|
||||
ILog ilog,
|
||||
IResources iRes,
|
||||
IVideoPlayer ivp,
|
||||
ISoundPlayer isp,
|
||||
IKeyboard ikb,
|
||||
IMouse imou,
|
||||
ITimeSpan itime
|
||||
) => mameMainMotion.Init(RomDir, ilog, iRes, ivp, isp, ikb, imou, itime);
|
||||
|
||||
public Dictionary<string, RomInfo> GetGameList() => mameMainMotion.GetGameList();
|
||||
public void LoadRom(string Name) => mameMainMotion.LoadRom(Name);
|
||||
public void GetGameScreenSize(out int _width, out int _height, out IntPtr _framePtr) => mameMainMotion.GetGameScreenSize(out _width, out _height, out _framePtr);
|
||||
public void StartGame() => mameMainMotion.StartGame();
|
||||
public void UpdateFrame() => Mame.mame_execute_UpdateMode_NextFrame();
|
||||
public void UnlockNextFreme(int moreTick = 1) => mameMainMotion.UnlockNextFreme(moreTick);
|
||||
public void StopGame() => mameMainMotion.StopGame();
|
||||
public long currEmuFrame => Video.screenstate.frame_number;
|
||||
|
||||
public void LoadState(BinaryReader sr)
|
||||
{
|
||||
Mame.paused = true;
|
||||
Thread.Sleep(20);
|
||||
State.loadstate_callback.Invoke(sr);
|
||||
Mame.postload();
|
||||
Thread.Sleep(20);
|
||||
Mame.paused = false;
|
||||
}
|
||||
|
||||
public void SaveState(BinaryWriter sw)
|
||||
{
|
||||
Mame.paused = true;
|
||||
Thread.Sleep(20);
|
||||
State.savestate_callback.Invoke(sw);
|
||||
Thread.Sleep(20);
|
||||
Mame.paused = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
mameMainMotion.StopGame();
|
||||
mameMainMotion = null;
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/MAMEEmu.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/MAMEEmu.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35d7d011a9c354848a421281c06f5f8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/Motion.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/Motion.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebd8f2e90f8767b498f2431f7394ede9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
616
MAME.Unity/Assets/Plugins/UMAME/Motion/MameMainMotion.cs
Normal file
616
MAME.Unity/Assets/Plugins/UMAME/Motion/MameMainMotion.cs
Normal file
@ -0,0 +1,616 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public class MameMainMotion
|
||||
{
|
||||
public string tsslStatus;
|
||||
public CheatMotion cheatmotion;
|
||||
public M68000Motion m68000motion;
|
||||
public Z80Motion z80motion;
|
||||
public M6809Motion m6809motion;
|
||||
public CpsMotion cpsmotion;
|
||||
public NeogeoMotion neogeomotion;
|
||||
public Konami68000Motion konami68000motion;
|
||||
public string sSelect;
|
||||
//public static Thread mainThread;
|
||||
|
||||
//初始化停帧信号量
|
||||
//public AutoResetEvent emuAutoLoopEvent;
|
||||
|
||||
public static IResources resource;
|
||||
public bool bRom => Machine.bRom;
|
||||
|
||||
public MameMainMotion()
|
||||
{
|
||||
neogeomotion = new NeogeoMotion();
|
||||
cheatmotion = new CheatMotion();
|
||||
m68000motion = new M68000Motion();
|
||||
m6809motion = new M6809Motion();
|
||||
z80motion = new Z80Motion();
|
||||
cpsmotion = new CpsMotion();
|
||||
konami68000motion = new Konami68000Motion();
|
||||
}
|
||||
|
||||
public void Init(
|
||||
string RomDir,
|
||||
ILog ilog,
|
||||
IResources iRes,
|
||||
IVideoPlayer ivp,
|
||||
ISoundPlayer isp,
|
||||
IKeyboard ikb,
|
||||
IMouse imou,
|
||||
ITimeSpan itime
|
||||
)
|
||||
{
|
||||
Mame.RomRoot = RomDir;
|
||||
EmuLogger.BindFunc(ilog);
|
||||
Video.BindFunc(ivp);
|
||||
Sound.BindFunc(isp);
|
||||
resource = iRes;
|
||||
|
||||
sSelect = string.Empty;
|
||||
|
||||
RomInfo.Rom = new RomInfo();
|
||||
LoadROMXML();
|
||||
Keyboard.InitializeInput(ikb);
|
||||
Mouse.InitialMouse(imou);
|
||||
AxiTimeSpan.Init(itime);
|
||||
}
|
||||
|
||||
private void LoadROMXML()
|
||||
{
|
||||
XElement xe = XElement.Parse(resource.mame);
|
||||
IEnumerable<XElement> elements = from ele in xe.Elements("game") select ele;
|
||||
showInfoByElements(elements);
|
||||
}
|
||||
|
||||
public Dictionary<string, RomInfo> GetGameList()
|
||||
{
|
||||
return RomInfo.dictName2Rom;
|
||||
}
|
||||
|
||||
public void GetGameScreenSize(out int _width, out int _height, out IntPtr _framePtr)
|
||||
{
|
||||
//_width = Video.fullwidth;
|
||||
//_height = Video.fullheight;
|
||||
//_framePtr = Video.bitmapcolor_Ptr;
|
||||
_width = Video.width;
|
||||
_height = Video.height;
|
||||
_framePtr = Video.bitmapcolorRect_Ptr;
|
||||
}
|
||||
|
||||
private void showInfoByElements(IEnumerable<XElement> elements)
|
||||
{
|
||||
RomInfo.romList = new List<RomInfo>();
|
||||
RomInfo.dictName2Rom = new Dictionary<string, RomInfo>();
|
||||
foreach (var ele in elements)
|
||||
{
|
||||
RomInfo rom = new RomInfo();
|
||||
rom.Name = ele.Attribute("name").Value;
|
||||
rom.Board = ele.Attribute("board").Value;
|
||||
rom.Parent = ele.Element("parent").Value;
|
||||
rom.Direction = ele.Element("direction").Value;
|
||||
rom.Description = ele.Element("description").Value;
|
||||
rom.Year = ele.Element("year").Value;
|
||||
rom.Manufacturer = ele.Element("manufacturer").Value;
|
||||
RomInfo.romList.Add(rom);
|
||||
RomInfo.dictName2Rom[rom.Name] = rom;
|
||||
//loadform.listView1.Items.Add(new ListViewItem(new string[] { rom.Description, rom.Year, rom.Name, rom.Parent, rom.Direction, rom.Manufacturer, rom.Board }));
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadRom(string Name)
|
||||
{
|
||||
RomInfo.Rom = RomInfo.GetRomByName(Name);
|
||||
if (RomInfo.Rom == null)
|
||||
{
|
||||
EmuLogger.Log("Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
EmuTimer.lt = new List<EmuTimer.emu_timer>();
|
||||
sSelect = RomInfo.Rom.Name;
|
||||
Machine.mainMotion = this;
|
||||
Machine.rom = RomInfo.Rom;
|
||||
Machine.sName = Machine.rom.Name;
|
||||
Machine.sParent = Machine.rom.Parent;
|
||||
Machine.sBoard = Machine.rom.Board;
|
||||
Machine.sDirection = Machine.rom.Direction;
|
||||
Machine.sDescription = Machine.rom.Description;
|
||||
Machine.sManufacturer = Machine.rom.Manufacturer;
|
||||
Machine.lsParents = RomInfo.GetParents(Machine.sName);
|
||||
int i;
|
||||
switch (Machine.sBoard)
|
||||
{
|
||||
case "CPS-1":
|
||||
case "CPS-1(QSound)":
|
||||
case "CPS2":
|
||||
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 2;
|
||||
//Video.nMode = 3;
|
||||
itemSelect();
|
||||
CPS.CPSInit();
|
||||
break;
|
||||
case "Data East":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Dataeast.DataeastInit();
|
||||
break;
|
||||
case "Tehkan":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Tehkan.PbactionInit();
|
||||
break;
|
||||
case "Neo Geo":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Neogeo.NeogeoInit();
|
||||
break;
|
||||
case "SunA8":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
SunA8.SunA8Init();
|
||||
break;
|
||||
case "Namco System 1":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Namcos1.Namcos1Init();
|
||||
break;
|
||||
case "IGS011":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
IGS011.IGS011Init();
|
||||
break;
|
||||
case "PGM":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
PGM.PGMInit();
|
||||
break;
|
||||
case "M72":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
M72.M72Init();
|
||||
break;
|
||||
case "M92":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
M92.M92Init();
|
||||
break;
|
||||
case "Taito":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Taito.TaitoInit();
|
||||
break;
|
||||
case "Taito B":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Taitob.TaitobInit();
|
||||
break;
|
||||
case "Konami 68000":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Konami68000.Konami68000Init();
|
||||
break;
|
||||
case "Capcom":
|
||||
Video.nMode = 1;
|
||||
Video.iMode = 0;
|
||||
itemSelect();
|
||||
Capcom.CapcomInit();
|
||||
break;
|
||||
}
|
||||
if (Machine.bRom)
|
||||
{
|
||||
EmuLogger.Log("MAME.NET: " + Machine.sDescription + " [" + Machine.sName + "]");
|
||||
Mame.init_machine();
|
||||
Generic.nvram_load();
|
||||
}
|
||||
else
|
||||
{
|
||||
EmuLogger.Log("error rom");
|
||||
}
|
||||
}
|
||||
|
||||
public void StartGame()
|
||||
{
|
||||
M68000Motion.iStatus = 0;
|
||||
M68000Motion.iValue = 0;
|
||||
Mame.exit_pending = false;
|
||||
|
||||
//初始化停帧信号量
|
||||
//emuAutoLoopEvent = new AutoResetEvent(false);
|
||||
|
||||
//mainThread = new Thread(Mame.mame_execute);
|
||||
//mainThread.Start();
|
||||
|
||||
Mame.mame_execute_UpdateMode_Start();
|
||||
}
|
||||
|
||||
|
||||
public static object unlockMoreFrameObj = new object();
|
||||
public static int unlockMoreFrame;
|
||||
/// <summary>
|
||||
/// 放开帧
|
||||
/// </summary>
|
||||
/// <param name="moveTick"></param>
|
||||
public void UnlockNextFreme(int moreTick = 1)
|
||||
{
|
||||
//emuAutoLoopEvent.Set();
|
||||
|
||||
//TODO 等待跳帧时测试
|
||||
if (moreTick > 1)
|
||||
{
|
||||
lock (unlockMoreFrameObj)
|
||||
{
|
||||
unlockMoreFrame += moreTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待放行帧
|
||||
/// </summary>
|
||||
public void WaitNextFrame()
|
||||
{
|
||||
//TODO 等待跳帧时测试
|
||||
lock (unlockMoreFrameObj)
|
||||
{
|
||||
if (unlockMoreFrame > 0)
|
||||
{
|
||||
unlockMoreFrame--;
|
||||
//还有记数,则直接放行
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//等待停帧数
|
||||
//Machine.mainMotion.emuAutoLoopEvent.WaitOne();
|
||||
}
|
||||
|
||||
public void StopGame()
|
||||
{
|
||||
if (Machine.bRom)
|
||||
{
|
||||
Mame.exit_pending = true;
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
private void itemSelect()
|
||||
{
|
||||
switch (Machine.sBoard)
|
||||
{
|
||||
case "CPS-1":
|
||||
case "CPS-1(QSound)":
|
||||
case "CPS2":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 0;
|
||||
Video.width = 512;
|
||||
Video.height = 512;
|
||||
}
|
||||
else if (Video.iMode == 1)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 256;
|
||||
Video.width = 512;
|
||||
Video.height = 256;
|
||||
}
|
||||
else if (Video.iMode == 2)
|
||||
{
|
||||
Video.offsetx = 64;
|
||||
Video.offsety = 272;
|
||||
Video.width = 384;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "Data East":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 16;
|
||||
Video.width = 256;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "Tehkan":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 16;
|
||||
Video.width = 256;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "Neo Geo":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 30;
|
||||
Video.offsety = 16;
|
||||
Video.width = 320;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "SunA8":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 16;
|
||||
Video.width = 256;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "Namco System 1":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 73;
|
||||
Video.offsety = 16;
|
||||
Video.width = 288;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "IGS011":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 0;
|
||||
Video.width = 512;
|
||||
Video.height = 240;
|
||||
}
|
||||
break;
|
||||
case "PGM":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 0;
|
||||
Video.width = 448;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "M72":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 64;
|
||||
Video.offsety = 0;
|
||||
Video.width = 384;
|
||||
Video.height = 256;
|
||||
}
|
||||
break;
|
||||
case "M92":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 80;
|
||||
Video.offsety = 8;
|
||||
Video.width = 320;
|
||||
Video.height = 240;
|
||||
}
|
||||
break;
|
||||
case "Taito":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
switch (Machine.sName)
|
||||
{
|
||||
case "tokio":
|
||||
case "tokioo":
|
||||
case "tokiou":
|
||||
case "tokiob":
|
||||
case "bublbobl":
|
||||
case "bublbobl1":
|
||||
case "bublboblr":
|
||||
case "bublboblr1":
|
||||
case "boblbobl":
|
||||
case "sboblbobl":
|
||||
case "sboblbobla":
|
||||
case "sboblboblb":
|
||||
case "sboblbobld":
|
||||
case "sboblboblc":
|
||||
case "bub68705":
|
||||
case "dland":
|
||||
case "bbredux":
|
||||
case "bublboblb":
|
||||
case "bublcave":
|
||||
case "boblcave":
|
||||
case "bublcave11":
|
||||
case "bublcave10":
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 16;
|
||||
Video.width = 256;
|
||||
Video.height = 224;
|
||||
break;
|
||||
case "opwolf":
|
||||
case "opwolfa":
|
||||
case "opwolfj":
|
||||
case "opwolfu":
|
||||
case "opwolfb":
|
||||
case "opwolfp":
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 8;
|
||||
Video.width = 320;
|
||||
Video.height = 240;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Taito B":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 16;
|
||||
Video.width = 320;
|
||||
Video.height = 224;
|
||||
}
|
||||
break;
|
||||
case "Konami 68000":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
switch (Machine.sName)
|
||||
{
|
||||
case "cuebrick":
|
||||
case "mia":
|
||||
case "mia2":
|
||||
case "tmnt2":
|
||||
case "tmnt2a":
|
||||
case "tmht22pe":
|
||||
case "tmht24pe":
|
||||
case "tmnt22pu":
|
||||
case "qgakumon":
|
||||
Video.offsetx = 104;
|
||||
Video.offsety = 16;
|
||||
Video.width = 304;
|
||||
Video.height = 224;
|
||||
break;
|
||||
case "tmnt":
|
||||
case "tmntu":
|
||||
case "tmntua":
|
||||
case "tmntub":
|
||||
case "tmht":
|
||||
case "tmhta":
|
||||
case "tmhtb":
|
||||
case "tmntj":
|
||||
case "tmnta":
|
||||
case "tmht2p":
|
||||
case "tmht2pa":
|
||||
case "tmnt2pj":
|
||||
case "tmnt2po":
|
||||
case "lgtnfght":
|
||||
case "lgtnfghta":
|
||||
case "lgtnfghtu":
|
||||
case "trigon":
|
||||
case "blswhstl":
|
||||
case "blswhstla":
|
||||
case "detatwin":
|
||||
Video.offsetx = 96;
|
||||
Video.offsety = 16;
|
||||
Video.width = 320;
|
||||
Video.height = 224;
|
||||
break;
|
||||
case "punkshot":
|
||||
case "punkshot2":
|
||||
case "punkshotj":
|
||||
case "glfgreat":
|
||||
case "glfgreatj":
|
||||
case "ssriders":
|
||||
case "ssriderseaa":
|
||||
case "ssridersebd":
|
||||
case "ssridersebc":
|
||||
case "ssridersuda":
|
||||
case "ssridersuac":
|
||||
case "ssridersuab":
|
||||
case "ssridersubc":
|
||||
case "ssridersadd":
|
||||
case "ssridersabd":
|
||||
case "ssridersjad":
|
||||
case "ssridersjac":
|
||||
case "ssridersjbd":
|
||||
case "thndrx2":
|
||||
case "thndrx2a":
|
||||
case "thndrx2j":
|
||||
case "prmrsocr":
|
||||
case "prmrsocrj":
|
||||
Video.offsetx = 112;
|
||||
Video.offsety = 16;
|
||||
Video.width = 288;
|
||||
Video.height = 224;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Capcom":
|
||||
if (Video.iMode == 0)
|
||||
{
|
||||
switch (Machine.sName)
|
||||
{
|
||||
case "gng":
|
||||
case "gnga":
|
||||
case "gngbl":
|
||||
case "gngprot":
|
||||
case "gngblita":
|
||||
case "gngc":
|
||||
case "gngt":
|
||||
case "makaimur":
|
||||
case "makaimurc":
|
||||
case "makaimurg":
|
||||
case "diamond":
|
||||
Video.offsetx = 0;
|
||||
Video.offsety = 16;
|
||||
Video.width = 256;
|
||||
Video.height = 224;
|
||||
break;
|
||||
case "sf":
|
||||
case "sfua":
|
||||
case "sfj":
|
||||
case "sfjan":
|
||||
case "sfan":
|
||||
case "sfp":
|
||||
Video.offsetx = 64;
|
||||
Video.offsety = 16;
|
||||
Video.width = 384;
|
||||
Video.height = 224;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (Machine.sDirection)
|
||||
{
|
||||
case "":
|
||||
case "180":
|
||||
TempWidth = Video.width + 38;
|
||||
TempHeight = Video.height + 108;
|
||||
break;
|
||||
case "90":
|
||||
case "270":
|
||||
TempWidth = Video.height + 38;
|
||||
TempHeight = Video.width + 108;
|
||||
break;
|
||||
}
|
||||
ResizeMain();
|
||||
}
|
||||
|
||||
int TempWidth = 0;
|
||||
int TempHeight = 0;
|
||||
private void ResizeMain()
|
||||
{
|
||||
int deltaX, deltaY;
|
||||
//switch (Machine.sDirection)
|
||||
//{
|
||||
// case "":
|
||||
// case "180":
|
||||
// deltaX = TempWidth - (Video.width + 38);
|
||||
// deltaY = TempHeight - (Video.height + 108);
|
||||
// pictureBox1.Width = Video.width + deltaX;
|
||||
// pictureBox1.Height = Video.height + deltaY;
|
||||
// break;
|
||||
// case "90":
|
||||
// case "270":
|
||||
// deltaX = TempWidth - (Video.height + 38);
|
||||
// deltaY = TempHeight - (Video.width + 108);
|
||||
// pictureBox1.Width = Video.height + deltaX;
|
||||
// pictureBox1.Height = Video.width + deltaY;
|
||||
// break;
|
||||
//}
|
||||
|
||||
//TODO reset 宽高
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eacdf053bdef1934d8cdec1c463f8847
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
138
MAME.Unity/Assets/Plugins/UMAME/Motion/cheatMotion.cs
Normal file
138
MAME.Unity/Assets/Plugins/UMAME/Motion/cheatMotion.cs
Normal file
@ -0,0 +1,138 @@
|
||||
using cpu.m68000;
|
||||
using cpu.nec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public partial class CheatMotion
|
||||
{
|
||||
public enum LockState
|
||||
{
|
||||
LOCK_NONE = 0,
|
||||
LOCK_SECOND,
|
||||
LOCK_FRAME,
|
||||
}
|
||||
public LockState lockState = LockState.LOCK_NONE;
|
||||
public List<int[]> lsCheatdata1;
|
||||
public List<int[]> lsCheatdata2;
|
||||
private string[] sde6 = new string[1] { "," }, sde7 = new string[1] { ";" }, sde9 = new string[1] { "$" }, sde10 = new string[] { "+" };
|
||||
public Func<int, byte> CheatReadByte;
|
||||
public Action<int, byte> CheatWriteByte;
|
||||
|
||||
|
||||
#region
|
||||
List<string> mTxList_tbResult = new List<string>();
|
||||
#endregion
|
||||
public CheatMotion()
|
||||
{
|
||||
cheatForm_Load();
|
||||
}
|
||||
private void cheatForm_Load()
|
||||
{
|
||||
switch (Machine.sBoard)
|
||||
{
|
||||
case "CPS-1":
|
||||
case "CPS-1(QSound)":
|
||||
case "CPS2":
|
||||
case "Data East":
|
||||
case "Tehkan":
|
||||
case "Neo Geo":
|
||||
case "Taito B":
|
||||
case "Konami 68000":
|
||||
case "Capcom":
|
||||
CheatReadByte = (int i1) => { return Memory.mainram[i1]; };
|
||||
CheatWriteByte = (int i1, byte b1) => { Memory.mainram[i1] = b1; };
|
||||
break;
|
||||
case "Namco System 1":
|
||||
CheatReadByte = (int i1) => { return Namcos1.N0ReadMemory((ushort)i1); };
|
||||
CheatWriteByte = (int i1, byte b1) => { Namcos1.N0WriteMemory((ushort)i1, b1); };
|
||||
break;
|
||||
case "IGS011":
|
||||
CheatReadByte = (int i1) => { return (byte)MC68000.m1.ReadByte(i1); };
|
||||
CheatWriteByte = (int i1, byte b1) => { MC68000.m1.WriteByte(i1, (sbyte)b1); };
|
||||
break;
|
||||
case "PGM":
|
||||
CheatReadByte = (int i1) => { return (byte)MC68000.m1.ReadByte(i1); };
|
||||
CheatWriteByte = (int i1, byte b1) => { MC68000.m1.WriteByte(i1, (sbyte)b1); };
|
||||
break;
|
||||
case "M72":
|
||||
case "M92":
|
||||
CheatReadByte = (int i1) => { return Nec.nn1[0].ReadByte(i1); };
|
||||
CheatWriteByte = (int i1, byte b1) => { Nec.nn1[0].WriteByte(i1, b1); };
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void GetCheatdata()
|
||||
{
|
||||
// lsCheatdata1 = new List<int[]>();
|
||||
// lsCheatdata2 = new List<int[]>();
|
||||
// int i1, i2, i3, iAddress, iOffsetAddress1, iOffsetAddress2, iValue2, n3;
|
||||
// string[] ss1, ss2, ss3;
|
||||
// foreach (ListViewItem item1 in listViewControl1.myListView.Items)
|
||||
// {
|
||||
// if (item1.Checked)
|
||||
// {
|
||||
// i1 = listViewControl1.myListView.Items.IndexOf(item1);
|
||||
// i2 = Array.IndexOf(listViewControl1.ssCItem[i1], item1.SubItems[1].Text);
|
||||
// ss1 = listViewControl1.ssCValue[i1][i2].Split(sde7, StringSplitOptions.RemoveEmptyEntries);
|
||||
// n3 = ss1.Length;
|
||||
// for (i3 = 0; i3 < n3; i3++)
|
||||
// {
|
||||
// ss3 = ss1[i3].Split(sde6, StringSplitOptions.RemoveEmptyEntries);
|
||||
// iValue2 = Convert.ToInt32(ss3[1], 16);
|
||||
// if (ss3[0].IndexOf("$") >= 0)
|
||||
// {
|
||||
// ss2 = ss3[0].Split(sde9, StringSplitOptions.RemoveEmptyEntries);
|
||||
// iOffsetAddress1 = Convert.ToInt32(ss2[0], 16);
|
||||
// iOffsetAddress2 = Convert.ToInt32(ss2[1], 16);
|
||||
// lsCheatdata1.Add(new int[] { iOffsetAddress1, iOffsetAddress2, iValue2 });
|
||||
// }
|
||||
// else if (ss3[0].IndexOf("+") >= 0)
|
||||
// {
|
||||
// ss2 = ss3[0].Split(sde10, StringSplitOptions.RemoveEmptyEntries);
|
||||
// iOffsetAddress1 = Convert.ToInt32(ss2[0], 16);
|
||||
// iOffsetAddress2 = Convert.ToInt32(ss2[1], 16);
|
||||
// iAddress = iOffsetAddress1 + iOffsetAddress2;
|
||||
// lsCheatdata2.Add(new int[] { iAddress, iValue2 });
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// iAddress = Convert.ToInt32(ss3[0], 16);
|
||||
// lsCheatdata2.Add(new int[] { iAddress, iValue2 });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
public void ApplyCheat()
|
||||
{
|
||||
int iAddress, iValue1;
|
||||
foreach (int[] ii1 in lsCheatdata1)
|
||||
{
|
||||
//iAddress = bbMem[ii1[0]] * 0x100 + bbMem[ii1[0] + 1] + ii1[1];
|
||||
//iValue1 = bbMem[iAddress];
|
||||
//bbMem[iAddress] = (byte)ii1[2];
|
||||
iAddress = CheatReadByte(ii1[0]) * 0x100 + CheatReadByte(ii1[0] + 1) + ii1[1];
|
||||
iValue1 = CheatReadByte(iAddress);
|
||||
CheatWriteByte(iAddress, (byte)ii1[2]);
|
||||
if (iValue1 != ii1[2])
|
||||
{
|
||||
mTxList_tbResult.Add(iAddress.ToString("X4") + " " + iValue1.ToString("X2") + " " + ii1[2].ToString("X2") + "\r\n");
|
||||
}
|
||||
}
|
||||
foreach (int[] ii1 in lsCheatdata2)
|
||||
{
|
||||
iAddress = ii1[0];
|
||||
//iValue1 = bbMem[iAddress];
|
||||
//bbMem[ii1[0]] = (byte)ii1[1];
|
||||
iValue1 = CheatReadByte(iAddress);
|
||||
CheatWriteByte(ii1[0], (byte)ii1[1]);
|
||||
if (iValue1 != ii1[1])
|
||||
{
|
||||
mTxList_tbResult.Add(ii1[0].ToString("X4") + " " + iValue1.ToString("X2") + " " + ii1[1].ToString("X2") + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Motion/cheatMotion.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Motion/cheatMotion.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 847edc5d4d82b7448a62f92c9d3dee10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
38
MAME.Unity/Assets/Plugins/UMAME/Motion/cpsMotion.cs
Normal file
38
MAME.Unity/Assets/Plugins/UMAME/Motion/cpsMotion.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public partial class CpsMotion
|
||||
{
|
||||
private string[] sde2 = new string[] { "," };
|
||||
private int locationX, locationY;
|
||||
|
||||
#region
|
||||
public bool cbLockpal = false;
|
||||
public bool cbRowscroll = false;
|
||||
public string tbInput = string.Empty;
|
||||
public bool cbL0 = false;
|
||||
public bool cbL1 = false;
|
||||
public bool cbL2 = false;
|
||||
public bool cbL3 = false;
|
||||
public string tbFile = string.Empty;
|
||||
public string tbPoint = string.Empty;
|
||||
public int cbLayer = 0;
|
||||
public string tbCode = string.Empty;
|
||||
public string tbColor = string.Empty;
|
||||
|
||||
public string tbScroll1x = string.Empty;
|
||||
public string tbScroll1y = string.Empty;
|
||||
public string tbScroll2x = string.Empty;
|
||||
public string tbScroll2y = string.Empty;
|
||||
public string tbScroll3x = string.Empty;
|
||||
public string tbScroll3y = string.Empty;
|
||||
public string tbScrollsx = string.Empty;
|
||||
public string tbScrollsy = string.Empty;
|
||||
public List<string> tbResult = new List<string>();
|
||||
#endregion
|
||||
public CpsMotion()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Motion/cpsMotion.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Motion/cpsMotion.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08bc0c1fe9979244e872263dfe2c09b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
MAME.Unity/Assets/Plugins/UMAME/Motion/konami68000Motion.cs
Normal file
19
MAME.Unity/Assets/Plugins/UMAME/Motion/konami68000Motion.cs
Normal file
@ -0,0 +1,19 @@
|
||||
namespace MAME.Core
|
||||
{
|
||||
public class Konami68000Motion
|
||||
{
|
||||
private int locationX, locationY;
|
||||
|
||||
#region
|
||||
public bool cbT0 = false;
|
||||
public bool cbT1 = false;
|
||||
public bool cbT2 = false;
|
||||
public bool cbSprite = false;
|
||||
public string tbSprite;
|
||||
#endregion
|
||||
public Konami68000Motion()
|
||||
{
|
||||
tbSprite = "0000-4000";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85d3575e43093a54f82622b4c53c1a40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
192
MAME.Unity/Assets/Plugins/UMAME/Motion/m68000Motion.cs
Normal file
192
MAME.Unity/Assets/Plugins/UMAME/Motion/m68000Motion.cs
Normal file
@ -0,0 +1,192 @@
|
||||
using cpu.m68000;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public class M68000Motion
|
||||
{
|
||||
private string[] sde6 = new string[1] { "," }, sde7 = new string[1] { ";" }, sde9 = new string[1] { "$" }, sde10 = new string[] { "+" };
|
||||
private bool bLogNew, bNew;
|
||||
public static int iStatus, iRAddress, iWAddress, iROp, iWOp, iValue;
|
||||
private int PPCTill, PPC, Addr;
|
||||
private ulong CyclesTill, TotalExecutedCycles;
|
||||
private List<int> lsAddr = new List<int>();
|
||||
private List<int> lsPPC = new List<int>();
|
||||
|
||||
|
||||
#region
|
||||
string[] mTxList_tbDs;
|
||||
string[] mTxList_tbAs;
|
||||
Boolean[] mBList_cbDs;
|
||||
Boolean[] mBList_cbAs;
|
||||
List<Boolean> mBList_lsCB;
|
||||
|
||||
string mTx_tbPPC = string.Empty;
|
||||
string mTx_tbOP = string.Empty;
|
||||
Boolean b_cbS = false;
|
||||
Boolean b_cbM = false;
|
||||
Boolean b_cbX = false;
|
||||
Boolean b_cbN = false;
|
||||
Boolean b_cbZ = false;
|
||||
Boolean b_cbV = false;
|
||||
Boolean b_cbC = false;
|
||||
Boolean b_cbPC = false;
|
||||
Boolean b_cbTotal = false;
|
||||
Boolean b_cbLog = false;
|
||||
string mTx_tbIML = string.Empty;
|
||||
string mTx_tbUSP = string.Empty;
|
||||
string mTx_tbSSP = string.Empty;
|
||||
string mTx_tbCycles = string.Empty;
|
||||
string mTx_tbPC = string.Empty;
|
||||
string mTx_tbDisassemble = string.Empty;
|
||||
List<string> mTxList_tbResult = new List<string>();
|
||||
public string mTx_tsslStatus = string.Empty;
|
||||
#endregion
|
||||
|
||||
public enum M68000State
|
||||
{
|
||||
M68000_NONE = 0,
|
||||
M68000_RUN,
|
||||
M68000_STEP,
|
||||
M68000_STEP2,
|
||||
M68000_STEP3,
|
||||
M68000_STOP,
|
||||
}
|
||||
public static M68000State m68000State, m68000FState;
|
||||
public M68000Motion()
|
||||
{
|
||||
int i;
|
||||
mTxList_tbDs = new string[8];
|
||||
mTxList_tbAs = new string[8];
|
||||
mBList_cbDs = new bool[8];
|
||||
mBList_cbAs = new bool[8];
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mTxList_tbDs[i] = string.Empty;
|
||||
mBList_cbDs[i] = false;
|
||||
mTxList_tbAs[i] = string.Empty;
|
||||
mBList_cbAs[i] = false;
|
||||
}
|
||||
|
||||
b_cbPC = false;
|
||||
b_cbTotal = false;
|
||||
mBList_lsCB = new List<bool>();
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mBList_lsCB.Add(mBList_cbDs[i]);
|
||||
mBList_lsCB.Add(mBList_cbAs[i]);
|
||||
}
|
||||
mBList_lsCB.Add(b_cbPC);
|
||||
}
|
||||
public void GetData()
|
||||
{
|
||||
int i;
|
||||
string sDisassemble, sDisassemble2 = "";
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mTxList_tbDs[i] = MC68000.m1.D[i].u32.ToString("X8");
|
||||
mTxList_tbAs[i] = MC68000.m1.A[i].u32.ToString("X8");
|
||||
}
|
||||
mTx_tbPPC = MC68000.m1.PPC.ToString("X6");
|
||||
mTx_tbOP = MC68000.m1.op.ToString("X4");
|
||||
b_cbS = MC68000.m1.S;
|
||||
b_cbM = MC68000.m1.M;
|
||||
b_cbX = MC68000.m1.X;
|
||||
b_cbN = MC68000.m1.N;
|
||||
b_cbZ = MC68000.m1.Z;
|
||||
b_cbV = MC68000.m1.V;
|
||||
b_cbC = MC68000.m1.C;
|
||||
mTx_tbIML = MC68000.m1.InterruptMaskLevel.ToString();
|
||||
mTx_tbUSP = MC68000.m1.usp.ToString("X8");
|
||||
mTx_tbSSP = MC68000.m1.ssp.ToString("X8");
|
||||
mTx_tbCycles = MC68000.m1.TotalExecutedCycles.ToString("X16");
|
||||
mTx_tbPC = MC68000.m1.PC.ToString("X6");
|
||||
sDisassemble = MC68000.m1.Disassemble(MC68000.m1.PPC).ToString();
|
||||
mTx_tbDisassemble = sDisassemble;
|
||||
sDisassemble2 = sDisassemble;
|
||||
foreach (bool cb in mBList_lsCB)
|
||||
{
|
||||
if (cb)
|
||||
{
|
||||
//sDisassemble2 += " " + cb + cb.TB.Text;
|
||||
sDisassemble2 += " " + cb + cb;
|
||||
}
|
||||
}
|
||||
if (b_cbTotal)
|
||||
{
|
||||
sDisassemble2 = MC68000.m1.TotalExecutedCycles.ToString("X") + " " + sDisassemble2;
|
||||
}
|
||||
mTxList_tbResult.Add(sDisassemble2 + "\r\n");
|
||||
}
|
||||
public void m68000_start_debug()
|
||||
{
|
||||
if (bLogNew && lsPPC.IndexOf(MC68000.m1.PPC) < 0)
|
||||
{
|
||||
m68000FState = m68000State;
|
||||
m68000State = M68000State.M68000_STOP;
|
||||
lsPPC.Add(MC68000.m1.PPC);
|
||||
mTxList_tbResult.Add(MC68000.m1.Disassemble(MC68000.m1.PPC).ToString() + "\r\n");
|
||||
m68000State = m68000FState;
|
||||
}
|
||||
PPC = MC68000.m1.PPC;
|
||||
TotalExecutedCycles = MC68000.m1.TotalExecutedCycles;
|
||||
if (iStatus == 1)
|
||||
{
|
||||
iStatus = 0;
|
||||
}
|
||||
if (m68000State == M68000State.M68000_STEP2)
|
||||
{
|
||||
if (MC68000.m1.PPC == PPCTill)
|
||||
{
|
||||
m68000State = M68000State.M68000_STOP;
|
||||
}
|
||||
}
|
||||
if (m68000State == M68000State.M68000_STEP3)
|
||||
{
|
||||
if (MC68000.m1.TotalExecutedCycles >= CyclesTill)
|
||||
{
|
||||
m68000State = M68000State.M68000_STOP;
|
||||
}
|
||||
}
|
||||
if (b_cbLog == true && (m68000State == M68000State.M68000_STEP2 || m68000State == M68000State.M68000_STEP3))
|
||||
{
|
||||
GetData();
|
||||
}
|
||||
if (m68000State == M68000State.M68000_STOP)
|
||||
{
|
||||
GetData();
|
||||
mTx_tsslStatus = "m68000 stop";
|
||||
}
|
||||
while (m68000State == M68000State.M68000_STOP)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
public void m68000_stop_debug()
|
||||
{
|
||||
if (iStatus == 1)
|
||||
{
|
||||
GetData();
|
||||
m68000State = M68000State.M68000_STOP;
|
||||
mTx_tsslStatus = "m68000 stop";
|
||||
iStatus = 2;
|
||||
}
|
||||
if (m68000State == M68000State.M68000_STEP)
|
||||
{
|
||||
m68000State = M68000State.M68000_STOP;
|
||||
mTx_tsslStatus = "m68000 stop";
|
||||
}
|
||||
if (iStatus == 0)
|
||||
{
|
||||
/*if(Memory.mainram[0xd1b]==0x05)
|
||||
{
|
||||
iStatus = 1;
|
||||
GetData();
|
||||
m68000State = M68000State.M68000_STOP;
|
||||
tsslStatus.Text = "m68000 stop";
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Motion/m68000Motion.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Motion/m68000Motion.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43abb82203533b94fa07632370f6ca15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
105
MAME.Unity/Assets/Plugins/UMAME/Motion/m6809Motion.cs
Normal file
105
MAME.Unity/Assets/Plugins/UMAME/Motion/m6809Motion.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using cpu.m6809;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
|
||||
public partial class M6809Motion
|
||||
{
|
||||
//private Disassembler disassembler;
|
||||
private bool bLogNew;
|
||||
public static int iStatus;
|
||||
private int PPCTill;
|
||||
private ulong CyclesTill;
|
||||
private List<ushort> lPPC = new List<ushort>();
|
||||
public static CPUState m6809State, m6809FState;
|
||||
|
||||
#region
|
||||
public List<string> tbResult = new List<string>();
|
||||
public string tsslStatus = string.Empty;
|
||||
public string tbD = string.Empty;
|
||||
public string tbDp = string.Empty;
|
||||
public string tbU = string.Empty;
|
||||
public string tbS = string.Empty;
|
||||
public string tbX = string.Empty;
|
||||
public string tbY = string.Empty;
|
||||
public string tbCc = string.Empty;
|
||||
public string tbIrqstate0 = string.Empty;
|
||||
public string tbIrqstate1 = string.Empty;
|
||||
public string tbIntstate = string.Empty;
|
||||
public string tbNmistate = string.Empty;
|
||||
public string tbPPC = string.Empty;
|
||||
public string tbCycles = string.Empty;
|
||||
public string tbDisassemble = string.Empty;
|
||||
#endregion
|
||||
|
||||
public M6809Motion()
|
||||
{
|
||||
}
|
||||
public void GetData()
|
||||
{
|
||||
int reg, offset;
|
||||
reg = M6809.mm1[0].PPC.LowWord / 0x2000;
|
||||
offset = M6809.mm1[0].PPC.LowWord & 0x1fff;
|
||||
tbD = M6809.mm1[0].D.LowWord.ToString("X4");
|
||||
tbDp = M6809.mm1[0].DP.LowWord.ToString("X4");
|
||||
tbU = M6809.mm1[0].U.LowWord.ToString("X4");
|
||||
tbS = M6809.mm1[0].S.LowWord.ToString("X4");
|
||||
tbX = M6809.mm1[0].X.LowWord.ToString("X4");
|
||||
tbY = M6809.mm1[0].Y.LowWord.ToString("X4");
|
||||
tbCc = M6809.mm1[0].CC.ToString("X2");
|
||||
tbIrqstate0 = M6809.mm1[0].irq_state[0].ToString("X2");
|
||||
tbIrqstate1 = M6809.mm1[0].irq_state[1].ToString("X2");
|
||||
tbIntstate = M6809.mm1[0].int_state.ToString("X2");
|
||||
tbNmistate = M6809.mm1[0].nmi_state.ToString("X2");
|
||||
tbPPC = (Namcos1.user1rom_offset[0, reg] + offset).ToString("X6");
|
||||
tbCycles = M6809.mm1[0].TotalExecutedCycles.ToString("X16");
|
||||
tbDisassemble = M6809.mm1[0].m6809_dasm(M6809.mm1[0].PPC.LowWord);
|
||||
|
||||
}
|
||||
public void m6809_start_debug()
|
||||
{
|
||||
if (bLogNew && lPPC.IndexOf(M6809.mm1[0].PPC.LowWord) < 0)
|
||||
{
|
||||
m6809FState = m6809State;
|
||||
m6809State = CPUState.STOP;
|
||||
lPPC.Add(M6809.mm1[0].PPC.LowWord);
|
||||
tbResult.Add(M6809.mm1[0].PPC.LowWord.ToString("X4") + ": ");
|
||||
m6809State = m6809FState;
|
||||
}
|
||||
if (m6809State == CPUState.STEP2)
|
||||
{
|
||||
if (M6809.mm1[0].PPC.LowWord == PPCTill)
|
||||
{
|
||||
m6809State = CPUState.STOP;
|
||||
}
|
||||
}
|
||||
if (m6809State == CPUState.STEP3)
|
||||
{
|
||||
if (M6809.mm1[0].TotalExecutedCycles >= CyclesTill)
|
||||
{
|
||||
m6809State = CPUState.STOP;
|
||||
}
|
||||
}
|
||||
if (m6809State == CPUState.STOP)
|
||||
{
|
||||
GetData();
|
||||
tsslStatus = "m6809 stop";
|
||||
}
|
||||
while (m6809State == CPUState.STOP)
|
||||
{
|
||||
Video.video_frame_update();
|
||||
//??
|
||||
//Application.DoEvents();
|
||||
}
|
||||
}
|
||||
public void m6809_stop_debug()
|
||||
{
|
||||
if (m6809State == CPUState.STEP)
|
||||
{
|
||||
m6809State = CPUState.STOP;
|
||||
tsslStatus = "m6809 stop";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Motion/m6809Motion.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Motion/m6809Motion.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c291a8abf15d254596af257bb937441
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
36
MAME.Unity/Assets/Plugins/UMAME/Motion/neogeoMotion.cs
Normal file
36
MAME.Unity/Assets/Plugins/UMAME/Motion/neogeoMotion.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public partial class NeogeoMotion
|
||||
{
|
||||
private string[] sde2 = new string[] { "," };
|
||||
private int locationX, locationY;
|
||||
public List<string> tbResult;
|
||||
public string tbSprite = string.Empty;
|
||||
public string tbPoint = string.Empty;
|
||||
public string tbFile = string.Empty;
|
||||
public string tbSOffset = string.Empty;
|
||||
public string tbPensoffset = string.Empty;
|
||||
|
||||
#region
|
||||
bool cbL0 = false;
|
||||
bool cbL1 = false;
|
||||
#endregion
|
||||
public NeogeoMotion()
|
||||
{
|
||||
tbResult = new List<string>();
|
||||
neogeoForm_Load();
|
||||
}
|
||||
private void neogeoForm_Load()
|
||||
{
|
||||
cbL0 = true;
|
||||
cbL1 = true;
|
||||
tbSprite = "000-17C";
|
||||
tbFile = "00";
|
||||
tbPoint = "350,240,30,16";
|
||||
tbSOffset = "01cb0600";
|
||||
tbPensoffset = "ed0";
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Motion/neogeoMotion.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Motion/neogeoMotion.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1dce3116faca2f43a19f5e965e245e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
132
MAME.Unity/Assets/Plugins/UMAME/Motion/z80Motion.cs
Normal file
132
MAME.Unity/Assets/Plugins/UMAME/Motion/z80Motion.cs
Normal file
@ -0,0 +1,132 @@
|
||||
using cpu.z80;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public enum CPUState
|
||||
{
|
||||
NONE = 0,
|
||||
RUN,
|
||||
STEP,
|
||||
STEP2,
|
||||
STEP3,
|
||||
STOP,
|
||||
}
|
||||
public partial class Z80Motion
|
||||
{
|
||||
private Disassembler disassembler;
|
||||
private bool bLogNew;
|
||||
public static int iStatus;
|
||||
private int PPCTill;
|
||||
private ulong CyclesTill;
|
||||
private List<ushort> lPPC = new List<ushort>();
|
||||
|
||||
#region
|
||||
string mTx_tbAF = string.Empty;
|
||||
string mTx_tbBC = string.Empty;
|
||||
string mTx_tbDE = string.Empty;
|
||||
string mTx_tbHL = string.Empty;
|
||||
string mTx_tbShadowAF = string.Empty;
|
||||
string mTx_tbShadowBC = string.Empty;
|
||||
string mTx_tbShadowDE = string.Empty;
|
||||
string mTx_tbShadowHL = string.Empty;
|
||||
string mTx_tbI = string.Empty;
|
||||
string mTx_tbR = string.Empty;
|
||||
string mTx_tbIX = string.Empty;
|
||||
string mTx_tbIY = string.Empty;
|
||||
string mTx_tbSP = string.Empty;
|
||||
string mTx_tbRPC = string.Empty;
|
||||
string mTx_tbPPC = string.Empty;
|
||||
string mTx_tbR2 = string.Empty;
|
||||
string mTx_tbWZ = string.Empty;
|
||||
string mTx_tbCycles = string.Empty;
|
||||
string mTx_tbDisassemble = string.Empty;
|
||||
|
||||
public string mTx_tsslStatus = string.Empty;
|
||||
List<string> mTxList_tbResult = new List<string>();
|
||||
#endregion
|
||||
public enum Z80AState
|
||||
{
|
||||
Z80A_NONE = 0,
|
||||
Z80A_RUN,
|
||||
Z80A_STEP,
|
||||
Z80A_STEP2,
|
||||
Z80A_STEP3,
|
||||
Z80A_STOP,
|
||||
}
|
||||
public static Z80AState z80State, z80FState;
|
||||
public Z80Motion()
|
||||
{
|
||||
disassembler = new Disassembler();
|
||||
Disassembler.GenerateOpcodeSizes();
|
||||
}
|
||||
|
||||
public void GetData()
|
||||
{
|
||||
string sDisassemble;
|
||||
mTx_tbAF = Z80A.zz1[0].RegisterAF.ToString("X4");
|
||||
mTx_tbBC = Z80A.zz1[0].RegisterBC.ToString("X4");
|
||||
mTx_tbDE = Z80A.zz1[0].RegisterDE.ToString("X4");
|
||||
mTx_tbHL = Z80A.zz1[0].RegisterHL.ToString("X4");
|
||||
mTx_tbShadowAF = Z80A.zz1[0].RegisterShadowAF.ToString("X4");
|
||||
mTx_tbShadowBC = Z80A.zz1[0].RegisterShadowBC.ToString("X4");
|
||||
mTx_tbShadowDE = Z80A.zz1[0].RegisterShadowDE.ToString("X4");
|
||||
mTx_tbShadowHL = Z80A.zz1[0].RegisterShadowHL.ToString("X4");
|
||||
mTx_tbI = Z80A.zz1[0].RegisterI.ToString("X2");
|
||||
mTx_tbR = Z80A.zz1[0].RegisterR.ToString("X2");
|
||||
mTx_tbIX = Z80A.zz1[0].RegisterIX.ToString("X4");
|
||||
mTx_tbIY = Z80A.zz1[0].RegisterIY.ToString("X4");
|
||||
mTx_tbSP = Z80A.zz1[0].RegisterSP.ToString("X4");
|
||||
mTx_tbRPC = Z80A.zz1[0].RegisterPC.ToString("X4");
|
||||
mTx_tbPPC = Z80A.zz1[0].PPC.ToString("X4");
|
||||
mTx_tbR2 = Z80A.zz1[0].RegisterR2.ToString("X2");
|
||||
mTx_tbWZ = Z80A.zz1[0].RegisterWZ.ToString("X4");
|
||||
mTx_tbCycles = Z80A.zz1[0].TotalExecutedCycles.ToString("X16");
|
||||
sDisassemble = disassembler.GetDisassembleInfo(Z80A.zz1[0].PPC);
|
||||
mTx_tbDisassemble = sDisassemble;
|
||||
mTxList_tbResult.Add(sDisassemble + "\r\n");
|
||||
}
|
||||
public void z80_start_debug()
|
||||
{
|
||||
if (bLogNew && lPPC.IndexOf(Z80A.zz1[0].PPC) < 0)
|
||||
{
|
||||
z80FState = z80State;
|
||||
z80State = Z80AState.Z80A_STOP;
|
||||
lPPC.Add(Z80A.zz1[0].PPC);
|
||||
mTxList_tbResult.Add(Z80A.zz1[0].PPC.ToString("X4") + ": " + disassembler.GetDisassembleInfo(Z80A.zz1[0].PPC) + "\r\n");
|
||||
z80State = z80FState;
|
||||
}
|
||||
if (z80State == Z80AState.Z80A_STEP2)
|
||||
{
|
||||
if (Z80A.zz1[0].PPC == PPCTill)
|
||||
{
|
||||
z80State = Z80AState.Z80A_STOP;
|
||||
}
|
||||
}
|
||||
if (z80State == Z80AState.Z80A_STEP3)
|
||||
{
|
||||
if (Z80A.zz1[0].TotalExecutedCycles >= CyclesTill)
|
||||
{
|
||||
z80State = Z80AState.Z80A_STOP;
|
||||
}
|
||||
}
|
||||
if (z80State == Z80AState.Z80A_STOP)
|
||||
{
|
||||
GetData();
|
||||
mTx_tsslStatus = "z80 stop";
|
||||
}
|
||||
while (z80State == Z80AState.Z80A_STOP)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
public void z80_stop_debug()
|
||||
{
|
||||
if (z80State == Z80AState.Z80A_STEP)
|
||||
{
|
||||
z80State = Z80AState.Z80A_STOP;
|
||||
mTx_tsslStatus = "z80 stop";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/Motion/z80Motion.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/Motion/z80Motion.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cb936512a0186e449fa3a9053127b42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/Properties.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/Properties.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0f2056e5d40c9e4b87a70bb42c0665d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87f805602538c22479c796f78f64b052
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\netstandard2.0\publish\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e66dd647cf36e64eba535a9422b5dfd
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2024-08-30T07:41:53.2597006Z||;True|2024-08-29T17:00:35.4694695+08:00||;True|2024-08-29T16:40:23.7314446+08:00||;True|2024-08-29T16:17:16.6219882+08:00||;False|2024-08-29T15:55:34.5778980+08:00||;True|2024-08-29T15:34:15.1410739+08:00||;False|2024-08-29T15:31:15.0815441+08:00||;False|2024-08-29T15:29:46.6749330+08:00||;False|2024-08-29T15:27:48.9116490+08:00||;False|2024-08-29T15:27:23.2208875+08:00||;True|2024-08-28T16:12:23.3416224+08:00||;True|2024-08-28T13:18:21.7983285+08:00||;True|2024-08-28T12:54:14.9742502+08:00||;True|2024-08-28T12:09:37.5280942+08:00||;True|2024-08-28T12:07:03.6717540+08:00||;True|2024-08-07T18:02:59.4096796+08:00||;False|2024-08-07T18:02:44.0239078+08:00||;True|2024-07-31T17:00:23.0585720+08:00||;True|2024-07-31T17:00:19.8123170+08:00||;True|2024-07-30T20:51:40.9773933+08:00||;True|2024-07-30T17:04:12.3440051+08:00||;True|2024-07-30T17:01:28.0849009+08:00||;True|2024-07-30T10:36:57.5301145+08:00||;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5cd247a5a04ff44bbdce6ed08ab6ccb
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/TimeSpan.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/TimeSpan.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69d9e952f0a1b3349b7127b9f01238f3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
13
MAME.Unity/Assets/Plugins/UMAME/TimeSpan/AxiTimeSpan.cs
Normal file
13
MAME.Unity/Assets/Plugins/UMAME/TimeSpan/AxiTimeSpan.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using MAME.Core;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public static class AxiTimeSpan
|
||||
{
|
||||
public static ITimeSpan itime { get; private set; }
|
||||
public static void Init(ITimeSpan itimespan)
|
||||
{
|
||||
itime = itimespan;
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/TimeSpan/AxiTimeSpan.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/TimeSpan/AxiTimeSpan.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13fc2a860c40ef54b917a94ebf44f187
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/cpu.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/cpu.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5256a2747754bc84095436214447d27b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efa49c62f62f6f048a465cb5e940eeae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
187
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ill02.cs
Normal file
187
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ill02.cs
Normal file
@ -0,0 +1,187 @@
|
||||
namespace cpu.m6502
|
||||
{
|
||||
public partial class M6502
|
||||
{
|
||||
private void ANC(int tmp)
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
a = (byte)(a & tmp);
|
||||
if ((a & 0x80) != 0)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void ASR(ref int tmp)
|
||||
{
|
||||
tmp &= a;
|
||||
LSR(ref tmp);
|
||||
}
|
||||
private void AST(int tmp)
|
||||
{
|
||||
sp.LowByte &= (byte)tmp;
|
||||
a = x = sp.LowByte;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void ARR(ref int tmp)
|
||||
{
|
||||
if ((p & F_D) != 0)
|
||||
{
|
||||
int lo, hi, t;
|
||||
tmp &= a;
|
||||
t = tmp;
|
||||
hi = tmp & 0xf0;
|
||||
lo = tmp & 0x0f;
|
||||
if ((p & F_C) != 0)
|
||||
{
|
||||
tmp = (tmp >> 1) | 0x80;
|
||||
p |= F_N;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp >>= 1;
|
||||
p &= (byte)~F_N;
|
||||
}
|
||||
if (tmp != 0)
|
||||
{
|
||||
p &= (byte)~F_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
p |= F_Z;
|
||||
}
|
||||
if (((t ^ tmp) & 0x40) != 0)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
else
|
||||
{
|
||||
p &= (byte)~F_V;
|
||||
}
|
||||
if (lo + (lo & 0x01) > 0x05)
|
||||
{
|
||||
tmp = (tmp & 0xf0) | ((tmp + 6) & 0xf);
|
||||
}
|
||||
if (hi + (hi & 0x10) > 0x50)
|
||||
{
|
||||
p |= F_C;
|
||||
tmp = (tmp + 0x60) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp &= a;
|
||||
ROR(ref tmp);
|
||||
p &= (byte)~(F_V | F_C);
|
||||
if ((tmp & 0x40) != 0)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
if ((tmp & 0x60) == 0x20 || (tmp & 0x60) == 0x40)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void ASX(int tmp)
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
x &= a;
|
||||
if (x >= tmp)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
x = (byte)(x - tmp);
|
||||
SET_NZ(x);
|
||||
}
|
||||
private void AXA(int tmp)
|
||||
{
|
||||
a = (byte)((a | 0xee) & x & tmp);
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void DCP(ref int tmp)
|
||||
{
|
||||
tmp = (byte)(tmp - 1);
|
||||
p &= (byte)~F_C;
|
||||
if (a >= tmp)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
SET_NZ((byte)(a - tmp));
|
||||
}
|
||||
private void ISB(ref int tmp)
|
||||
{
|
||||
tmp = (byte)(tmp + 1);
|
||||
SBC(tmp);
|
||||
}
|
||||
private void LAX(int tmp)
|
||||
{
|
||||
a = x = (byte)tmp;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void OAL(int tmp)
|
||||
{
|
||||
a = x = (byte)((a | 0xee) & tmp);
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void RLA(ref int tmp)
|
||||
{
|
||||
tmp = (tmp << 1) | (p & F_C);
|
||||
p = (byte)((p & ~F_C) | ((tmp >> 8) & F_C));
|
||||
tmp = (byte)tmp;
|
||||
a &= (byte)tmp;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void RRA(ref int tmp)
|
||||
{
|
||||
tmp |= (p & F_C) << 8;
|
||||
p = (byte)((p & ~F_C) | (tmp & F_C));
|
||||
tmp = (byte)(tmp >> 1);
|
||||
ADC(tmp);
|
||||
}
|
||||
private void SAX(ref int tmp)
|
||||
{
|
||||
tmp = a & x;
|
||||
}
|
||||
private void SLO(ref int tmp)
|
||||
{
|
||||
p = (byte)((p & ~F_C) | ((tmp >> 7) & F_C));
|
||||
tmp = (byte)(tmp << 1);
|
||||
a |= (byte)tmp;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void SRE(ref int tmp)
|
||||
{
|
||||
p = (byte)((p & ~F_C) | (tmp & F_C));
|
||||
tmp = (byte)tmp >> 1;
|
||||
a ^= (byte)tmp;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void SAH(ref int tmp)
|
||||
{
|
||||
tmp = a & x & (ea.HighByte + 1);
|
||||
}
|
||||
private void SSH(ref int tmp)
|
||||
{
|
||||
sp.LowByte = (byte)(a & x);
|
||||
tmp = sp.LowByte & (ea.HighByte + 1);
|
||||
}
|
||||
private void SXH(ref int tmp)
|
||||
{
|
||||
tmp = x & (ea.HighByte + 1);
|
||||
}
|
||||
private void SYH(ref int tmp)
|
||||
{
|
||||
tmp = y & (ea.HighByte + 1);
|
||||
}
|
||||
private void KIL()
|
||||
{
|
||||
pc.LowWord--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ill02.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ill02.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f888c964f0338f48a49e0eaedeb54ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
273
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502.cs
Normal file
273
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502.cs
Normal file
@ -0,0 +1,273 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.IO;
|
||||
//using System.IO;
|
||||
|
||||
namespace cpu.m6502
|
||||
{
|
||||
public partial class M6502 : cpuexec_data
|
||||
{
|
||||
public static M6502[] mm1;
|
||||
public Action[] insn, insn6502;
|
||||
public byte subtype;
|
||||
public Register ppc, pc, sp, zp, ea;
|
||||
public byte p, a, x, y, pending_irq, after_cli, nmi_state, irq_state, so_state;
|
||||
public delegate int irq_delegate(int i);
|
||||
public irq_delegate irq_callback;
|
||||
public delegate byte read8handler(ushort offset);
|
||||
public delegate void write8handler(ushort offset, byte value);
|
||||
public read8handler rdmem_id;
|
||||
public write8handler wrmem_id;
|
||||
private ushort M6502_NMI_VEC = 0xfffa, M6502_RST_VEC = 0xfffc, M6502_IRQ_VEC = 0xfffe;
|
||||
private int M6502_SET_OVERFLOW = 1;
|
||||
private int m6502_IntOccured;
|
||||
protected ulong totalExecutedCycles;
|
||||
protected int pendingCycles;
|
||||
public override ulong TotalExecutedCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalExecutedCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
totalExecutedCycles = value;
|
||||
}
|
||||
}
|
||||
public override int PendingCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return pendingCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
pendingCycles = value;
|
||||
}
|
||||
}
|
||||
public Func<ushort, byte> ReadOp, ReadOpArg;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
public byte default_rdmem_id(ushort offset)
|
||||
{
|
||||
return ReadMemory(offset);
|
||||
}
|
||||
private void default_wdmem_id(ushort offset, byte data)
|
||||
{
|
||||
WriteMemory(offset, data);
|
||||
}
|
||||
public M6502()
|
||||
{
|
||||
insn6502 = new Action[]{
|
||||
m6502_00,m6502_01,m6502_02,m6502_03,m6502_04,m6502_05,m6502_06,m6502_07,
|
||||
m6502_08,m6502_09,m6502_0a,m6502_0b,m6502_0c,m6502_0d,m6502_0e,m6502_0f,
|
||||
m6502_10,m6502_11,m6502_12,m6502_13,m6502_14,m6502_15,m6502_16,m6502_17,
|
||||
m6502_18,m6502_19,m6502_1a,m6502_1b,m6502_1c,m6502_1d,m6502_1e,m6502_1f,
|
||||
m6502_20,m6502_21,m6502_22,m6502_23,m6502_24,m6502_25,m6502_26,m6502_27,
|
||||
m6502_28,m6502_29,m6502_2a,m6502_2b,m6502_2c,m6502_2d,m6502_2e,m6502_2f,
|
||||
m6502_30,m6502_31,m6502_32,m6502_33,m6502_34,m6502_35,m6502_36,m6502_37,
|
||||
m6502_38,m6502_39,m6502_3a,m6502_3b,m6502_3c,m6502_3d,m6502_3e,m6502_3f,
|
||||
m6502_40,m6502_41,m6502_42,m6502_43,m6502_44,m6502_45,m6502_46,m6502_47,
|
||||
m6502_48,m6502_49,m6502_4a,m6502_4b,m6502_4c,m6502_4d,m6502_4e,m6502_4f,
|
||||
m6502_50,m6502_51,m6502_52,m6502_53,m6502_54,m6502_55,m6502_56,m6502_57,
|
||||
m6502_58,m6502_59,m6502_5a,m6502_5b,m6502_5c,m6502_5d,m6502_5e,m6502_5f,
|
||||
m6502_60,m6502_61,m6502_62,m6502_63,m6502_64,m6502_65,m6502_66,m6502_67,
|
||||
m6502_68,m6502_69,m6502_6a,m6502_6b,m6502_6c,m6502_6d,m6502_6e,m6502_6f,
|
||||
m6502_70,m6502_71,m6502_72,m6502_73,m6502_74,m6502_75,m6502_76,m6502_77,
|
||||
m6502_78,m6502_79,m6502_7a,m6502_7b,m6502_7c,m6502_7d,m6502_7e,m6502_7f,
|
||||
m6502_80,m6502_81,m6502_82,m6502_83,m6502_84,m6502_85,m6502_86,m6502_87,
|
||||
m6502_88,m6502_89,m6502_8a,m6502_8b,m6502_8c,m6502_8d,m6502_8e,m6502_8f,
|
||||
m6502_90,m6502_91,m6502_92,m6502_93,m6502_94,m6502_95,m6502_96,m6502_97,
|
||||
m6502_98,m6502_99,m6502_9a,m6502_9b,m6502_9c,m6502_9d,m6502_9e,m6502_9f,
|
||||
m6502_a0,m6502_a1,m6502_a2,m6502_a3,m6502_a4,m6502_a5,m6502_a6,m6502_a7,
|
||||
m6502_a8,m6502_a9,m6502_aa,m6502_ab,m6502_ac,m6502_ad,m6502_ae,m6502_af,
|
||||
m6502_b0,m6502_b1,m6502_b2,m6502_b3,m6502_b4,m6502_b5,m6502_b6,m6502_b7,
|
||||
m6502_b8,m6502_b9,m6502_ba,m6502_bb,m6502_bc,m6502_bd,m6502_be,m6502_bf,
|
||||
m6502_c0,m6502_c1,m6502_c2,m6502_c3,m6502_c4,m6502_c5,m6502_c6,m6502_c7,
|
||||
m6502_c8,m6502_c9,m6502_ca,m6502_cb,m6502_cc,m6502_cd,m6502_ce,m6502_cf,
|
||||
m6502_d0,m6502_d1,m6502_d2,m6502_d3,m6502_d4,m6502_d5,m6502_d6,m6502_d7,
|
||||
m6502_d8,m6502_d9,m6502_da,m6502_db,m6502_dc,m6502_dd,m6502_de,m6502_df,
|
||||
m6502_e0,m6502_e1,m6502_e2,m6502_e3,m6502_e4,m6502_e5,m6502_e6,m6502_e7,
|
||||
m6502_e8,m6502_e9,m6502_ea,m6502_eb,m6502_ec,m6502_ed,m6502_ee,m6502_ef,
|
||||
m6502_f0,m6502_f1,m6502_f2,m6502_f3,m6502_f4,m6502_f5,m6502_f6,m6502_f7,
|
||||
m6502_f8,m6502_f9,m6502_fa,m6502_fb,m6502_fc,m6502_fd,m6502_fe,m6502_ff
|
||||
};
|
||||
insn = insn6502;
|
||||
}
|
||||
public void m6502_common_init(irq_delegate irqcallback)
|
||||
{
|
||||
irq_callback = irqcallback;
|
||||
subtype = 0;
|
||||
rdmem_id = default_rdmem_id;
|
||||
wrmem_id = default_wdmem_id;
|
||||
}
|
||||
public override void Reset()
|
||||
{
|
||||
m6502_reset();
|
||||
}
|
||||
public void m6502_reset()
|
||||
{
|
||||
pc.LowByte = RDMEM(M6502_RST_VEC);
|
||||
pc.HighByte = RDMEM((ushort)(M6502_RST_VEC + 1));
|
||||
sp.d = 0x01ff;
|
||||
p = (byte)(F_T | F_I | F_Z | F_B | (p & F_D));
|
||||
pending_irq = 0;
|
||||
after_cli = 0;
|
||||
irq_state = 0;
|
||||
nmi_state = 0;
|
||||
}
|
||||
public void m6502_take_irq()
|
||||
{
|
||||
if ((p & F_I) == 0)
|
||||
{
|
||||
ea.d = M6502_IRQ_VEC;
|
||||
pendingCycles -= 2;
|
||||
PUSH(pc.HighByte);
|
||||
PUSH(pc.LowByte);
|
||||
PUSH((byte)(p & ~F_B));
|
||||
p |= F_I;
|
||||
pc.LowByte = RDMEM((ushort)ea.d);
|
||||
pc.HighByte = RDMEM((ushort)(ea.d + 1));
|
||||
if (irq_callback != null)
|
||||
{
|
||||
irq_callback(0);
|
||||
}
|
||||
}
|
||||
pending_irq = 0;
|
||||
}
|
||||
public override int ExecuteCycles(int cycles)
|
||||
{
|
||||
return m6502_execute(cycles);
|
||||
}
|
||||
public int m6502_execute(int cycles)
|
||||
{
|
||||
pendingCycles = cycles;
|
||||
do
|
||||
{
|
||||
byte op;
|
||||
ppc.d = pc.d;
|
||||
//debugger_instruction_hook(Machine, PCD);
|
||||
if (pending_irq != 0)
|
||||
{
|
||||
m6502_take_irq();
|
||||
}
|
||||
op = ReadOp(pc.LowWord);
|
||||
pc.LowWord++;
|
||||
pendingCycles -= 1;
|
||||
insn[op]();
|
||||
if (after_cli != 0)
|
||||
{
|
||||
after_cli = 0;
|
||||
if (irq_state != (byte)LineState.CLEAR_LINE)
|
||||
{
|
||||
pending_irq = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pending_irq == 2)
|
||||
{
|
||||
if (m6502_IntOccured - pendingCycles > 1)
|
||||
{
|
||||
pending_irq = 1;
|
||||
}
|
||||
}
|
||||
if (pending_irq == 1)
|
||||
{
|
||||
m6502_take_irq();
|
||||
}
|
||||
if (pending_irq == 2)
|
||||
{
|
||||
pending_irq = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (pendingCycles > 0);
|
||||
return cycles - pendingCycles;
|
||||
}
|
||||
public override void set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
m6502_set_irq_line(irqline, state);
|
||||
}
|
||||
public override void cpunum_set_input_line_and_vector(int cpunum, int line, LineState state, int vector)
|
||||
{
|
||||
EmuTimer.timer_set_internal(Cpuint.cpunum_empty_event_queue, "cpunum_empty_event_queue");
|
||||
}
|
||||
private void m6502_set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
if (irqline == (byte)LineState.INPUT_LINE_NMI)
|
||||
{
|
||||
if (nmi_state == (byte)state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
nmi_state = (byte)state;
|
||||
if (state != LineState.CLEAR_LINE)
|
||||
{
|
||||
ea.d = M6502_NMI_VEC;
|
||||
pendingCycles -= 2;
|
||||
PUSH(pc.HighByte);
|
||||
PUSH(pc.LowByte);
|
||||
PUSH((byte)(p & ~F_B));
|
||||
p |= F_I;
|
||||
pc.LowByte = RDMEM((ushort)ea.d);
|
||||
pc.HighByte = RDMEM((ushort)(ea.d + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (irqline == M6502_SET_OVERFLOW)
|
||||
{
|
||||
if (so_state != 0 && state == 0)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
so_state = (byte)state;
|
||||
return;
|
||||
}
|
||||
irq_state = (byte)state;
|
||||
if (state != LineState.CLEAR_LINE)
|
||||
{
|
||||
pending_irq = 1;
|
||||
m6502_IntOccured = pendingCycles;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(subtype);
|
||||
writer.Write(ppc.LowWord);
|
||||
writer.Write(pc.LowWord);
|
||||
writer.Write(sp.LowWord);
|
||||
writer.Write(p);
|
||||
writer.Write(a);
|
||||
writer.Write(x);
|
||||
writer.Write(y);
|
||||
writer.Write(pending_irq);
|
||||
writer.Write(after_cli);
|
||||
writer.Write(nmi_state);
|
||||
writer.Write(irq_state);
|
||||
writer.Write(so_state);
|
||||
writer.Write(TotalExecutedCycles);
|
||||
writer.Write(PendingCycles);
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
subtype = reader.ReadByte();
|
||||
ppc.LowWord = reader.ReadUInt16();
|
||||
pc.LowWord = reader.ReadUInt16();
|
||||
sp.LowWord = reader.ReadUInt16();
|
||||
p = reader.ReadByte();
|
||||
a = reader.ReadByte();
|
||||
x = reader.ReadByte();
|
||||
y = reader.ReadByte();
|
||||
pending_irq = reader.ReadByte();
|
||||
after_cli = reader.ReadByte();
|
||||
nmi_state = reader.ReadByte();
|
||||
irq_state = reader.ReadByte();
|
||||
so_state = reader.ReadByte();
|
||||
TotalExecutedCycles = reader.ReadUInt64();
|
||||
PendingCycles = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e27c96a34afca8c4f991cc6209a8895e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
293
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502op.cs
Normal file
293
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502op.cs
Normal file
@ -0,0 +1,293 @@
|
||||
namespace cpu.m6502
|
||||
{
|
||||
public partial class M6502
|
||||
{
|
||||
protected void m6502_00() { BRK(); }
|
||||
protected void m6502_20() { JSR(); }
|
||||
protected void m6502_40() { RTI(); }
|
||||
protected void m6502_60() { RTS(); }
|
||||
protected void m6502_80() { int tmp; tmp = RDOPARG(); }
|
||||
protected void m6502_a0() { int tmp; tmp = RDOPARG(); LDY(tmp); }
|
||||
protected void m6502_c0() { int tmp; tmp = RDOPARG(); CPY(tmp); }
|
||||
protected void m6502_e0() { int tmp; tmp = RDOPARG(); CPX(tmp); }
|
||||
|
||||
protected void m6502_10() { BPL(); }
|
||||
protected void m6502_30() { BMI(); }
|
||||
protected void m6502_50() { BVC(); }
|
||||
protected void m6502_70() { BVS(); }
|
||||
protected void m6502_90() { BCC(); }
|
||||
protected void m6502_b0() { BCS(); }
|
||||
protected void m6502_d0() { BNE(); }
|
||||
protected void m6502_f0() { BEQ(); }
|
||||
|
||||
protected void m6502_01() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; ORA(tmp); }
|
||||
protected void m6502_21() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; AND(tmp); }
|
||||
protected void m6502_41() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; EOR(tmp); }
|
||||
protected void m6502_61() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; ADC(tmp); }
|
||||
protected void m6502_81() { int tmp = 0; STA(ref tmp); EA_IDX(); wrmem_id((ushort)ea.d, (byte)tmp); pendingCycles -= 1; }
|
||||
protected void m6502_a1() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; LDA(tmp); }
|
||||
protected void m6502_c1() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; CMP(tmp); }
|
||||
protected void m6502_e1() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; SBC(tmp); }
|
||||
|
||||
protected void m6502_11() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; ORA(tmp); }
|
||||
protected void m6502_31() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; AND(tmp); }
|
||||
protected void m6502_51() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; EOR(tmp); }
|
||||
protected void m6502_71() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; ADC(tmp); }
|
||||
protected void m6502_91() { int tmp = 0; STA(ref tmp); EA_IDY_NP(); wrmem_id((ushort)ea.d, (byte)tmp); pendingCycles -= 1; }
|
||||
protected void m6502_b1() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; LDA(tmp); }
|
||||
protected void m6502_d1() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; CMP(tmp); }
|
||||
protected void m6502_f1() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; SBC(tmp); }
|
||||
|
||||
protected void m6502_02() { KIL(); }
|
||||
protected void m6502_22() { KIL(); }
|
||||
protected void m6502_42() { KIL(); }
|
||||
protected void m6502_62() { KIL(); }
|
||||
protected void m6502_82() { int tmp; tmp = RDOPARG(); }
|
||||
protected void m6502_a2() { int tmp; tmp = RDOPARG(); LDX(tmp); }
|
||||
protected void m6502_c2() { int tmp; tmp = RDOPARG(); }
|
||||
protected void m6502_e2() { int tmp; tmp = RDOPARG(); }
|
||||
|
||||
protected void m6502_12() { KIL(); }
|
||||
protected void m6502_32() { KIL(); }
|
||||
protected void m6502_52() { KIL(); }
|
||||
protected void m6502_72() { KIL(); }
|
||||
protected void m6502_92() { KIL(); }
|
||||
protected void m6502_b2() { KIL(); }
|
||||
protected void m6502_d2() { KIL(); }
|
||||
protected void m6502_f2() { KIL(); }
|
||||
|
||||
protected void m6502_03() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_23() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_43() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_63() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_83() { int tmp = 0; SAX(ref tmp); EA_IDX(); wrmem_id((ushort)ea.d, (byte)tmp); pendingCycles -= 1; }
|
||||
protected void m6502_a3() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; LAX(tmp); }
|
||||
protected void m6502_c3() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_e3() { int tmp; EA_IDX(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_13() { int tmp; EA_IDY_NP(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_33() { int tmp; EA_IDY_NP(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_53() { int tmp; EA_IDY_NP(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_73() { int tmp; EA_IDY_NP(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_93() { int tmp = 0; EA_IDY_NP(); SAH(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_b3() { int tmp; EA_IDY_P(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; LAX(tmp); }
|
||||
protected void m6502_d3() { int tmp; EA_IDY_NP(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_f3() { int tmp; EA_IDY_NP(); tmp = rdmem_id((ushort)ea.d); pendingCycles -= 1; WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_04() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_24() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); BIT(tmp); }
|
||||
protected void m6502_44() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_64() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_84() { int tmp = 0; STY(ref tmp); EA_ZPG(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_a4() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); LDY(tmp); }
|
||||
protected void m6502_c4() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); CPY(tmp); }
|
||||
protected void m6502_e4() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); CPX(tmp); }
|
||||
|
||||
protected void m6502_14() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_34() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_54() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_74() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_94() { int tmp = 0; STY(ref tmp); EA_ZPX(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_b4() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); LDY(tmp); }
|
||||
protected void m6502_d4() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_f4() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); }
|
||||
|
||||
protected void m6502_05() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); ORA(tmp); }
|
||||
protected void m6502_25() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); AND(tmp); }
|
||||
protected void m6502_45() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); EOR(tmp); }
|
||||
protected void m6502_65() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); ADC(tmp); }
|
||||
protected void m6502_85() { int tmp = 0; STA(ref tmp); EA_ZPG(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_a5() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); LDA(tmp); }
|
||||
protected void m6502_c5() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); CMP(tmp); }
|
||||
protected void m6502_e5() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); SBC(tmp); }
|
||||
|
||||
protected void m6502_15() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); ORA(tmp); }
|
||||
protected void m6502_35() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); AND(tmp); }
|
||||
protected void m6502_55() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); EOR(tmp); }
|
||||
protected void m6502_75() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); ADC(tmp); }
|
||||
protected void m6502_95() { int tmp = 0; STA(ref tmp); EA_ZPX(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_b5() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); LDA(tmp); }
|
||||
protected void m6502_d5() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); CMP(tmp); }
|
||||
protected void m6502_f5() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); SBC(tmp); }
|
||||
|
||||
protected void m6502_06() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ASL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_26() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_46() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); LSR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_66() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_86() { int tmp = 0; STX(ref tmp); EA_ZPG(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_a6() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); LDX(tmp); }
|
||||
protected void m6502_c6() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DEC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_e6() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); INC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_16() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ASL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_36() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_56() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); LSR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_76() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_96() { int tmp = 0; STX(ref tmp); EA_ZPY(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_b6() { int tmp; EA_ZPY(); tmp = RDMEM((ushort)ea.d); LDX(tmp); }
|
||||
protected void m6502_d6() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DEC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_f6() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); INC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_07() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_27() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_47() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_67() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_87() { int tmp = 0; SAX(ref tmp); EA_ZPG(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_a7() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); LAX(tmp); }
|
||||
protected void m6502_c7() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_e7() { int tmp; EA_ZPG(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_17() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_37() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_57() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_77() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_97() { int tmp = 0; SAX(ref tmp); EA_ZPY(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_b7() { int tmp; EA_ZPY(); tmp = RDMEM((ushort)ea.d); LAX(tmp); }
|
||||
protected void m6502_d7() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_f7() { int tmp; EA_ZPX(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_08() { RDMEM(pc.LowWord); PHP(); }
|
||||
protected void m6502_28() { RDMEM(pc.LowWord); PLP(); }
|
||||
protected void m6502_48() { RDMEM(pc.LowWord); PHA(); }
|
||||
protected void m6502_68() { RDMEM(pc.LowWord); PLA(); }
|
||||
protected void m6502_88() { RDMEM(pc.LowWord); DEY(); }
|
||||
protected void m6502_a8() { RDMEM(pc.LowWord); TAY(); }
|
||||
protected void m6502_c8() { RDMEM(pc.LowWord); INY(); }
|
||||
protected void m6502_e8() { RDMEM(pc.LowWord); INX(); }
|
||||
|
||||
protected void m6502_18() { RDMEM(pc.LowWord); CLC(); }
|
||||
protected void m6502_38() { RDMEM(pc.LowWord); SEC(); }
|
||||
protected void m6502_58() { RDMEM(pc.LowWord); CLI(); }
|
||||
protected void m6502_78() { RDMEM(pc.LowWord); SEI(); }
|
||||
protected void m6502_98() { RDMEM(pc.LowWord); TYA(); }
|
||||
protected void m6502_b8() { RDMEM(pc.LowWord); CLV(); }
|
||||
protected void m6502_d8() { RDMEM(pc.LowWord); CLD(); }
|
||||
protected void m6502_f8() { RDMEM(pc.LowWord); SED(); }
|
||||
|
||||
protected void m6502_09() { int tmp; tmp = RDOPARG(); ORA(tmp); }
|
||||
protected void m6502_29() { int tmp; tmp = RDOPARG(); AND(tmp); }
|
||||
protected void m6502_49() { int tmp; tmp = RDOPARG(); EOR(tmp); }
|
||||
protected void m6502_69() { int tmp; tmp = RDOPARG(); ADC(tmp); }
|
||||
protected void m6502_89() { int tmp; tmp = RDOPARG(); }
|
||||
protected void m6502_a9() { int tmp; tmp = RDOPARG(); LDA(tmp); }
|
||||
protected void m6502_c9() { int tmp; tmp = RDOPARG(); CMP(tmp); }
|
||||
protected void m6502_e9() { int tmp; tmp = RDOPARG(); SBC(tmp); }
|
||||
|
||||
protected void m6502_19() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); ORA(tmp); }
|
||||
protected void m6502_39() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); AND(tmp); }
|
||||
protected void m6502_59() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); EOR(tmp); }
|
||||
protected void m6502_79() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); ADC(tmp); }
|
||||
protected void m6502_99() { int tmp = 0; STA(ref tmp); EA_ABY_NP(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_b9() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); LDA(tmp); }
|
||||
protected void m6502_d9() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); CMP(tmp); }
|
||||
protected void m6502_f9() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); SBC(tmp); }
|
||||
|
||||
protected void m6502_0a() { int tmp; RDMEM(pc.LowWord); tmp = a; ASL(ref tmp); a = (byte)tmp; }
|
||||
protected void m6502_2a() { int tmp; RDMEM(pc.LowWord); tmp = a; ROL(ref tmp); a = (byte)tmp; }
|
||||
protected void m6502_4a() { int tmp; RDMEM(pc.LowWord); tmp = a; LSR(ref tmp); a = (byte)tmp; }
|
||||
protected void m6502_6a() { int tmp; RDMEM(pc.LowWord); tmp = a; ROR(ref tmp); a = (byte)tmp; }
|
||||
protected void m6502_8a() { RDMEM(pc.LowWord); TXA(); }
|
||||
protected void m6502_aa() { RDMEM(pc.LowWord); TAX(); }
|
||||
protected void m6502_ca() { RDMEM(pc.LowWord); DEX(); }
|
||||
protected void m6502_ea() { RDMEM(pc.LowWord); }
|
||||
|
||||
protected void m6502_1a() { RDMEM(pc.LowWord); }
|
||||
protected void m6502_3a() { RDMEM(pc.LowWord); }
|
||||
protected void m6502_5a() { RDMEM(pc.LowWord); }
|
||||
protected void m6502_7a() { RDMEM(pc.LowWord); }
|
||||
protected void m6502_9a() { RDMEM(pc.LowWord); TXS(); }
|
||||
protected void m6502_ba() { RDMEM(pc.LowWord); TSX(); }
|
||||
protected void m6502_da() { RDMEM(pc.LowWord); }
|
||||
protected void m6502_fa() { RDMEM(pc.LowWord); }
|
||||
|
||||
protected void m6502_0b() { int tmp; tmp = RDOPARG(); ANC(tmp); }
|
||||
protected void m6502_2b() { int tmp; tmp = RDOPARG(); ANC(tmp); }
|
||||
protected void m6502_4b() { int tmp; tmp = RDOPARG(); ASR(ref tmp); a = (byte)tmp; }
|
||||
protected void m6502_6b() { int tmp; tmp = RDOPARG(); ARR(ref tmp); a = (byte)tmp; }
|
||||
protected void m6502_8b() { int tmp; tmp = RDOPARG(); AXA(tmp); }
|
||||
protected void m6502_ab() { int tmp; tmp = RDOPARG(); OAL(tmp); }
|
||||
protected void m6502_cb() { int tmp; tmp = RDOPARG(); ASX(tmp); }
|
||||
protected void m6502_eb() { int tmp; tmp = RDOPARG(); SBC(tmp); }
|
||||
|
||||
protected void m6502_1b() { int tmp; EA_ABY_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_3b() { int tmp; EA_ABY_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_5b() { int tmp; EA_ABY_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_7b() { int tmp; EA_ABY_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_9b() { int tmp = 0; EA_ABY_NP(); SSH(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_bb() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); AST(tmp); }
|
||||
protected void m6502_db() { int tmp; EA_ABY_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_fb() { int tmp; EA_ABY_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_0c() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_2c() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); BIT(tmp); }
|
||||
protected void m6502_4c() { EA_ABS(); JMP(); }
|
||||
protected void m6502_6c() { int tmp; EA_IND(); JMP(); }
|
||||
protected void m6502_8c() { int tmp = 0; STY(ref tmp); EA_ABS(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_ac() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); LDY(tmp); }
|
||||
protected void m6502_cc() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); CPY(tmp); }
|
||||
protected void m6502_ec() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); CPX(tmp); }
|
||||
|
||||
protected void m6502_1c() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_3c() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_5c() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_7c() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_9c() { int tmp = 0; EA_ABX_NP(); SYH(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_bc() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); LDY(tmp); }
|
||||
protected void m6502_dc() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); }
|
||||
protected void m6502_fc() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); }
|
||||
|
||||
protected void m6502_0d() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); ORA(tmp); }
|
||||
protected void m6502_2d() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); AND(tmp); }
|
||||
protected void m6502_4d() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); EOR(tmp); }
|
||||
protected void m6502_6d() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); ADC(tmp); }
|
||||
protected void m6502_8d() { int tmp = 0; STA(ref tmp); EA_ABS(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_ad() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); LDA(tmp); }
|
||||
protected void m6502_cd() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); CMP(tmp); }
|
||||
protected void m6502_ed() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); SBC(tmp); }
|
||||
|
||||
protected void m6502_1d() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); ORA(tmp); }
|
||||
protected void m6502_3d() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); AND(tmp); }
|
||||
protected void m6502_5d() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); EOR(tmp); }
|
||||
protected void m6502_7d() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); ADC(tmp); }
|
||||
protected void m6502_9d() { int tmp = 0; STA(ref tmp); EA_ABX_NP(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_bd() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); LDA(tmp); }
|
||||
protected void m6502_dd() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); CMP(tmp); }
|
||||
protected void m6502_fd() { int tmp; EA_ABX_P(); tmp = RDMEM((ushort)ea.d); SBC(tmp); }
|
||||
|
||||
protected void m6502_0e() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ASL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_2e() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_4e() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); LSR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_6e() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_8e() { int tmp = 0; STX(ref tmp); EA_ABS(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_ae() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); LDX(tmp); }
|
||||
protected void m6502_ce() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DEC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_ee() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); INC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_1e() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ASL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_3e() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROL(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_5e() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); LSR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_7e() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ROR(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_9e() { int tmp = 0; EA_ABY_NP(); SXH(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_be() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); LDX(tmp); }
|
||||
protected void m6502_de() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DEC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_fe() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); INC(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_0f() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_2f() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_4f() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_6f() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_8f() { int tmp = 0; SAX(ref tmp); EA_ABS(); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_af() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); LAX(tmp); }
|
||||
protected void m6502_cf() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_ef() { int tmp; EA_ABS(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
|
||||
protected void m6502_1f() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SLO(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_3f() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RLA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_5f() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); SRE(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_7f() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); RRA(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_9f() { int tmp = 0; EA_ABY_NP(); SAH(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_bf() { int tmp; EA_ABY_P(); tmp = RDMEM((ushort)ea.d); LAX(tmp); }
|
||||
protected void m6502_df() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); DCP(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
protected void m6502_ff() { int tmp; EA_ABX_NP(); tmp = RDMEM((ushort)ea.d); WRMEM((ushort)ea.d, (byte)tmp); ISB(ref tmp); WRMEM((ushort)ea.d, (byte)tmp); }
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502op.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/M6502op.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb223c61fecbecc4fb762d9ebe649194
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
589
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ops02.cs
Normal file
589
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ops02.cs
Normal file
@ -0,0 +1,589 @@
|
||||
using MAME.Core;
|
||||
|
||||
namespace cpu.m6502
|
||||
{
|
||||
public partial class M6502
|
||||
{
|
||||
public byte F_C = 0x01, F_Z = 0x02, F_I = 0x04, F_D = 0x08, F_B = 0x10, F_T = 0x20, F_V = 0x40, F_N = 0x80;
|
||||
private void SET_NZ(byte n)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
p = (byte)((p & ~F_N) | F_Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = (byte)((p & ~(F_N | F_Z)) | (n & F_N));
|
||||
}
|
||||
}
|
||||
private void SET_Z(byte n)
|
||||
{
|
||||
if ((n) == 0)
|
||||
{
|
||||
p |= F_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
p &= (byte)(~F_Z);
|
||||
}
|
||||
}
|
||||
private byte RDOPARG()
|
||||
{
|
||||
byte b1;
|
||||
b1 = ReadOpArg(pc.LowWord++);
|
||||
pendingCycles -= 1;
|
||||
return b1;
|
||||
}
|
||||
private byte RDMEM(ushort addr)
|
||||
{
|
||||
byte b1;
|
||||
b1 = ReadMemory(addr);
|
||||
pendingCycles -= 1;
|
||||
return b1;
|
||||
}
|
||||
private void WRMEM(ushort addr, byte data)
|
||||
{
|
||||
WriteMemory(addr, data);
|
||||
pendingCycles -= 1;
|
||||
}
|
||||
private void BRA(bool cond)
|
||||
{
|
||||
sbyte tmp2 = (sbyte)RDOPARG();
|
||||
if (cond)
|
||||
{
|
||||
RDMEM(pc.LowWord);
|
||||
ea.LowWord = (ushort)(pc.LowWord + (sbyte)tmp2);
|
||||
if (ea.HighByte != pc.HighByte)
|
||||
{
|
||||
RDMEM((ushort)((pc.HighByte << 8) | ea.LowByte));
|
||||
}
|
||||
pc.d = ea.d;
|
||||
}
|
||||
}
|
||||
private void EA_ZPG()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
ea.d = zp.d;
|
||||
}
|
||||
private void EA_ZPX()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
RDMEM((ushort)zp.d);
|
||||
zp.LowByte = (byte)(x + zp.LowByte);
|
||||
ea.d = zp.d;
|
||||
}
|
||||
private void EA_ZPY()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
RDMEM((ushort)zp.d);
|
||||
zp.LowByte = (byte)(y + zp.LowByte);
|
||||
ea.d = zp.d;
|
||||
}
|
||||
private void EA_ABS()
|
||||
{
|
||||
ea.LowByte = RDOPARG();
|
||||
ea.HighByte = RDOPARG();
|
||||
}
|
||||
private void EA_ABX_P()
|
||||
{
|
||||
EA_ABS();
|
||||
if (ea.LowByte + x > 0xff)
|
||||
{
|
||||
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + x) & 0xff)));
|
||||
}
|
||||
ea.LowWord += x;
|
||||
}
|
||||
private void EA_ABX_NP()
|
||||
{
|
||||
EA_ABS();
|
||||
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + x) & 0xff)));
|
||||
ea.LowWord += x;
|
||||
}
|
||||
private void EA_ABY_P()
|
||||
{
|
||||
EA_ABS();
|
||||
if (ea.LowByte + y > 0xff)
|
||||
{
|
||||
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
|
||||
}
|
||||
ea.LowWord += y;
|
||||
}
|
||||
private void EA_ABY_NP()
|
||||
{
|
||||
EA_ABS();
|
||||
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
|
||||
ea.LowWord += y;
|
||||
}
|
||||
private void EA_IDX()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
RDMEM((ushort)zp.d);
|
||||
zp.LowByte = (byte)(zp.LowByte + x);
|
||||
ea.LowByte = RDMEM((ushort)zp.d);
|
||||
zp.LowByte++;
|
||||
ea.HighByte = RDMEM((ushort)zp.d);
|
||||
}
|
||||
private void EA_IDY_P()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
ea.LowByte = RDMEM((ushort)zp.d);
|
||||
zp.LowByte++;
|
||||
ea.HighByte = RDMEM((ushort)zp.d);
|
||||
if (ea.LowByte + y > 0xff)
|
||||
{
|
||||
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
|
||||
}
|
||||
ea.LowWord += y;
|
||||
}
|
||||
private void EA_IDY_NP()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
ea.LowByte = RDMEM((ushort)zp.d);
|
||||
zp.LowByte++;
|
||||
ea.HighByte = RDMEM((ushort)zp.d);
|
||||
RDMEM((ushort)((ea.HighByte << 8) | ((ea.LowByte + y) & 0xff)));
|
||||
ea.LowWord += y;
|
||||
}
|
||||
private void EA_ZPI()
|
||||
{
|
||||
zp.LowByte = RDOPARG();
|
||||
ea.LowByte = RDMEM((ushort)zp.d);
|
||||
zp.LowByte++;
|
||||
ea.HighByte = RDMEM((ushort)zp.d);
|
||||
}
|
||||
private void EA_IND()
|
||||
{
|
||||
byte tmp;
|
||||
EA_ABS();
|
||||
tmp = RDMEM((ushort)ea.d);
|
||||
ea.LowByte++;
|
||||
ea.HighByte = RDMEM((ushort)ea.d);
|
||||
ea.LowByte = tmp;
|
||||
}
|
||||
private void PUSH(byte Rg)
|
||||
{
|
||||
WRMEM((ushort)sp.d, Rg);
|
||||
sp.LowByte--;
|
||||
}
|
||||
private void PULL(ref byte Rg)
|
||||
{
|
||||
sp.LowByte++;
|
||||
Rg = RDMEM((ushort)sp.d);
|
||||
}
|
||||
private void ADC(int tmp)
|
||||
{
|
||||
if ((p & F_D) != 0)
|
||||
{
|
||||
int c = (p & F_C);
|
||||
int lo = (a & 0x0f) + (tmp & 0x0f) + c;
|
||||
int hi = (a & 0xf0) + (tmp & 0xf0);
|
||||
p &= (byte)(~(F_V | F_C | F_N | F_Z));
|
||||
if (((lo + hi) & 0xff) == 0)
|
||||
{
|
||||
p |= F_Z;
|
||||
}
|
||||
if (lo > 0x09)
|
||||
{
|
||||
hi += 0x10;
|
||||
lo += 0x06;
|
||||
}
|
||||
if ((hi & 0x80) != 0)
|
||||
{
|
||||
p |= F_N;
|
||||
}
|
||||
if ((~(a ^ tmp) & (a ^ hi) & F_N) != 0)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
if (hi > 0x90)
|
||||
{
|
||||
hi += 0x60;
|
||||
}
|
||||
if ((hi & 0xff00) != 0)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
a = (byte)((lo & 0x0f) + (hi & 0xf0));
|
||||
}
|
||||
else
|
||||
{
|
||||
int c = (p & F_C);
|
||||
int sum = a + tmp + c;
|
||||
p &= (byte)(~(F_V | F_C));
|
||||
if ((~(a ^ tmp) & (a ^ sum) & F_N) != 0)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
if ((sum & 0xff00) != 0)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
a = (byte)sum;
|
||||
SET_NZ(a);
|
||||
}
|
||||
}
|
||||
private void AND(int tmp)
|
||||
{
|
||||
a = (byte)(a & tmp);
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void ASL(ref int tmp)
|
||||
{
|
||||
p = (byte)((p & ~F_C) | ((tmp >> 7) & F_C));
|
||||
tmp = (byte)(tmp << 1);
|
||||
SET_NZ((byte)tmp);
|
||||
}
|
||||
private void BCC()
|
||||
{
|
||||
BRA((p & F_C) == 0);
|
||||
}
|
||||
private void BCS()
|
||||
{
|
||||
BRA((p & F_C) != 0);
|
||||
}
|
||||
private void BEQ()
|
||||
{
|
||||
BRA((p & F_Z) != 0);
|
||||
}
|
||||
private void BIT(int tmp)
|
||||
{
|
||||
p &= (byte)(~(F_N | F_V | F_Z));
|
||||
p |= (byte)(tmp & (F_N | F_V));
|
||||
if ((tmp & a) == 0)
|
||||
{
|
||||
p |= F_Z;
|
||||
}
|
||||
}
|
||||
private void BMI()
|
||||
{
|
||||
BRA((p & F_N) != 0);
|
||||
}
|
||||
private void BNE()
|
||||
{
|
||||
BRA((p & F_Z) == 0);
|
||||
}
|
||||
private void BPL()
|
||||
{
|
||||
BRA((p & F_N) == 0);
|
||||
}
|
||||
private void BRK()
|
||||
{
|
||||
RDOPARG();
|
||||
PUSH(pc.HighByte);
|
||||
PUSH(pc.LowByte);
|
||||
PUSH((byte)(p | F_B));
|
||||
p = ((byte)(p | F_I));
|
||||
pc.LowByte = RDMEM(M6502_IRQ_VEC);
|
||||
pc.HighByte = RDMEM((ushort)(M6502_IRQ_VEC + 1));
|
||||
}
|
||||
private void BVC()
|
||||
{
|
||||
BRA((p & F_V) == 0);
|
||||
}
|
||||
private void BVS()
|
||||
{
|
||||
BRA((p & F_V) != 0);
|
||||
}
|
||||
private void CLC()
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
}
|
||||
private void CLD()
|
||||
{
|
||||
p &= (byte)~F_D;
|
||||
}
|
||||
private void CLI()
|
||||
{
|
||||
if ((irq_state != (byte)LineState.CLEAR_LINE) && ((p & F_I) != 0))
|
||||
{
|
||||
after_cli = 1;
|
||||
}
|
||||
p &= (byte)~F_I;
|
||||
}
|
||||
private void CLV()
|
||||
{
|
||||
p &= (byte)~F_V;
|
||||
}
|
||||
private void CMP(int tmp)
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
if (a >= tmp)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
SET_NZ((byte)(a - tmp));
|
||||
}
|
||||
private void CPX(int tmp)
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
if (x >= tmp)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
SET_NZ((byte)(x - tmp));
|
||||
}
|
||||
private void CPY(int tmp)
|
||||
{
|
||||
p &= (byte)~F_C;
|
||||
if (y >= tmp)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
SET_NZ((byte)(y - tmp));
|
||||
}
|
||||
private void DEC(ref int tmp)
|
||||
{
|
||||
tmp = (byte)(tmp - 1);
|
||||
SET_NZ((byte)tmp);
|
||||
}
|
||||
private void DEX()
|
||||
{
|
||||
x = (byte)(x - 1);
|
||||
SET_NZ(x);
|
||||
}
|
||||
private void DEY()
|
||||
{
|
||||
y = (byte)(y - 1);
|
||||
SET_NZ(y);
|
||||
}
|
||||
private void EOR(int tmp)
|
||||
{
|
||||
a = (byte)(a ^ tmp);
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void INC(ref int tmp)
|
||||
{
|
||||
tmp = (byte)(tmp + 1);
|
||||
SET_NZ((byte)tmp);
|
||||
}
|
||||
private void INX()
|
||||
{
|
||||
x = (byte)(x + 1);
|
||||
SET_NZ(x);
|
||||
}
|
||||
private void INY()
|
||||
{
|
||||
y = (byte)(y + 1);
|
||||
SET_NZ(y);
|
||||
}
|
||||
private void JMP()
|
||||
{
|
||||
if (ea.d == ppc.d && pending_irq == 0 && after_cli == 0)
|
||||
{
|
||||
if (pendingCycles > 0)
|
||||
{
|
||||
pendingCycles = 0;
|
||||
}
|
||||
}
|
||||
pc.d = ea.d;
|
||||
}
|
||||
private void JSR()
|
||||
{
|
||||
ea.LowByte = RDOPARG();
|
||||
RDMEM((ushort)sp.d);
|
||||
PUSH(pc.HighByte);
|
||||
PUSH(pc.LowByte);
|
||||
ea.HighByte = RDOPARG();
|
||||
pc.d = ea.d;
|
||||
}
|
||||
private void LDA(int tmp)
|
||||
{
|
||||
a = (byte)tmp;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void LDX(int tmp)
|
||||
{
|
||||
x = (byte)tmp;
|
||||
SET_NZ(x);
|
||||
}
|
||||
private void LDY(int tmp)
|
||||
{
|
||||
y = (byte)tmp;
|
||||
SET_NZ(y);
|
||||
}
|
||||
private void LSR(ref int tmp)
|
||||
{
|
||||
p = (byte)((p & ~F_C) | (tmp & F_C));
|
||||
tmp = (byte)tmp >> 1;
|
||||
SET_NZ((byte)tmp);
|
||||
}
|
||||
private void ORA(int tmp)
|
||||
{
|
||||
a = (byte)(a | tmp);
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void PHA()
|
||||
{
|
||||
PUSH(a);
|
||||
}
|
||||
private void PHP()
|
||||
{
|
||||
PUSH(p);
|
||||
}
|
||||
private void PLA()
|
||||
{
|
||||
RDMEM((ushort)sp.d);
|
||||
PULL(ref a);
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void PLP()
|
||||
{
|
||||
RDMEM((ushort)sp.d);
|
||||
if ((p & F_I) != 0)
|
||||
{
|
||||
PULL(ref p);
|
||||
if ((irq_state != (byte)LineState.CLEAR_LINE) && ((p & F_I) == 0))
|
||||
{
|
||||
after_cli = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PULL(ref p);
|
||||
}
|
||||
p |= (byte)(F_T | F_B);
|
||||
}
|
||||
private void ROL(ref int tmp)
|
||||
{
|
||||
tmp = (tmp << 1) | (p & F_C);
|
||||
p = (byte)((p & ~F_C) | ((tmp >> 8) & F_C));
|
||||
tmp = (byte)tmp;
|
||||
SET_NZ((byte)tmp);
|
||||
}
|
||||
private void ROR(ref int tmp)
|
||||
{
|
||||
tmp |= (p & F_C) << 8;
|
||||
p = (byte)((p & ~F_C) | (tmp & F_C));
|
||||
tmp = (byte)(tmp >> 1);
|
||||
SET_NZ((byte)tmp);
|
||||
}
|
||||
private void RTI()
|
||||
{
|
||||
RDOPARG();
|
||||
RDMEM((ushort)sp.d);
|
||||
PULL(ref p);
|
||||
PULL(ref pc.LowByte);
|
||||
PULL(ref pc.HighByte);
|
||||
p |= (byte)(F_T | F_B);
|
||||
if ((irq_state != (byte)LineState.CLEAR_LINE) && ((p & F_I) == 0))
|
||||
{
|
||||
after_cli = 1;
|
||||
}
|
||||
}
|
||||
private void RTS()
|
||||
{
|
||||
RDOPARG();
|
||||
RDMEM((ushort)sp.d);
|
||||
PULL(ref pc.LowByte);
|
||||
PULL(ref pc.HighByte);
|
||||
RDMEM(pc.LowWord);
|
||||
pc.LowWord++;
|
||||
}
|
||||
private void SBC(int tmp)
|
||||
{
|
||||
if ((p & F_D) != 0)
|
||||
{
|
||||
int c = (p & F_C) ^ F_C;
|
||||
int sum = a - tmp - c;
|
||||
int lo = (a & 0x0f) - (tmp & 0x0f) - c;
|
||||
int hi = (a & 0xf0) - (tmp & 0xf0);
|
||||
if ((lo & 0x10) != 0)
|
||||
{
|
||||
lo -= 6;
|
||||
hi--;
|
||||
}
|
||||
p &= (byte)~(F_V | F_C | F_Z | F_N);
|
||||
if (((a ^ tmp) & (a ^ sum) & F_N) != 0)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
if ((hi & 0x0100) != 0)
|
||||
{
|
||||
hi -= 0x60;
|
||||
}
|
||||
if ((sum & 0xff00) == 0)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
if (((a - tmp - c) & 0xff) == 0)
|
||||
{
|
||||
p |= F_Z;
|
||||
}
|
||||
if (((a - tmp - c) & 0x80) != 0)
|
||||
{
|
||||
p |= F_N;
|
||||
}
|
||||
a = (byte)((lo & 0x0f) | (hi & 0xf0));
|
||||
}
|
||||
else
|
||||
{
|
||||
int c = (p & F_C) ^ F_C;
|
||||
int sum = a - tmp - c;
|
||||
p &= (byte)~(F_V | F_C);
|
||||
if (((a ^ tmp) & (a ^ sum) & F_N) != 0)
|
||||
{
|
||||
p |= F_V;
|
||||
}
|
||||
if ((sum & 0xff00) == 0)
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
a = (byte)sum;
|
||||
SET_NZ(a);
|
||||
}
|
||||
}
|
||||
private void SEC()
|
||||
{
|
||||
p |= F_C;
|
||||
}
|
||||
private void SED()
|
||||
{
|
||||
p |= F_D;
|
||||
}
|
||||
private void SEI()
|
||||
{
|
||||
p |= F_I;
|
||||
}
|
||||
private void STA(ref int tmp)
|
||||
{
|
||||
tmp = a;
|
||||
}
|
||||
private void STX(ref int tmp)
|
||||
{
|
||||
tmp = x;
|
||||
}
|
||||
private void STY(ref int tmp)
|
||||
{
|
||||
tmp = y;
|
||||
}
|
||||
private void TAX()
|
||||
{
|
||||
x = a;
|
||||
SET_NZ(x);
|
||||
}
|
||||
private void TAY()
|
||||
{
|
||||
y = a;
|
||||
SET_NZ(y);
|
||||
}
|
||||
private void TSX()
|
||||
{
|
||||
x = sp.LowByte;
|
||||
SET_NZ(x);
|
||||
}
|
||||
private void TXA()
|
||||
{
|
||||
a = x;
|
||||
SET_NZ(a);
|
||||
}
|
||||
private void TXS()
|
||||
{
|
||||
sp.LowByte = x;
|
||||
}
|
||||
private void TYA()
|
||||
{
|
||||
a = y;
|
||||
SET_NZ(a);
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ops02.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6502/Ops02.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df989ce237c20a84aa97ead349d2093e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 317be4f8630ce90409e488310814c936
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1386
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800.cs
Normal file
1386
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b048d365a2726014e8b35b00934ba716
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1889
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800op.cs
Normal file
1889
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800op.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800op.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6800/M6800op.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ac480a98cd915a488d75cf520ceeb12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5363a2171a5a06e458069790876245da
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
144
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Disassembler.cs
Normal file
144
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Disassembler.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using System.Text;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
public sealed class DisassemblyInfo
|
||||
{
|
||||
public int PC;
|
||||
public string Mnemonic;
|
||||
public string Args;
|
||||
public string RawBytes;
|
||||
public int Length;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0:X6}: {3,-20} {1,-8} {2}", PC, Mnemonic, Args, RawBytes);
|
||||
}
|
||||
}
|
||||
|
||||
partial class MC68000
|
||||
{
|
||||
public DisassemblyInfo Disassemble(int pc)
|
||||
{
|
||||
var info = new DisassemblyInfo { Mnemonic = "UNKNOWN", PC = pc, Length = 2 };
|
||||
op = (ushort)ReadOpWord(pc);
|
||||
|
||||
if (Opcodes[op] == MOVE) MOVE_Disasm(info);//
|
||||
else if (Opcodes[op] == MOVEA) MOVEA_Disasm(info);
|
||||
else if (Opcodes[op] == MOVEQ) MOVEQ_Disasm(info);
|
||||
else if (Opcodes[op] == MOVEM0) MOVEM0_Disasm(info);
|
||||
else if (Opcodes[op] == MOVEM1) MOVEM1_Disasm(info);
|
||||
else if (Opcodes[op] == LEA) LEA_Disasm(info);//
|
||||
else if (Opcodes[op] == CLR) CLR_Disasm(info);
|
||||
else if (Opcodes[op] == EXT) EXT_Disasm(info);
|
||||
else if (Opcodes[op] == PEA) PEA_Disasm(info);
|
||||
else if (Opcodes[op] == ANDI) ANDI_Disasm(info);
|
||||
else if (Opcodes[op] == ANDI_CCR) ANDI_CCR_Disasm(info);
|
||||
else if (Opcodes[op] == EORI) EORI_Disasm(info);
|
||||
else if (Opcodes[op] == EORI_CCR) EORI_CCR_Disasm(info);
|
||||
else if (Opcodes[op] == ORI) ORI_Disasm(info);
|
||||
else if (Opcodes[op] == ORI_CCR) ORI_CCR_Disasm(info);
|
||||
else if (Opcodes[op] == ASLd) ASLd_Disasm(info);
|
||||
else if (Opcodes[op] == ASRd) ASRd_Disasm(info);
|
||||
else if (Opcodes[op] == LSLd) LSLd_Disasm(info);
|
||||
else if (Opcodes[op] == LSRd) LSRd_Disasm(info);
|
||||
else if (Opcodes[op] == ROXLd) ROXLd_Disasm(info);
|
||||
else if (Opcodes[op] == ROXRd) ROXRd_Disasm(info);
|
||||
else if (Opcodes[op] == ROLd) ROLd_Disasm(info);
|
||||
else if (Opcodes[op] == RORd) RORd_Disasm(info);
|
||||
else if (Opcodes[op] == ASLd0) ASLd0_Disasm(info);
|
||||
else if (Opcodes[op] == ASRd0) ASRd0_Disasm(info);
|
||||
else if (Opcodes[op] == LSLd0) LSLd0_Disasm(info);
|
||||
else if (Opcodes[op] == LSRd0) LSRd0_Disasm(info);
|
||||
else if (Opcodes[op] == ROXLd0) ROXLd0_Disasm(info);
|
||||
else if (Opcodes[op] == ROXRd0) ROXRd0_Disasm(info);
|
||||
else if (Opcodes[op] == ROLd0) ROLd0_Disasm(info);
|
||||
else if (Opcodes[op] == RORd0) RORd0_Disasm(info);
|
||||
else if (Opcodes[op] == SWAP) SWAP_Disasm(info);
|
||||
else if (Opcodes[op] == AND0) AND0_Disasm(info);
|
||||
else if (Opcodes[op] == AND1) AND1_Disasm(info);
|
||||
else if (Opcodes[op] == EOR) EOR_Disasm(info);
|
||||
else if (Opcodes[op] == OR0) OR0_Disasm(info);
|
||||
else if (Opcodes[op] == OR1) OR1_Disasm(info);
|
||||
else if (Opcodes[op] == NOT) NOT_Disasm(info);
|
||||
else if (Opcodes[op] == NEG) NEG_Disasm(info);
|
||||
else if (Opcodes[op] == JMP) JMP_Disasm(info);
|
||||
else if (Opcodes[op] == JSR) JSR_Disasm(info);
|
||||
else if (Opcodes[op] == Bcc) Bcc_Disasm(info);
|
||||
else if (Opcodes[op] == BRA) BRA_Disasm(info);
|
||||
else if (Opcodes[op] == BSR) BSR_Disasm(info);
|
||||
else if (Opcodes[op] == DBcc) DBcc_Disasm(info);
|
||||
else if (Opcodes[op] == Scc) Scc_Disasm(info);
|
||||
else if (Opcodes[op] == RTE) RTE_Disasm(info);
|
||||
else if (Opcodes[op] == RTS) RTS_Disasm(info);
|
||||
else if (Opcodes[op] == RTR) RTR_Disasm(info);
|
||||
else if (Opcodes[op] == TST) TST_Disasm(info);
|
||||
else if (Opcodes[op] == BTSTi) BTSTi_Disasm(info);
|
||||
else if (Opcodes[op] == BTSTr) BTSTr_Disasm(info);
|
||||
else if (Opcodes[op] == BCHGi) BCHGi_Disasm(info);
|
||||
else if (Opcodes[op] == BCHGr) BCHGr_Disasm(info);
|
||||
else if (Opcodes[op] == BCLRi) BCLRi_Disasm(info);
|
||||
else if (Opcodes[op] == BCLRr) BCLRr_Disasm(info);
|
||||
else if (Opcodes[op] == BSETi) BSETi_Disasm(info);
|
||||
else if (Opcodes[op] == BSETr) BSETr_Disasm(info);
|
||||
else if (Opcodes[op] == LINK) LINK_Disasm(info);
|
||||
else if (Opcodes[op] == UNLK) UNLK_Disasm(info);
|
||||
else if (Opcodes[op] == RESET) RESET_Disasm(info);
|
||||
else if (Opcodes[op] == NOP) NOP_Disasm(info);
|
||||
else if (Opcodes[op] == ADD0) ADD_Disasm(info);
|
||||
else if (Opcodes[op] == ADD1) ADD_Disasm(info);
|
||||
else if (Opcodes[op] == ADDA) ADDA_Disasm(info);
|
||||
else if (Opcodes[op] == ADDI) ADDI_Disasm(info);
|
||||
else if (Opcodes[op] == ADDQ) ADDQ_Disasm(info);
|
||||
else if (Opcodes[op] == SUB0) SUB_Disasm(info);
|
||||
else if (Opcodes[op] == SUB1) SUB_Disasm(info);
|
||||
else if (Opcodes[op] == SUBA) SUBA_Disasm(info);
|
||||
else if (Opcodes[op] == SUBI) SUBI_Disasm(info);
|
||||
else if (Opcodes[op] == SUBQ) SUBQ_Disasm(info);
|
||||
else if (Opcodes[op] == CMP) CMP_Disasm(info);
|
||||
else if (Opcodes[op] == CMPM) CMPM_Disasm(info);
|
||||
else if (Opcodes[op] == CMPA) CMPA_Disasm(info);
|
||||
else if (Opcodes[op] == CMPI) CMPI_Disasm(info);
|
||||
else if (Opcodes[op] == MULU) MULU_Disasm(info);
|
||||
else if (Opcodes[op] == MULS) MULS_Disasm(info);
|
||||
else if (Opcodes[op] == DIVU) DIVU_Disasm(info);
|
||||
else if (Opcodes[op] == DIVS) DIVS_Disasm(info);
|
||||
else if (Opcodes[op] == MOVEtSR) MOVEtSR_Disasm(info);//
|
||||
else if (Opcodes[op] == MOVEfSR) MOVEfSR_Disasm(info);
|
||||
else if (Opcodes[op] == MOVEUSP) MOVEUSP_Disasm(info);
|
||||
else if (Opcodes[op] == ANDI_SR) ANDI_SR_Disasm(info);
|
||||
else if (Opcodes[op] == EORI_SR) EORI_SR_Disasm(info);
|
||||
else if (Opcodes[op] == ORI_SR) ORI_SR_Disasm(info);
|
||||
else if (Opcodes[op] == MOVECCR) MOVECCR_Disasm(info);
|
||||
else if (Opcodes[op] == TRAP) TRAP_Disasm(info);
|
||||
else if (Opcodes[op] == NBCD) NBCD_Disasm(info);
|
||||
else if (Opcodes[op] == ILLEGAL) ILLEGAL_Disasm(info);
|
||||
else if (Opcodes[op] == STOP) STOP_Disasm(info);
|
||||
else if (Opcodes[op] == TRAPV) TRAPV_Disasm(info);
|
||||
else if (Opcodes[op] == CHK) CHK_Disasm(info);
|
||||
else if (Opcodes[op] == NEGX) NEGX_Disasm(info);
|
||||
else if (Opcodes[op] == SBCD0) SBCD0_Disasm(info);
|
||||
else if (Opcodes[op] == SBCD1) SBCD1_Disasm(info);
|
||||
else if (Opcodes[op] == ABCD0) ABCD0_Disasm(info);
|
||||
else if (Opcodes[op] == ABCD1) ABCD1_Disasm(info);
|
||||
else if (Opcodes[op] == EXGdd) EXGdd_Disasm(info);
|
||||
else if (Opcodes[op] == EXGaa) EXGaa_Disasm(info);
|
||||
else if (Opcodes[op] == EXGda) EXGda_Disasm(info);
|
||||
else if (Opcodes[op] == TAS) TAS_Disasm(info);
|
||||
else if (Opcodes[op] == MOVEP) MOVEP_Disasm(info);
|
||||
else if (Opcodes[op] == ADDX0) ADDX0_Disasm(info);
|
||||
else if (Opcodes[op] == ADDX1) ADDX1_Disasm(info);
|
||||
else if (Opcodes[op] == SUBX0) SUBX0_Disasm(info);
|
||||
else if (Opcodes[op] == SUBX1) SUBX1_Disasm(info);
|
||||
else if (Opcodes[op] == ILL) ILL_Disasm(info);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
for (int p = info.PC; p < info.PC + info.Length; p += 2)
|
||||
{
|
||||
sb.AppendFormat("{0:X4} ", ReadOpWord(p));
|
||||
}
|
||||
info.RawBytes = sb.ToString();
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59a132d3fbbd20c488b17cf0b0bedd22
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae3b5a67d5c131646a72ea967ddd303f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d595cf6577109d144b95da9cb77cfdd9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,726 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
partial class MC68000
|
||||
{
|
||||
void MOVE()
|
||||
{
|
||||
int size = ((op >> 12) & 0x03);
|
||||
int dstMode = ((op >> 6) & 0x07);
|
||||
int dstReg = ((op >> 9) & 0x07);
|
||||
int srcMode = ((op >> 3) & 0x07);
|
||||
int srcReg = (op & 0x07);
|
||||
|
||||
int value = 0;
|
||||
switch (size)
|
||||
{
|
||||
case 1: // Byte
|
||||
value = ReadValueB(srcMode, srcReg);
|
||||
WriteValueB(dstMode, dstReg, (sbyte)value);
|
||||
pendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)];
|
||||
N = (value & 0x80) != 0;
|
||||
break;
|
||||
case 3: // Word
|
||||
value = ReadValueW(srcMode, srcReg);
|
||||
WriteValueW(dstMode, dstReg, (short)value);
|
||||
pendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)];
|
||||
N = (value & 0x8000) != 0;
|
||||
break;
|
||||
case 2: // Long
|
||||
value = ReadValueL(srcMode, srcReg);
|
||||
WriteValueL(dstMode, dstReg, value);
|
||||
pendingCycles -= MoveCyclesL[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)];
|
||||
N = (value & 0x80000000) != 0;
|
||||
break;
|
||||
}
|
||||
|
||||
V = false;
|
||||
C = false;
|
||||
Z = (value == 0);
|
||||
}
|
||||
|
||||
void MOVE_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int size = ((op >> 12) & 0x03);
|
||||
int dstMode = ((op >> 6) & 0x07);
|
||||
int dstReg = ((op >> 9) & 0x07);
|
||||
int srcMode = ((op >> 3) & 0x07);
|
||||
int srcReg = (op & 0x07);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
info.Mnemonic = "move.b";
|
||||
info.Args = DisassembleValue(srcMode, srcReg, 1, ref pc) + ", ";
|
||||
info.Args += DisassembleValue(dstMode, dstReg, 1, ref pc);
|
||||
break;
|
||||
case 3:
|
||||
info.Mnemonic = "move.w";
|
||||
info.Args = DisassembleValue(srcMode, srcReg, 2, ref pc) + ", ";
|
||||
info.Args += DisassembleValue(dstMode, dstReg, 2, ref pc);
|
||||
break;
|
||||
case 2:
|
||||
info.Mnemonic = "move.l";
|
||||
info.Args = DisassembleValue(srcMode, srcReg, 4, ref pc) + ", ";
|
||||
info.Args += DisassembleValue(dstMode, dstReg, 4, ref pc);
|
||||
break;
|
||||
}
|
||||
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVEA()
|
||||
{
|
||||
int size = ((op >> 12) & 0x03);
|
||||
int dstReg = ((op >> 9) & 0x07);
|
||||
int srcMode = ((op >> 3) & 0x07);
|
||||
int srcReg = (op & 0x07);
|
||||
|
||||
if (size == 3) // Word
|
||||
{
|
||||
A[dstReg].s32 = ReadValueW(srcMode, srcReg);
|
||||
switch (srcMode)
|
||||
{
|
||||
case 0: pendingCycles -= 4; break;
|
||||
case 1: pendingCycles -= 4; break;
|
||||
case 2: pendingCycles -= 8; break;
|
||||
case 3: pendingCycles -= 8; break;
|
||||
case 4: pendingCycles -= 10; break;
|
||||
case 5: pendingCycles -= 12; break;
|
||||
case 6: pendingCycles -= 14; break;
|
||||
case 7:
|
||||
switch (srcReg)
|
||||
{
|
||||
case 0: pendingCycles -= 12; break;
|
||||
case 1: pendingCycles -= 16; break;
|
||||
case 2: pendingCycles -= 12; break;
|
||||
case 3: pendingCycles -= 14; break;
|
||||
case 4: pendingCycles -= 8; break;
|
||||
default: throw new InvalidOperationException();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Long
|
||||
A[dstReg].s32 = ReadValueL(srcMode, srcReg);
|
||||
switch (srcMode)
|
||||
{
|
||||
case 0: pendingCycles -= 4; break;
|
||||
case 1: pendingCycles -= 4; break;
|
||||
case 2: pendingCycles -= 12; break;
|
||||
case 3: pendingCycles -= 12; break;
|
||||
case 4: pendingCycles -= 14; break;
|
||||
case 5: pendingCycles -= 16; break;
|
||||
case 6: pendingCycles -= 18; break;
|
||||
case 7:
|
||||
switch (srcReg)
|
||||
{
|
||||
case 0: pendingCycles -= 16; break;
|
||||
case 1: pendingCycles -= 20; break;
|
||||
case 2: pendingCycles -= 16; break;
|
||||
case 3: pendingCycles -= 18; break;
|
||||
case 4: pendingCycles -= 12; break;
|
||||
default: throw new InvalidOperationException();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MOVEA_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int size = ((op >> 12) & 0x03);
|
||||
int dstReg = ((op >> 9) & 0x07);
|
||||
int srcMode = ((op >> 3) & 0x07);
|
||||
int srcReg = (op & 0x07);
|
||||
|
||||
if (size == 3)
|
||||
{
|
||||
info.Mnemonic = "movea.w";
|
||||
info.Args = DisassembleValue(srcMode, srcReg, 2, ref pc) + ", A" + dstReg;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.Mnemonic = "movea.l";
|
||||
info.Args = DisassembleValue(srcMode, srcReg, 4, ref pc) + ", A" + dstReg;
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVEP()
|
||||
{
|
||||
int dReg = ((op >> 9) & 0x07);
|
||||
int dir = ((op >> 7) & 0x01);
|
||||
int size = ((op >> 6) & 0x01);
|
||||
int aReg = (op & 0x07);
|
||||
if (dir == 0 && size == 0)
|
||||
{
|
||||
int ea;
|
||||
ea = A[aReg].s32 + ReadOpWord(PC); PC += 2;
|
||||
D[dReg].u32 = (D[dReg].u32 & 0xffff0000) | (ushort)(((byte)ReadByte(ea) << 8) + (byte)ReadByte(ea + 2));
|
||||
pendingCycles -= 16;
|
||||
}
|
||||
else if (dir == 0 && size == 1)
|
||||
{
|
||||
int ea;
|
||||
ea = A[aReg].s32 + ReadOpWord(PC); PC += 2;
|
||||
D[dReg].u32 = (uint)(((byte)ReadByte(ea) << 24) + ((byte)ReadByte(ea + 2) << 16) + ((byte)ReadByte(ea + 4) << 8) + (byte)ReadByte(ea + 6));
|
||||
pendingCycles -= 24;
|
||||
}
|
||||
else if (dir == 1 && size == 0)
|
||||
{
|
||||
uint src;
|
||||
int ea;
|
||||
ea = A[aReg].s32 + ReadOpWord(PC); PC += 2;
|
||||
src = D[dReg].u32;
|
||||
WriteByte(ea, (sbyte)((src >> 8) & 0xff));
|
||||
WriteByte(ea + 2, (sbyte)(src & 0xff));
|
||||
pendingCycles -= 16;
|
||||
}
|
||||
else if (dir == 1 && size == 1)
|
||||
{
|
||||
uint src;
|
||||
int ea;
|
||||
ea = A[aReg].s32 + ReadOpWord(PC); PC += 2;
|
||||
src = D[dReg].u32;
|
||||
WriteByte(ea, (sbyte)((src >> 24) & 0xff));
|
||||
WriteByte(ea + 2, (sbyte)((src >> 16) & 0xff));
|
||||
WriteByte(ea + 4, (sbyte)((src >> 8) & 0xff));
|
||||
WriteByte(ea + 6, (sbyte)(src & 0xff));
|
||||
pendingCycles -= 24;
|
||||
}
|
||||
}
|
||||
|
||||
void MOVEP_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int dReg = ((op >> 9) & 0x07);
|
||||
int dir = ((op >> 7) & 0x01);
|
||||
int size = ((op >> 6) & 0x01);
|
||||
int aReg = (op & 0x07);
|
||||
if (size == 0)
|
||||
{
|
||||
info.Mnemonic = "movep.w";
|
||||
if (dir == 0)
|
||||
{
|
||||
info.Args = DisassembleValue(5, aReg, 2, ref pc) + ", D" + dReg;
|
||||
}
|
||||
else if (dir == 1)
|
||||
{
|
||||
info.Args = "D" + dReg + ", " + DisassembleValue(5, aReg, 2, ref pc);
|
||||
}
|
||||
}
|
||||
else if (size == 1)
|
||||
{
|
||||
info.Mnemonic = "movep.l";
|
||||
if (dir == 0)
|
||||
{
|
||||
info.Args = DisassembleValue(5, aReg, 4, ref pc) + ", D" + dReg;
|
||||
}
|
||||
else if (dir == 1)
|
||||
{
|
||||
info.Args = "D" + dReg + ", " + DisassembleValue(5, aReg, 4, ref pc);
|
||||
}
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVEQ()
|
||||
{
|
||||
int value = (sbyte)op; // 8-bit data payload is sign-extended to 32-bits.
|
||||
N = (value & 0x80) != 0;
|
||||
Z = (value == 0);
|
||||
V = false;
|
||||
C = false;
|
||||
D[(op >> 9) & 7].s32 = value;
|
||||
pendingCycles -= 4;
|
||||
}
|
||||
|
||||
void MOVEQ_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "moveq";
|
||||
info.Args = String.Format("${0:X}, D{1}", (int)((sbyte)op), (op >> 9) & 7);
|
||||
}
|
||||
|
||||
static string DisassembleRegisterList0(ushort registers)
|
||||
{
|
||||
var str = new StringBuilder();
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 0x8000) != 0)
|
||||
{
|
||||
if (count > 0) str.Append(",");
|
||||
str.Append("D" + i);
|
||||
count++;
|
||||
}
|
||||
registers <<= 1;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 0x8000) != 0)
|
||||
{
|
||||
if (count > 0) str.Append(",");
|
||||
str.Append("A" + i);
|
||||
count++;
|
||||
}
|
||||
registers <<= 1;
|
||||
}
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
static string DisassembleRegisterList1(ushort registers)
|
||||
{
|
||||
var str = new StringBuilder();
|
||||
int count = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 1) != 0)
|
||||
{
|
||||
if (count > 0) str.Append(",");
|
||||
str.Append("D" + i);
|
||||
count++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 1) != 0)
|
||||
{
|
||||
if (count > 0) str.Append(",");
|
||||
str.Append("A" + i);
|
||||
count++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
void MOVEM0()
|
||||
{
|
||||
// Move register to memory
|
||||
int size = (op >> 6) & 1;
|
||||
int dstMode = (op >> 3) & 7;
|
||||
int dstReg = (op >> 0) & 7;
|
||||
|
||||
ushort registers = (ushort)ReadOpWord(PC); PC += 2;
|
||||
int address = ReadAddress(dstMode, dstReg);
|
||||
int regCount = 0;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
// word-assign
|
||||
if (dstMode == 4) // decrement address
|
||||
{
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
address -= 2;
|
||||
WriteWord(address, A[i].s16);
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
address -= 2;
|
||||
WriteWord(address, D[i].s16);
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
A[dstReg].s32 = address;
|
||||
}
|
||||
else
|
||||
{ // increment address
|
||||
for (int i = 0; i <= 7; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
WriteWord(address, D[i].s16);
|
||||
address += 2;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 0; i <= 7; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
WriteWord(address, A[i].s16);
|
||||
address += 2;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
}
|
||||
pendingCycles -= regCount * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// long-assign
|
||||
if (dstMode == 4) // decrement address
|
||||
{
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
address -= 4;
|
||||
WriteLong(address, A[i].s32);
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
address -= 4;
|
||||
WriteLong(address, D[i].s32);
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
A[dstReg].s32 = address;
|
||||
}
|
||||
else
|
||||
{ // increment address
|
||||
for (int i = 0; i <= 7; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
WriteLong(address, D[i].s32);
|
||||
address += 4;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 0; i <= 7; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
WriteLong(address, A[i].s32);
|
||||
address += 4;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
}
|
||||
pendingCycles -= regCount * 8;
|
||||
}
|
||||
|
||||
switch (dstMode)
|
||||
{
|
||||
case 2: pendingCycles -= 8; break;
|
||||
case 3: pendingCycles -= 8; break;
|
||||
case 4: pendingCycles -= 8; break;
|
||||
case 5: pendingCycles -= 12; break;
|
||||
case 6: pendingCycles -= 14; break;
|
||||
case 7:
|
||||
switch (dstReg)
|
||||
{
|
||||
case 0: pendingCycles -= 12; break;
|
||||
case 1: pendingCycles -= 16; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MOVEM0_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int size = (op >> 6) & 1;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
ushort registers = (ushort)ReadOpWord(pc); pc += 2;
|
||||
string address = DisassembleAddress(mode, reg, ref pc);
|
||||
|
||||
info.Mnemonic = size == 0 ? "movem.w" : "movem.l";
|
||||
info.Args = DisassembleRegisterList0(registers) + ", " + address;
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVEM1()
|
||||
{
|
||||
// Move memory to register
|
||||
int size = (op >> 6) & 1;
|
||||
int srcMode = (op >> 3) & 7;
|
||||
int srcReg = (op >> 0) & 7;
|
||||
|
||||
ushort registers = (ushort)ReadOpWord(PC); PC += 2;
|
||||
int address = ReadAddress(srcMode, srcReg);
|
||||
int regCount = 0;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
// word-assign
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
if (srcMode == 7 && (srcReg == 2 || srcReg == 3))
|
||||
{
|
||||
D[i].s32 = ReadPcrelWord(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
D[i].s32 = ReadWord(address);
|
||||
}
|
||||
address += 2;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
if (srcMode == 7 && (srcReg == 2 || srcReg == 3))
|
||||
{
|
||||
A[i].s32 = ReadPcrelWord(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
A[i].s32 = ReadWord(address);
|
||||
}
|
||||
address += 2;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
pendingCycles -= regCount * 4;
|
||||
if (srcMode == 3)
|
||||
A[srcReg].s32 = address;
|
||||
}
|
||||
else
|
||||
{
|
||||
// long-assign
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
if (srcMode == 7 && (srcReg == 2 || srcReg == 3))
|
||||
{
|
||||
D[i].s32 = ReadPcrelLong(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
D[i].s32 = ReadLong(address);
|
||||
}
|
||||
address += 4;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((registers & 1) == 1)
|
||||
{
|
||||
if (srcMode == 7 && (srcReg == 2 || srcReg == 3))
|
||||
{
|
||||
A[i].s32 = ReadPcrelLong(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
A[i].s32 = ReadLong(address);
|
||||
}
|
||||
address += 4;
|
||||
regCount++;
|
||||
}
|
||||
registers >>= 1;
|
||||
}
|
||||
pendingCycles -= regCount * 8;
|
||||
if (srcMode == 3)
|
||||
A[srcReg].s32 = address;
|
||||
}
|
||||
|
||||
switch (srcMode)
|
||||
{
|
||||
case 2: pendingCycles -= 12; break;
|
||||
case 3: pendingCycles -= 12; break;
|
||||
case 4: pendingCycles -= 12; break;
|
||||
case 5: pendingCycles -= 16; break;
|
||||
case 6: pendingCycles -= 18; break;
|
||||
case 7:
|
||||
switch (srcReg)
|
||||
{
|
||||
case 0: pendingCycles -= 16; break;
|
||||
case 1: pendingCycles -= 20; break;
|
||||
case 2: pendingCycles -= 16; break;
|
||||
case 3: pendingCycles -= 18; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MOVEM1_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int size = (op >> 6) & 1;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
ushort registers = (ushort)ReadOpWord(pc); pc += 2;
|
||||
string address = DisassembleAddress(mode, reg, ref pc);
|
||||
|
||||
info.Mnemonic = size == 0 ? "movem.w" : "movem.l";
|
||||
info.Args = address + ", " + DisassembleRegisterList1(registers);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void LEA()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int sReg = (op >> 0) & 7;
|
||||
int dReg = (op >> 9) & 7;
|
||||
|
||||
A[dReg].u32 = (uint)ReadAddress(mode, sReg);
|
||||
switch (mode)
|
||||
{
|
||||
case 2: pendingCycles -= 4; break;
|
||||
case 5: pendingCycles -= 8; break;
|
||||
case 6: pendingCycles -= 12; break;
|
||||
case 7:
|
||||
switch (sReg)
|
||||
{
|
||||
case 0: pendingCycles -= 8; break;
|
||||
case 1: pendingCycles -= 12; break;
|
||||
case 2: pendingCycles -= 8; break;
|
||||
case 3: pendingCycles -= 12; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LEA_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int sReg = (op >> 0) & 7;
|
||||
int dReg = (op >> 9) & 7;
|
||||
|
||||
info.Mnemonic = "lea";
|
||||
info.Args = DisassembleAddress(mode, sReg, ref pc);
|
||||
info.Args += ", A" + dReg;
|
||||
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void CLR()
|
||||
{
|
||||
int size = (op >> 6) & 3;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: WriteValueB(mode, reg, 0); pendingCycles -= mode == 0 ? 4 : 8 + EACyclesBW[mode, reg]; break;
|
||||
case 1:
|
||||
WriteValueW(mode, reg, 0);
|
||||
pendingCycles -= mode == 0 ? 4 : 8 + EACyclesBW[mode, reg]; break;
|
||||
case 2: WriteValueL(mode, reg, 0); pendingCycles -= mode == 0 ? 6 : 12 + EACyclesL[mode, reg]; break;
|
||||
}
|
||||
|
||||
N = V = C = false;
|
||||
Z = true;
|
||||
}
|
||||
|
||||
void CLR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int size = (op >> 6) & 3;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: info.Mnemonic = "clr.b"; info.Args = DisassembleValue(mode, reg, 1, ref pc); break;
|
||||
case 1: info.Mnemonic = "clr.w"; info.Args = DisassembleValue(mode, reg, 2, ref pc); break;
|
||||
case 2: info.Mnemonic = "clr.l"; info.Args = DisassembleValue(mode, reg, 4, ref pc); break;
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void EXT()
|
||||
{
|
||||
int size = (op >> 6) & 1;
|
||||
int reg = op & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: // ext.w
|
||||
D[reg].s16 = D[reg].s8;
|
||||
N = (D[reg].s16 & 0x8000) != 0;
|
||||
Z = (D[reg].s16 == 0);
|
||||
break;
|
||||
case 1: // ext.l
|
||||
D[reg].s32 = D[reg].s16;
|
||||
N = (D[reg].s32 & 0x80000000) != 0;
|
||||
Z = (D[reg].s32 == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
V = false;
|
||||
C = false;
|
||||
pendingCycles -= 4;
|
||||
}
|
||||
|
||||
void EXT_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int size = (op >> 6) & 1;
|
||||
int reg = op & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: info.Mnemonic = "ext.w"; info.Args = "D" + reg; break;
|
||||
case 1: info.Mnemonic = "ext.l"; info.Args = "D" + reg; break;
|
||||
}
|
||||
}
|
||||
|
||||
void PEA()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
int ea = ReadAddress(mode, reg);
|
||||
|
||||
A[7].s32 -= 4;
|
||||
WriteLong(A[7].s32, ea);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 2: pendingCycles -= 12; break;
|
||||
case 5: pendingCycles -= 16; break;
|
||||
case 6: pendingCycles -= 20; break;
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: pendingCycles -= 16; break;
|
||||
case 1: pendingCycles -= 20; break;
|
||||
case 2: pendingCycles -= 16; break;
|
||||
case 3: pendingCycles -= 20; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PEA_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
info.Mnemonic = "pea";
|
||||
info.Args = DisassembleAddress(mode, reg, ref pc);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b9a46ea2abd2a04b88ef2ad2aa34650
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f00bdfe992953ee40bfa6536dcda1148
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,789 @@
|
||||
using System;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
partial class MC68000
|
||||
{
|
||||
bool TestCondition(int condition)
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
case 0x00: return true; // True
|
||||
case 0x01: return false; // False
|
||||
case 0x02: return !C && !Z; // High (Unsigned)
|
||||
case 0x03: return C || Z; // Less or Same (Unsigned)
|
||||
case 0x04: return !C; // Carry Clear (High or Same)
|
||||
case 0x05: return C; // Carry Set (Lower)
|
||||
case 0x06: return !Z; // Not Equal
|
||||
case 0x07: return Z; // Equal
|
||||
case 0x08: return !V; // Overflow Clear
|
||||
case 0x09: return V; // Overflow Set
|
||||
case 0x0A: return !N; // Plus (Positive)
|
||||
case 0x0B: return N; // Minus (Negative)
|
||||
case 0x0C: return N && V || !N && !V; // Greater or Equal
|
||||
case 0x0D: return N && !V || !N && V; // Less Than
|
||||
case 0x0E: return N && V && !Z || !N && !V && !Z; // Greater Than
|
||||
case 0x0F: return Z || N && !V || !N && V; // Less or Equal
|
||||
default:
|
||||
throw new Exception("Invalid condition " + condition);
|
||||
}
|
||||
}
|
||||
|
||||
string DisassembleCondition(int condition)
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
case 0x00: return "t"; // True
|
||||
case 0x01: return "f"; // False
|
||||
case 0x02: return "hi"; // High (Unsigned)
|
||||
case 0x03: return "ls"; // Less or Same (Unsigned)
|
||||
case 0x04: return "cc"; // Carry Clear (High or Same)
|
||||
case 0x05: return "cs"; // Carry Set (Lower)
|
||||
case 0x06: return "ne"; // Not Equal
|
||||
case 0x07: return "eq"; // Equal
|
||||
case 0x08: return "vc"; // Overflow Clear
|
||||
case 0x09: return "vs"; // Overflow Set
|
||||
case 0x0A: return "pl"; // Plus (Positive)
|
||||
case 0x0B: return "mi"; // Minus (Negative)
|
||||
case 0x0C: return "ge"; // Greater or Equal
|
||||
case 0x0D: return "lt"; // Less Than
|
||||
case 0x0E: return "gt"; // Greater Than
|
||||
case 0x0F: return "le"; // Less or Equal
|
||||
default: return "??"; // Invalid condition
|
||||
}
|
||||
}
|
||||
|
||||
void Bcc() // Branch on condition
|
||||
{
|
||||
sbyte displacement8 = (sbyte)op;
|
||||
int cond = (op >> 8) & 0x0F;
|
||||
|
||||
if (TestCondition(cond) == true)
|
||||
{
|
||||
if (displacement8 != 0)
|
||||
{
|
||||
// use opcode-embedded displacement
|
||||
PC += displacement8;
|
||||
pendingCycles -= 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use extension word displacement
|
||||
PC += ReadOpWord(PC);
|
||||
pendingCycles -= 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // false
|
||||
if (displacement8 != 0)
|
||||
pendingCycles -= 8;
|
||||
else
|
||||
{
|
||||
PC += 2;
|
||||
pendingCycles -= 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bcc_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
sbyte displacement8 = (sbyte)op;
|
||||
int cond = (op >> 8) & 0x0F;
|
||||
|
||||
info.Mnemonic = "b" + DisassembleCondition(cond);
|
||||
if (displacement8 != 0)
|
||||
{
|
||||
info.Args = string.Format("${0:X}", pc + displacement8);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.Args = string.Format("${0:X}", pc + ReadOpWord(pc));
|
||||
pc += 2;
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BRA()
|
||||
{
|
||||
sbyte displacement8 = (sbyte)op;
|
||||
|
||||
if (displacement8 != 0)
|
||||
PC += displacement8;
|
||||
else
|
||||
PC += ReadOpWord(PC);
|
||||
if (PPC == PC)
|
||||
{
|
||||
pendingCycles = 0;
|
||||
}
|
||||
pendingCycles -= 10;
|
||||
}
|
||||
|
||||
void BRA_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
info.Mnemonic = "bra";
|
||||
|
||||
sbyte displacement8 = (sbyte)op;
|
||||
if (displacement8 != 0)
|
||||
info.Args = String.Format("${0:X}", pc + displacement8);
|
||||
else
|
||||
{
|
||||
info.Args = String.Format("${0:X}", pc + ReadOpWord(pc));
|
||||
pc += 2;
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BSR()
|
||||
{
|
||||
sbyte displacement8 = (sbyte)op;
|
||||
|
||||
A[7].s32 -= 4;
|
||||
if (displacement8 != 0)
|
||||
{
|
||||
// use embedded displacement
|
||||
WriteLong(A[7].s32, PC);
|
||||
PC += displacement8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use extension word displacement
|
||||
WriteLong(A[7].s32, PC + 2);
|
||||
PC += ReadOpWord(PC);
|
||||
}
|
||||
pendingCycles -= 18;
|
||||
}
|
||||
|
||||
void BSR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
info.Mnemonic = "bsr";
|
||||
|
||||
sbyte displacement8 = (sbyte)op;
|
||||
if (displacement8 != 0)
|
||||
info.Args = String.Format("${0:X}", pc + displacement8);
|
||||
else
|
||||
{
|
||||
info.Args = String.Format("${0:X}", pc + ReadOpWord(pc));
|
||||
pc += 2;
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void DBcc()
|
||||
{
|
||||
if (TestCondition((op >> 8) & 0x0F) == true)
|
||||
{
|
||||
PC += 2; // condition met, break out of loop
|
||||
pendingCycles -= 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
int reg = op & 7;
|
||||
D[reg].u16--;
|
||||
|
||||
if (D[reg].u16 == 0xFFFF)
|
||||
{
|
||||
PC += 2; // counter underflowed, break out of loop
|
||||
pendingCycles -= 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
PC += ReadOpWord(PC); // condition false and counter not exhausted, so branch.
|
||||
pendingCycles -= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBcc_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int cond = (op >> 8) & 0x0F;
|
||||
info.Mnemonic = "db" + DisassembleCondition(cond);
|
||||
|
||||
int pc = info.PC + 2;
|
||||
info.Args = String.Format("D{0}, ${1:X}", op & 7, pc + ReadWord(pc));
|
||||
info.Length = 4;
|
||||
}
|
||||
|
||||
void RTS()
|
||||
{
|
||||
PC = ReadLong(A[7].s32);
|
||||
A[7].s32 += 4;
|
||||
pendingCycles -= 16;
|
||||
}
|
||||
|
||||
void RTS_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "rts";
|
||||
info.Args = "";
|
||||
}
|
||||
|
||||
void RTR()
|
||||
{
|
||||
short value = ReadWord(A[7].s32);
|
||||
A[7].s32 += 2;
|
||||
CCR = value;
|
||||
PC = ReadLong(A[7].s32);
|
||||
A[7].s32 += 4;
|
||||
pendingCycles -= 20;
|
||||
}
|
||||
|
||||
void RTR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "rtr";
|
||||
info.Args = "";
|
||||
}
|
||||
|
||||
void RESET()
|
||||
{
|
||||
if (S)
|
||||
{
|
||||
pendingCycles -= 132;
|
||||
}
|
||||
else
|
||||
{
|
||||
TrapVector2(8);
|
||||
}
|
||||
}
|
||||
|
||||
void RESET_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "reset";
|
||||
info.Args = "";
|
||||
}
|
||||
|
||||
void RTE()
|
||||
{
|
||||
short newSR = ReadWord(A[7].s32);
|
||||
A[7].s32 += 2;
|
||||
PC = ReadLong(A[7].s32);
|
||||
A[7].s32 += 4;
|
||||
SR = newSR;
|
||||
pendingCycles -= 20;
|
||||
}
|
||||
|
||||
void RTE_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "rte";
|
||||
info.Args = "";
|
||||
}
|
||||
|
||||
void TAS()
|
||||
{
|
||||
int mode = (op >> 3) & 0x07;
|
||||
int reg = op & 0x07;
|
||||
byte result;
|
||||
//result = (byte)ReadValueB(mode, reg);
|
||||
result = (byte)PeekValueB(mode, reg);
|
||||
Z = (result == 0);
|
||||
N = ((result & 0x80) != 0);
|
||||
V = false;
|
||||
C = false;
|
||||
/*if (mode == 0)
|
||||
{
|
||||
//D[reg].u8 = (byte)(result | 0x80);
|
||||
}*/
|
||||
WriteValueB(mode, reg, (sbyte)(result | 0x80));
|
||||
pendingCycles -= (mode == 0) ? 4 : 14 + EACyclesBW[mode, reg];
|
||||
}
|
||||
|
||||
void TAS_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
info.Mnemonic = "tas.b";
|
||||
info.Args = DisassembleValue(mode, reg, 1, ref pc);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void TST()
|
||||
{
|
||||
int size = (op >> 6) & 3;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
int value;
|
||||
switch (size)
|
||||
{
|
||||
case 0: value = ReadValueB(mode, reg); pendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x80) != 0; break;
|
||||
case 1: value = ReadValueW(mode, reg); pendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x8000) != 0; break;
|
||||
default: value = ReadValueL(mode, reg); pendingCycles -= 4 + EACyclesL[mode, reg]; N = (value & 0x80000000) != 0; break;
|
||||
}
|
||||
V = false;
|
||||
C = false;
|
||||
Z = (value == 0);
|
||||
}
|
||||
|
||||
void TST_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int size = (op >> 6) & 3;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: info.Mnemonic = "tst.b"; info.Args = DisassembleValue(mode, reg, 1, ref pc); break;
|
||||
case 1: info.Mnemonic = "tst.w"; info.Args = DisassembleValue(mode, reg, 2, ref pc); break;
|
||||
case 2: info.Mnemonic = "tst.l"; info.Args = DisassembleValue(mode, reg, 4, ref pc); break;
|
||||
}
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BTSTi()
|
||||
{
|
||||
int bit = ReadOpWord(PC); PC += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
pendingCycles -= 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
Z = (ReadValueB(mode, reg) & mask) == 0;
|
||||
pendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BTSTi_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int bit = ReadOpWord(pc); pc += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "btst";
|
||||
info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BTSTr()
|
||||
{
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
int bit = D[dReg].s32;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
pendingCycles -= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
Z = (ReadValueB(mode, reg) & mask) == 0;
|
||||
pendingCycles -= 4 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BTSTr_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "btst";
|
||||
info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BCHGi()
|
||||
{
|
||||
int bit = ReadOpWord(PC); PC += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
D[reg].s32 ^= mask;
|
||||
pendingCycles -= 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
sbyte value = PeekValueB(mode, reg);
|
||||
Z = (value & mask) == 0;
|
||||
value ^= (sbyte)mask;
|
||||
WriteValueB(mode, reg, value);
|
||||
pendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BCHGi_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int bit = ReadOpWord(pc); pc += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "bchg";
|
||||
info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BCHGr()
|
||||
{
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
int bit = D[dReg].s32;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
D[reg].s32 ^= mask;
|
||||
pendingCycles -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
sbyte value = PeekValueB(mode, reg);
|
||||
Z = (value & mask) == 0;
|
||||
value ^= (sbyte)mask;
|
||||
WriteValueB(mode, reg, value);
|
||||
pendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BCHGr_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "bchg";
|
||||
info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BCLRi()
|
||||
{
|
||||
int bit = ReadOpWord(PC); PC += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
D[reg].s32 &= ~mask;
|
||||
pendingCycles -= 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
sbyte value = PeekValueB(mode, reg);
|
||||
Z = (value & mask) == 0;
|
||||
value &= (sbyte)~mask;
|
||||
WriteValueB(mode, reg, value);
|
||||
pendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BCLRi_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int bit = ReadOpWord(pc); pc += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "bclr";
|
||||
info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BCLRr()
|
||||
{
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
int bit = D[dReg].s32;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
D[reg].s32 &= ~mask;
|
||||
pendingCycles -= 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
sbyte value = PeekValueB(mode, reg);
|
||||
Z = (value & mask) == 0;
|
||||
value &= (sbyte)~mask;
|
||||
WriteValueB(mode, reg, value);
|
||||
pendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BCLRr_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "bclr";
|
||||
info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BSETi()
|
||||
{
|
||||
int bit = ReadOpWord(PC); PC += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
D[reg].s32 |= mask;
|
||||
pendingCycles -= 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
sbyte value = PeekValueB(mode, reg);
|
||||
Z = (value & mask) == 0;
|
||||
value |= (sbyte)mask;
|
||||
WriteValueB(mode, reg, value);
|
||||
pendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BSETi_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int bit = ReadOpWord(pc); pc += 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "bset";
|
||||
info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void BSETr()
|
||||
{
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
int bit = D[dReg].s32;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
bit &= 31;
|
||||
int mask = 1 << bit;
|
||||
Z = (D[reg].s32 & mask) == 0;
|
||||
D[reg].s32 |= mask;
|
||||
pendingCycles -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bit &= 7;
|
||||
int mask = 1 << bit;
|
||||
sbyte value = PeekValueB(mode, reg);
|
||||
Z = (value & mask) == 0;
|
||||
value |= (sbyte)mask;
|
||||
WriteValueB(mode, reg, value);
|
||||
pendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void BSETr_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int dReg = (op >> 9) & 7;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = op & 7;
|
||||
|
||||
info.Mnemonic = "bset";
|
||||
info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc));
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void JMP()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
PC = ReadAddress(mode, reg);
|
||||
if (PPC == PC)
|
||||
{
|
||||
pendingCycles = 0;
|
||||
}
|
||||
switch (mode)
|
||||
{
|
||||
case 2: pendingCycles -= 8; break;
|
||||
case 5: pendingCycles -= 10; break;
|
||||
case 6: pendingCycles -= 14; break;
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: pendingCycles -= 10; break;
|
||||
case 1: pendingCycles -= 12; break;
|
||||
case 2: pendingCycles -= 10; break;
|
||||
case 3: pendingCycles -= 14; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JMP_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
info.Mnemonic = "jmp";
|
||||
info.Args = DisassembleValue(mode, reg, 1, ref pc);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void JSR()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
int addr = ReadAddress(mode, reg);
|
||||
|
||||
A[7].s32 -= 4;
|
||||
WriteLong(A[7].s32, PC);
|
||||
PC = addr;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 2: pendingCycles -= 16; break;
|
||||
case 5: pendingCycles -= 18; break;
|
||||
case 6: pendingCycles -= 22; break;
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: pendingCycles -= 18; break;
|
||||
case 1: pendingCycles -= 20; break;
|
||||
case 2: pendingCycles -= 18; break;
|
||||
case 3: pendingCycles -= 22; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JSR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
info.Mnemonic = "jsr";
|
||||
info.Args = DisassembleAddress(mode, reg, ref pc);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void LINK()
|
||||
{
|
||||
int reg = op & 7;
|
||||
A[7].s32 -= 4;
|
||||
short offset = ReadOpWord(PC); PC += 2;
|
||||
WriteLong(A[7].s32, A[reg].s32);
|
||||
A[reg].s32 = A[7].s32;
|
||||
A[7].s32 += offset;
|
||||
pendingCycles -= 16;
|
||||
}
|
||||
|
||||
void LINK_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int reg = op & 7;
|
||||
info.Mnemonic = "link";
|
||||
info.Args = "A" + reg + ", " + DisassembleImmediate(2, ref pc); // TODO need a DisassembleSigned or something
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void UNLK()
|
||||
{
|
||||
int reg = op & 7;
|
||||
A[7].s32 = A[reg].s32;
|
||||
A[reg].s32 = ReadLong(A[7].s32);
|
||||
A[7].s32 += 4;
|
||||
pendingCycles -= 12;
|
||||
}
|
||||
|
||||
void UNLK_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int reg = op & 7;
|
||||
info.Mnemonic = "unlk";
|
||||
info.Args = "A" + reg;
|
||||
info.Length = 2;
|
||||
}
|
||||
|
||||
void NOP()
|
||||
{
|
||||
pendingCycles -= 4;
|
||||
}
|
||||
|
||||
void NOP_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "nop";
|
||||
}
|
||||
|
||||
void Scc() // Set on condition
|
||||
{
|
||||
int cond = (op >> 8) & 0x0F;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
if (TestCondition(cond) == true)
|
||||
{
|
||||
WriteValueB(mode, reg, -1);
|
||||
if (mode == 0) pendingCycles -= 6;
|
||||
else pendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteValueB(mode, reg, 0);
|
||||
if (mode == 0)
|
||||
pendingCycles -= 4;
|
||||
else
|
||||
pendingCycles -= 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
}
|
||||
|
||||
void Scc_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int cond = (op >> 8) & 0x0F;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
info.Mnemonic = "s" + DisassembleCondition(cond);
|
||||
info.Args = DisassembleValue(mode, reg, 1, ref pc);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2095e1daba88c5b4b935aaa55d3ed2e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,192 @@
|
||||
using System;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
partial class MC68000
|
||||
{
|
||||
void MOVEtSR()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
if (S == false)
|
||||
{
|
||||
//throw new Exception("Write to SR when not in supervisor mode. supposed to trap or something...");
|
||||
TrapVector2(8);
|
||||
}
|
||||
else
|
||||
{
|
||||
SR = ReadValueW(mode, reg);
|
||||
}
|
||||
pendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||
}
|
||||
|
||||
void MOVEtSR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
info.Mnemonic = "move";
|
||||
info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", SR";
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVEfSR()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
WriteValueW(mode, reg, (short)SR);
|
||||
pendingCycles -= (mode == 0) ? 6 : 8 + EACyclesBW[mode, reg];
|
||||
}
|
||||
|
||||
void MOVEfSR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
info.Mnemonic = "move";
|
||||
info.Args = "SR, " + DisassembleValue(mode, reg, 2, ref pc);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVEUSP()
|
||||
{
|
||||
int dir = (op >> 3) & 1;
|
||||
int reg = op & 7;
|
||||
if (S == false)
|
||||
{
|
||||
//throw new Exception("MOVE to USP when not supervisor. needs to trap");
|
||||
TrapVector2(8);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir == 0)
|
||||
{
|
||||
usp = A[reg].s32;
|
||||
}
|
||||
else
|
||||
{
|
||||
A[reg].s32 = usp;
|
||||
}
|
||||
}
|
||||
pendingCycles -= 4;
|
||||
}
|
||||
|
||||
void MOVEUSP_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int dir = (op >> 3) & 1;
|
||||
int reg = op & 7;
|
||||
info.Mnemonic = "move";
|
||||
info.Args = (dir == 0) ? ("A" + reg + ", USP") : ("USP, A" + reg);
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void ANDI_SR()
|
||||
{
|
||||
if (S == false)
|
||||
throw new Exception("trap!");
|
||||
SR &= ReadOpWord(PC); PC += 2;
|
||||
pendingCycles -= 20;
|
||||
}
|
||||
|
||||
void ANDI_SR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
info.Mnemonic = "andi";
|
||||
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void EORI_SR()
|
||||
{
|
||||
if (S == false)
|
||||
throw new Exception("trap!");
|
||||
SR ^= ReadOpWord(PC); PC += 2;
|
||||
pendingCycles -= 20;
|
||||
}
|
||||
|
||||
void EORI_SR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
info.Mnemonic = "eori";
|
||||
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void ORI_SR()
|
||||
{
|
||||
if (S == false)
|
||||
throw new Exception("trap!");
|
||||
SR |= ReadOpWord(PC); PC += 2;
|
||||
pendingCycles -= 20;
|
||||
}
|
||||
|
||||
void ORI_SR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
info.Mnemonic = "ori";
|
||||
info.Args = DisassembleImmediate(2, ref pc) + ", SR";
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void MOVECCR()
|
||||
{
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
|
||||
/*ushort sr = (ushort)(SR & 0xFF00);
|
||||
sr |= (byte)ReadValueB(mode, reg);
|
||||
SR = (short)sr;*/
|
||||
short value = ReadValueW(mode, reg);
|
||||
CCR = value;
|
||||
pendingCycles -= 12 + EACyclesBW[mode, reg];
|
||||
}
|
||||
|
||||
void MOVECCR_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
int pc = info.PC + 2;
|
||||
int mode = (op >> 3) & 7;
|
||||
int reg = (op >> 0) & 7;
|
||||
info.Mnemonic = "move";
|
||||
info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", CCR";
|
||||
info.Length = pc - info.PC;
|
||||
}
|
||||
|
||||
void TRAP()
|
||||
{
|
||||
int vector = 32 + (op & 0x0F);
|
||||
TrapVector(vector);
|
||||
pendingCycles -= 4;
|
||||
}
|
||||
|
||||
void TRAP_Disasm(DisassemblyInfo info)
|
||||
{
|
||||
info.Mnemonic = "trap";
|
||||
info.Args = string.Format("${0:X}", op & 0xF);
|
||||
}
|
||||
|
||||
void TrapVector(int vector)
|
||||
{
|
||||
short sr = (short)SR; // capture current SR.
|
||||
S = true; // switch to supervisor mode, if not already in it.
|
||||
A[7].s32 -= 4; // Push PC on stack
|
||||
WriteLong(A[7].s32, PC);
|
||||
A[7].s32 -= 2; // Push SR on stack
|
||||
WriteWord(A[7].s32, sr);
|
||||
PC = ReadLong(vector * 4); // Jump to vector
|
||||
pendingCycles -= CyclesException[vector];
|
||||
}
|
||||
|
||||
void TrapVector2(int vector)
|
||||
{
|
||||
short sr = (short)SR; // capture current SR.
|
||||
S = true; // switch to supervisor mode, if not already in it.
|
||||
A[7].s32 -= 4; // Push PPC on stack
|
||||
WriteLong(A[7].s32, PPC);
|
||||
A[7].s32 -= 2; // Push SR on stack
|
||||
WriteWord(A[7].s32, sr);
|
||||
PC = ReadLong(vector * 4); // Jump to vector
|
||||
pendingCycles -= CyclesException[vector];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8ae0dd765643d44da568a00571a176e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
441
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs
Normal file
441
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs
Normal file
@ -0,0 +1,441 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
public sealed partial class MC68000 : cpuexec_data
|
||||
{
|
||||
public static MC68000 m1;
|
||||
// Machine State
|
||||
public Register[] D = new Register[8];
|
||||
public Register[] A = new Register[8];
|
||||
public int PC, PPC;
|
||||
private ulong totalExecutedCycles;
|
||||
private int pendingCycles;
|
||||
public override ulong TotalExecutedCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalExecutedCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
totalExecutedCycles = value;
|
||||
}
|
||||
}
|
||||
public override int PendingCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return pendingCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
pendingCycles = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Status Registers
|
||||
public int int_cycles;
|
||||
public int InterruptMaskLevel;
|
||||
bool s, m;
|
||||
public int usp, ssp;
|
||||
public bool stopped;
|
||||
|
||||
/// <summary>Machine/Interrupt mode</summary>
|
||||
public bool M { get { return m; } set { m = value; } } // TODO probably have some switch logic maybe
|
||||
|
||||
public void SetS(bool b1)
|
||||
{
|
||||
s = b1;
|
||||
}
|
||||
public void m68k_set_irq(int interrupt)
|
||||
{
|
||||
Interrupt = interrupt;
|
||||
m68ki_check_interrupts();
|
||||
}
|
||||
|
||||
/// <summary>Supervisor/User mode</summary>
|
||||
public bool S
|
||||
{
|
||||
get
|
||||
{
|
||||
return s;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == s)
|
||||
return;
|
||||
if (value == true) // entering supervisor mode
|
||||
{
|
||||
//EmuLogger.Log("&^&^&^&^& ENTER SUPERVISOR MODE");
|
||||
usp = A[7].s32;
|
||||
A[7].s32 = ssp;
|
||||
s = true;
|
||||
}
|
||||
else
|
||||
{ // exiting supervisor mode
|
||||
//EmuLogger.Log("&^&^&^&^& LEAVE SUPERVISOR MODE");
|
||||
ssp = A[7].s32;
|
||||
A[7].s32 = usp;
|
||||
s = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Extend Flag</summary>
|
||||
public bool X;
|
||||
/// <summary>Negative Flag</summary>
|
||||
public bool N;
|
||||
/// <summary>Zero Flag</summary>
|
||||
public bool Z;
|
||||
/// <summary>Overflow Flag</summary>
|
||||
public bool V;
|
||||
/// <summary>Carry Flag</summary>
|
||||
public bool C;
|
||||
|
||||
|
||||
|
||||
/// <summary>Status Register</summary>
|
||||
public short SR
|
||||
{
|
||||
get
|
||||
{
|
||||
short value = 0;
|
||||
if (C) value |= 0x0001;
|
||||
if (V) value |= 0x0002;
|
||||
if (Z) value |= 0x0004;
|
||||
if (N) value |= 0x0008;
|
||||
if (X) value |= 0x0010;
|
||||
if (M) value |= 0x1000;
|
||||
if (S) value |= 0x2000;
|
||||
value |= (short)((InterruptMaskLevel & 7) << 8);
|
||||
return value;
|
||||
}
|
||||
set
|
||||
{
|
||||
C = (value & 0x0001) != 0;
|
||||
V = (value & 0x0002) != 0;
|
||||
Z = (value & 0x0004) != 0;
|
||||
N = (value & 0x0008) != 0;
|
||||
X = (value & 0x0010) != 0;
|
||||
M = (value & 0x1000) != 0;
|
||||
S = (value & 0x2000) != 0;
|
||||
InterruptMaskLevel = (value >> 8) & 7;
|
||||
//m68ki_check_interrupts();
|
||||
}
|
||||
}
|
||||
public short CCR
|
||||
{
|
||||
get
|
||||
{
|
||||
short value = 0;
|
||||
if (C) value |= 0x0001;
|
||||
if (V) value |= 0x0002;
|
||||
if (Z) value |= 0x0004;
|
||||
if (N) value |= 0x0008;
|
||||
if (X) value |= 0x0010;
|
||||
return value;
|
||||
}
|
||||
set
|
||||
{
|
||||
C = (value & 0x0001) != 0;
|
||||
V = (value & 0x0002) != 0;
|
||||
Z = (value & 0x0004) != 0;
|
||||
N = (value & 0x0008) != 0;
|
||||
X = (value & 0x0010) != 0;
|
||||
}
|
||||
}
|
||||
public int Interrupt { get; set; }
|
||||
|
||||
// Memory Access
|
||||
public Func<int, sbyte> ReadOpByte, ReadByte;
|
||||
public Func<int, short> ReadOpWord, ReadPcrelWord, ReadWord;
|
||||
public Func<int, int> ReadOpLong, ReadPcrelLong, ReadLong;
|
||||
|
||||
public Action<int, sbyte> WriteByte;
|
||||
public Action<int, short> WriteWord;
|
||||
public Action<int, int> WriteLong;
|
||||
|
||||
public delegate void debug_delegate();
|
||||
public debug_delegate debugger_start_cpu_hook_callback, debugger_stop_cpu_hook_callback;
|
||||
|
||||
// Initialization
|
||||
|
||||
public MC68000()
|
||||
{
|
||||
BuildOpcodeTable();
|
||||
}
|
||||
public override void Reset()
|
||||
{
|
||||
Pulse_Reset();
|
||||
}
|
||||
public override void set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
if (irqline == (int)LineState.INPUT_LINE_NMI)
|
||||
irqline = 7;
|
||||
switch (state)
|
||||
{
|
||||
case LineState.CLEAR_LINE:
|
||||
m68k_set_irq(0);
|
||||
break;
|
||||
case LineState.ASSERT_LINE:
|
||||
m68k_set_irq(irqline);
|
||||
break;
|
||||
default:
|
||||
m68k_set_irq(irqline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public override void cpunum_set_input_line_and_vector(int cpunum, int line, LineState state, int vector)
|
||||
{
|
||||
EmuTimer.timer_set_internal(Cpuint.cpunum_empty_event_queue, "cpunum_empty_event_queue");
|
||||
}
|
||||
public void Pulse_Reset()
|
||||
{
|
||||
stopped = false;
|
||||
pendingCycles = 0;
|
||||
S = true;
|
||||
M = false;
|
||||
InterruptMaskLevel = 7;
|
||||
Interrupt = 0;
|
||||
A[7].s32 = ReadOpLong(0);
|
||||
PC = ReadOpLong(4);
|
||||
}
|
||||
|
||||
public Action[] Opcodes = new Action[0x10000];
|
||||
public ushort op;
|
||||
|
||||
public void Step()
|
||||
{
|
||||
//EmuLogger.Log(Disassemble(PC));
|
||||
|
||||
op = (ushort)ReadOpWord(PC); PC += 2;
|
||||
Opcodes[op]();
|
||||
}
|
||||
|
||||
public override int ExecuteCycles(int cycles)
|
||||
{
|
||||
if (!stopped)
|
||||
{
|
||||
pendingCycles = cycles;
|
||||
int ran;
|
||||
pendingCycles -= int_cycles;
|
||||
int_cycles = 0;
|
||||
do
|
||||
{
|
||||
int prevCycles = pendingCycles;
|
||||
PPC = PC;
|
||||
debugger_start_cpu_hook_callback();
|
||||
op = (ushort)ReadOpWord(PC); PC += 2;
|
||||
Opcodes[op]();
|
||||
m68ki_check_interrupts();
|
||||
debugger_stop_cpu_hook_callback();
|
||||
int delta = prevCycles - pendingCycles;
|
||||
totalExecutedCycles += (ulong)delta;
|
||||
}
|
||||
while (pendingCycles > 0);
|
||||
pendingCycles -= int_cycles;
|
||||
//totalExecutedCycles += (ulong)int_cycles;
|
||||
int_cycles = 0;
|
||||
ran = cycles - pendingCycles;
|
||||
return ran;
|
||||
}
|
||||
pendingCycles = 0;
|
||||
int_cycles = 0;
|
||||
return cycles;
|
||||
}
|
||||
public void m68ki_check_interrupts()
|
||||
{
|
||||
if (Interrupt > 0 && (Interrupt > InterruptMaskLevel || Interrupt > 7))
|
||||
{
|
||||
stopped = false;
|
||||
//int vector = Cpuint.cpu_irq_callback(cpunum, Interrupt);
|
||||
short sr = (short)SR; // capture current SR.
|
||||
S = true; // switch to supervisor mode, if not already in it.
|
||||
A[7].s32 -= 4; // Push PC on stack
|
||||
WriteLong(A[7].s32, PC);
|
||||
A[7].s32 -= 2; // Push SR on stack
|
||||
WriteWord(A[7].s32, sr);
|
||||
PC = ReadLong((24 + Interrupt) * 4); // Jump to interrupt vector
|
||||
InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered
|
||||
Interrupt = 0; // "ack" interrupt. Note: this is wrong.
|
||||
int_cycles += 0x2c;
|
||||
}
|
||||
}
|
||||
|
||||
public string State()
|
||||
{
|
||||
string a = Disassemble(PC).ToString().PadRight(64);
|
||||
//string a = string.Format("{0:X6}: {1:X4}", PC, ReadWord(PC)).PadRight(64);
|
||||
string b = string.Format("D0:{0:X8} D1:{1:X8} D2:{2:X8} D3:{3:X8} D4:{4:X8} D5:{5:X8} D6:{6:X8} D7:{7:X8} ", D[0].u32, D[1].u32, D[2].u32, D[3].u32, D[4].u32, D[5].u32, D[6].u32, D[7].u32);
|
||||
string c = string.Format("A0:{0:X8} A1:{1:X8} A2:{2:X8} A3:{3:X8} A4:{4:X8} A5:{5:X8} A6:{6:X8} A7:{7:X8} ", A[0].u32, A[1].u32, A[2].u32, A[3].u32, A[4].u32, A[5].u32, A[6].u32, A[7].u32);
|
||||
string d = string.Format("SR:{0:X4} Pending {1}", SR, pendingCycles);
|
||||
return a + b + c + d;
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 0x08; i++)
|
||||
{
|
||||
writer.Write(MC68000.m1.D[i].u32);
|
||||
}
|
||||
for (i = 0; i < 0x08; i++)
|
||||
{
|
||||
writer.Write(MC68000.m1.A[i].u32);
|
||||
}
|
||||
writer.Write(MC68000.m1.PPC);
|
||||
writer.Write(MC68000.m1.PC);
|
||||
writer.Write(MC68000.m1.S);
|
||||
writer.Write(MC68000.m1.M);
|
||||
writer.Write(MC68000.m1.X);
|
||||
writer.Write(MC68000.m1.N);
|
||||
writer.Write(MC68000.m1.Z);
|
||||
writer.Write(MC68000.m1.V);
|
||||
writer.Write(MC68000.m1.C);
|
||||
writer.Write(MC68000.m1.InterruptMaskLevel);
|
||||
writer.Write(MC68000.m1.Interrupt);
|
||||
writer.Write(MC68000.m1.int_cycles);
|
||||
writer.Write(MC68000.m1.usp);
|
||||
writer.Write(MC68000.m1.ssp);
|
||||
writer.Write(MC68000.m1.stopped);
|
||||
writer.Write(MC68000.m1.TotalExecutedCycles);
|
||||
writer.Write(MC68000.m1.PendingCycles);
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 0x08; i++)
|
||||
{
|
||||
MC68000.m1.D[i].u32 = reader.ReadUInt32();
|
||||
}
|
||||
for (i = 0; i < 0x08; i++)
|
||||
{
|
||||
MC68000.m1.A[i].u32 = reader.ReadUInt32();
|
||||
}
|
||||
MC68000.m1.PPC = reader.ReadInt32();
|
||||
MC68000.m1.PC = reader.ReadInt32();
|
||||
MC68000.m1.SetS(reader.ReadBoolean());
|
||||
MC68000.m1.M = reader.ReadBoolean();
|
||||
MC68000.m1.X = reader.ReadBoolean();
|
||||
MC68000.m1.N = reader.ReadBoolean();
|
||||
MC68000.m1.Z = reader.ReadBoolean();
|
||||
MC68000.m1.V = reader.ReadBoolean();
|
||||
MC68000.m1.C = reader.ReadBoolean();
|
||||
MC68000.m1.InterruptMaskLevel = reader.ReadInt32();
|
||||
MC68000.m1.Interrupt = reader.ReadInt32();
|
||||
MC68000.m1.int_cycles = reader.ReadInt32();
|
||||
MC68000.m1.usp = reader.ReadInt32();
|
||||
MC68000.m1.ssp = reader.ReadInt32();
|
||||
MC68000.m1.stopped = reader.ReadBoolean();
|
||||
MC68000.m1.TotalExecutedCycles = reader.ReadUInt64();
|
||||
MC68000.m1.PendingCycles = reader.ReadInt32();
|
||||
}
|
||||
public void SaveStateText(TextWriter writer, string id)
|
||||
{
|
||||
writer.WriteLine("[{0}]", id);
|
||||
writer.WriteLine("D0 {0:X8}", D[0].s32);
|
||||
writer.WriteLine("D1 {0:X8}", D[1].s32);
|
||||
writer.WriteLine("D2 {0:X8}", D[2].s32);
|
||||
writer.WriteLine("D3 {0:X8}", D[3].s32);
|
||||
writer.WriteLine("D4 {0:X8}", D[4].s32);
|
||||
writer.WriteLine("D5 {0:X8}", D[5].s32);
|
||||
writer.WriteLine("D6 {0:X8}", D[6].s32);
|
||||
writer.WriteLine("D7 {0:X8}", D[7].s32);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.WriteLine("A0 {0:X8}", A[0].s32);
|
||||
writer.WriteLine("A1 {0:X8}", A[1].s32);
|
||||
writer.WriteLine("A2 {0:X8}", A[2].s32);
|
||||
writer.WriteLine("A3 {0:X8}", A[3].s32);
|
||||
writer.WriteLine("A4 {0:X8}", A[4].s32);
|
||||
writer.WriteLine("A5 {0:X8}", A[5].s32);
|
||||
writer.WriteLine("A6 {0:X8}", A[6].s32);
|
||||
writer.WriteLine("A7 {0:X8}", A[7].s32);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.WriteLine("PC {0:X6}", PC);
|
||||
writer.WriteLine("InterruptMaskLevel {0}", InterruptMaskLevel);
|
||||
writer.WriteLine("USP {0:X8}", usp);
|
||||
writer.WriteLine("SSP {0:X8}", ssp);
|
||||
writer.WriteLine("S {0}", s);
|
||||
writer.WriteLine("M {0}", m);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.WriteLine("TotalExecutedCycles {0}", totalExecutedCycles);
|
||||
writer.WriteLine("PendingCycles {0}", pendingCycles);
|
||||
|
||||
writer.WriteLine("[/{0}]", id);
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader, string id)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0].Trim() == "") continue;
|
||||
if (args[0] == "[/" + id + "]") break;
|
||||
else if (args[0] == "D0") D[0].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D1") D[1].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D2") D[2].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D3") D[3].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D4") D[4].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D5") D[5].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D6") D[6].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "D7") D[7].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
|
||||
else if (args[0] == "A0") A[0].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A1") A[1].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A2") A[2].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A3") A[3].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A4") A[4].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A5") A[5].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A6") A[6].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "A7") A[7].s32 = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
|
||||
else if (args[0] == "PC") PC = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "InterruptMaskLevel") InterruptMaskLevel = int.Parse(args[1]);
|
||||
else if (args[0] == "USP") usp = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "SSP") ssp = int.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "S") s = bool.Parse(args[1]);
|
||||
else if (args[0] == "M") m = bool.Parse(args[1]);
|
||||
|
||||
else if (args[0] == "TotalExecutedCycles") totalExecutedCycles = ulong.Parse(args[1]);
|
||||
else if (args[0] == "PendingCycles") pendingCycles = int.Parse(args[1]);
|
||||
|
||||
else
|
||||
{
|
||||
//EmuLogger.Log("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct Register
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public uint u32;
|
||||
[FieldOffset(0)]
|
||||
public int s32;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public ushort u16;
|
||||
[FieldOffset(0)]
|
||||
public short s16;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public byte u8;
|
||||
[FieldOffset(0)]
|
||||
public sbyte s8;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0:X8}", u32);
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/MC68000.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cde299f017f5c6c4d83cb4a8e4cfe543
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
623
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Memory.cs
Normal file
623
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Memory.cs
Normal file
@ -0,0 +1,623 @@
|
||||
using System;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
partial class MC68000
|
||||
{
|
||||
sbyte ReadValueB(int mode, int reg)
|
||||
{
|
||||
sbyte value;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
return D[reg].s8;
|
||||
case 1: // An
|
||||
return A[reg].s8;
|
||||
case 2: // (An)
|
||||
return ReadByte(A[reg].s32);
|
||||
case 3: // (An)+
|
||||
value = ReadByte(A[reg].s32);
|
||||
A[reg].s32 += reg == 7 ? 2 : 1;
|
||||
return value;
|
||||
case 4: // -(An)
|
||||
A[reg].s32 -= reg == 7 ? 2 : 1;
|
||||
return ReadByte(A[reg].s32);
|
||||
case 5: // (d16,An)
|
||||
value = ReadByte((A[reg].s32 + ReadOpWord(PC))); PC += 2;
|
||||
return value;
|
||||
case 6: // (d8,An,Xn)
|
||||
return ReadByte(A[reg].s32 + GetIndex());
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // (imm).W
|
||||
value = ReadByte(ReadOpWord(PC)); PC += 2;
|
||||
return value;
|
||||
case 1: // (imm).L
|
||||
value = ReadByte(ReadOpLong(PC)); PC += 4;
|
||||
return value;
|
||||
case 2: // (d16,PC)
|
||||
value = ReadOpByte(PC + ReadOpWord(PC)); PC += 2;
|
||||
return value;
|
||||
case 3: // (d8,PC,Xn)
|
||||
int pc = PC;
|
||||
value = ReadOpByte((pc + GetIndex()));
|
||||
return value;
|
||||
case 4: // immediate
|
||||
value = (sbyte)ReadOpWord(PC); PC += 2;
|
||||
return value;
|
||||
default:
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
short ReadValueW(int mode, int reg)
|
||||
{
|
||||
short value;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
return D[reg].s16;
|
||||
case 1: // An
|
||||
return A[reg].s16;
|
||||
case 2: // (An)
|
||||
return ReadWord(A[reg].s32);
|
||||
case 3: // (An)+
|
||||
value = ReadWord(A[reg].s32);
|
||||
A[reg].s32 += 2;
|
||||
return value;
|
||||
case 4: // -(An)
|
||||
A[reg].s32 -= 2;
|
||||
return ReadWord(A[reg].s32);
|
||||
case 5: // (d16,An)
|
||||
value = ReadWord((A[reg].s32 + ReadOpWord(PC))); PC += 2;
|
||||
return value;
|
||||
case 6: // (d8,An,Xn)
|
||||
return ReadWord(A[reg].s32 + GetIndex());
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // (imm).W
|
||||
value = ReadWord(ReadOpWord(PC)); PC += 2;
|
||||
return value;
|
||||
case 1: // (imm).L
|
||||
value = ReadWord(ReadOpLong(PC)); PC += 4;
|
||||
return value;
|
||||
case 2: // (d16,PC)
|
||||
value = ReadOpWord(PC + ReadOpWord(PC)); PC += 2;
|
||||
return value;
|
||||
case 3: // (d8,PC,Xn)
|
||||
int pc = PC;
|
||||
value = ReadOpWord((pc + GetIndex()));
|
||||
return value;
|
||||
case 4: // immediate
|
||||
value = ReadOpWord(PC); PC += 2;
|
||||
return value;
|
||||
default:
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
int ReadValueL(int mode, int reg)
|
||||
{
|
||||
int value;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
return D[reg].s32;
|
||||
case 1: // An
|
||||
return A[reg].s32;
|
||||
case 2: // (An)
|
||||
return ReadLong(A[reg].s32);
|
||||
case 3: // (An)+
|
||||
value = ReadLong(A[reg].s32);
|
||||
A[reg].s32 += 4;
|
||||
return value;
|
||||
case 4: // -(An)
|
||||
A[reg].s32 -= 4;
|
||||
return ReadLong(A[reg].s32);
|
||||
case 5: // (d16,An)
|
||||
value = ReadLong((A[reg].s32 + ReadOpWord(PC))); PC += 2;
|
||||
return value;
|
||||
case 6: // (d8,An,Xn)
|
||||
return ReadLong(A[reg].s32 + GetIndex());
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // (imm).W
|
||||
value = ReadLong(ReadOpWord(PC)); PC += 2;
|
||||
return value;
|
||||
case 1: // (imm).L
|
||||
value = ReadLong(ReadOpLong(PC)); PC += 4;
|
||||
return value;
|
||||
case 2: // (d16,PC)
|
||||
value = ReadOpLong(PC + ReadOpWord(PC)); PC += 2;
|
||||
return value;
|
||||
case 3: // (d8,PC,Xn)
|
||||
int pc = PC;
|
||||
value = ReadOpLong((pc + GetIndex()));
|
||||
return value;
|
||||
case 4: // immediate
|
||||
value = ReadOpLong(PC); PC += 4;
|
||||
return value;
|
||||
default:
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
sbyte PeekValueB(int mode, int reg)
|
||||
{
|
||||
sbyte value;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
return D[reg].s8;
|
||||
case 1: // An
|
||||
return A[reg].s8;
|
||||
case 2: // (An)
|
||||
return ReadByte(A[reg].s32);
|
||||
case 3: // (An)+
|
||||
value = ReadByte(A[reg].s32);
|
||||
return value;
|
||||
case 4: // -(An)
|
||||
value = ReadByte(A[reg].s32 - (reg == 7 ? 2 : 1));
|
||||
return value;
|
||||
case 5: // (d16,An)
|
||||
value = ReadByte((A[reg].s32 + ReadOpWord(PC)));
|
||||
return value;
|
||||
case 6: // (d8,An,Xn)
|
||||
return ReadByte(A[reg].s32 + PeekIndex());
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // (imm).W
|
||||
value = ReadByte(ReadOpWord(PC));
|
||||
return value;
|
||||
case 1: // (imm).L
|
||||
value = ReadByte(ReadOpLong(PC));
|
||||
return value;
|
||||
case 2: // (d16,PC)
|
||||
value = ReadByte(PC + ReadOpWord(PC));
|
||||
return value;
|
||||
case 3: // (d8,PC,Xn)
|
||||
value = ReadByte((PC + PeekIndex()));
|
||||
return value;
|
||||
case 4: // immediate
|
||||
return (sbyte)ReadOpWord(PC);
|
||||
default:
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
short PeekValueW(int mode, int reg)
|
||||
{
|
||||
short value;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
return D[reg].s16;
|
||||
case 1: // An
|
||||
return A[reg].s16;
|
||||
case 2: // (An)
|
||||
return ReadWord(A[reg].s32);
|
||||
case 3: // (An)+
|
||||
value = ReadWord(A[reg].s32);
|
||||
return value;
|
||||
case 4: // -(An)
|
||||
value = ReadWord(A[reg].s32 - 2);
|
||||
return value;
|
||||
case 5: // (d16,An)
|
||||
value = ReadWord((A[reg].s32 + ReadOpWord(PC)));
|
||||
return value;
|
||||
case 6: // (d8,An,Xn)
|
||||
return ReadWord(A[reg].s32 + PeekIndex());
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // (imm).W
|
||||
value = ReadWord(ReadOpWord(PC));
|
||||
return value;
|
||||
case 1: // (imm).L
|
||||
value = ReadWord(ReadOpLong(PC));
|
||||
return value;
|
||||
case 2: // (d16,PC)
|
||||
value = ReadWord(PC + ReadOpWord(PC));
|
||||
return value;
|
||||
case 3: // (d8,PC,Xn)
|
||||
value = ReadWord((PC + PeekIndex()));
|
||||
return value;
|
||||
case 4: // immediate
|
||||
return ReadOpWord(PC);
|
||||
default:
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
int PeekValueL(int mode, int reg)
|
||||
{
|
||||
int value;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Dn
|
||||
return D[reg].s32;
|
||||
case 1: // An
|
||||
return A[reg].s32;
|
||||
case 2: // (An)
|
||||
return ReadLong(A[reg].s32);
|
||||
case 3: // (An)+
|
||||
value = ReadLong(A[reg].s32);
|
||||
return value;
|
||||
case 4: // -(An)
|
||||
value = ReadLong(A[reg].s32 - 4);
|
||||
return value;
|
||||
case 5: // (d16,An)
|
||||
value = ReadLong((A[reg].s32 + ReadOpWord(PC)));
|
||||
return value;
|
||||
case 6: // (d8,An,Xn)
|
||||
return ReadLong(A[reg].s32 + PeekIndex());
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // (imm).W
|
||||
value = ReadLong(ReadOpWord(PC));
|
||||
return value;
|
||||
case 1: // (imm).L
|
||||
value = ReadLong(ReadOpLong(PC));
|
||||
return value;
|
||||
case 2: // (d16,PC)
|
||||
value = ReadLong(PC + ReadOpWord(PC));
|
||||
return value;
|
||||
case 3: // (d8,PC,Xn)
|
||||
value = ReadLong((PC + PeekIndex()));
|
||||
return value;
|
||||
case 4: // immediate
|
||||
return ReadOpLong(PC);
|
||||
default:
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
int ReadAddress(int mode, int reg)
|
||||
{
|
||||
int addr;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: throw new Exception("Invalid addressing mode!"); // Dn
|
||||
case 1: throw new Exception("Invalid addressing mode!"); // An
|
||||
case 2: return A[reg].s32; // (An)
|
||||
case 3: return A[reg].s32; // (An)+
|
||||
case 4: return A[reg].s32; // -(An)
|
||||
case 5: addr = A[reg].s32 + ReadOpWord(PC); PC += 2; return addr; // (d16,An)
|
||||
case 6: return A[reg].s32 + GetIndex(); // (d8,An,Xn)
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: addr = ReadOpWord(PC); PC += 2; return addr; // (imm).w
|
||||
case 1: addr = ReadOpLong(PC); PC += 4; return addr; // (imm).l
|
||||
case 2: addr = PC; addr += ReadOpWord(PC); PC += 2; return addr; // (d16,PC)
|
||||
case 3: addr = PC; addr += GetIndex(); return addr; // (d8,PC,Xn)
|
||||
case 4: throw new Exception("Invalid addressing mode!"); // immediate
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
string DisassembleValue(int mode, int reg, int size, ref int pc)
|
||||
{
|
||||
string value;
|
||||
int addr;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: return "D" + reg; // Dn
|
||||
case 1: return "A" + reg; // An
|
||||
case 2: return "(A" + reg + ")"; // (An)
|
||||
case 3: return "(A" + reg + ")+"; // (An)+
|
||||
case 4: return "-(A" + reg + ")"; // -(An)
|
||||
case 5: value = string.Format("(${0:X},A{1})", ReadOpWord(pc), reg); pc += 2; return value; // (d16,An)
|
||||
case 6: addr = ReadOpWord(pc); pc += 2; return DisassembleIndex("A" + reg, (short)addr); // (d8,An,Xn)
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: value = String.Format("(${0:X})", ReadOpWord(pc)); pc += 2; return value; // (imm).W
|
||||
case 1: value = String.Format("(${0:X})", ReadOpLong(pc)); pc += 4; return value; // (imm).L
|
||||
case 2: value = String.Format("(${0:X})", pc + ReadOpWord(pc)); pc += 2; return value; // (d16,PC)
|
||||
case 3: addr = ReadOpWord(pc); pc += 2; return DisassembleIndex("PC", (short)addr); // (d8,PC,Xn)
|
||||
case 4:
|
||||
switch (size)
|
||||
{
|
||||
case 1: value = String.Format("${0:X}", (byte)ReadOpWord(pc)); pc += 2; return value;
|
||||
case 2: value = String.Format("${0:X}", ReadOpWord(pc)); pc += 2; return value;
|
||||
case 4: value = String.Format("${0:X}", ReadOpLong(pc)); pc += 4; return value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
string DisassembleImmediate(int size, ref int pc)
|
||||
{
|
||||
int immed;
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
immed = (byte)ReadOpWord(pc); pc += 2;
|
||||
return String.Format("${0:X}", immed);
|
||||
case 2:
|
||||
immed = (ushort)ReadOpWord(pc); pc += 2;
|
||||
return String.Format("${0:X}", immed);
|
||||
case 4:
|
||||
immed = ReadOpLong(pc); pc += 4;
|
||||
return String.Format("${0:X}", immed);
|
||||
}
|
||||
throw new ArgumentException("Invalid size");
|
||||
}
|
||||
|
||||
string DisassembleAddress(int mode, int reg, ref int pc)
|
||||
{
|
||||
int addr;
|
||||
switch (mode)
|
||||
{
|
||||
case 0: return "INVALID"; // Dn
|
||||
case 1: return "INVALID"; // An
|
||||
case 2: return "(A" + reg + ")"; // (An)
|
||||
case 3: return "(A" + reg + ")+"; // (An)+
|
||||
case 4: return "-(A" + reg + ")"; // -(An)
|
||||
case 5: addr = ReadOpWord(pc); pc += 2; return String.Format("(${0:X},A{1})", (short)addr, reg); // (d16,An)
|
||||
case 6: addr = ReadOpWord(pc); pc += 2; return DisassembleIndex("A" + reg, (short)addr); // (d8,An,Xn)
|
||||
case 7:
|
||||
switch (reg)
|
||||
{
|
||||
case 0: addr = ReadOpWord(pc); pc += 2; return String.Format("${0:X}.w", addr); // (imm).w
|
||||
case 1: addr = ReadOpLong(pc); pc += 4; return String.Format("${0:X}.l", addr); // (imm).l
|
||||
case 2: addr = ReadOpWord(pc); pc += 2; return String.Format("(${0:X},PC)", addr); // (d16,PC)
|
||||
case 3: addr = ReadOpWord(pc); pc += 2; return DisassembleIndex("PC", (short)addr); // (d8,PC,Xn)
|
||||
case 4: return "INVALID"; // immediate
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
|
||||
void WriteValueB(int mode, int reg, sbyte value)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0x00: // Dn
|
||||
D[reg].s8 = value;
|
||||
return;
|
||||
case 0x01: // An
|
||||
A[reg].s32 = value;
|
||||
return;
|
||||
case 0x02: // (An)
|
||||
WriteByte(A[reg].s32, value);
|
||||
return;
|
||||
case 0x03: // (An)+
|
||||
WriteByte(A[reg].s32, value);
|
||||
A[reg].s32 += reg == 7 ? 2 : 1;
|
||||
return;
|
||||
case 0x04: // -(An)
|
||||
A[reg].s32 -= reg == 7 ? 2 : 1;
|
||||
WriteByte(A[reg].s32, value);
|
||||
return;
|
||||
case 0x05: // (d16,An)
|
||||
WriteByte(A[reg].s32 + ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x06: // (d8,An,Xn)
|
||||
WriteByte(A[reg].s32 + GetIndex(), value);
|
||||
return;
|
||||
case 0x07:
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: // (imm).W
|
||||
WriteByte(ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x01: // (imm).L
|
||||
WriteByte(ReadOpLong(PC), value); PC += 4;
|
||||
return;
|
||||
case 0x02: // (d16,PC)
|
||||
WriteByte(PC + ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x03: // (d8,PC,Xn)
|
||||
int pc = PC;
|
||||
WriteByte(pc + PeekIndex(), value);
|
||||
PC += 2;
|
||||
return;
|
||||
default: throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WriteValueW(int mode, int reg, short value)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0x00: // Dn
|
||||
D[reg].s16 = value;
|
||||
return;
|
||||
case 0x01: // An
|
||||
A[reg].s32 = value;
|
||||
return;
|
||||
case 0x02: // (An)
|
||||
WriteWord(A[reg].s32, value);
|
||||
return;
|
||||
case 0x03: // (An)+
|
||||
WriteWord(A[reg].s32, value);
|
||||
A[reg].s32 += 2;
|
||||
return;
|
||||
case 0x04: // -(An)
|
||||
A[reg].s32 -= 2;
|
||||
WriteWord(A[reg].s32, value);
|
||||
return;
|
||||
case 0x05: // (d16,An)
|
||||
WriteWord(A[reg].s32 + ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x06: // (d8,An,Xn)
|
||||
WriteWord(A[reg].s32 + GetIndex(), value);
|
||||
return;
|
||||
case 0x07:
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: // (imm).W
|
||||
WriteWord(ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x01: // (imm).L
|
||||
WriteWord(ReadOpLong(PC), value); PC += 4;
|
||||
return;
|
||||
case 0x02: // (d16,PC)
|
||||
WriteWord(PC + ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x03: // (d8,PC,Xn)
|
||||
int pc = PC;
|
||||
WriteWord(pc + PeekIndex(), value);
|
||||
PC += 2;
|
||||
return;
|
||||
default: throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WriteValueL(int mode, int reg, int value)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0x00: // Dn
|
||||
D[reg].s32 = value;
|
||||
return;
|
||||
case 0x01: // An
|
||||
A[reg].s32 = value;
|
||||
return;
|
||||
case 0x02: // (An)
|
||||
WriteLong(A[reg].s32, value);
|
||||
return;
|
||||
case 0x03: // (An)+
|
||||
WriteLong(A[reg].s32, value);
|
||||
A[reg].s32 += 4;
|
||||
return;
|
||||
case 0x04: // -(An)
|
||||
A[reg].s32 -= 4;
|
||||
WriteLong(A[reg].s32, value);
|
||||
return;
|
||||
case 0x05: // (d16,An)
|
||||
WriteLong(A[reg].s32 + ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x06: // (d8,An,Xn)
|
||||
WriteLong(A[reg].s32 + GetIndex(), value);
|
||||
return;
|
||||
case 0x07:
|
||||
switch (reg)
|
||||
{
|
||||
case 0x00: // (imm).W
|
||||
WriteLong(ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x01: // (imm).L
|
||||
WriteLong(ReadOpLong(PC), value); PC += 4;
|
||||
return;
|
||||
case 0x02: // (d16,PC)
|
||||
WriteLong(PC + ReadOpWord(PC), value); PC += 2;
|
||||
return;
|
||||
case 0x03: // (d8,PC,Xn)
|
||||
int pc = PC;
|
||||
WriteLong(pc + PeekIndex(), value);
|
||||
PC += 2;
|
||||
return;
|
||||
default: throw new Exception("Invalid addressing mode!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GetIndex()
|
||||
{
|
||||
//EmuLogger.Log("IN INDEX PORTION - NOT VERIFIED!!!");
|
||||
// TODO kid chameleon triggers this in startup sequence
|
||||
|
||||
short extension = ReadOpWord(PC); PC += 2;
|
||||
|
||||
int da = (extension >> 15) & 0x1;
|
||||
int reg = (extension >> 12) & 0x7;
|
||||
int size = (extension >> 11) & 0x1;
|
||||
int scale = (extension >> 9) & 0x3;
|
||||
sbyte displacement = (sbyte)extension;
|
||||
|
||||
int indexReg;
|
||||
switch (scale)
|
||||
{
|
||||
case 0: indexReg = 1; break;
|
||||
case 1: indexReg = 2; break;
|
||||
case 2: indexReg = 4; break;
|
||||
default: indexReg = 8; break;
|
||||
}
|
||||
if (da == 0)
|
||||
indexReg *= size == 0 ? D[reg].s16 : D[reg].s32;
|
||||
else
|
||||
indexReg *= size == 0 ? A[reg].s16 : A[reg].s32;
|
||||
|
||||
return displacement + indexReg;
|
||||
}
|
||||
|
||||
int PeekIndex()
|
||||
{
|
||||
//EmuLogger.Log("IN INDEX PORTION - NOT VERIFIED!!!");
|
||||
|
||||
short extension = ReadOpWord(PC);
|
||||
|
||||
int da = (extension >> 15) & 0x1;
|
||||
int reg = (extension >> 12) & 0x7;
|
||||
int size = (extension >> 11) & 0x1;
|
||||
int scale = (extension >> 9) & 0x3;
|
||||
sbyte displacement = (sbyte)extension;
|
||||
|
||||
int indexReg;
|
||||
switch (scale)
|
||||
{
|
||||
case 0: indexReg = 1; break;
|
||||
case 1: indexReg = 2; break;
|
||||
case 2: indexReg = 4; break;
|
||||
default: indexReg = 8; break;
|
||||
}
|
||||
if (da == 0)
|
||||
indexReg *= size == 0 ? D[reg].s16 : D[reg].s32;
|
||||
else
|
||||
indexReg *= size == 0 ? A[reg].s16 : A[reg].s32;
|
||||
|
||||
return displacement + indexReg;
|
||||
}
|
||||
|
||||
string DisassembleIndex(string baseRegister, short extension)
|
||||
{
|
||||
int d_a = (extension >> 15) & 0x1;
|
||||
int reg = (extension >> 12) & 0x7;
|
||||
int size = (extension >> 11) & 0x1;
|
||||
int scale = (extension >> 9) & 0x3;
|
||||
sbyte displacement = (sbyte)extension;
|
||||
|
||||
string scaleFactor;
|
||||
switch (scale)
|
||||
{
|
||||
case 0: scaleFactor = ""; break;
|
||||
case 1: scaleFactor = "2"; break;
|
||||
case 2: scaleFactor = "4"; break;
|
||||
default: scaleFactor = "8"; break;
|
||||
}
|
||||
|
||||
string offsetRegister = (d_a == 0) ? "D" : "A";
|
||||
string sizeStr = size == 0 ? ".w" : ".l";
|
||||
string displacementStr = displacement == 0 ? "" : ("," + (displacement >= 0 ? "$" + displacement.ToString("X") : "-$" + (-displacement).ToString("X")));
|
||||
return string.Format("({0},{1}{2}{3}{4}{5})", baseRegister, scaleFactor, offsetRegister, reg, sizeStr, displacementStr);
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Memory.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Memory.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ca60a438b9bb004189843e1d4dad73c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
870
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/OpcodeTable.cs
Normal file
870
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/OpcodeTable.cs
Normal file
@ -0,0 +1,870 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace cpu.m68000
|
||||
{
|
||||
partial class MC68000
|
||||
{
|
||||
void BuildOpcodeTable()
|
||||
{
|
||||
Assign("ill", ILL, "", "Data8", "Data8");//
|
||||
Assign("ori2ccr", ORI_CCR, "0000000000111100");//
|
||||
Assign("ori2sr", ORI_SR, "0000000001111100");
|
||||
Assign("ori", ORI, "00000000", "Size2_1", "OAmXn");
|
||||
Assign("andi2ccr", ANDI_CCR, "0000001000111100");//
|
||||
Assign("andi2sr", ANDI_SR, "0000001001111100");
|
||||
Assign("andi", ANDI, "00000010", "Size2_1", "OAmXn");
|
||||
Assign("subi", SUBI, "00000100", "Size2_1", "OAmXn");
|
||||
Assign("addi", ADDI, "00000110", "Size2_1", "OAmXn");
|
||||
Assign("eori2ccr", EORI_CCR, "0000101000111100");//
|
||||
Assign("eori2sr", EORI_SR, "0000101001111100");
|
||||
Assign("eori", EORI, "00001010", "Size2_1", "OAmXn");
|
||||
Assign("cmpi", CMPI, "00001100", "Size2_1", "OAmXn");
|
||||
Assign("btst", BTSTi, "0000100000", "BAmXn");
|
||||
Assign("bchg", BCHGi, "0000100001", "OAmXn");
|
||||
Assign("bclr", BCLRi, "0000100010", "OAmXn");
|
||||
Assign("bset", BSETi, "0000100011", "OAmXn");
|
||||
Assign("btst", BTSTr, "0000", "Xn", "100", "AmXn");
|
||||
Assign("bchg", BCHGr, "0000", "Xn", "101", "OAmXn");
|
||||
Assign("bclr", BCLRr, "0000", "Xn", "110", "OAmXn");
|
||||
Assign("bset", BSETr, "0000", "Xn", "111", "OAmXn");
|
||||
Assign("movep", MOVEP, "0000", "Xn", "1", "Data1", "Size1", "001", "Xn");//
|
||||
Assign("movea", MOVEA, "00", "Size2_2", "Xn", "001", "AmXn");
|
||||
Assign("move", MOVE, "00", "01", "OXnAm", "MAmXn");
|
||||
Assign("move", MOVE, "00", "Size2_2", "OXnAm", "AmXn");
|
||||
Assign("movefsr", MOVEfSR, "0100000011", "OAmXn");
|
||||
Assign("moveccr", MOVECCR, "0100010011", "MAmXn");
|
||||
Assign("move2sr", MOVEtSR, "0100011011", "MAmXn");
|
||||
Assign("negx", NEGX, "01000000", "Size2_1", "OAmXn");//
|
||||
Assign("clr", CLR, "01000010", "Size2_1", "OAmXn");
|
||||
Assign("neg", NEG, "01000100", "Size2_1", "OAmXn");
|
||||
Assign("not", NOT, "01000110", "Size2_1", "OAmXn");
|
||||
Assign("ext", EXT, "010010001", "Size1", "000", "Xn");
|
||||
Assign("nbcd", NBCD, "0100100000", "OAmXn");//
|
||||
Assign("swap", SWAP, "0100100001000", "Xn");
|
||||
Assign("pea", PEA, "0100100001", "LAmXn");
|
||||
Assign("illegal", ILLEGAL, "0100101011111100");//
|
||||
Assign("tas", TAS, "0100101011", "OAmXn");//
|
||||
Assign("tst", TST, "01001010", "Size2_1", "OAmXn");
|
||||
Assign("trap", TRAP, "010011100100", "Data4");
|
||||
Assign("link", LINK, "0100111001010", "Xn");
|
||||
Assign("unlk", UNLK, "0100111001011", "Xn");
|
||||
Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn");
|
||||
Assign("reset", RESET, "0100111001110000");//
|
||||
Assign("nop", NOP, "0100111001110001");
|
||||
Assign("stop", STOP, "0100111001110010");//
|
||||
Assign("rte", RTE, "0100111001110011");
|
||||
Assign("rts", RTS, "0100111001110101");
|
||||
Assign("trapv", TRAPV, "0100111001110110");//
|
||||
Assign("rtr", RTR, "0100111001110111");
|
||||
Assign("jsr", JSR, "0100111010", "LAmXn");
|
||||
Assign("jmp", JMP, "0100111011", "LAmXn");
|
||||
Assign("movem", MOVEM0, "010010001", "Size1", "M2AmXn");
|
||||
Assign("movem", MOVEM1, "010011001", "Size1", "M3AmXn");
|
||||
Assign("lea", LEA, "0100", "Xn", "111", "LAmXn");
|
||||
Assign("chk", CHK, "0100", "Xn", "110", "MAmXn");//
|
||||
Assign("addq", ADDQ, "0101", "Data3", "0", "00", "OAmXn");
|
||||
Assign("addq", ADDQ, "0101", "Data3", "0", "Size2_3", "A2AmXn");
|
||||
Assign("subq", SUBQ, "0101", "Data3", "1", "00", "OAmXn");
|
||||
Assign("subq", SUBQ, "0101", "Data3", "1", "Size2_3", "A2AmXn");
|
||||
Assign("scc", Scc, "0101", "CondAll", "11", "OAmXn");
|
||||
Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn");
|
||||
Assign("bra", BRA, "01100000", "Data8");
|
||||
Assign("bsr", BSR, "01100001", "Data8");
|
||||
Assign("bcc", Bcc, "0110", "CondMain", "Data8");
|
||||
Assign("moveq", MOVEQ, "0111", "Xn", "0", "Data8");
|
||||
Assign("divu", DIVU, "1000", "Xn", "011", "MAmXn");
|
||||
Assign("divs", DIVS, "1000", "Xn", "111", "MAmXn");
|
||||
Assign("sbcd", SBCD0, "1000", "Xn", "100000", "Xn");//
|
||||
Assign("sbcd", SBCD1, "1000", "Xn", "100001", "Xn");//
|
||||
Assign("or", OR0, "1000", "Xn", "0", "Size2_1", "MAmXn");
|
||||
Assign("or", OR1, "1000", "Xn", "1", "Size2_1", "O2AmXn");
|
||||
Assign("sub", SUB0, "1001", "Xn", "0", "00", "MAmXn");
|
||||
Assign("sub", SUB0, "1001", "Xn", "0", "Size2_3", "AmXn");
|
||||
Assign("sub", SUB1, "1001", "Xn", "1", "00", "O2AmXn");
|
||||
Assign("sub", SUB1, "1001", "Xn", "1", "Size2_3", "A2AmXn");
|
||||
Assign("subx", SUBX0, "1001", "Xn", "1", "Size2_1", "000", "Xn");//
|
||||
Assign("subx", SUBX1, "1001", "Xn", "1", "Size2_1", "001", "Xn");//
|
||||
Assign("suba", SUBA, "1001", "Xn", "Size1", "11", "AmXn");
|
||||
Assign("eor", EOR, "1011", "Xn", "1", "Size2_1", "OAmXn");
|
||||
Assign("cmpm", CMPM, "1011", "Xn", "1", "Size2_1", "001", "Xn");
|
||||
Assign("cmp", CMP, "1011", "Xn", "0", "00", "MAmXn");
|
||||
Assign("cmp", CMP, "1011", "Xn", "0", "Size2_3", "AmXn");
|
||||
Assign("cmpa", CMPA, "1011", "Xn", "Size1", "11", "AmXn");
|
||||
Assign("mulu", MULU, "1100", "Xn", "011", "MAmXn");
|
||||
Assign("muls", MULS, "1100", "Xn", "111", "MAmXn");
|
||||
Assign("abcd", ABCD0, "1100", "Xn", "100000", "Xn");//
|
||||
Assign("abcd", ABCD1, "1100", "Xn", "100001", "Xn");//
|
||||
Assign("exg", EXGdd, "1100", "Xn", "101000", "Xn");//
|
||||
Assign("exg", EXGaa, "1100", "Xn", "101001", "Xn");//
|
||||
Assign("exg", EXGda, "1100", "Xn", "110001", "Xn");//
|
||||
Assign("and", AND0, "1100", "Xn", "0", "Size2_1", "MAmXn");
|
||||
Assign("and", AND1, "1100", "Xn", "1", "Size2_1", "O2AmXn");
|
||||
Assign("add", ADD0, "1101", "Xn", "0", "00", "MAmXn");
|
||||
Assign("add", ADD0, "1101", "Xn", "0", "Size2_3", "AmXn");
|
||||
Assign("add", ADD1, "1101", "Xn", "1", "Size2_1", "O2AmXn");
|
||||
Assign("addx", ADDX0, "1101", "Xn", "1", "Size2_1", "000", "Xn");//
|
||||
Assign("addx", ADDX1, "1101", "Xn", "1", "Size2_1", "001", "Xn");//
|
||||
Assign("adda", ADDA, "1101", "Xn", "Size1", "11", "AmXn");
|
||||
Assign("asl", ASLd0, "1110000111", "O2AmXn");//
|
||||
Assign("asr", ASRd0, "1110000011", "O2AmXn");//
|
||||
Assign("lsl", LSLd0, "1110001111", "O2AmXn");//
|
||||
Assign("lsr", LSRd0, "1110001011", "O2AmXn");//
|
||||
Assign("roxl", ROXLd0, "1110010111", "O2AmXn");//
|
||||
Assign("roxr", ROXRd0, "1110010011", "O2AmXn");//
|
||||
Assign("rol", ROLd0, "1110011111", "O2AmXn");//
|
||||
Assign("ror", RORd0, "1110011011", "O2AmXn");//
|
||||
Assign("asl", ASLd, "1110", "Data3", "1", "Size2_1", "Data1", "00", "Xn");
|
||||
Assign("asr", ASRd, "1110", "Data3", "0", "Size2_1", "Data1", "00", "Xn");
|
||||
Assign("lsl", LSLd, "1110", "Data3", "1", "Size2_1", "Data1", "01", "Xn");
|
||||
Assign("lsr", LSRd, "1110", "Data3", "0", "Size2_1", "Data1", "01", "Xn");
|
||||
Assign("roxl", ROXLd, "1110", "Data3", "1", "Size2_1", "Data1", "10", "Xn");
|
||||
Assign("roxr", ROXRd, "1110", "Data3", "0", "Size2_1", "Data1", "10", "Xn");
|
||||
Assign("rol", ROLd, "1110", "Data3", "1", "Size2_1", "Data1", "11", "Xn");
|
||||
Assign("ror", RORd, "1110", "Data3", "0", "Size2_1", "Data1", "11", "Xn");
|
||||
}
|
||||
|
||||
void Assign(string instr, Action exec, string root, params string[] bitfield)
|
||||
{
|
||||
List<string> opList = new List<string>();
|
||||
opList.Add(root);
|
||||
foreach (var component in bitfield)
|
||||
{
|
||||
if (IsBinary(component)) AppendConstant(opList, component);
|
||||
else if (component == "Size1") opList = AppendPermutations(opList, Size1);
|
||||
else if (component == "Size2_0") opList = AppendPermutations(opList, Size2_0);
|
||||
else if (component == "Size2_1") opList = AppendPermutations(opList, Size2_1);
|
||||
else if (component == "Size2_2") opList = AppendPermutations(opList, Size2_2);
|
||||
else if (component == "Size2_3") opList = AppendPermutations(opList, Size2_3);
|
||||
else if (component == "OXnAm") opList = AppendPermutations(opList, OXn3Am3);//0,2-6,7_0-7_1
|
||||
else if (component == "AmXn") opList = AppendPermutations(opList, Am3Xn3);//0-6,7_0-7_4
|
||||
else if (component == "OAmXn") opList = AppendPermutations(opList, OAm3Xn3);//0,2-6,7_0-7_1
|
||||
else if (component == "BAmXn") opList = AppendPermutations(opList, BAm3Xn3);//0,2-6,7_0-7_3
|
||||
else if (component == "MAmXn") opList = AppendPermutations(opList, MAm3Xn3);//0,2-6,7_0-7_4
|
||||
else if (component == "AAmXn") opList = AppendPermutations(opList, AAm3Xn3);//1-6,7_0-7_4
|
||||
else if (component == "LAmXn") opList = AppendPermutations(opList, LAm3Xn3);//2,5-6,7_0-7_3
|
||||
else if (component == "M2AmXn") opList = AppendPermutations(opList, M2Am3Xn3);//2,4-6,7_0-7_1
|
||||
else if (component == "M3AmXn") opList = AppendPermutations(opList, M3Am3Xn3);//2-3,5-6,7_0-7_3
|
||||
else if (component == "A2AmXn") opList = AppendPermutations(opList, A2Am3Xn3);//0-6,7_0-7_1
|
||||
else if (component == "O2AmXn") opList = AppendPermutations(opList, O2Am3Xn3);//2-6,7_0-7_1
|
||||
else if (component == "Xn") opList = AppendPermutations(opList, Xn3);
|
||||
else if (component == "CondMain") opList = AppendPermutations(opList, ConditionMain);
|
||||
else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll);
|
||||
else if (component == "Data1") opList = AppendData(opList, 1);
|
||||
else if (component == "Data3") opList = AppendData(opList, 3);
|
||||
else if (component == "Data4") opList = AppendData(opList, 4);
|
||||
else if (component == "Data8") opList = AppendData(opList, 8);
|
||||
}
|
||||
foreach (var opcode in opList)
|
||||
{
|
||||
int opc = Convert.ToInt32(opcode, 2);
|
||||
Opcodes[opc] = exec;
|
||||
}
|
||||
}
|
||||
|
||||
void AppendConstant(List<string> ops, string constant)
|
||||
{
|
||||
for (int i = 0; i < ops.Count; i++)
|
||||
ops[i] = ops[i] + constant;
|
||||
}
|
||||
|
||||
List<string> AppendPermutations(List<string> ops, string[] permutations)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
|
||||
foreach (var input in ops)
|
||||
foreach (var perm in permutations)
|
||||
output.Add(input + perm);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
List<string> AppendData(List<string> ops, int bits)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
|
||||
foreach (var input in ops)
|
||||
for (int i = 0; i < BinaryExp(bits); i++)
|
||||
output.Add(input + Convert.ToString(i, 2).PadLeft(bits, '0'));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int BinaryExp(int bits)
|
||||
{
|
||||
int res = 1;
|
||||
for (int i = 0; i < bits; i++)
|
||||
res *= 2;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IsBinary(string str)
|
||||
{
|
||||
for (int i = 0; i < str.Length; i++)
|
||||
{
|
||||
char c = str[i];
|
||||
if (c == '0' || c == '1')
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Tables
|
||||
|
||||
static readonly string[] Size2_0 = { "01", "11", "10" };
|
||||
static readonly string[] Size2_1 = { "00", "01", "10" };
|
||||
static readonly string[] Size2_2 = { "11", "10" };
|
||||
static readonly string[] Size2_3 = { "01", "10" };
|
||||
static readonly string[] Size1 = { "0", "1" };
|
||||
static readonly string[] Xn3 = { "000", "001", "010", "011", "100", "101", "110", "111" };
|
||||
|
||||
static readonly string[] OXn3Am3 = {
|
||||
"000000", // Dn Data register
|
||||
"001000",
|
||||
"010000",
|
||||
"011000",
|
||||
"100000",
|
||||
"101000",
|
||||
"110000",
|
||||
"111000",
|
||||
|
||||
"000010", // (An) Address
|
||||
"001010",
|
||||
"010010",
|
||||
"011010",
|
||||
"100010",
|
||||
"101010",
|
||||
"110010",
|
||||
"111010",
|
||||
|
||||
"000011", // (An)+ Address with Postincrement
|
||||
"001011",
|
||||
"010011",
|
||||
"011011",
|
||||
"100011",
|
||||
"101011",
|
||||
"110011",
|
||||
"111011",
|
||||
|
||||
"000100", // -(An) Address with Predecrement
|
||||
"001100",
|
||||
"010100",
|
||||
"011100",
|
||||
"100100",
|
||||
"101100",
|
||||
"110100",
|
||||
"111100",
|
||||
|
||||
"000101", // (d16, An) Address with Displacement
|
||||
"001101",
|
||||
"010101",
|
||||
"011101",
|
||||
"100101",
|
||||
"101101",
|
||||
"110101",
|
||||
"111101",
|
||||
|
||||
"000110", // (d8, An, Xn) Address with Index
|
||||
"001110",
|
||||
"010110",
|
||||
"011110",
|
||||
"100110",
|
||||
"101110",
|
||||
"110110",
|
||||
"111110",
|
||||
|
||||
"000111", // (xxx).W Absolute Short
|
||||
"001111", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] Am3Xn3 = {
|
||||
"000000", // Dn Data register
|
||||
"000001",
|
||||
"000010",
|
||||
"000011",
|
||||
"000100",
|
||||
"000101",
|
||||
"000110",
|
||||
"000111",
|
||||
|
||||
"001000", // An Address register
|
||||
"001001",
|
||||
"001010",
|
||||
"001011",
|
||||
"001100",
|
||||
"001101",
|
||||
"001110",
|
||||
"001111",
|
||||
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111010", // (d16, PC) PC with Displacement
|
||||
"111011", // (d8, PC, Xn) PC with Index
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
"111100", // #imm Immediate
|
||||
};
|
||||
|
||||
static readonly string[] OAm3Xn3 = {
|
||||
"000000", // Dn Data register
|
||||
"000001",
|
||||
"000010",
|
||||
"000011",
|
||||
"000100",
|
||||
"000101",
|
||||
"000110",
|
||||
"000111",
|
||||
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] BAm3Xn3 = {
|
||||
"000000", // Dn Data register
|
||||
"000001",
|
||||
"000010",
|
||||
"000011",
|
||||
"000100",
|
||||
"000101",
|
||||
"000110",
|
||||
"000111",
|
||||
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111010", // (d16, PC) PC with Displacement
|
||||
"111011", // (d8, PC, Xn) PC with Index
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] MAm3Xn3 = {
|
||||
"000000", // Dn Data register
|
||||
"000001",
|
||||
"000010",
|
||||
"000011",
|
||||
"000100",
|
||||
"000101",
|
||||
"000110",
|
||||
"000111",
|
||||
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111010", // (d16, PC) PC with Displacement
|
||||
"111011", // (d8, PC, Xn) PC with Index
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
"111100", // #imm Immediate
|
||||
};
|
||||
|
||||
static readonly string[] AAm3Xn3 = {
|
||||
"001000", // An Address register
|
||||
"001001",
|
||||
"001010",
|
||||
"001011",
|
||||
"001100",
|
||||
"001101",
|
||||
"001110",
|
||||
"001111",
|
||||
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111010", // (d16, PC) PC with Displacement
|
||||
"111011", // (d8, PC, Xn) PC with Index
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
"111100", // #imm Immediate
|
||||
};
|
||||
|
||||
static readonly string[] LAm3Xn3 = {
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111010", // (d16, PC) PC with Displacement
|
||||
"111011", // (d8, PC, Xn) PC with Index
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] M2Am3Xn3 = {
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] M3Am3Xn3 = {
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111010", // (d16, PC) PC with Displacement
|
||||
"111011", // (d8, PC, Xn) PC with Index
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] A2Am3Xn3 = {
|
||||
"000000", // Dn Data register
|
||||
"000001",
|
||||
"000010",
|
||||
"000011",
|
||||
"000100",
|
||||
"000101",
|
||||
"000110",
|
||||
"000111",
|
||||
|
||||
"001000", // An Address register
|
||||
"001001",
|
||||
"001010",
|
||||
"001011",
|
||||
"001100",
|
||||
"001101",
|
||||
"001110",
|
||||
"001111",
|
||||
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] O2Am3Xn3 = {
|
||||
"010000", // (An) Address
|
||||
"010001",
|
||||
"010010",
|
||||
"010011",
|
||||
"010100",
|
||||
"010101",
|
||||
"010110",
|
||||
"010111",
|
||||
|
||||
"011000", // (An)+ Address with Postincrement
|
||||
"011001",
|
||||
"011010",
|
||||
"011011",
|
||||
"011100",
|
||||
"011101",
|
||||
"011110",
|
||||
"011111",
|
||||
|
||||
"100000", // -(An) Address with Predecrement
|
||||
"100001",
|
||||
"100010",
|
||||
"100011",
|
||||
"100100",
|
||||
"100101",
|
||||
"100110",
|
||||
"100111",
|
||||
|
||||
"101000", // (d16, An) Address with Displacement
|
||||
"101001",
|
||||
"101010",
|
||||
"101011",
|
||||
"101100",
|
||||
"101101",
|
||||
"101110",
|
||||
"101111",
|
||||
|
||||
"110000", // (d8, An, Xn) Address with Index
|
||||
"110001",
|
||||
"110010",
|
||||
"110011",
|
||||
"110100",
|
||||
"110101",
|
||||
"110110",
|
||||
"110111",
|
||||
|
||||
"111000", // (xxx).W Absolute Short
|
||||
"111001", // (xxx).L Absolute Long
|
||||
};
|
||||
|
||||
static readonly string[] ConditionMain = {
|
||||
"0010", // HI Higher (unsigned)
|
||||
"0011", // LS Lower or Same (unsigned)
|
||||
"0100", // CC Carry Clear (aka Higher or Same, unsigned)
|
||||
"0101", // CS Carry Set (aka Lower, unsigned)
|
||||
"0110", // NE Not Equal
|
||||
"0111", // EQ Equal
|
||||
"1000", // VC Overflow Clear
|
||||
"1001", // VS Overflow Set
|
||||
"1010", // PL Plus
|
||||
"1011", // MI Minus
|
||||
"1100", // GE Greater or Equal (signed)
|
||||
"1101", // LT Less Than (signed)
|
||||
"1110", // GT Greater Than (signed)
|
||||
"1111" // LE Less or Equal (signed)
|
||||
};
|
||||
|
||||
static readonly string[] ConditionAll = {
|
||||
"0000", // T True
|
||||
"0001", // F False
|
||||
"0010", // HI Higher (unsigned)
|
||||
"0011", // LS Lower or Same (unsigned)
|
||||
"0100", // CC Carry Clear (aka Higher or Same, unsigned)
|
||||
"0101", // CS Carry Set (aka Lower, unsigned)
|
||||
"0110", // NE Not Equal
|
||||
"0111", // EQ Equal
|
||||
"1000", // VC Overflow Clear
|
||||
"1001", // VS Overflow Set
|
||||
"1010", // PL Plus
|
||||
"1011", // MI Minus
|
||||
"1100", // GE Greater or Equal (signed)
|
||||
"1101", // LT Less Than (signed)
|
||||
"1110", // GT Greater Than (signed)
|
||||
"1111" // LE Less or Equal (signed)
|
||||
};
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f558f03c67bd724291c979f90d0acff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
70
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Tables.cs
Normal file
70
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Tables.cs
Normal file
@ -0,0 +1,70 @@
|
||||
namespace cpu.m68000
|
||||
{
|
||||
partial class MC68000
|
||||
{
|
||||
static readonly int[,] MoveCyclesBW = new int[12, 9]
|
||||
{
|
||||
{ 4, 4, 8, 8, 8, 12, 14, 12, 16 },
|
||||
{ 4, 4, 8, 8, 8, 12, 14, 12, 16 },
|
||||
{ 8, 8, 12, 12, 12, 16, 18, 16, 20 },
|
||||
{ 8, 8, 12, 12, 12, 16, 18, 16, 20 },
|
||||
{ 10, 10, 14, 14, 14, 18, 20, 18, 22 },
|
||||
{ 12, 12, 16, 16, 16, 20, 22, 20, 24 },
|
||||
{ 14, 14, 18, 18, 18, 22, 24, 22, 26 },
|
||||
{ 12, 12, 16, 16, 16, 20, 22, 20, 24 },
|
||||
{ 16, 16, 20, 20, 20, 24, 26, 24, 28 },
|
||||
{ 12, 12, 16, 16, 16, 20, 22, 20, 24 },
|
||||
{ 14, 14, 18, 18, 18, 22, 24, 22, 26 },
|
||||
{ 8, 8, 12, 12, 12, 16, 18, 16, 20 }
|
||||
};
|
||||
|
||||
static readonly int[,] MoveCyclesL = new int[12, 9]
|
||||
{
|
||||
{ 4, 4, 12, 12, 12, 16, 18, 16, 20 },
|
||||
{ 4, 4, 12, 12, 12, 16, 18, 16, 20 },
|
||||
{ 12, 12, 20, 20, 20, 24, 26, 24, 28 },
|
||||
{ 12, 12, 20, 20, 20, 24, 26, 24, 28 },
|
||||
{ 14, 14, 22, 22, 22, 26, 28, 26, 30 },
|
||||
{ 16, 16, 24, 24, 24, 28, 30, 28, 32 },
|
||||
{ 18, 18, 26, 26, 26, 30, 32, 30, 34 },
|
||||
{ 16, 16, 24, 24, 24, 28, 30, 28, 32 },
|
||||
{ 20, 20, 28, 28, 28, 32, 34, 32, 36 },
|
||||
{ 16, 16, 24, 24, 24, 28, 30, 28, 32 },
|
||||
{ 18, 18, 26, 26, 26, 30, 32, 30, 34 },
|
||||
{ 12, 12, 20, 20, 20, 24, 26, 24, 28 }
|
||||
};
|
||||
|
||||
static readonly int[,] EACyclesBW = new int[8, 8]
|
||||
{
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||
{ 6, 6, 6, 6, 6, 6, 6, 6 },
|
||||
{ 8, 8, 8, 8, 8, 8, 8, 8 },
|
||||
{ 10, 10, 10, 10, 10, 10, 10, 10 },
|
||||
{ 8, 12, 8, 10, 4, 99, 99, 99 }
|
||||
};
|
||||
|
||||
static readonly int[,] EACyclesL = new int[8, 8]
|
||||
{
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 8, 8, 8, 8, 8, 8, 8, 8 },
|
||||
{ 8, 8, 8, 8, 8, 8, 8, 8 },
|
||||
{ 10, 10, 10, 10, 10, 10, 10, 10 },
|
||||
{ 12, 12, 12, 12, 12, 12, 12, 12 },
|
||||
{ 14, 14, 14, 14, 14, 14, 14, 14 },
|
||||
{ 12, 16, 12, 14, 8, 99, 99, 99 }
|
||||
};
|
||||
static readonly int[] CyclesException = new int[0x30]
|
||||
{
|
||||
0x04, 0x04, 0x32, 0x32, 0x22, 0x26, 0x28, 0x22,
|
||||
0x22, 0x22, 0x04, 0x04, 0x04, 0x04, 0x04, 0x2C,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
|
||||
};
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Tables.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m68000/Tables.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd115883ec0396d42abef36787464a37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cec51d80caf2184681dc0898d9dec38
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
911
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805.cs
Normal file
911
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805.cs
Normal file
@ -0,0 +1,911 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace cpu.m6805
|
||||
{
|
||||
public partial class M6805 : cpuexec_data
|
||||
{
|
||||
public static M6805 m1;
|
||||
public Register ea, pc, s;
|
||||
public int subtype;
|
||||
public ushort sp_mask;
|
||||
public ushort sp_low;
|
||||
public byte a, x, cc;
|
||||
public ushort pending_interrupts;
|
||||
public delegate int irq_delegate(int i);
|
||||
public irq_delegate irq_callback;
|
||||
public int[] irq_state;
|
||||
public int nmi_state;
|
||||
public byte CFLAG = 0x01, ZFLAG = 0x02, NFLAG = 0x04, IFLAG = 0x08, HFLAG = 0x10;
|
||||
public int SUBTYPE_M6805 = 0, SUBTYPE_M68705 = 1, SUBTYPE_HD63705 = 2;
|
||||
public byte[] flags8i = new byte[256] /* increment */
|
||||
{
|
||||
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,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
|
||||
};
|
||||
public byte[] flags8d = new byte[256] /* decrement */
|
||||
{
|
||||
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,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
|
||||
};
|
||||
public byte[] cycles1 = new byte[]
|
||||
{
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
/*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
/*1*/ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
/*2*/ 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
/*3*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 0, 6, 6, 0,
|
||||
/*4*/ 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
|
||||
/*5*/ 4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
|
||||
/*6*/ 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7,
|
||||
/*7*/ 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6,
|
||||
/*8*/ 9, 6, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*9*/ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2,
|
||||
/*A*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 8, 2, 0,
|
||||
/*B*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5,
|
||||
/*C*/ 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
|
||||
/*D*/ 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 5, 9, 6, 7,
|
||||
/*E*/ 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
|
||||
/*F*/ 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5
|
||||
};
|
||||
private ulong totalExecutedCycles;
|
||||
private int pendingCycles;
|
||||
public override ulong TotalExecutedCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalExecutedCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
totalExecutedCycles = value;
|
||||
}
|
||||
}
|
||||
public override int PendingCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return pendingCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
pendingCycles = value;
|
||||
}
|
||||
}
|
||||
public Func<ushort, byte> ReadOp, ReadOpArg;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
|
||||
public M6805()
|
||||
{
|
||||
irq_state = new int[9];
|
||||
m6805_init(Cpuint.cpu_3_irq_callback);
|
||||
}
|
||||
public override void Reset()
|
||||
{
|
||||
m6805_reset();
|
||||
}
|
||||
private void SP_INC()
|
||||
{
|
||||
if (++s.LowWord > sp_mask)
|
||||
{
|
||||
s.LowWord = sp_low;
|
||||
}
|
||||
}
|
||||
private void SP_DEC()
|
||||
{
|
||||
if (--s.LowWord < sp_low)
|
||||
{
|
||||
s.LowWord = sp_mask;
|
||||
}
|
||||
}
|
||||
private ushort SP_ADJUST(ushort a)
|
||||
{
|
||||
return (ushort)(((a) & sp_mask) | sp_low);
|
||||
}
|
||||
private void IMMBYTE(ref byte b)
|
||||
{
|
||||
b = ReadOpArg(pc.LowWord++);
|
||||
}
|
||||
private void IMMWORD(ref Register w)
|
||||
{
|
||||
w.d = 0;
|
||||
w.HighByte = ReadOpArg(pc.LowWord);
|
||||
w.LowByte = ReadOpArg((ushort)(pc.LowWord + 1));
|
||||
pc.LowWord += 2;
|
||||
}
|
||||
private void PUSHBYTE(ref byte b)
|
||||
{
|
||||
wr_s_handler_b(ref b);
|
||||
}
|
||||
private void PUSHWORD(ref Register w)
|
||||
{
|
||||
wr_s_handler_w(ref w);
|
||||
}
|
||||
private void PULLBYTE(ref byte b)
|
||||
{
|
||||
rd_s_handler_b(ref b);
|
||||
}
|
||||
private void PULLWORD(ref Register w)
|
||||
{
|
||||
rd_s_handler_w(ref w);
|
||||
}
|
||||
private void CLR_NZ()
|
||||
{
|
||||
cc &= (byte)~(NFLAG | ZFLAG);
|
||||
}
|
||||
private void CLR_HNZC()
|
||||
{
|
||||
cc &= (byte)~(HFLAG | NFLAG | ZFLAG | CFLAG);
|
||||
}
|
||||
private void CLR_Z()
|
||||
{
|
||||
cc &= (byte)~(ZFLAG);
|
||||
}
|
||||
private void CLR_NZC()
|
||||
{
|
||||
cc &= (byte)~(NFLAG | ZFLAG | CFLAG);
|
||||
}
|
||||
private void CLR_ZC()
|
||||
{
|
||||
cc &= (byte)~(ZFLAG | CFLAG);
|
||||
}
|
||||
private void SET_Z(byte b)
|
||||
{
|
||||
if (b == 0)
|
||||
{
|
||||
SEZ();
|
||||
}
|
||||
}
|
||||
private void SET_Z8(byte b)
|
||||
{
|
||||
SET_Z((byte)b);
|
||||
}
|
||||
private void SET_N8(byte b)
|
||||
{
|
||||
cc |= (byte)((b & 0x80) >> 5);
|
||||
}
|
||||
private void SET_H(byte a, byte b, byte r)
|
||||
{
|
||||
cc |= (byte)((a ^ b ^ r) & 0x10);
|
||||
}
|
||||
private void SET_C8(ushort b)
|
||||
{
|
||||
cc |= (byte)((b & 0x100) >> 8);
|
||||
}
|
||||
private void SET_FLAGS8I(byte b)
|
||||
{
|
||||
cc |= flags8i[b & 0xff];
|
||||
}
|
||||
private void SET_FLAGS8D(byte b)
|
||||
{
|
||||
cc |= flags8d[b & 0xff];
|
||||
}
|
||||
private void SET_NZ8(byte b)
|
||||
{
|
||||
SET_N8(b);
|
||||
SET_Z(b);
|
||||
}
|
||||
private void SET_FLAGS8(byte a, byte b, ushort r)
|
||||
{
|
||||
SET_N8((byte)r);
|
||||
SET_Z8((byte)r);
|
||||
SET_C8(r);
|
||||
}
|
||||
private short SIGNED(byte b)
|
||||
{
|
||||
return (short)((b & 0x80) != 0 ? b | 0xff00 : b);
|
||||
}
|
||||
private void DIRECT()
|
||||
{
|
||||
ea.d = 0;
|
||||
IMMBYTE(ref ea.LowByte);
|
||||
}
|
||||
private void IMM8()
|
||||
{
|
||||
ea.LowWord = pc.LowWord++;
|
||||
}
|
||||
private void EXTENDED()
|
||||
{
|
||||
IMMWORD(ref ea);
|
||||
}
|
||||
private void INDEXED()
|
||||
{
|
||||
ea.LowWord = x;
|
||||
}
|
||||
private void INDEXED1()
|
||||
{
|
||||
ea.d = 0;
|
||||
IMMBYTE(ref ea.LowByte);
|
||||
ea.LowWord += x;
|
||||
}
|
||||
private void INDEXED2()
|
||||
{
|
||||
IMMWORD(ref ea);
|
||||
ea.LowWord += x;
|
||||
}
|
||||
private void SEC()
|
||||
{
|
||||
cc |= CFLAG;
|
||||
}
|
||||
private void CLC()
|
||||
{
|
||||
cc &= (byte)~CFLAG;
|
||||
}
|
||||
private void SEZ()
|
||||
{
|
||||
cc |= ZFLAG;
|
||||
}
|
||||
private void CLZ()
|
||||
{
|
||||
cc &= (byte)~ZFLAG;
|
||||
}
|
||||
private void SEN()
|
||||
{
|
||||
cc |= NFLAG;
|
||||
}
|
||||
private void CLN()
|
||||
{
|
||||
cc &= (byte)~NFLAG;
|
||||
}
|
||||
private void SEH()
|
||||
{
|
||||
cc |= HFLAG;
|
||||
}
|
||||
private void CLH()
|
||||
{
|
||||
cc &= (byte)~HFLAG;
|
||||
}
|
||||
private void SEI()
|
||||
{
|
||||
cc |= IFLAG;
|
||||
}
|
||||
private void CLI()
|
||||
{
|
||||
cc &= (byte)~IFLAG;
|
||||
}
|
||||
private void DIRBYTE(ref byte b)
|
||||
{
|
||||
DIRECT();
|
||||
b = ReadMemory((ushort)ea.d);
|
||||
}
|
||||
private void EXTBYTE(ref byte b)
|
||||
{
|
||||
EXTENDED();
|
||||
b = ReadMemory((ushort)ea.d);
|
||||
}
|
||||
private void IDXBYTE(ref byte b)
|
||||
{
|
||||
INDEXED();
|
||||
b = ReadMemory((ushort)ea.d);
|
||||
}
|
||||
private void IDX1BYTE(ref byte b)
|
||||
{
|
||||
INDEXED1();
|
||||
b = ReadMemory((ushort)ea.d);
|
||||
}
|
||||
private void IDX2BYTE(ref byte b)
|
||||
{
|
||||
INDEXED2();
|
||||
b = ReadMemory((ushort)ea.d);
|
||||
}
|
||||
private void BRANCH(bool f)
|
||||
{
|
||||
byte t = 0;
|
||||
IMMBYTE(ref t);
|
||||
if (f)
|
||||
{
|
||||
pc.LowWord += (ushort)SIGNED(t);
|
||||
//change_pc(PC);
|
||||
if (t == 0xfe)
|
||||
{
|
||||
if (pendingCycles > 0)
|
||||
{
|
||||
pendingCycles = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void CLEAR_PAIR(ref Register p)
|
||||
{
|
||||
p.d = 0;
|
||||
}
|
||||
private void rd_s_handler_b(ref byte b)
|
||||
{
|
||||
SP_INC();
|
||||
b = ReadMemory(s.LowWord);
|
||||
}
|
||||
private void rd_s_handler_w(ref Register p)
|
||||
{
|
||||
CLEAR_PAIR(ref p);
|
||||
SP_INC();
|
||||
p.HighByte = ReadMemory(s.LowWord);
|
||||
SP_INC();
|
||||
p.LowByte = ReadMemory(s.LowWord);
|
||||
}
|
||||
private void wr_s_handler_b(ref byte b)
|
||||
{
|
||||
WriteMemory(s.LowWord, b);
|
||||
SP_DEC();
|
||||
}
|
||||
private void wr_s_handler_w(ref Register p)
|
||||
{
|
||||
WriteMemory(s.LowWord, p.LowByte);
|
||||
SP_DEC();
|
||||
WriteMemory(s.LowWord, p.HighByte);
|
||||
SP_DEC();
|
||||
}
|
||||
protected void RM16(uint Addr, ref Register p)
|
||||
{
|
||||
CLEAR_PAIR(ref p);
|
||||
p.HighByte = ReadMemory((ushort)Addr);
|
||||
++Addr;
|
||||
p.LowByte = ReadMemory((ushort)Addr);
|
||||
}
|
||||
private void m68705_Interrupt()
|
||||
{
|
||||
if ((pending_interrupts & ((1 << 0) | 0x03)) != 0)
|
||||
{
|
||||
if ((cc & IFLAG) == 0)
|
||||
{
|
||||
PUSHWORD(ref pc);
|
||||
PUSHBYTE(ref x);
|
||||
PUSHBYTE(ref a);
|
||||
PUSHBYTE(ref cc);
|
||||
SEI();
|
||||
if (irq_callback != null)
|
||||
{
|
||||
irq_callback(0);
|
||||
}
|
||||
if ((pending_interrupts & (1 << 0)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)(~(1 << 0)));
|
||||
RM16(0xfffa, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x01)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)(~(1 << 0x01)));
|
||||
RM16(0xfff8, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
}
|
||||
pendingCycles -= 11;
|
||||
}
|
||||
}
|
||||
private void Interrupt()
|
||||
{
|
||||
if ((pending_interrupts & (1 << 0x08)) != 0)
|
||||
{
|
||||
PUSHWORD(ref pc);
|
||||
PUSHBYTE(ref x);
|
||||
PUSHBYTE(ref a);
|
||||
PUSHBYTE(ref cc);
|
||||
SEI();
|
||||
if (irq_callback != null)
|
||||
{
|
||||
irq_callback(0);
|
||||
}
|
||||
RM16(0x1ffc, ref pc);
|
||||
//change_pc(PC);
|
||||
pending_interrupts &= unchecked((ushort)(~(1 << 0x08)));
|
||||
pendingCycles -= 11;
|
||||
}
|
||||
else if ((pending_interrupts & ((1 << 0) | 0x1ff)) != 0)
|
||||
{
|
||||
if ((cc & IFLAG) == 0)
|
||||
{
|
||||
{
|
||||
PUSHWORD(ref pc);
|
||||
PUSHBYTE(ref x);
|
||||
PUSHBYTE(ref a);
|
||||
PUSHBYTE(ref cc);
|
||||
SEI();
|
||||
if (irq_callback != null)
|
||||
{
|
||||
irq_callback(0);
|
||||
}
|
||||
if (subtype == SUBTYPE_HD63705)
|
||||
{
|
||||
if ((pending_interrupts & (1 << 0x00)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x00));
|
||||
RM16(0x1ff8, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x01)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x01));
|
||||
RM16(0x1fec, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x07)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x07));
|
||||
RM16(0x1fea, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x02)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x02));
|
||||
RM16(0x1ff6, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x03)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x03));
|
||||
RM16(0x1ff4, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x04)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x04));
|
||||
RM16(0x1ff2, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x05)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x05));
|
||||
RM16(0x1ff0, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
else if ((pending_interrupts & (1 << 0x06)) != 0)
|
||||
{
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0x06));
|
||||
RM16(0x1fee, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RM16(0xffff - 5, ref pc);
|
||||
//change_pc(PC);
|
||||
}
|
||||
|
||||
} // CC & IFLAG
|
||||
pending_interrupts &= unchecked((ushort)~(1 << 0));
|
||||
}
|
||||
pendingCycles -= 11;
|
||||
}
|
||||
}
|
||||
private void m6805_init(irq_delegate irqcallback)
|
||||
{
|
||||
irq_callback = irqcallback;
|
||||
}
|
||||
protected void m6805_reset()
|
||||
{
|
||||
/*int (*save_irqcallback)(int) = m6805.irq_callback;
|
||||
memset(&m6805, 0, sizeof(m6805));
|
||||
m6805.irq_callback = save_irqcallback;*/
|
||||
int i;
|
||||
ea.d = 0;
|
||||
pc.d = 0;
|
||||
s.d = 0;
|
||||
a = 0;
|
||||
x = 0;
|
||||
cc = 0;
|
||||
pending_interrupts = 0;
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
irq_state[i] = 0;
|
||||
}
|
||||
nmi_state = 0;
|
||||
subtype = SUBTYPE_M6805;
|
||||
sp_mask = 0x07f;
|
||||
sp_low = 0x060;
|
||||
s.LowWord = sp_mask;
|
||||
SEI();
|
||||
RM16(0xfffe, ref pc);
|
||||
}
|
||||
public override void set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
if (irq_state[0] == (int)state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
irq_state[0] = (int)state;
|
||||
if (state != (int)LineState.CLEAR_LINE)
|
||||
{
|
||||
pending_interrupts |= 1 << 0;
|
||||
}
|
||||
}
|
||||
public override void cpunum_set_input_line_and_vector(int cpunum, int line, LineState state, int vector)
|
||||
{
|
||||
EmuTimer.timer_set_internal(Cpuint.cpunum_empty_event_queue, "cpunum_empty_event_queue");
|
||||
}
|
||||
public override int ExecuteCycles(int cycles)
|
||||
{
|
||||
return m6805_execute(cycles);
|
||||
}
|
||||
public int m6805_execute(int cycles)
|
||||
{
|
||||
byte ireg;
|
||||
pendingCycles = cycles;
|
||||
do
|
||||
{
|
||||
int prevCycles = pendingCycles;
|
||||
if (pending_interrupts != 0)
|
||||
{
|
||||
if (subtype == SUBTYPE_M68705)
|
||||
{
|
||||
m68705_Interrupt();
|
||||
}
|
||||
else
|
||||
{
|
||||
Interrupt();
|
||||
}
|
||||
}
|
||||
//debugger_instruction_hook(Machine, PC);
|
||||
ireg = ReadOp(pc.LowWord++);
|
||||
switch (ireg)
|
||||
{
|
||||
case 0x00: brset(0x01); break;
|
||||
case 0x01: brclr(0x01); break;
|
||||
case 0x02: brset(0x02); break;
|
||||
case 0x03: brclr(0x02); break;
|
||||
case 0x04: brset(0x04); break;
|
||||
case 0x05: brclr(0x04); break;
|
||||
case 0x06: brset(0x08); break;
|
||||
case 0x07: brclr(0x08); break;
|
||||
case 0x08: brset(0x10); break;
|
||||
case 0x09: brclr(0x10); break;
|
||||
case 0x0A: brset(0x20); break;
|
||||
case 0x0B: brclr(0x20); break;
|
||||
case 0x0C: brset(0x40); break;
|
||||
case 0x0D: brclr(0x40); break;
|
||||
case 0x0E: brset(0x80); break;
|
||||
case 0x0F: brclr(0x80); break;
|
||||
case 0x10: bset(0x01); break;
|
||||
case 0x11: bclr(0x01); break;
|
||||
case 0x12: bset(0x02); break;
|
||||
case 0x13: bclr(0x02); break;
|
||||
case 0x14: bset(0x04); break;
|
||||
case 0x15: bclr(0x04); break;
|
||||
case 0x16: bset(0x08); break;
|
||||
case 0x17: bclr(0x08); break;
|
||||
case 0x18: bset(0x10); break;
|
||||
case 0x19: bclr(0x10); break;
|
||||
case 0x1a: bset(0x20); break;
|
||||
case 0x1b: bclr(0x20); break;
|
||||
case 0x1c: bset(0x40); break;
|
||||
case 0x1d: bclr(0x40); break;
|
||||
case 0x1e: bset(0x80); break;
|
||||
case 0x1f: bclr(0x80); break;
|
||||
case 0x20: bra(); break;
|
||||
case 0x21: brn(); break;
|
||||
case 0x22: bhi(); break;
|
||||
case 0x23: bls(); break;
|
||||
case 0x24: bcc(); break;
|
||||
case 0x25: bcs(); break;
|
||||
case 0x26: bne(); break;
|
||||
case 0x27: beq(); break;
|
||||
case 0x28: bhcc(); break;
|
||||
case 0x29: bhcs(); break;
|
||||
case 0x2a: bpl(); break;
|
||||
case 0x2b: bmi(); break;
|
||||
case 0x2c: bmc(); break;
|
||||
case 0x2d: bms(); break;
|
||||
case 0x2e: bil(); break;
|
||||
case 0x2f: bih(); break;
|
||||
case 0x30: neg_di(); break;
|
||||
case 0x31: illegal(); break;
|
||||
case 0x32: illegal(); break;
|
||||
case 0x33: com_di(); break;
|
||||
case 0x34: lsr_di(); break;
|
||||
case 0x35: illegal(); break;
|
||||
case 0x36: ror_di(); break;
|
||||
case 0x37: asr_di(); break;
|
||||
case 0x38: lsl_di(); break;
|
||||
case 0x39: rol_di(); break;
|
||||
case 0x3a: dec_di(); break;
|
||||
case 0x3b: illegal(); break;
|
||||
case 0x3c: inc_di(); break;
|
||||
case 0x3d: tst_di(); break;
|
||||
case 0x3e: illegal(); break;
|
||||
case 0x3f: clr_di(); break;
|
||||
case 0x40: nega(); break;
|
||||
case 0x41: illegal(); break;
|
||||
case 0x42: illegal(); break;
|
||||
case 0x43: coma(); break;
|
||||
case 0x44: lsra(); break;
|
||||
case 0x45: illegal(); break;
|
||||
case 0x46: rora(); break;
|
||||
case 0x47: asra(); break;
|
||||
case 0x48: lsla(); break;
|
||||
case 0x49: rola(); break;
|
||||
case 0x4a: deca(); break;
|
||||
case 0x4b: illegal(); break;
|
||||
case 0x4c: inca(); break;
|
||||
case 0x4d: tsta(); break;
|
||||
case 0x4e: illegal(); break;
|
||||
case 0x4f: clra(); break;
|
||||
case 0x50: negx(); break;
|
||||
case 0x51: illegal(); break;
|
||||
case 0x52: illegal(); break;
|
||||
case 0x53: comx(); break;
|
||||
case 0x54: lsrx(); break;
|
||||
case 0x55: illegal(); break;
|
||||
case 0x56: rorx(); break;
|
||||
case 0x57: asrx(); break;
|
||||
case 0x58: aslx(); break;
|
||||
case 0x59: rolx(); break;
|
||||
case 0x5a: decx(); break;
|
||||
case 0x5b: illegal(); break;
|
||||
case 0x5c: incx(); break;
|
||||
case 0x5d: tstx(); break;
|
||||
case 0x5e: illegal(); break;
|
||||
case 0x5f: clrx(); break;
|
||||
case 0x60: neg_ix1(); break;
|
||||
case 0x61: illegal(); break;
|
||||
case 0x62: illegal(); break;
|
||||
case 0x63: com_ix1(); break;
|
||||
case 0x64: lsr_ix1(); break;
|
||||
case 0x65: illegal(); break;
|
||||
case 0x66: ror_ix1(); break;
|
||||
case 0x67: asr_ix1(); break;
|
||||
case 0x68: lsl_ix1(); break;
|
||||
case 0x69: rol_ix1(); break;
|
||||
case 0x6a: dec_ix1(); break;
|
||||
case 0x6b: illegal(); break;
|
||||
case 0x6c: inc_ix1(); break;
|
||||
case 0x6d: tst_ix1(); break;
|
||||
case 0x6e: illegal(); break;
|
||||
case 0x6f: clr_ix1(); break;
|
||||
case 0x70: neg_ix(); break;
|
||||
case 0x71: illegal(); break;
|
||||
case 0x72: illegal(); break;
|
||||
case 0x73: com_ix(); break;
|
||||
case 0x74: lsr_ix(); break;
|
||||
case 0x75: illegal(); break;
|
||||
case 0x76: ror_ix(); break;
|
||||
case 0x77: asr_ix(); break;
|
||||
case 0x78: lsl_ix(); break;
|
||||
case 0x79: rol_ix(); break;
|
||||
case 0x7a: dec_ix(); break;
|
||||
case 0x7b: illegal(); break;
|
||||
case 0x7c: inc_ix(); break;
|
||||
case 0x7d: tst_ix(); break;
|
||||
case 0x7e: illegal(); break;
|
||||
case 0x7f: clr_ix(); break;
|
||||
case 0x80: rti(); break;
|
||||
case 0x81: rts(); break;
|
||||
case 0x82: illegal(); break;
|
||||
case 0x83: swi(); break;
|
||||
case 0x84: illegal(); break;
|
||||
case 0x85: illegal(); break;
|
||||
case 0x86: illegal(); break;
|
||||
case 0x87: illegal(); break;
|
||||
case 0x88: illegal(); break;
|
||||
case 0x89: illegal(); break;
|
||||
case 0x8a: illegal(); break;
|
||||
case 0x8b: illegal(); break;
|
||||
case 0x8c: illegal(); break;
|
||||
case 0x8d: illegal(); break;
|
||||
case 0x8e: illegal(); break;
|
||||
case 0x8f: illegal(); break;
|
||||
case 0x90: illegal(); break;
|
||||
case 0x91: illegal(); break;
|
||||
case 0x92: illegal(); break;
|
||||
case 0x93: illegal(); break;
|
||||
case 0x94: illegal(); break;
|
||||
case 0x95: illegal(); break;
|
||||
case 0x96: illegal(); break;
|
||||
case 0x97: tax(); break;
|
||||
case 0x98: CLC(); break;
|
||||
case 0x99: SEC(); break;
|
||||
case 0x9a: CLI(); break;
|
||||
case 0x9b: SEI(); break;
|
||||
case 0x9c: rsp(); break;
|
||||
case 0x9d: nop(); break;
|
||||
case 0x9e: illegal(); break;
|
||||
case 0x9f: txa(); break;
|
||||
case 0xa0: suba_im(); break;
|
||||
case 0xa1: cmpa_im(); break;
|
||||
case 0xa2: sbca_im(); break;
|
||||
case 0xa3: cpx_im(); break;
|
||||
case 0xa4: anda_im(); break;
|
||||
case 0xa5: bita_im(); break;
|
||||
case 0xa6: lda_im(); break;
|
||||
case 0xa7: illegal(); break;
|
||||
case 0xa8: eora_im(); break;
|
||||
case 0xa9: adca_im(); break;
|
||||
case 0xaa: ora_im(); break;
|
||||
case 0xab: adda_im(); break;
|
||||
case 0xac: illegal(); break;
|
||||
case 0xad: bsr(); break;
|
||||
case 0xae: ldx_im(); break;
|
||||
case 0xaf: illegal(); break;
|
||||
case 0xb0: suba_di(); break;
|
||||
case 0xb1: cmpa_di(); break;
|
||||
case 0xb2: sbca_di(); break;
|
||||
case 0xb3: cpx_di(); break;
|
||||
case 0xb4: anda_di(); break;
|
||||
case 0xb5: bita_di(); break;
|
||||
case 0xb6: lda_di(); break;
|
||||
case 0xb7: sta_di(); break;
|
||||
case 0xb8: eora_di(); break;
|
||||
case 0xb9: adca_di(); break;
|
||||
case 0xba: ora_di(); break;
|
||||
case 0xbb: adda_di(); break;
|
||||
case 0xbc: jmp_di(); break;
|
||||
case 0xbd: jsr_di(); break;
|
||||
case 0xbe: ldx_di(); break;
|
||||
case 0xbf: stx_di(); break;
|
||||
case 0xc0: suba_ex(); break;
|
||||
case 0xc1: cmpa_ex(); break;
|
||||
case 0xc2: sbca_ex(); break;
|
||||
case 0xc3: cpx_ex(); break;
|
||||
case 0xc4: anda_ex(); break;
|
||||
case 0xc5: bita_ex(); break;
|
||||
case 0xc6: lda_ex(); break;
|
||||
case 0xc7: sta_ex(); break;
|
||||
case 0xc8: eora_ex(); break;
|
||||
case 0xc9: adca_ex(); break;
|
||||
case 0xca: ora_ex(); break;
|
||||
case 0xcb: adda_ex(); break;
|
||||
case 0xcc: jmp_ex(); break;
|
||||
case 0xcd: jsr_ex(); break;
|
||||
case 0xce: ldx_ex(); break;
|
||||
case 0xcf: stx_ex(); break;
|
||||
case 0xd0: suba_ix2(); break;
|
||||
case 0xd1: cmpa_ix2(); break;
|
||||
case 0xd2: sbca_ix2(); break;
|
||||
case 0xd3: cpx_ix2(); break;
|
||||
case 0xd4: anda_ix2(); break;
|
||||
case 0xd5: bita_ix2(); break;
|
||||
case 0xd6: lda_ix2(); break;
|
||||
case 0xd7: sta_ix2(); break;
|
||||
case 0xd8: eora_ix2(); break;
|
||||
case 0xd9: adca_ix2(); break;
|
||||
case 0xda: ora_ix2(); break;
|
||||
case 0xdb: adda_ix2(); break;
|
||||
case 0xdc: jmp_ix2(); break;
|
||||
case 0xdd: jsr_ix2(); break;
|
||||
case 0xde: ldx_ix2(); break;
|
||||
case 0xdf: stx_ix2(); break;
|
||||
case 0xe0: suba_ix1(); break;
|
||||
case 0xe1: cmpa_ix1(); break;
|
||||
case 0xe2: sbca_ix1(); break;
|
||||
case 0xe3: cpx_ix1(); break;
|
||||
case 0xe4: anda_ix1(); break;
|
||||
case 0xe5: bita_ix1(); break;
|
||||
case 0xe6: lda_ix1(); break;
|
||||
case 0xe7: sta_ix1(); break;
|
||||
case 0xe8: eora_ix1(); break;
|
||||
case 0xe9: adca_ix1(); break;
|
||||
case 0xea: ora_ix1(); break;
|
||||
case 0xeb: adda_ix1(); break;
|
||||
case 0xec: jmp_ix1(); break;
|
||||
case 0xed: jsr_ix1(); break;
|
||||
case 0xee: ldx_ix1(); break;
|
||||
case 0xef: stx_ix1(); break;
|
||||
case 0xf0: suba_ix(); break;
|
||||
case 0xf1: cmpa_ix(); break;
|
||||
case 0xf2: sbca_ix(); break;
|
||||
case 0xf3: cpx_ix(); break;
|
||||
case 0xf4: anda_ix(); break;
|
||||
case 0xf5: bita_ix(); break;
|
||||
case 0xf6: lda_ix(); break;
|
||||
case 0xf7: sta_ix(); break;
|
||||
case 0xf8: eora_ix(); break;
|
||||
case 0xf9: adca_ix(); break;
|
||||
case 0xfa: ora_ix(); break;
|
||||
case 0xfb: adda_ix(); break;
|
||||
case 0xfc: jmp_ix(); break;
|
||||
case 0xfd: jsr_ix(); break;
|
||||
case 0xfe: ldx_ix(); break;
|
||||
case 0xff: stx_ix(); break;
|
||||
}
|
||||
pendingCycles -= cycles1[ireg];
|
||||
int delta = prevCycles - pendingCycles;
|
||||
totalExecutedCycles += (ulong)delta;
|
||||
}
|
||||
while (pendingCycles > 0);
|
||||
return cycles - pendingCycles;
|
||||
}
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
int i;
|
||||
writer.Write(ea.LowWord);
|
||||
writer.Write(pc.LowWord);
|
||||
writer.Write(s.LowWord);
|
||||
writer.Write(subtype);
|
||||
writer.Write(a);
|
||||
writer.Write(x);
|
||||
writer.Write(cc);
|
||||
writer.Write(pending_interrupts);
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
writer.Write(irq_state[i]);
|
||||
}
|
||||
writer.Write(nmi_state);
|
||||
writer.Write(TotalExecutedCycles);
|
||||
writer.Write(PendingCycles);
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
int i;
|
||||
ea.LowWord = reader.ReadUInt16();
|
||||
pc.LowWord = reader.ReadUInt16();
|
||||
s.LowWord = reader.ReadUInt16();
|
||||
subtype = reader.ReadInt32();
|
||||
a = reader.ReadByte();
|
||||
x = reader.ReadByte();
|
||||
cc = reader.ReadByte();
|
||||
pending_interrupts = reader.ReadUInt16();
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
irq_state[i] = reader.ReadInt32();
|
||||
}
|
||||
nmi_state = reader.ReadInt32();
|
||||
TotalExecutedCycles = reader.ReadUInt64();
|
||||
PendingCycles = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
public class M68705 : M6805
|
||||
{
|
||||
public M68705()
|
||||
{
|
||||
m68705_init(Cpuint.cpu_3_irq_callback);
|
||||
}
|
||||
private void m68705_init(irq_delegate irqcallback)
|
||||
{
|
||||
irq_callback = irqcallback;
|
||||
}
|
||||
public override void Reset()
|
||||
{
|
||||
m68705_reset();
|
||||
}
|
||||
private void m68705_reset()
|
||||
{
|
||||
m6805_reset();
|
||||
subtype = SUBTYPE_M68705;
|
||||
RM16(0xfffe, ref pc);
|
||||
}
|
||||
public override void set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
m68705_set_irq_line(irqline, state);
|
||||
}
|
||||
private void m68705_set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
if (irq_state[irqline] == (int)state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
irq_state[irqline] = (int)state;
|
||||
if (state != (int)LineState.CLEAR_LINE)
|
||||
{
|
||||
pending_interrupts |= (ushort)(1 << irqline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84fc920b98828f14c8f326b4f1520eb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1896
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805op.cs
Normal file
1896
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805op.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805op.cs.meta
Normal file
11
MAME.Unity/Assets/Plugins/UMAME/cpu/m6805/M6805op.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0c310d005b3a9f4d8861c58a32603b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6809.meta
Normal file
8
MAME.Unity/Assets/Plugins/UMAME/cpu/m6809.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24967d13608942c4289d335114c41269
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
604
MAME.Unity/Assets/Plugins/UMAME/cpu/m6809/Disassembler.cs
Normal file
604
MAME.Unity/Assets/Plugins/UMAME/cpu/m6809/Disassembler.cs
Normal file
@ -0,0 +1,604 @@
|
||||
namespace cpu.m6809
|
||||
{
|
||||
public partial class M6809
|
||||
{
|
||||
public class opcodeinfo
|
||||
{
|
||||
public byte opcode;
|
||||
public int length;
|
||||
public string name;
|
||||
public m6809_addressing_modes mode;
|
||||
public uint flags;
|
||||
public opcodeinfo(byte _opcode, int _length, string _name, m6809_addressing_modes _mode)
|
||||
{
|
||||
opcode = _opcode;
|
||||
length = _length;
|
||||
name = _name;
|
||||
mode = _mode;
|
||||
}
|
||||
public opcodeinfo(byte _opcode, int _length, string _name, m6809_addressing_modes _mode, uint _flags)
|
||||
{
|
||||
opcode = _opcode;
|
||||
length = _length;
|
||||
name = _name;
|
||||
mode = _mode;
|
||||
flags = _flags;
|
||||
}
|
||||
}
|
||||
public static uint DASMFLAG_STEP_OVER = 0x20000000, DASMFLAG_SUPPORTED = 0x80000000;
|
||||
public enum m6809_addressing_modes
|
||||
{
|
||||
INH, // Inherent
|
||||
DIR, // Direct
|
||||
IND, // Indexed
|
||||
REL, // Relative (8 bit)
|
||||
LREL, // Long relative (16 bit)
|
||||
EXT, // Extended
|
||||
IMM, // Immediate
|
||||
IMM_RR, // Register-to-register
|
||||
PG1, // Switch to page 1 opcodes
|
||||
PG2 // Switch to page 2 opcodes
|
||||
}
|
||||
public opcodeinfo[] m6809_pg0opcodes = new opcodeinfo[]{
|
||||
new opcodeinfo(0x00, 2, "NEG",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x03, 2, "COM",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x04, 2, "LSR",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x06, 2, "ROR",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x07, 2, "ASR",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x08, 2, "ASL",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x09, 2, "ROL",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x0A, 2, "DEC",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x0C, 2, "INC",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x0D, 2, "TST",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x0E, 2, "JMP",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x0F, 2, "CLR",m6809_addressing_modes.DIR),
|
||||
|
||||
new opcodeinfo(0x10, 1, "page1",m6809_addressing_modes.PG1),
|
||||
new opcodeinfo(0x11, 1, "page2",m6809_addressing_modes.PG2),
|
||||
new opcodeinfo(0x12, 1, "NOP",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x13, 1, "SYNC",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x16, 3, "LBRA",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x17, 3, "LBSR",m6809_addressing_modes.LREL,DASMFLAG_STEP_OVER),
|
||||
new opcodeinfo(0x19, 1, "DAA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x1A, 2, "ORCC",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x1C, 2, "ANDCC",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x1D, 1, "SEX",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x1E, 2, "EXG",m6809_addressing_modes.IMM_RR),
|
||||
new opcodeinfo(0x1F, 2, "TFR",m6809_addressing_modes.IMM_RR),
|
||||
|
||||
new opcodeinfo(0x20, 2, "BRA",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x21, 2, "BRN",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x22, 2, "BHI",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x23, 2, "BLS",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x24, 2, "BCC",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x25, 2, "BCS",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x26, 2, "BNE",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x27, 2, "BEQ",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x28, 2, "BVC",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x29, 2, "BVS",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x2A, 2, "BPL",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x2B, 2, "BMI",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x2C, 2, "BGE",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x2D, 2, "BLT",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x2E, 2, "BGT",m6809_addressing_modes.REL),
|
||||
new opcodeinfo(0x2F, 2, "BLE",m6809_addressing_modes.REL),
|
||||
|
||||
new opcodeinfo(0x30, 2, "LEAX",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x31, 2, "LEAY",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x32, 2, "LEAS",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x33, 2, "LEAU",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x34, 2, "PSHS",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x35, 2, "PULS",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x36, 2, "PSHU",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x37, 2, "PULU",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x39, 1, "RTS",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x3A, 1, "ABX",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x3B, 1, "RTI",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x3C, 2, "CWAI",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x3D, 1, "MUL",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x3F, 1, "SWI",m6809_addressing_modes.INH),
|
||||
|
||||
new opcodeinfo(0x40, 1, "NEGA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x43, 1, "COMA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x44, 1, "LSRA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x46, 1, "RORA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x47, 1, "ASRA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x48, 1, "ASLA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x49, 1, "ROLA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x4A, 1, "DECA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x4C, 1, "INCA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x4D, 1, "TSTA",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x4F, 1, "CLRA",m6809_addressing_modes.INH),
|
||||
|
||||
new opcodeinfo(0x50, 1, "NEGB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x53, 1, "COMB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x54, 1, "LSRB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x56, 1, "RORB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x57, 1, "ASRB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x58, 1, "ASLB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x59, 1, "ROLB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x5A, 1, "DECB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x5C, 1, "INCB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x5D, 1, "TSTB",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x5F, 1, "CLRB",m6809_addressing_modes.INH),
|
||||
|
||||
new opcodeinfo(0x60, 2, "NEG",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x63, 2, "COM",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x64, 2, "LSR",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x66, 2, "ROR",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x67, 2, "ASR",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x68, 2, "ASL",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x69, 2, "ROL",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x6A, 2, "DEC",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x6C, 2, "INC",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x6D, 2, "TST",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x6E, 2, "JMP",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0x6F, 2, "CLR",m6809_addressing_modes.IND),
|
||||
|
||||
new opcodeinfo(0x70, 3, "NEG",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x73, 3, "COM",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x74, 3, "LSR",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x76, 3, "ROR",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x77, 3, "ASR",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x78, 3, "ASL",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x79, 3, "ROL",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x7A, 3, "DEC",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x7C, 3, "INC",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x7D, 3, "TST",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x7E, 3, "JMP",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0x7F, 3, "CLR",m6809_addressing_modes.EXT),
|
||||
|
||||
new opcodeinfo(0x80, 2, "SUBA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x81, 2, "CMPA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x82, 2, "SBCA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x83, 3, "SUBD",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x84, 2, "ANDA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x85, 2, "BITA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x86, 2, "LDA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x88, 2, "EORA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x89, 2, "ADCA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8A, 2, "ORA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8B, 2, "ADDA",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8C, 3, "CMPX",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8D, 2, "BSR",m6809_addressing_modes.REL,DASMFLAG_STEP_OVER),
|
||||
new opcodeinfo(0x8E, 3, "LDX",m6809_addressing_modes.IMM),
|
||||
|
||||
new opcodeinfo(0x90, 2, "SUBA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x91, 2, "CMPA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x92, 2, "SBCA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x93, 2, "SUBD",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x94, 2, "ANDA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x95, 2, "BITA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x96, 2, "LDA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x97, 2, "STA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x98, 2, "EORA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x99, 2, "ADCA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9A, 2, "ORA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9B, 2, "ADDA",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9C, 2, "CMPX",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9D, 2, "JSR",m6809_addressing_modes.DIR,DASMFLAG_STEP_OVER),
|
||||
new opcodeinfo(0x9E, 2, "LDX",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9F, 2, "STX",m6809_addressing_modes.DIR),
|
||||
|
||||
new opcodeinfo(0xA0, 2, "SUBA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA1, 2, "CMPA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA2, 2, "SBCA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA3, 2, "SUBD",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA4, 2, "ANDA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA5, 2, "BITA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA6, 2, "LDA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA7, 2, "STA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA8, 2, "EORA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xA9, 2, "ADCA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAA, 2, "ORA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAB, 2, "ADDA",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAC, 2, "CMPX",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAD, 2, "JSR",m6809_addressing_modes.IND,DASMFLAG_STEP_OVER),
|
||||
new opcodeinfo(0xAE, 2, "LDX",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAF, 2, "STX",m6809_addressing_modes.IND),
|
||||
|
||||
new opcodeinfo(0xB0, 3, "SUBA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB1, 3, "CMPA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB2, 3, "SBCA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB3, 3, "SUBD",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB4, 3, "ANDA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB5, 3, "BITA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB6, 3, "LDA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB7, 3, "STA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB8, 3, "EORA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xB9, 3, "ADCA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBA, 3, "ORA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBB, 3, "ADDA",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBC, 3, "CMPX",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBD, 3, "JSR",m6809_addressing_modes.EXT,DASMFLAG_STEP_OVER),
|
||||
new opcodeinfo(0xBE, 3, "LDX",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBF, 3, "STX",m6809_addressing_modes.EXT),
|
||||
|
||||
new opcodeinfo(0xC0, 2, "SUBB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC1, 2, "CMPB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC2, 2, "SBCB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC3, 3, "ADDD",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC4, 2, "ANDB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC5, 2, "BITB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC6, 2, "LDB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC8, 2, "EORB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xC9, 2, "ADCB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xCA, 2, "ORB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xCB, 2, "ADDB",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xCC, 3, "LDD",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xCE, 3, "LDU",m6809_addressing_modes.IMM),
|
||||
|
||||
new opcodeinfo(0xD0, 2, "SUBB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD1, 2, "CMPB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD2, 2, "SBCB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD3, 2, "ADDD",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD4, 2, "ANDB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD5, 2, "BITB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD6, 2, "LDB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD7, 2, "STB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD8, 2, "EORB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xD9, 2, "ADCB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDA, 2, "ORB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDB, 2, "ADDB",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDC, 2, "LDD",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDD, 2, "STD",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDE, 2, "LDU",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDF, 2, "STU",m6809_addressing_modes.DIR),
|
||||
|
||||
new opcodeinfo(0xE0, 2, "SUBB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE1, 2, "CMPB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE2, 2, "SBCB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE3, 2, "ADDD",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE4, 2, "ANDB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE5, 2, "BITB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE6, 2, "LDB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE7, 2, "STB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE8, 2, "EORB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xE9, 2, "ADCB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xEA, 2, "ORB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xEB, 2, "ADDB",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xEC, 2, "LDD",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xED, 2, "STD",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xEE, 2, "LDU",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xEF, 2, "STU",m6809_addressing_modes.IND),
|
||||
|
||||
new opcodeinfo(0xF0, 3, "SUBB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF1, 3, "CMPB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF2, 3, "SBCB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF3, 3, "ADDD",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF4, 3, "ANDB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF5, 3, "BITB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF6, 3, "LDB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF7, 3, "STB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF8, 3, "EORB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xF9, 3, "ADCB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFA, 3, "ORB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFB, 3, "ADDB",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFC, 3, "LDD",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFD, 3, "STD",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFE, 3, "LDU",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFF, 3, "STU",m6809_addressing_modes.EXT),
|
||||
};
|
||||
public opcodeinfo[] m6809_pg1opcodes = new opcodeinfo[]{
|
||||
new opcodeinfo(0x21, 4, "LBRN",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x22, 4, "LBHI",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x23, 4, "LBLS",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x24, 4, "LBCC",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x25, 4, "LBCS",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x26, 4, "LBNE",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x27, 4, "LBEQ",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x28, 4, "LBVC",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x29, 4, "LBVS",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x2A, 4, "LBPL",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x2B, 4, "LBMI",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x2C, 4, "LBGE",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x2D, 4, "LBLT",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x2E, 4, "LBGT",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x2F, 4, "LBLE",m6809_addressing_modes.LREL),
|
||||
new opcodeinfo(0x3F, 2, "SWI2",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x83, 4, "CMPD",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8C, 4, "CMPY",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8E, 4, "LDY",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x93, 3, "CMPD",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9C, 3, "CMPY",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9E, 3, "LDY",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9F, 3, "STY",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xA3, 3, "CMPD",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAC, 3, "CMPY",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAE, 3, "LDY",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAF, 3, "STY",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xB3, 4, "CMPD",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBC, 4, "CMPY",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBE, 4, "LDY",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBF, 4, "STY",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xCE, 4, "LDS",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0xDE, 3, "LDS",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xDF, 3, "STS",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xEE, 3, "LDS",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xEF, 3, "STS",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xFE, 4, "LDS",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xFF, 4, "STS",m6809_addressing_modes.EXT)
|
||||
};
|
||||
public opcodeinfo[] m6809_pg2opcodes = new opcodeinfo[]{
|
||||
new opcodeinfo(0x3F, 2, "SWI3",m6809_addressing_modes.INH),
|
||||
new opcodeinfo(0x83, 4, "CMPU",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x8C, 4, "CMPS",m6809_addressing_modes.IMM),
|
||||
new opcodeinfo(0x93, 3, "CMPU",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0x9C, 3, "CMPS",m6809_addressing_modes.DIR),
|
||||
new opcodeinfo(0xA3, 3, "CMPU",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xAC, 3, "CMPS",m6809_addressing_modes.IND),
|
||||
new opcodeinfo(0xB3, 4, "CMPU",m6809_addressing_modes.EXT),
|
||||
new opcodeinfo(0xBC, 4, "CMPS",m6809_addressing_modes.EXT)
|
||||
};
|
||||
public opcodeinfo[][] m6809_pgpointers;
|
||||
public int[] m6809_numops;
|
||||
public static string[] m6809_regs = new string[] { "X", "Y", "U", "S", "PC" };
|
||||
public static string[] m6809_regs_te = new string[]
|
||||
{
|
||||
"D", "X", "Y", "U", "S", "PC", "inv", "inv",
|
||||
"A", "B", "CC", "DP", "inv", "inv", "inv", "inv"
|
||||
};
|
||||
public byte op;
|
||||
public void DisassemblerInit()
|
||||
{
|
||||
m6809_pgpointers = new opcodeinfo[3][] { m6809_pg0opcodes, m6809_pg1opcodes, m6809_pg2opcodes };
|
||||
m6809_numops = new int[3] { m6809_pg0opcodes.Length, m6809_pg1opcodes.Length, m6809_pg2opcodes.Length };
|
||||
}
|
||||
public string m6809_dasm(int ppc)
|
||||
{
|
||||
string buffer = "";
|
||||
|
||||
byte opcode, pb, pbm, reg;
|
||||
m6809_addressing_modes mode;
|
||||
byte[] operandarray;
|
||||
int ea;
|
||||
uint flags;
|
||||
int numoperands, offset;
|
||||
int i, j, i1, page = 0;
|
||||
ushort p = (ushort)ppc;
|
||||
if (ppc == 0xc010)
|
||||
{
|
||||
i1 = 1;
|
||||
}
|
||||
buffer = ReadOp(p).ToString("X2");
|
||||
bool indirect, opcode_found = false;
|
||||
do
|
||||
{
|
||||
opcode = ReadOp(p);
|
||||
p++;
|
||||
for (i = 0; i < m6809_numops[page]; i++)
|
||||
if (m6809_pgpointers[page][i].opcode == opcode)
|
||||
break;
|
||||
if (i < m6809_numops[page])
|
||||
opcode_found = true;
|
||||
else
|
||||
{
|
||||
buffer += " Illegal Opcode";
|
||||
return buffer;
|
||||
}
|
||||
if (m6809_pgpointers[page][i].mode >= m6809_addressing_modes.PG1)
|
||||
{
|
||||
page = m6809_pgpointers[page][i].mode - m6809_addressing_modes.PG1 + 1;
|
||||
opcode_found = false;
|
||||
}
|
||||
} while (!opcode_found);
|
||||
if (page == 0)
|
||||
numoperands = m6809_pgpointers[page][i].length - 1;
|
||||
else
|
||||
numoperands = m6809_pgpointers[page][i].length - 2;
|
||||
operandarray = new byte[numoperands];
|
||||
for (j = 0; j < numoperands; j++)
|
||||
{
|
||||
operandarray[j] = ReadOpArg((ushort)(p + j));
|
||||
}
|
||||
p += (ushort)numoperands;
|
||||
ppc += numoperands;
|
||||
mode = m6809_pgpointers[page][i].mode;
|
||||
flags = m6809_pgpointers[page][i].flags;
|
||||
|
||||
buffer += m6809_pgpointers[page][i].name.PadLeft(6);
|
||||
switch (mode)
|
||||
{
|
||||
case m6809_addressing_modes.INH:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x34: // PSHS
|
||||
case 0x36: // PSHU
|
||||
pb = operandarray[0];
|
||||
if ((pb & 0x80) != 0)
|
||||
buffer += "PC";
|
||||
if ((pb & 0x40) != 0)
|
||||
buffer += (((pb & 0x80) != 0) ? "," : "") + ((opcode == 0x34) ? "U" : "S");
|
||||
if ((pb & 0x20) != 0)
|
||||
buffer += (((pb & 0xc0) != 0) ? "," : "") + "Y";
|
||||
if ((pb & 0x10) != 0)
|
||||
buffer += (((pb & 0xe0) != 0) ? "," : "") + "X";
|
||||
if ((pb & 0x08) != 0)
|
||||
buffer += (((pb & 0xf0) != 0) ? "," : "") + "DP";
|
||||
if ((pb & 0x04) != 0)
|
||||
buffer += (((pb & 0xf8) != 0) ? "," : "") + "B";
|
||||
if ((pb & 0x02) != 0)
|
||||
buffer += (((pb & 0xfc) != 0) ? "," : "") + "A";
|
||||
if ((pb & 0x01) != 0)
|
||||
buffer += (((pb & 0xfe) != 0) ? "," : "") + "CC";
|
||||
break;
|
||||
case 0x35: // PULS
|
||||
case 0x37: // PULU
|
||||
pb = operandarray[0];
|
||||
if ((pb & 0x01) != 0)
|
||||
buffer += "CC";
|
||||
if ((pb & 0x02) != 0)
|
||||
buffer += (((pb & 0x01) != 0) ? "," : "") + "A";
|
||||
if ((pb & 0x04) != 0)
|
||||
buffer += (((pb & 0x03) != 0) ? "," : "") + "B";
|
||||
if ((pb & 0x08) != 0)
|
||||
buffer += (((pb & 0x07) != 0) ? "," : "") + "DP";
|
||||
if ((pb & 0x10) != 0)
|
||||
buffer += (((pb & 0x0f) != 0) ? "," : "") + "X";
|
||||
if ((pb & 0x20) != 0)
|
||||
buffer += (((pb & 0x1f) != 0) ? "," : "") + "Y";
|
||||
if ((pb & 0x40) != 0)
|
||||
buffer += (((pb & 0x3f) != 0) ? "," : "") + ((opcode == 0x35) ? "U" : "S");
|
||||
if ((pb & 0x80) != 0)
|
||||
buffer += (((pb & 0x7f) != 0) ? "," : "") + "PC ; (PUL? PC=RTS)";
|
||||
break;
|
||||
default:
|
||||
// No operands
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.DIR:
|
||||
ea = operandarray[0];
|
||||
buffer += ea.ToString("X2");
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.REL:
|
||||
offset = (sbyte)operandarray[0];
|
||||
buffer += ((ppc + offset) & 0xffff).ToString("X4");
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.LREL:
|
||||
offset = (short)((operandarray[0] << 8) + operandarray[1]);
|
||||
buffer += ((ppc + offset) & 0xffff).ToString("X4");
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.EXT:
|
||||
ea = ((operandarray[0] << 8) + operandarray[1]);
|
||||
buffer += ea.ToString("X4");
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.IND:
|
||||
pb = operandarray[0];
|
||||
reg = (byte)((pb >> 5) & 3);
|
||||
pbm = (byte)(pb & 0x8f);
|
||||
indirect = ((pb & 0x90) == 0x90) ? true : false;
|
||||
// open brackets if indirect
|
||||
if (indirect && pbm != 0x80 && pbm != 0x82)
|
||||
buffer += "[";
|
||||
switch (pbm)
|
||||
{
|
||||
case 0x80: // ,R+
|
||||
if (indirect)
|
||||
buffer = "Illegal Postbyte";
|
||||
else
|
||||
buffer += "," + m6809_regs[reg] + "+";
|
||||
break;
|
||||
|
||||
case 0x81: // ,R++
|
||||
buffer += "," + m6809_regs[reg] + "++";
|
||||
break;
|
||||
|
||||
case 0x82: // ,-R
|
||||
if (indirect)
|
||||
buffer = "Illegal Postbyte";
|
||||
else
|
||||
buffer += ",-" + m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x83: // ,--R
|
||||
buffer += ",--" + m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x84: // ,R
|
||||
buffer += "," + m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x85: // (+/- B),R
|
||||
buffer += "B," + m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x86: // (+/- A),R
|
||||
buffer += "A," + m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
buffer = "Illegal Postbyte";
|
||||
break;
|
||||
|
||||
case 0x88: // (+/- 7 bit offset),R
|
||||
offset = (sbyte)ReadOpArg(p);
|
||||
p++;
|
||||
buffer += ((offset < 0) ? "-" : "");
|
||||
buffer += ((offset < 0) ? -offset : offset).ToString("X2");
|
||||
buffer += m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x89: // (+/- 15 bit offset),R
|
||||
offset = (short)((ReadOpArg(p) << 8) + ReadOpArg((ushort)(p + 1)));
|
||||
p += 2;
|
||||
buffer += ((offset < 0) ? "-" : "");
|
||||
buffer += ((offset < 0) ? -offset : offset).ToString("X4");
|
||||
buffer += m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x8a:
|
||||
buffer = "Illegal Postbyte";
|
||||
break;
|
||||
|
||||
case 0x8b: // (+/- D),R
|
||||
buffer += "D," + m6809_regs[reg];
|
||||
break;
|
||||
|
||||
case 0x8c: // (+/- 7 bit offset),PC
|
||||
offset = (sbyte)ReadOpArg(p);
|
||||
p++;
|
||||
buffer += ((offset < 0) ? "-" : "");
|
||||
buffer += "$" + ((offset < 0) ? -offset : offset).ToString("X2") + ",PC";
|
||||
break;
|
||||
|
||||
case 0x8d: // (+/- 15 bit offset),PC
|
||||
offset = (short)((ReadOpArg(p) << 8) + ReadOpArg((ushort)(p + 1)));
|
||||
p += 2;
|
||||
buffer += ((offset < 0) ? "-" : "");
|
||||
buffer += "$" + ((offset < 0) ? -offset : offset).ToString("X4") + ",PC";
|
||||
break;
|
||||
|
||||
case 0x8e:
|
||||
buffer = "Illegal Postbyte";
|
||||
break;
|
||||
|
||||
case 0x8f: // address
|
||||
ea = (short)((ReadOpArg(p) << 8) + ReadOpArg((ushort)(p + 1)));
|
||||
p += 2;
|
||||
buffer += "$" + ea.ToString("X4");
|
||||
break;
|
||||
|
||||
default: // (+/- 4 bit offset),R
|
||||
offset = pb & 0x1f;
|
||||
if (offset > 15)
|
||||
offset = offset - 32;
|
||||
buffer += ((offset < 0) ? "-" : "");
|
||||
buffer += "$" + ((offset < 0) ? -offset : offset).ToString("X") + ",";
|
||||
buffer += m6809_regs[reg];
|
||||
break;
|
||||
}
|
||||
|
||||
// close brackets if indirect
|
||||
if (indirect && pbm != 0x80 && pbm != 0x82)
|
||||
buffer += "]";
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.IMM:
|
||||
if (numoperands == 2)
|
||||
{
|
||||
ea = (operandarray[0] << 8) + operandarray[1];
|
||||
buffer += "#$" + ea.ToString("X4");
|
||||
}
|
||||
else
|
||||
if (numoperands == 1)
|
||||
{
|
||||
ea = operandarray[0];
|
||||
buffer += "#$" + ea.ToString("X2");
|
||||
}
|
||||
break;
|
||||
|
||||
case m6809_addressing_modes.IMM_RR:
|
||||
pb = operandarray[0];
|
||||
buffer += m6809_regs_te[(pb >> 4) & 0xf] + "," + m6809_regs_te[pb & 0xf];
|
||||
break;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05a5a82c4182e0f4082c1e8329ddde79
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
907
MAME.Unity/Assets/Plugins/UMAME/cpu/m6809/M6809.cs
Normal file
907
MAME.Unity/Assets/Plugins/UMAME/cpu/m6809/M6809.cs
Normal file
@ -0,0 +1,907 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace cpu.m6809
|
||||
{
|
||||
public partial class M6809 : cpuexec_data
|
||||
{
|
||||
public static M6809[] mm1;
|
||||
public Action[] insn;
|
||||
public Register PC, PPC, D, DP, U, S, X, Y, EA;
|
||||
public byte CC, ireg;
|
||||
public LineState[] irq_state = new LineState[2];
|
||||
public int extra_cycles; /* cycles used up by interrupts */
|
||||
public byte int_state;
|
||||
public LineState nmi_state;
|
||||
private byte CC_C = 0x01, CC_V = 0x02, CC_Z = 0x04, CC_N = 0x08, CC_II = 0x10, CC_H = 0x20, CC_IF = 0x40, CC_E = 0x80;
|
||||
private byte M6809_CWAI = 8, M6809_SYNC = 16, M6809_LDS = 32;
|
||||
private byte M6809_IRQ_LINE = 0, M6809_FIRQ_LINE = 1;
|
||||
public Func<ushort, byte> ReadOp, ReadOpArg;
|
||||
public Func<ushort, byte> RM;
|
||||
public Action<ushort, byte> WM;
|
||||
public Func<ushort, byte> ReadIO;
|
||||
public Action<ushort, byte> WriteIO;
|
||||
public delegate int irq_delegate(int irqline);
|
||||
public irq_delegate irq_callback;
|
||||
public delegate void debug_delegate();
|
||||
public debug_delegate debugger_start_cpu_hook_callback, debugger_stop_cpu_hook_callback;
|
||||
private ulong totalExecutedCycles;
|
||||
private int pendingCycles;
|
||||
public override ulong TotalExecutedCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return totalExecutedCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
totalExecutedCycles = value;
|
||||
}
|
||||
}
|
||||
public override int PendingCycles
|
||||
{
|
||||
get
|
||||
{
|
||||
return pendingCycles;
|
||||
}
|
||||
set
|
||||
{
|
||||
pendingCycles = value;
|
||||
}
|
||||
}
|
||||
public byte[] flags8i = new byte[256]
|
||||
{
|
||||
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x0a,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08
|
||||
};
|
||||
public byte[] flags8d = new byte[256]
|
||||
{
|
||||
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08
|
||||
};
|
||||
private byte[] cycles_6809 = new byte[]
|
||||
{
|
||||
0x06,0x06,0x02,0x06,0x06,0x02,0x06,0x06,0x06,0x06,0x06,0x02,0x06,0x06,0x03,0x06,
|
||||
0x00,0x00,0x02,0x04,0x02,0x02,0x05,0x09,0x02,0x02,0x03,0x02,0x03,0x02,0x08,0x06,
|
||||
0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
|
||||
0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x02,0x05,0x03,0x06,0x14,0x0b,0x02,0x13,
|
||||
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
|
||||
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
|
||||
0x06,0x02,0x02,0x06,0x06,0x02,0x06,0x06,0x06,0x06,0x06,0x02,0x06,0x06,0x03,0x06,
|
||||
0x07,0x02,0x02,0x07,0x07,0x02,0x07,0x07,0x07,0x07,0x07,0x02,0x07,0x07,0x04,0x07,
|
||||
0x02,0x02,0x02,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x07,0x03,0x02,
|
||||
0x04,0x04,0x04,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x07,0x05,0x05,
|
||||
0x04,0x04,0x04,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x07,0x05,0x05,
|
||||
0x05,0x05,0x05,0x07,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x07,0x08,0x06,0x06,
|
||||
0x02,0x02,0x02,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x03,0x03,
|
||||
0x04,0x04,0x04,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,
|
||||
0x04,0x04,0x04,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,
|
||||
0x05,0x05,0x05,0x07,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06
|
||||
};
|
||||
public M6809()
|
||||
{
|
||||
insn = new Action[]{
|
||||
neg_di,neg_di,illegal,com_di,lsr_di,illegal,ror_di,asr_di,
|
||||
asl_di,rol_di,dec_di,illegal,inc_di,tst_di,jmp_di,clr_di,
|
||||
pref10,pref11,nop,sync,illegal,illegal,lbra,lbsr,
|
||||
illegal,daa,orcc,illegal,andcc,sex,exg,tfr,
|
||||
bra,brn,bhi,bls,bcc,bcs,bne,beq,
|
||||
bvc,bvs,bpl,bmi,bge,blt,bgt,ble,
|
||||
leax,leay,leas,leau,pshs,puls,pshu,pulu,
|
||||
illegal,rts,abx,rti,cwai,mul,illegal,swi,
|
||||
nega,illegal,illegal,coma,lsra,illegal,rora,asra,
|
||||
asla,rola,deca,illegal,inca,tsta,illegal,clra,
|
||||
negb,illegal,illegal,comb,lsrb,illegal,rorb,asrb,
|
||||
aslb,rolb,decb,illegal,incb,tstb,illegal,clrb,
|
||||
neg_ix,illegal,illegal,com_ix,lsr_ix,illegal,ror_ix,asr_ix,
|
||||
asl_ix,rol_ix,dec_ix,illegal,inc_ix,tst_ix,jmp_ix,clr_ix,
|
||||
neg_ex,illegal,illegal,com_ex,lsr_ex,illegal,ror_ex,asr_ex,
|
||||
asl_ex,rol_ex,dec_ex,illegal,inc_ex,tst_ex,jmp_ex,clr_ex,
|
||||
suba_im,cmpa_im,sbca_im,subd_im,anda_im,bita_im,lda_im,sta_im,
|
||||
eora_im,adca_im,ora_im,adda_im,cmpx_im,bsr,ldx_im,stx_im,
|
||||
suba_di,cmpa_di,sbca_di,subd_di,anda_di,bita_di,lda_di,sta_di,
|
||||
eora_di,adca_di,ora_di,adda_di,cmpx_di,jsr_di,ldx_di,stx_di,
|
||||
suba_ix,cmpa_ix,sbca_ix,subd_ix,anda_ix,bita_ix,lda_ix,sta_ix,
|
||||
eora_ix,adca_ix,ora_ix,adda_ix,cmpx_ix,jsr_ix,ldx_ix,stx_ix,
|
||||
suba_ex,cmpa_ex,sbca_ex,subd_ex,anda_ex,bita_ex,lda_ex,sta_ex,
|
||||
eora_ex,adca_ex,ora_ex,adda_ex,cmpx_ex,jsr_ex,ldx_ex,stx_ex,
|
||||
subb_im,cmpb_im,sbcb_im,addd_im,andb_im,bitb_im,ldb_im,stb_im,
|
||||
eorb_im,adcb_im,orb_im,addb_im,ldd_im,std_im,ldu_im,stu_im,
|
||||
subb_di,cmpb_di,sbcb_di,addd_di,andb_di,bitb_di,ldb_di,stb_di,
|
||||
eorb_di,adcb_di,orb_di,addb_di,ldd_di,std_di,ldu_di,stu_di,
|
||||
subb_ix,cmpb_ix,sbcb_ix,addd_ix,andb_ix,bitb_ix,ldb_ix,stb_ix,
|
||||
eorb_ix,adcb_ix,orb_ix,addb_ix,ldd_ix,std_ix,ldu_ix,stu_ix,
|
||||
subb_ex,cmpb_ex,sbcb_ex,addd_ex,andb_ex,bitb_ex,ldb_ex,stb_ex,
|
||||
eorb_ex,adcb_ex,orb_ex,addb_ex,ldd_ex,std_ex,ldu_ex,stu_ex
|
||||
};
|
||||
}
|
||||
public override void Reset()
|
||||
{
|
||||
m6809_reset();
|
||||
}
|
||||
private void CHECK_IRQ_LINES()
|
||||
{
|
||||
if (irq_state[M6809_IRQ_LINE] != LineState.CLEAR_LINE || irq_state[M6809_FIRQ_LINE] != LineState.CLEAR_LINE)
|
||||
int_state &= (byte)(~M6809_SYNC);
|
||||
if (irq_state[M6809_FIRQ_LINE] != LineState.CLEAR_LINE && (CC & CC_IF) == 0)
|
||||
{
|
||||
if ((int_state & M6809_CWAI) != 0)
|
||||
{
|
||||
int_state &= (byte)(~M6809_CWAI);
|
||||
extra_cycles += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC &= (byte)(~CC_E);
|
||||
PUSHWORD(PC);
|
||||
PUSHBYTE(CC);
|
||||
extra_cycles += 10;
|
||||
}
|
||||
CC |= (byte)(CC_IF | CC_II);
|
||||
PC.LowWord = RM16(0xfff6);
|
||||
if (irq_callback != null)
|
||||
{
|
||||
irq_callback(M6809_FIRQ_LINE);
|
||||
}
|
||||
}
|
||||
else if (irq_state[M6809_IRQ_LINE] != LineState.CLEAR_LINE && (CC & CC_II) == 0)
|
||||
{
|
||||
|
||||
if ((int_state & M6809_CWAI) != 0)
|
||||
{
|
||||
int_state &= (byte)(~M6809_CWAI);
|
||||
extra_cycles += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC |= CC_E;
|
||||
PUSHWORD(PC);
|
||||
PUSHWORD(U);
|
||||
PUSHWORD(Y);
|
||||
PUSHWORD(X);
|
||||
PUSHBYTE(DP.HighByte);
|
||||
PUSHBYTE(D.LowByte);
|
||||
PUSHBYTE(D.HighByte);
|
||||
PUSHBYTE(CC);
|
||||
extra_cycles += 19;
|
||||
}
|
||||
CC |= CC_II;
|
||||
PC.LowWord = RM16(0xfff8);
|
||||
if (irq_callback != null)
|
||||
{
|
||||
irq_callback(M6809_IRQ_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
private byte IMMBYTE()
|
||||
{
|
||||
byte b = ReadOpArg(PC.LowWord);
|
||||
PC.LowWord++;
|
||||
return b;
|
||||
}
|
||||
private Register IMMWORD()
|
||||
{
|
||||
Register w = new Register();
|
||||
w.d = (uint)((ReadOpArg(PC.LowWord) << 8) | ReadOpArg((ushort)((PC.LowWord + 1) & 0xffff)));
|
||||
PC.LowWord += 2;
|
||||
return w;
|
||||
}
|
||||
private void PUSHBYTE(byte b)
|
||||
{
|
||||
--S.LowWord;
|
||||
WM(S.LowWord, b);
|
||||
}
|
||||
private void PUSHWORD(Register w)
|
||||
{
|
||||
--S.LowWord;
|
||||
WM(S.LowWord, w.LowByte);
|
||||
--S.LowWord;
|
||||
WM(S.LowWord, w.HighByte);
|
||||
}
|
||||
private byte PULLBYTE()
|
||||
{
|
||||
byte b;
|
||||
b = RM(S.LowWord);
|
||||
S.LowWord++;
|
||||
return b;
|
||||
}
|
||||
private ushort PULLWORD()
|
||||
{
|
||||
ushort w;
|
||||
w = (ushort)(RM(S.LowWord) << 8);
|
||||
S.LowWord++;
|
||||
w |= RM(S.LowWord);
|
||||
S.LowWord++;
|
||||
return w;
|
||||
}
|
||||
private void PSHUBYTE(byte b)
|
||||
{
|
||||
--U.LowWord; WM(U.LowWord, b);
|
||||
}
|
||||
private void PSHUWORD(Register w)
|
||||
{
|
||||
--U.LowWord;
|
||||
WM(U.LowWord, w.LowByte);
|
||||
--U.LowWord;
|
||||
WM(U.LowWord, w.HighByte);
|
||||
}
|
||||
private byte PULUBYTE()
|
||||
{
|
||||
byte b;
|
||||
b = RM(U.LowWord);
|
||||
U.LowWord++;
|
||||
return b;
|
||||
}
|
||||
private ushort PULUWORD()
|
||||
{
|
||||
ushort w;
|
||||
w = (ushort)(RM(U.LowWord) << 8);
|
||||
U.LowWord++;
|
||||
w |= RM(U.LowWord);
|
||||
U.LowWord++;
|
||||
return w;
|
||||
}
|
||||
private void CLR_HNZVC()
|
||||
{
|
||||
CC &= (byte)(~(CC_H | CC_N | CC_Z | CC_V | CC_C));
|
||||
}
|
||||
private void CLR_NZV()
|
||||
{
|
||||
CC &= (byte)(~(CC_N | CC_Z | CC_V));
|
||||
}
|
||||
private void CLR_NZ()
|
||||
{
|
||||
CC &= (byte)(~(CC_N | CC_Z));
|
||||
}
|
||||
private void CLR_HNZC()
|
||||
{
|
||||
CC &= (byte)(~(CC_H | CC_N | CC_Z | CC_C));
|
||||
}
|
||||
private void CLR_NZVC()
|
||||
{
|
||||
CC &= (byte)(~(CC_N | CC_Z | CC_V | CC_C));
|
||||
}
|
||||
private void CLR_Z()
|
||||
{
|
||||
CC &= (byte)(~(CC_Z));
|
||||
}
|
||||
private void CLR_NZC()
|
||||
{
|
||||
CC &= (byte)(~(CC_N | CC_Z | CC_C));
|
||||
}
|
||||
private void CLR_ZC()
|
||||
{
|
||||
CC &= (byte)(~(CC_Z | CC_C));
|
||||
}
|
||||
private void SET_Z(uint a)
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
SEZ();
|
||||
}
|
||||
}
|
||||
private void SET_Z8(byte a)
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
SEZ();
|
||||
}
|
||||
}
|
||||
private void SET_Z16(ushort a)
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
SEZ();
|
||||
}
|
||||
}
|
||||
private void SET_N8(byte a)
|
||||
{
|
||||
CC |= (byte)((a & 0x80) >> 4);
|
||||
}
|
||||
private void SET_N16(ushort a)
|
||||
{
|
||||
CC |= (byte)((a & 0x8000) >> 12);
|
||||
}
|
||||
private void SET_H(byte a, byte b, byte r)
|
||||
{
|
||||
CC |= (byte)(((a ^ b ^ r) & 0x10) << 1);
|
||||
}
|
||||
private void SET_C8(ushort a)
|
||||
{
|
||||
CC |= (byte)((a & 0x100) >> 8);
|
||||
}
|
||||
private void SET_C16(uint a)
|
||||
{
|
||||
CC |= (byte)((a & 0x10000) >> 16);
|
||||
}
|
||||
private void SET_V8(byte a, ushort b, ushort r)
|
||||
{
|
||||
CC |= (byte)(((a ^ b ^ r ^ (r >> 1)) & 0x80) >> 6);
|
||||
}
|
||||
private void SET_V16(ushort a, ushort b, uint r)
|
||||
{
|
||||
CC |= (byte)(((a ^ b ^ r ^ (r >> 1)) & 0x8000) >> 14);
|
||||
}
|
||||
private void SET_FLAGS8I(byte a)
|
||||
{
|
||||
CC |= flags8i[(a) & 0xff];
|
||||
}
|
||||
private void SET_FLAGS8D(byte a)
|
||||
{
|
||||
CC |= flags8d[(a) & 0xff];
|
||||
}
|
||||
private void SET_NZ8(byte a)
|
||||
{
|
||||
SET_N8(a);
|
||||
SET_Z(a);
|
||||
}
|
||||
private void SET_NZ16(ushort a)
|
||||
{
|
||||
SET_N16(a);
|
||||
SET_Z(a);
|
||||
}
|
||||
private void SET_FLAGS8(byte a, ushort b, ushort r)
|
||||
{
|
||||
SET_N8((byte)r);
|
||||
SET_Z8((byte)r);
|
||||
SET_V8(a, b, r);
|
||||
SET_C8(r);
|
||||
}
|
||||
private void SET_FLAGS16(ushort a, ushort b, uint r)
|
||||
{
|
||||
SET_N16((ushort)r);
|
||||
SET_Z16((ushort)r);
|
||||
SET_V16(a, b, r);
|
||||
SET_C16(r);
|
||||
}
|
||||
private ushort SIGNED(byte b)
|
||||
{
|
||||
return (ushort)((b & 0x80) != 0 ? b | 0xff00 : b);
|
||||
}
|
||||
private void DIRECT()
|
||||
{
|
||||
EA.d = DP.d;
|
||||
EA.LowByte = IMMBYTE();
|
||||
}
|
||||
private void IMM8()
|
||||
{
|
||||
EA.d = PC.d;
|
||||
PC.LowWord++;
|
||||
}
|
||||
private void IMM16()
|
||||
{
|
||||
EA.d = PC.d;
|
||||
PC.LowWord += 2;
|
||||
}
|
||||
private void EXTENDED()
|
||||
{
|
||||
EA = IMMWORD();
|
||||
}
|
||||
private void SEC()
|
||||
{
|
||||
CC |= CC_C;
|
||||
}
|
||||
private void CLC()
|
||||
{
|
||||
CC &= (byte)(~CC_C);
|
||||
}
|
||||
private void SEZ()
|
||||
{
|
||||
CC |= CC_Z;
|
||||
}
|
||||
private void CLZ()
|
||||
{
|
||||
CC &= (byte)(~CC_Z);
|
||||
}
|
||||
private void SEN()
|
||||
{
|
||||
CC |= CC_N;
|
||||
}
|
||||
private void CLN()
|
||||
{
|
||||
CC &= (byte)(~CC_N);
|
||||
}
|
||||
private void SEV()
|
||||
{
|
||||
CC |= CC_V;
|
||||
}
|
||||
private void CLV()
|
||||
{
|
||||
CC &= (byte)(~CC_V);
|
||||
}
|
||||
private void SEH()
|
||||
{
|
||||
CC |= CC_H;
|
||||
}
|
||||
private void CLH()
|
||||
{
|
||||
CC &= (byte)(~CC_H);
|
||||
}
|
||||
private byte DIRBYTE()
|
||||
{
|
||||
DIRECT();
|
||||
return RM(EA.LowWord);
|
||||
}
|
||||
private Register DIRWORD()
|
||||
{
|
||||
Register w = new Register();
|
||||
DIRECT();
|
||||
w.LowWord = RM16(EA.LowWord);
|
||||
return w;
|
||||
}
|
||||
private byte EXTBYTE()
|
||||
{
|
||||
EXTENDED();
|
||||
return RM(EA.LowWord);
|
||||
}
|
||||
private Register EXTWORD()
|
||||
{
|
||||
Register w = new Register();
|
||||
EXTENDED();
|
||||
w.LowWord = RM16(EA.LowWord);
|
||||
return w;
|
||||
}
|
||||
private void BRANCH(bool f)
|
||||
{
|
||||
byte t = IMMBYTE();
|
||||
if (f)
|
||||
{
|
||||
PC.LowWord += (ushort)SIGNED(t);
|
||||
}
|
||||
}
|
||||
private void LBRANCH(bool f)
|
||||
{
|
||||
Register t = IMMWORD();
|
||||
if (f)
|
||||
{
|
||||
pendingCycles -= 1;
|
||||
PC.LowWord += t.LowWord;
|
||||
}
|
||||
}
|
||||
private byte NXORV()
|
||||
{
|
||||
return (byte)((CC & CC_N) ^ ((CC & CC_V) << 2));
|
||||
}
|
||||
private ushort RM16(ushort Addr)
|
||||
{
|
||||
ushort result = (ushort)(RM(Addr) << 8);
|
||||
return (ushort)(result | RM((ushort)((Addr + 1) & 0xffff)));
|
||||
}
|
||||
private void WM16(ushort Addr, Register p)
|
||||
{
|
||||
WM(Addr, p.HighByte);
|
||||
WM((ushort)((Addr + 1) & 0xffff), p.LowByte);
|
||||
}
|
||||
private void m6809_reset()
|
||||
{
|
||||
int_state = 0;
|
||||
nmi_state = LineState.CLEAR_LINE;
|
||||
irq_state[0] = LineState.CLEAR_LINE;
|
||||
irq_state[1] = LineState.CLEAR_LINE;
|
||||
DP.d = 0; /* Reset direct page register */
|
||||
CC |= CC_II; /* IRQ disabled */
|
||||
CC |= CC_IF; /* FIRQ disabled */
|
||||
PC.LowWord = RM16(0xfffe);
|
||||
}
|
||||
public override void set_irq_line(int irqline, LineState state)
|
||||
{
|
||||
if (irqline == (int)LineState.INPUT_LINE_NMI)
|
||||
{
|
||||
if (nmi_state == state)
|
||||
return;
|
||||
nmi_state = state;
|
||||
if (state == LineState.CLEAR_LINE)
|
||||
return;
|
||||
if ((int_state & M6809_LDS) == 0)
|
||||
return;
|
||||
int_state &= (byte)(~M6809_SYNC);
|
||||
if ((int_state & M6809_CWAI) != 0)
|
||||
{
|
||||
int_state &= (byte)(~M6809_CWAI);
|
||||
extra_cycles += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC |= CC_E;
|
||||
PUSHWORD(PC);
|
||||
PUSHWORD(U);
|
||||
PUSHWORD(Y);
|
||||
PUSHWORD(X);
|
||||
PUSHBYTE(DP.HighByte);
|
||||
PUSHBYTE(D.LowByte);
|
||||
PUSHBYTE(D.HighByte);
|
||||
PUSHBYTE(CC);
|
||||
extra_cycles += 19;
|
||||
}
|
||||
CC |= (byte)(CC_IF | CC_II);
|
||||
PC.LowWord = RM16(0xfffc);
|
||||
}
|
||||
else if (irqline < 2)
|
||||
{
|
||||
irq_state[irqline] = state;
|
||||
if (state == LineState.CLEAR_LINE)
|
||||
return;
|
||||
CHECK_IRQ_LINES();
|
||||
}
|
||||
}
|
||||
public override void cpunum_set_input_line_and_vector(int cpunum, int line, LineState state, int vector)
|
||||
{
|
||||
EmuTimer.timer_set_internal(Cpuint.cpunum_empty_event_queue, "cpunum_empty_event_queue");
|
||||
}
|
||||
public override int ExecuteCycles(int cycles)
|
||||
{
|
||||
pendingCycles = cycles - extra_cycles;
|
||||
extra_cycles = 0;
|
||||
if ((int_state & (M6809_CWAI | M6809_SYNC)) != 0)
|
||||
{
|
||||
//debugger_instruction_hook(Machine, PCD);
|
||||
pendingCycles = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
int prevCycles = pendingCycles;
|
||||
PPC = PC;
|
||||
//debugger_instruction_hook(Machine, PCD);
|
||||
ireg = ReadOp(PC.LowWord);
|
||||
PC.LowWord++;
|
||||
debugger_start_cpu_hook_callback();
|
||||
insn[ireg]();
|
||||
pendingCycles -= cycles_6809[ireg];
|
||||
debugger_stop_cpu_hook_callback();
|
||||
int delta = prevCycles - pendingCycles;
|
||||
totalExecutedCycles += (ulong)delta;
|
||||
} while (pendingCycles > 0);
|
||||
|
||||
pendingCycles -= extra_cycles;
|
||||
extra_cycles = 0;
|
||||
}
|
||||
return cycles - pendingCycles;
|
||||
}
|
||||
private void fetch_effective_address()
|
||||
{
|
||||
byte postbyte = ReadOpArg(PC.LowWord);
|
||||
PC.LowWord++;
|
||||
switch (postbyte)
|
||||
{
|
||||
case 0x00: EA.LowWord = X.LowWord; pendingCycles -= 1; break;
|
||||
case 0x01: EA.LowWord = (ushort)(X.LowWord + 1); pendingCycles -= 1; break;
|
||||
case 0x02: EA.LowWord = (ushort)(X.LowWord + 2); pendingCycles -= 1; break;
|
||||
case 0x03: EA.LowWord = (ushort)(X.LowWord + 3); pendingCycles -= 1; break;
|
||||
case 0x04: EA.LowWord = (ushort)(X.LowWord + 4); pendingCycles -= 1; break;
|
||||
case 0x05: EA.LowWord = (ushort)(X.LowWord + 5); pendingCycles -= 1; break;
|
||||
case 0x06: EA.LowWord = (ushort)(X.LowWord + 6); pendingCycles -= 1; break;
|
||||
case 0x07: EA.LowWord = (ushort)(X.LowWord + 7); pendingCycles -= 1; break;
|
||||
case 0x08: EA.LowWord = (ushort)(X.LowWord + 8); pendingCycles -= 1; break;
|
||||
case 0x09: EA.LowWord = (ushort)(X.LowWord + 9); pendingCycles -= 1; break;
|
||||
case 0x0a: EA.LowWord = (ushort)(X.LowWord + 10); pendingCycles -= 1; break;
|
||||
case 0x0b: EA.LowWord = (ushort)(X.LowWord + 11); pendingCycles -= 1; break;
|
||||
case 0x0c: EA.LowWord = (ushort)(X.LowWord + 12); pendingCycles -= 1; break;
|
||||
case 0x0d: EA.LowWord = (ushort)(X.LowWord + 13); pendingCycles -= 1; break;
|
||||
case 0x0e: EA.LowWord = (ushort)(X.LowWord + 14); pendingCycles -= 1; break;
|
||||
case 0x0f: EA.LowWord = (ushort)(X.LowWord + 15); pendingCycles -= 1; break;
|
||||
|
||||
case 0x10: EA.LowWord = (ushort)(X.LowWord - 16); pendingCycles -= 1; break;
|
||||
case 0x11: EA.LowWord = (ushort)(X.LowWord - 15); pendingCycles -= 1; break;
|
||||
case 0x12: EA.LowWord = (ushort)(X.LowWord - 14); pendingCycles -= 1; break;
|
||||
case 0x13: EA.LowWord = (ushort)(X.LowWord - 13); pendingCycles -= 1; break;
|
||||
case 0x14: EA.LowWord = (ushort)(X.LowWord - 12); pendingCycles -= 1; break;
|
||||
case 0x15: EA.LowWord = (ushort)(X.LowWord - 11); pendingCycles -= 1; break;
|
||||
case 0x16: EA.LowWord = (ushort)(X.LowWord - 10); pendingCycles -= 1; break;
|
||||
case 0x17: EA.LowWord = (ushort)(X.LowWord - 9); pendingCycles -= 1; break;
|
||||
case 0x18: EA.LowWord = (ushort)(X.LowWord - 8); pendingCycles -= 1; break;
|
||||
case 0x19: EA.LowWord = (ushort)(X.LowWord - 7); pendingCycles -= 1; break;
|
||||
case 0x1a: EA.LowWord = (ushort)(X.LowWord - 6); pendingCycles -= 1; break;
|
||||
case 0x1b: EA.LowWord = (ushort)(X.LowWord - 5); pendingCycles -= 1; break;
|
||||
case 0x1c: EA.LowWord = (ushort)(X.LowWord - 4); pendingCycles -= 1; break;
|
||||
case 0x1d: EA.LowWord = (ushort)(X.LowWord - 3); pendingCycles -= 1; break;
|
||||
case 0x1e: EA.LowWord = (ushort)(X.LowWord - 2); pendingCycles -= 1; break;
|
||||
case 0x1f: EA.LowWord = (ushort)(X.LowWord - 1); pendingCycles -= 1; break;
|
||||
|
||||
case 0x20: EA.LowWord = Y.LowWord; pendingCycles -= 1; break;
|
||||
case 0x21: EA.LowWord = (ushort)(Y.LowWord + 1); pendingCycles -= 1; break;
|
||||
case 0x22: EA.LowWord = (ushort)(Y.LowWord + 2); pendingCycles -= 1; break;
|
||||
case 0x23: EA.LowWord = (ushort)(Y.LowWord + 3); pendingCycles -= 1; break;
|
||||
case 0x24: EA.LowWord = (ushort)(Y.LowWord + 4); pendingCycles -= 1; break;
|
||||
case 0x25: EA.LowWord = (ushort)(Y.LowWord + 5); pendingCycles -= 1; break;
|
||||
case 0x26: EA.LowWord = (ushort)(Y.LowWord + 6); pendingCycles -= 1; break;
|
||||
case 0x27: EA.LowWord = (ushort)(Y.LowWord + 7); pendingCycles -= 1; break;
|
||||
case 0x28: EA.LowWord = (ushort)(Y.LowWord + 8); pendingCycles -= 1; break;
|
||||
case 0x29: EA.LowWord = (ushort)(Y.LowWord + 9); pendingCycles -= 1; break;
|
||||
case 0x2a: EA.LowWord = (ushort)(Y.LowWord + 10); pendingCycles -= 1; break;
|
||||
case 0x2b: EA.LowWord = (ushort)(Y.LowWord + 11); pendingCycles -= 1; break;
|
||||
case 0x2c: EA.LowWord = (ushort)(Y.LowWord + 12); pendingCycles -= 1; break;
|
||||
case 0x2d: EA.LowWord = (ushort)(Y.LowWord + 13); pendingCycles -= 1; break;
|
||||
case 0x2e: EA.LowWord = (ushort)(Y.LowWord + 14); pendingCycles -= 1; break;
|
||||
case 0x2f: EA.LowWord = (ushort)(Y.LowWord + 15); pendingCycles -= 1; break;
|
||||
|
||||
case 0x30: EA.LowWord = (ushort)(Y.LowWord - 16); pendingCycles -= 1; break;
|
||||
case 0x31: EA.LowWord = (ushort)(Y.LowWord - 15); pendingCycles -= 1; break;
|
||||
case 0x32: EA.LowWord = (ushort)(Y.LowWord - 14); pendingCycles -= 1; break;
|
||||
case 0x33: EA.LowWord = (ushort)(Y.LowWord - 13); pendingCycles -= 1; break;
|
||||
case 0x34: EA.LowWord = (ushort)(Y.LowWord - 12); pendingCycles -= 1; break;
|
||||
case 0x35: EA.LowWord = (ushort)(Y.LowWord - 11); pendingCycles -= 1; break;
|
||||
case 0x36: EA.LowWord = (ushort)(Y.LowWord - 10); pendingCycles -= 1; break;
|
||||
case 0x37: EA.LowWord = (ushort)(Y.LowWord - 9); pendingCycles -= 1; break;
|
||||
case 0x38: EA.LowWord = (ushort)(Y.LowWord - 8); pendingCycles -= 1; break;
|
||||
case 0x39: EA.LowWord = (ushort)(Y.LowWord - 7); pendingCycles -= 1; break;
|
||||
case 0x3a: EA.LowWord = (ushort)(Y.LowWord - 6); pendingCycles -= 1; break;
|
||||
case 0x3b: EA.LowWord = (ushort)(Y.LowWord - 5); pendingCycles -= 1; break;
|
||||
case 0x3c: EA.LowWord = (ushort)(Y.LowWord - 4); pendingCycles -= 1; break;
|
||||
case 0x3d: EA.LowWord = (ushort)(Y.LowWord - 3); pendingCycles -= 1; break;
|
||||
case 0x3e: EA.LowWord = (ushort)(Y.LowWord - 2); pendingCycles -= 1; break;
|
||||
case 0x3f: EA.LowWord = (ushort)(Y.LowWord - 1); pendingCycles -= 1; break;
|
||||
|
||||
case 0x40: EA.LowWord = U.LowWord; pendingCycles -= 1; break;
|
||||
case 0x41: EA.LowWord = (ushort)(U.LowWord + 1); pendingCycles -= 1; break;
|
||||
case 0x42: EA.LowWord = (ushort)(U.LowWord + 2); pendingCycles -= 1; break;
|
||||
case 0x43: EA.LowWord = (ushort)(U.LowWord + 3); pendingCycles -= 1; break;
|
||||
case 0x44: EA.LowWord = (ushort)(U.LowWord + 4); pendingCycles -= 1; break;
|
||||
case 0x45: EA.LowWord = (ushort)(U.LowWord + 5); pendingCycles -= 1; break;
|
||||
case 0x46: EA.LowWord = (ushort)(U.LowWord + 6); pendingCycles -= 1; break;
|
||||
case 0x47: EA.LowWord = (ushort)(U.LowWord + 7); pendingCycles -= 1; break;
|
||||
case 0x48: EA.LowWord = (ushort)(U.LowWord + 8); pendingCycles -= 1; break;
|
||||
case 0x49: EA.LowWord = (ushort)(U.LowWord + 9); pendingCycles -= 1; break;
|
||||
case 0x4a: EA.LowWord = (ushort)(U.LowWord + 10); pendingCycles -= 1; break;
|
||||
case 0x4b: EA.LowWord = (ushort)(U.LowWord + 11); pendingCycles -= 1; break;
|
||||
case 0x4c: EA.LowWord = (ushort)(U.LowWord + 12); pendingCycles -= 1; break;
|
||||
case 0x4d: EA.LowWord = (ushort)(U.LowWord + 13); pendingCycles -= 1; break;
|
||||
case 0x4e: EA.LowWord = (ushort)(U.LowWord + 14); pendingCycles -= 1; break;
|
||||
case 0x4f: EA.LowWord = (ushort)(U.LowWord + 15); pendingCycles -= 1; break;
|
||||
|
||||
case 0x50: EA.LowWord = (ushort)(U.LowWord - 16); pendingCycles -= 1; break;
|
||||
case 0x51: EA.LowWord = (ushort)(U.LowWord - 15); pendingCycles -= 1; break;
|
||||
case 0x52: EA.LowWord = (ushort)(U.LowWord - 14); pendingCycles -= 1; break;
|
||||
case 0x53: EA.LowWord = (ushort)(U.LowWord - 13); pendingCycles -= 1; break;
|
||||
case 0x54: EA.LowWord = (ushort)(U.LowWord - 12); pendingCycles -= 1; break;
|
||||
case 0x55: EA.LowWord = (ushort)(U.LowWord - 11); pendingCycles -= 1; break;
|
||||
case 0x56: EA.LowWord = (ushort)(U.LowWord - 10); pendingCycles -= 1; break;
|
||||
case 0x57: EA.LowWord = (ushort)(U.LowWord - 9); pendingCycles -= 1; break;
|
||||
case 0x58: EA.LowWord = (ushort)(U.LowWord - 8); pendingCycles -= 1; break;
|
||||
case 0x59: EA.LowWord = (ushort)(U.LowWord - 7); pendingCycles -= 1; break;
|
||||
case 0x5a: EA.LowWord = (ushort)(U.LowWord - 6); pendingCycles -= 1; break;
|
||||
case 0x5b: EA.LowWord = (ushort)(U.LowWord - 5); pendingCycles -= 1; break;
|
||||
case 0x5c: EA.LowWord = (ushort)(U.LowWord - 4); pendingCycles -= 1; break;
|
||||
case 0x5d: EA.LowWord = (ushort)(U.LowWord - 3); pendingCycles -= 1; break;
|
||||
case 0x5e: EA.LowWord = (ushort)(U.LowWord - 2); pendingCycles -= 1; break;
|
||||
case 0x5f: EA.LowWord = (ushort)(U.LowWord - 1); pendingCycles -= 1; break;
|
||||
|
||||
case 0x60: EA.LowWord = S.LowWord; pendingCycles -= 1; break;
|
||||
case 0x61: EA.LowWord = (ushort)(S.LowWord + 1); pendingCycles -= 1; break;
|
||||
case 0x62: EA.LowWord = (ushort)(S.LowWord + 2); pendingCycles -= 1; break;
|
||||
case 0x63: EA.LowWord = (ushort)(S.LowWord + 3); pendingCycles -= 1; break;
|
||||
case 0x64: EA.LowWord = (ushort)(S.LowWord + 4); pendingCycles -= 1; break;
|
||||
case 0x65: EA.LowWord = (ushort)(S.LowWord + 5); pendingCycles -= 1; break;
|
||||
case 0x66: EA.LowWord = (ushort)(S.LowWord + 6); pendingCycles -= 1; break;
|
||||
case 0x67: EA.LowWord = (ushort)(S.LowWord + 7); pendingCycles -= 1; break;
|
||||
case 0x68: EA.LowWord = (ushort)(S.LowWord + 8); pendingCycles -= 1; break;
|
||||
case 0x69: EA.LowWord = (ushort)(S.LowWord + 9); pendingCycles -= 1; break;
|
||||
case 0x6a: EA.LowWord = (ushort)(S.LowWord + 10); pendingCycles -= 1; break;
|
||||
case 0x6b: EA.LowWord = (ushort)(S.LowWord + 11); pendingCycles -= 1; break;
|
||||
case 0x6c: EA.LowWord = (ushort)(S.LowWord + 12); pendingCycles -= 1; break;
|
||||
case 0x6d: EA.LowWord = (ushort)(S.LowWord + 13); pendingCycles -= 1; break;
|
||||
case 0x6e: EA.LowWord = (ushort)(S.LowWord + 14); pendingCycles -= 1; break;
|
||||
case 0x6f: EA.LowWord = (ushort)(S.LowWord + 15); pendingCycles -= 1; break;
|
||||
|
||||
case 0x70: EA.LowWord = (ushort)(S.LowWord - 16); pendingCycles -= 1; break;
|
||||
case 0x71: EA.LowWord = (ushort)(S.LowWord - 15); pendingCycles -= 1; break;
|
||||
case 0x72: EA.LowWord = (ushort)(S.LowWord - 14); pendingCycles -= 1; break;
|
||||
case 0x73: EA.LowWord = (ushort)(S.LowWord - 13); pendingCycles -= 1; break;
|
||||
case 0x74: EA.LowWord = (ushort)(S.LowWord - 12); pendingCycles -= 1; break;
|
||||
case 0x75: EA.LowWord = (ushort)(S.LowWord - 11); pendingCycles -= 1; break;
|
||||
case 0x76: EA.LowWord = (ushort)(S.LowWord - 10); pendingCycles -= 1; break;
|
||||
case 0x77: EA.LowWord = (ushort)(S.LowWord - 9); pendingCycles -= 1; break;
|
||||
case 0x78: EA.LowWord = (ushort)(S.LowWord - 8); pendingCycles -= 1; break;
|
||||
case 0x79: EA.LowWord = (ushort)(S.LowWord - 7); pendingCycles -= 1; break;
|
||||
case 0x7a: EA.LowWord = (ushort)(S.LowWord - 6); pendingCycles -= 1; break;
|
||||
case 0x7b: EA.LowWord = (ushort)(S.LowWord - 5); pendingCycles -= 1; break;
|
||||
case 0x7c: EA.LowWord = (ushort)(S.LowWord - 4); pendingCycles -= 1; break;
|
||||
case 0x7d: EA.LowWord = (ushort)(S.LowWord - 3); pendingCycles -= 1; break;
|
||||
case 0x7e: EA.LowWord = (ushort)(S.LowWord - 2); pendingCycles -= 1; break;
|
||||
case 0x7f: EA.LowWord = (ushort)(S.LowWord - 1); pendingCycles -= 1; break;
|
||||
|
||||
case 0x80: EA.LowWord = X.LowWord; X.LowWord++; pendingCycles -= 2; break;
|
||||
case 0x81: EA.LowWord = X.LowWord; X.LowWord += 2; pendingCycles -= 3; break;
|
||||
case 0x82: X.LowWord--; EA.LowWord = X.LowWord; pendingCycles -= 2; break;
|
||||
case 0x83: X.LowWord -= 2; EA.LowWord = X.LowWord; pendingCycles -= 3; break;
|
||||
case 0x84: EA.LowWord = X.LowWord; break;
|
||||
case 0x85: EA.LowWord = (ushort)(X.LowWord + SIGNED(D.LowByte)); pendingCycles -= 1; break;
|
||||
case 0x86: EA.LowWord = (ushort)(X.LowWord + SIGNED(D.HighByte)); pendingCycles -= 1; break;
|
||||
case 0x87: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0x88: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(X.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break; /* this is a hack to make Vectrex work. It should be m6809_ICount-=1. Dunno where the cycle was lost :( */
|
||||
case 0x89: EA = IMMWORD(); EA.LowWord += X.LowWord; pendingCycles -= 4; break;
|
||||
case 0x8a: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0x8b: EA.LowWord = (ushort)(X.LowWord + D.LowWord); pendingCycles -= 4; break;
|
||||
case 0x8c: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0x8d: EA = IMMWORD(); EA.LowWord += PC.LowWord; pendingCycles -= 5; break;
|
||||
case 0x8e: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0x8f: EA = IMMWORD(); pendingCycles -= 5; break;
|
||||
|
||||
case 0x90: EA.LowWord = X.LowWord; X.LowWord++; EA.d = RM16(EA.LowWord); pendingCycles -= 5; break; /* Indirect ,R+ not in my specs */
|
||||
case 0x91: EA.LowWord = X.LowWord; X.LowWord += 2; EA.d = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0x92: X.LowWord--; EA.LowWord = X.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0x93: X.LowWord -= 2; EA.LowWord = X.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0x94: EA.LowWord = X.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 3; break;
|
||||
case 0x95: EA.LowWord = (ushort)(X.LowWord + SIGNED(D.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0x96: EA.LowWord = (ushort)(X.LowWord + SIGNED(D.HighByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0x97: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0x98: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(X.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0x99: EA = IMMWORD(); EA.LowWord += X.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0x9a: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0x9b: EA.LowWord = (ushort)(X.LowWord + D.LowWord); EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0x9c: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0x9d: EA = IMMWORD(); EA.LowWord += PC.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
case 0x9e: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0x9f: EA = IMMWORD(); EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
|
||||
case 0xa0: EA.LowWord = Y.LowWord; Y.LowWord++; pendingCycles -= 2; break;
|
||||
case 0xa1: EA.LowWord = Y.LowWord; Y.LowWord += 2; pendingCycles -= 3; break;
|
||||
case 0xa2: Y.LowWord--; EA.LowWord = Y.LowWord; pendingCycles -= 2; break;
|
||||
case 0xa3: Y.LowWord -= 2; EA.LowWord = Y.LowWord; pendingCycles -= 3; break;
|
||||
case 0xa4: EA.LowWord = Y.LowWord; break;
|
||||
case 0xa5: EA.LowWord = (ushort)(Y.LowWord + SIGNED(D.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xa6: EA.LowWord = (ushort)(Y.LowWord + SIGNED(D.HighByte)); pendingCycles -= 1; break;
|
||||
case 0xa7: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0xa8: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(Y.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xa9: EA = IMMWORD(); EA.LowWord += Y.LowWord; pendingCycles -= 4; break;
|
||||
case 0xaa: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0xab: EA.LowWord = (ushort)(Y.LowWord + D.LowWord); pendingCycles -= 4; break;
|
||||
case 0xac: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xad: EA = IMMWORD(); EA.LowWord += PC.LowWord; pendingCycles -= 5; break;
|
||||
case 0xae: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0xaf: EA = IMMWORD(); pendingCycles -= 5; break;
|
||||
|
||||
case 0xb0: EA.LowWord = Y.LowWord; Y.LowWord++; EA.LowWord = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0xb1: EA.LowWord = Y.LowWord; Y.LowWord += 2; EA.LowWord = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0xb2: Y.LowWord--; EA.LowWord = Y.LowWord; EA.LowWord = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0xb3: Y.LowWord -= 2; EA.LowWord = Y.LowWord; EA.LowWord = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0xb4: EA.LowWord = Y.LowWord; EA.LowWord = RM16(EA.LowWord); pendingCycles -= 3; break;
|
||||
case 0xb5: EA.LowWord = (ushort)(Y.LowWord + SIGNED(D.LowByte)); EA.LowWord = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xb6: EA.LowWord = (ushort)(Y.LowWord + SIGNED(D.HighByte)); EA.LowWord = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xb7: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0xb8: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(Y.LowWord + SIGNED(EA.LowByte)); EA.LowWord = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xb9: EA = IMMWORD(); EA.LowWord += Y.LowWord; EA.LowWord = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0xba: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0xbb: EA.LowWord = (ushort)(Y.LowWord + D.LowWord); EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0xbc: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xbd: EA = IMMWORD(); EA.LowWord += PC.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
case 0xbe: EA.LowWord = 0; break; /* ILLEGAL*/
|
||||
case 0xbf: EA = IMMWORD(); EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
|
||||
case 0xc0: EA.LowWord = U.LowWord; U.LowWord++; pendingCycles -= 2; break;
|
||||
case 0xc1: EA.LowWord = U.LowWord; U.LowWord += 2; pendingCycles -= 3; break;
|
||||
case 0xc2: U.LowWord--; EA.LowWord = U.LowWord; pendingCycles -= 2; break;
|
||||
case 0xc3: U.LowWord -= 2; EA.LowWord = U.LowWord; pendingCycles -= 3; break;
|
||||
case 0xc4: EA.LowWord = U.LowWord; break;
|
||||
case 0xc5: EA.LowWord = (ushort)(U.LowWord + SIGNED(D.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xc6: EA.LowWord = (ushort)(U.LowWord + SIGNED(D.HighByte)); pendingCycles -= 1; break;
|
||||
case 0xc7: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xc8: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(U.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xc9: EA = IMMWORD(); EA.LowWord += U.LowWord; pendingCycles -= 4; break;
|
||||
case 0xca: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xcb: EA.LowWord = (ushort)(U.LowWord + D.LowWord); pendingCycles -= 4; break;
|
||||
case 0xcc: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xcd: EA = IMMWORD(); EA.LowWord += PC.LowWord; pendingCycles -= 5; break;
|
||||
case 0xce: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xcf: EA = IMMWORD(); pendingCycles -= 5; break;
|
||||
|
||||
case 0xd0: EA.LowWord = U.LowWord; U.LowWord++; EA.d = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0xd1: EA.LowWord = U.LowWord; U.LowWord += 2; EA.d = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0xd2: U.LowWord--; EA.LowWord = U.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0xd3: U.LowWord -= 2; EA.LowWord = U.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0xd4: EA.LowWord = U.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 3; break;
|
||||
case 0xd5: EA.LowWord = (ushort)(U.LowWord + SIGNED(D.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xd6: EA.LowWord = (ushort)(U.LowWord + SIGNED(D.HighByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xd7: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xd8: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(U.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xd9: EA = IMMWORD(); EA.LowWord += U.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0xda: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xdb: EA.LowWord = (ushort)(U.LowWord + D.LowWord); EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0xdc: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xdd: EA = IMMWORD(); EA.LowWord += PC.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
case 0xde: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xdf: EA = IMMWORD(); EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
|
||||
case 0xe0: EA.LowWord = S.LowWord; S.LowWord++; pendingCycles -= 2; break;
|
||||
case 0xe1: EA.LowWord = S.LowWord; S.LowWord += 2; pendingCycles -= 3; break;
|
||||
case 0xe2: S.LowWord--; EA.LowWord = S.LowWord; pendingCycles -= 2; break;
|
||||
case 0xe3: S.LowWord -= 2; EA.LowWord = S.LowWord; pendingCycles -= 3; break;
|
||||
case 0xe4: EA.LowWord = S.LowWord; break;
|
||||
case 0xe5: EA.LowWord = (ushort)(S.LowWord + SIGNED(D.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xe6: EA.LowWord = (ushort)(S.LowWord + SIGNED(D.HighByte)); pendingCycles -= 1; break;
|
||||
case 0xe7: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xe8: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(S.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xe9: EA = IMMWORD(); EA.LowWord += S.LowWord; pendingCycles -= 4; break;
|
||||
case 0xea: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xeb: EA.LowWord = (ushort)(S.LowWord + D.LowWord); pendingCycles -= 4; break;
|
||||
case 0xec: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); pendingCycles -= 1; break;
|
||||
case 0xed: EA = IMMWORD(); EA.LowWord += PC.LowWord; pendingCycles -= 5; break;
|
||||
case 0xee: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xef: EA = IMMWORD(); pendingCycles -= 5; break;
|
||||
|
||||
case 0xf0: EA.LowWord = S.LowWord; S.LowWord++; EA.d = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0xf1: EA.LowWord = S.LowWord; S.LowWord += 2; EA.d = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0xf2: S.LowWord--; EA.LowWord = S.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 5; break;
|
||||
case 0xf3: S.LowWord -= 2; EA.LowWord = S.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 6; break;
|
||||
case 0xf4: EA.LowWord = S.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 3; break;
|
||||
case 0xf5: EA.LowWord = (ushort)(S.LowWord + SIGNED(D.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xf6: EA.LowWord = (ushort)(S.LowWord + SIGNED(D.HighByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xf7: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xf8: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(S.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xf9: EA = IMMWORD(); EA.LowWord += S.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0xfa: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xfb: EA.LowWord = (ushort)(S.LowWord + D.LowWord); EA.d = RM16(EA.LowWord); pendingCycles -= 7; break;
|
||||
case 0xfc: EA.LowWord = IMMBYTE(); EA.LowWord = (ushort)(PC.LowWord + SIGNED(EA.LowByte)); EA.d = RM16(EA.LowWord); pendingCycles -= 4; break;
|
||||
case 0xfd: EA = IMMWORD(); EA.LowWord += PC.LowWord; EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
case 0xfe: EA.LowWord = 0; break; /*ILLEGAL*/
|
||||
case 0xff: EA = IMMWORD(); EA.d = RM16(EA.LowWord); pendingCycles -= 8; break;
|
||||
}
|
||||
}
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(PC.LowWord);
|
||||
writer.Write(PPC.LowWord);
|
||||
writer.Write(D.LowWord);
|
||||
writer.Write(DP.LowWord);
|
||||
writer.Write(U.LowWord);
|
||||
writer.Write(S.LowWord);
|
||||
writer.Write(X.LowWord);
|
||||
writer.Write(Y.LowWord);
|
||||
writer.Write(CC);
|
||||
writer.Write((byte)irq_state[0]);
|
||||
writer.Write((byte)irq_state[1]);
|
||||
writer.Write(int_state);
|
||||
writer.Write((byte)nmi_state);
|
||||
writer.Write(TotalExecutedCycles);
|
||||
writer.Write(PendingCycles);
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
PC.LowWord = reader.ReadUInt16();
|
||||
PPC.LowWord = reader.ReadUInt16();
|
||||
D.LowWord = reader.ReadUInt16();
|
||||
DP.LowWord = reader.ReadUInt16();
|
||||
U.LowWord = reader.ReadUInt16();
|
||||
S.LowWord = reader.ReadUInt16();
|
||||
X.LowWord = reader.ReadUInt16();
|
||||
Y.LowWord = reader.ReadUInt16();
|
||||
CC = reader.ReadByte();
|
||||
irq_state[0] = (LineState)reader.ReadByte();
|
||||
irq_state[1] = (LineState)reader.ReadByte();
|
||||
int_state = reader.ReadByte();
|
||||
nmi_state = (LineState)reader.ReadByte();
|
||||
TotalExecutedCycles = reader.ReadUInt64();
|
||||
PendingCycles = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user