Update驱动

This commit is contained in:
sin365 2025-01-16 11:51:17 +08:00
parent aa984889d9
commit c1f23ea66f
505 changed files with 129587 additions and 68 deletions

View File

@ -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:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 302b2980355568a4c807b1ba31964637
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,3 @@
{
"name": "AxiReplay"
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0a45db2096af23647aaafe5b70ccb4d7
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 896ff07370157db46b612575616020ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a8fcda365e5a7f428f88bc130eb913b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 452b58ff73a0853449845fd9e1134cc2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42df5a138f4f4ae488815f35d8e748da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 66e0e18d1f5981745a3078e8460cb0e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dc53a3d9a3e1749438b6ad1cef7b39bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a84f6259c44984045a42bd9e64c43b0a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f996a7038b3e4a04bbc4722c030e7c0e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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; }
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b94fc4b46eb73b541b66a64f2831e49c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 19fb05683c89f9d438ce6cb7e65de2ec
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 152466b6f17e41244be3f9dd18aee4e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35d7d011a9c354848a421281c06f5f8c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ebd8f2e90f8767b498f2431f7394ede9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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 宽高
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eacdf053bdef1934d8cdec1c463f8847
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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");
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 847edc5d4d82b7448a62f92c9d3dee10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 08bc0c1fe9979244e872263dfe2c09b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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";
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85d3575e43093a54f82622b4c53c1a40
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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";
}*/
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43abb82203533b94fa07632370f6ca15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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";
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2c291a8abf15d254596af257bb937441
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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";
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b1dce3116faca2f43a19f5e965e245e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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";
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0cb936512a0186e449fa3a9053127b42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e0f2056e5d40c9e4b87a70bb42c0665d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 87f805602538c22479c796f78f64b052
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6e66dd647cf36e64eba535a9422b5dfd
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a5cd247a5a04ff44bbdce6ed08ab6ccb
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69d9e952f0a1b3349b7127b9f01238f3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 13fc2a860c40ef54b917a94ebf44f187
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5256a2747754bc84095436214447d27b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: efa49c62f62f6f048a465cb5e940eeae
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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--;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f888c964f0338f48a49e0eaedeb54ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e27c96a34afca8c4f991cc6209a8895e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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); }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb223c61fecbecc4fb762d9ebe649194
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df989ce237c20a84aa97ead349d2093e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 317be4f8630ce90409e488310814c936
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b048d365a2726014e8b35b00934ba716
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ac480a98cd915a488d75cf520ceeb12
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5363a2171a5a06e458069790876245da
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 59a132d3fbbd20c488b17cf0b0bedd22
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d595cf6577109d144b95da9cb77cfdd9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f00bdfe992953ee40bfa6536dcda1148
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2095e1daba88c5b4b935aaa55d3ed2e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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];
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8ae0dd765643d44da568a00571a176e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cde299f017f5c6c4d83cb4a8e4cfe543
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8ca60a438b9bb004189843e1d4dad73c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f558f03c67bd724291c979f90d0acff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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
};
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dd115883ec0396d42abef36787464a37
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1cec51d80caf2184681dc0898d9dec38
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 84fc920b98828f14c8f326b4f1520eb0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0c310d005b3a9f4d8861c58a32603b9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24967d13608942c4289d335114c41269
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05a5a82c4182e0f4082c1e8329ddde79
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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