This commit is contained in:
ALIENJACK\alien 2025-01-25 10:01:07 +08:00
commit c4825696d6
507 changed files with 150128 additions and 144 deletions

View File

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

View File

@ -0,0 +1,33 @@
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);
}
public static void Assert(bool conditional, string msg)
{
if (conditional)
return;
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

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 271a8a6401146c04ab5fb754032a2dd5

View File

@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace MAME.Core
{
public class MAMEDBHelper
{
public static void LoadROMXML(string xmbString)
{
XElement xe = XElement.Parse(xmbString);
IEnumerable<XElement> elements = from ele in xe.Elements("game") select ele;
showInfoByElements(elements);
}
static 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 }));
}
}
}
}

View File

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

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
namespace MAME.Core
{
public class MAMEEmu : IDisposable
{
public MameMainMotion mameMainMotion { get; private set; }
//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 void ResetRomRoot(string RomDir) => mameMainMotion.ResetRomRoot(RomDir);
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 StartGame_WithNewThread() => mameMainMotion.StartGame_WithNewThread();
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 bool IsPaused => Mame.paused;
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();
AxiMemoryEx.FreeAllGCHandle();
}
public void SetPaused(bool ispaused)
{
Mame.paused = ispaused;
}
}
}

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,14 @@
{
"name": "Mame.Core",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9cfb12a06e639a448b797cd60959004e
AssemblyDefinitionImporter:
externalObjects: {}
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,613 @@
using System;
using System.Collections.Generic;
using System.Threading;
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
)
{
AxiMemoryEx.Init();
AxiTimeSpan.Init(itime);
Mame.RomRoot = RomDir;
EmuLogger.BindFunc(ilog);
Video.BindFunc(ivp);
Sound.BindFunc(isp);
resource = iRes;
sSelect = string.Empty;
RomInfo.Rom = new RomInfo();
MAMEDBHelper.LoadROMXML(resource.mame);
Keyboard.InitializeInput(ikb);
Mouse.InitialMouse(imou);
}
public void ResetRomRoot(string RomDir)
{
Mame.RomRoot = RomDir;
}
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;
}
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()
{
bIsNewThreadMode = false;
Mame.exit_pending = false;
Mame.mame_execute_UpdateMode_Start();
}
public void StartGame_WithNewThread()
{
bIsNewThreadMode = true;
Mame.exit_pending = false;
//初始化停帧信号量
emuAutoLoopEvent = new AutoResetEvent(false);
mainThread = new Thread(Mame.mame_execute);
mainThread.Start();
}
public static object unlockMoreFrameObj = new object();
public static int unlockMoreFrame;
/// <summary>
/// 放开帧
/// </summary>
/// <param name="moveTick"></param>
public void UnlockNextFreme(int moreTick = 1)
{
if (!bIsNewThreadMode)
return;
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.WaitAutoEvent();
}
private void WaitAutoEvent()
{
if (!bIsNewThreadMode)
return;
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 bool bIsNewThreadMode;
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,9 @@
namespace MAME.Core
{
public partial class CpsMotion
{
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,9 @@
namespace MAME.Core
{
public class Konami68000Motion
{
public Konami68000Motion()
{
}
}
}

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,13 @@
using cpu.m68000;
using System;
using System.Collections.Generic;
namespace MAME.Core
{
public class M68000Motion
{
public M68000Motion()
{
}
}
}

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,13 @@
using cpu.m6809;
using System.Collections.Generic;
namespace MAME.Core
{
public partial class M6809Motion
{
public M6809Motion()
{
}
}
}

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,11 @@
using System.Collections.Generic;
namespace MAME.Core
{
public partial class NeogeoMotion
{
public NeogeoMotion()
{
}
}
}

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,14 @@
using cpu.z80;
using System.Collections.Generic;
namespace MAME.Core
{
public partial class Z80Motion
{
public Z80Motion()
{
}
}
}

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,438 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace MAME.Core
{
internal static class ObjectPoolAuto
{
/************************************************************************************************************************/
/// <summary>
/// 获取或者创建一个新的
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
public static T Acquire<T>()
where T : class, new()
=> ObjectPool<T>.Acquire();
/// <summary>
/// 获取或者创建一个新的
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
public static void Acquire<T>(out T item)
where T : class, new()
=> item = ObjectPool<T>.Acquire();
/************************************************************************************************************************/
/// <summary>
/// 回收对象
/// </summary>
public static void Release<T>(T item)
where T : class, new()
=> ObjectPool<T>.Release(item);
/// <summary>
/// 回收对象
/// </summary>
public static void Release<T>(ref T item) where T : class, new()
{
if (item != null)
{
ObjectPool<T>.Release(item);
item = null;
}
}
/************************************************************************************************************************/
public const string
NotClearError = " They must be cleared before being released to the pool and not modified after that.";
/************************************************************************************************************************/
/// <summary>
/// 获取或创建List
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(List{T})"/> 回收参见此方法</remarks>
public static List<T> AcquireList<T>()
{
var list = ObjectPool<List<T>>.Acquire();
EmuLogger.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
return list;
}
/// <summary>
/// 回收List
/// </summary>
public static void Release<T>(List<T> list)
{
list.Clear();
ObjectPool<List<T>>.Release(list);
}
/// <summary>
/// 回收List内容
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
public static void ReleaseListContent<T>(List<T> list) where T : class, new()
{
foreach (var item in list)
{
ObjectPool<T>.Release(item);
}
list.Clear();
}
/************************************************************************************************************************/
/// <summary>
/// 获取或创建HashSet
/// </summary>
public static HashSet<T> AcquireSet<T>()
{
var set = ObjectPool<HashSet<T>>.Acquire();
EmuLogger.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
return set;
}
/// <summary>
/// 释放HashSet
/// </summary>
public static void Release<T>(HashSet<T> set)
{
set.Clear();
ObjectPool<HashSet<T>>.Release(set);
}
/************************************************************************************************************************/
/// <summary>
/// 获取一个字符串StringBuilder
/// </summary>
/// <remarks>Remember to <see cref="Release(StringBuilder)"/>回收参见这个</remarks>
public static StringBuilder AcquireStringBuilder()
{
var builder = ObjectPool<StringBuilder>.Acquire();
EmuLogger.Assert(builder.Length == 0, $"A pooled {nameof(StringBuilder)} is not empty." + NotClearError);
return builder;
}
/// <summary>
/// 回收 StringBuilder
/// </summary>
public static void Release(StringBuilder builder)
{
builder.Length = 0;
ObjectPool<StringBuilder>.Release(builder);
}
/// <summary>
/// 回收 StringBuilder
/// </summary>
public static string ReleaseToString(this StringBuilder builder)
{
var result = builder.ToString();
Release(builder);
return result;
}
/************************************************************************************************************************/
private static class Cache<T>
{
public static readonly Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>
Results = new Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>();
}
/// <summary>
/// 此方法主要用于频繁绘制缓存比如说GUI绘制
/// </summary>
public static T GetCachedResult<T>(Func<T> function)
{
var method = function.Method;
if (!Cache<T>.Results.TryGetValue(method, out var result))
{
result = new KeyValuePair<Func<T>, T>(function, function());
Cache<T>.Results.Add(method, result);
}
else if (result.Key != function)
{
EmuLogger.Log(
$"{nameof(GetCachedResult)}<{typeof(T).Name}>" +
$" was previously called on {method.Name} with a different target." +
" This likely means that a new delegate is being passed into every call" +
" so it can't actually return the same cached object.");
}
return result.Value;
}
/************************************************************************************************************************/
public static class Disposable
{
/************************************************************************************************************************/
/// <summary>
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
/// </summary>
public static IDisposable Acquire<T>(out T item)
where T : class, new()
=> ObjectPool<T>.Disposable.Acquire(out item);
/************************************************************************************************************************/
/// <summary>
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
/// </summary>
public static IDisposable AcquireList<T>(out List<T> list)
{
var disposable = ObjectPool<List<T>>.Disposable.Acquire(out list, onRelease: (l) => l.Clear());
EmuLogger.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
return disposable;
}
/************************************************************************************************************************/
/// <summary>
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="HashSet{T}"/> if
/// </summary>
public static IDisposable AcquireSet<T>(out HashSet<T> set)
{
var disposable = ObjectPool<HashSet<T>>.Disposable.Acquire(out set, onRelease: (s) => s.Clear());
EmuLogger.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
return disposable;
}
/************************************************************************************************************************/
}
/************************************************************************************************************************/
public static class ObjectPool<T> where T : class, new()
{
/************************************************************************************************************************/
private static readonly List<T>
Items = new List<T>();
/************************************************************************************************************************/
/// <summary>The number of spare items currently in the pool.</summary>
public static int Count
{
get => Items.Count;
set
{
var count = Items.Count;
if (count < value)
{
if (Items.Capacity < value)
Items.Capacity = NextPowerOfTwo(value);
do
{
Items.Add(new T());
count++;
}
while (count < value);
}
else if (count > value)
{
Items.RemoveRange(value, count - value);
}
}
}
// 计算大于或等于给定数的最小的2的幂
public static int NextPowerOfTwo(int value)
{
// 处理value为0的特殊情况
if (value == 0)
return 1;
// value已经是2的幂的情况
if ((value & (value - 1)) == 0)
return value;
// 不断左移直到找到一个大于或等于value的2的幂
int powerOfTwo = 1;
while (powerOfTwo < value)
{
powerOfTwo <<= 1; // 左移一位相当于乘以2
}
return powerOfTwo;
}
/************************************************************************************************************************/
/// <summary>
/// If the <see cref="Count"/> is less than the specified value, this method increases it to that value by
/// creating new objects.
/// </summary>
public static void SetMinCount(int count)
{
if (Count < count)
Count = count;
}
/************************************************************************************************************************/
/// <summary>The <see cref="List{T}.Capacity"/> of the internal list of spare items.</summary>
public static int Capacity
{
get => Items.Capacity;
set
{
if (Items.Count > value)
Items.RemoveRange(value, Items.Count - value);
Items.Capacity = value;
}
}
/************************************************************************************************************************/
/// <summary>Returns a spare item if there are any, or creates a new one.</summary>
/// <remarks>Remember to <see cref="Release(T)"/> it when you are done.</remarks>
public static T Acquire()
{
var count = Items.Count;
if (count == 0)
{
return new T();
}
else
{
count--;
var item = Items[count];
Items.RemoveAt(count);
return item;
}
}
/************************************************************************************************************************/
/// <summary>Adds the `item` to the list of spares so it can be reused.</summary>
public static void Release(T item)
{
Items.Add(item);
}
/************************************************************************************************************************/
/// <summary>Returns a description of the state of this pool.</summary>
public static string GetDetails()
{
return
$"{typeof(T).Name}" +
$" ({nameof(Count)} = {Items.Count}" +
$", {nameof(Capacity)} = {Items.Capacity}" +
")";
}
/************************************************************************************************************************/
/// <summary>
/// An <see cref="IDisposable"/> system to allow pooled objects to be acquired and released within <c>using</c>
/// statements instead of needing to manually release everything.
/// </summary>
public sealed class Disposable : IDisposable
{
/************************************************************************************************************************/
private static readonly List<Disposable> LazyStack = new List<Disposable>();
private static int _ActiveDisposables;
private T _Item;
private Action<T> _OnRelease;
/************************************************************************************************************************/
private Disposable() { }
/// <summary>
/// Calls <see cref="ObjectPool{T}.Acquire"/> to set the `item` and returns an <see cref="IDisposable"/>
/// that will call <see cref="Release(T)"/> on the `item` when disposed.
/// </summary>
public static IDisposable Acquire(out T item, Action<T> onRelease = null)
{
Disposable disposable;
if (LazyStack.Count <= _ActiveDisposables)
{
LazyStack.Add(disposable = new Disposable());
}
else
{
disposable = LazyStack[_ActiveDisposables];
}
_ActiveDisposables++;
disposable._Item = item = ObjectPool<T>.Acquire();
disposable._OnRelease = onRelease;
return disposable;
}
/************************************************************************************************************************/
void IDisposable.Dispose()
{
_OnRelease?.Invoke(_Item);
Release(_Item);
_ActiveDisposables--;
}
/************************************************************************************************************************/
}
}
#region ExtFunctions
public struct PoolHandle<T> : IDisposable
where T : class, new()
{
public T Ins;
internal static PoolHandle<T> Create(T poolIns)
{
return new PoolHandle<T> { Ins = poolIns };
}
public void Dispose()
{
ObjectPoolAuto.Release<T>(Ins);
}
}
public struct PoolListHandle<T> : IDisposable
{
public List<T> Ins;
internal static PoolListHandle<T> Create(List<T> poolIns)
{
return new PoolListHandle<T> { Ins = poolIns };
}
public void Dispose()
{
ObjectPoolAuto.Release<T>(Ins);
}
}
public static PoolHandle<T> PoolScope<T>()
where T : class, new()
{
return PoolHandle<T>.Create(ObjectPoolAuto.Acquire<T>());
}
public static PoolListHandle<T> PoolListScope<T>()
{
return PoolListHandle<T>.Create(ObjectPoolAuto.AcquireList<T>());
}
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f22c2fa157c9e6045ad5307124c8a365
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,272 @@
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;
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(EmuTimer.TIME_ACT.Cpuint_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,8 @@
fileFormatVersion: 2
guid: ae3b5a67d5c131646a72ea967ddd303f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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

View File

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

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,543 @@
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 BRA()
{
sbyte displacement8 = (sbyte)op;
if (displacement8 != 0)
PC += displacement8;
else
PC += ReadOpWord(PC);
if (PPC == PC)
{
pendingCycles = 0;
}
pendingCycles -= 10;
}
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 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 RTS()
{
PC = ReadLong(A[7].s32);
A[7].s32 += 4;
pendingCycles -= 16;
}
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 RESET()
{
if (S)
{
pendingCycles -= 132;
}
else
{
TrapVector2(8);
}
}
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 NOP()
{
pendingCycles -= 4;
}
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];
}
}
}
}

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,150 @@
using System;
namespace cpu.m68000
{
partial class MC68000
{
unsafe 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];
fixed (int* EACyclesBW_mode = &EACyclesBW[mode,0])
{
pendingCycles -= 12 + EACyclesBW_mode[reg];
}
}
//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 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 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 ANDI_SR()
{
if (S == false)
throw new Exception("trap!");
SR &= ReadOpWord(PC); PC += 2;
pendingCycles -= 20;
}
void EORI_SR()
{
if (S == false)
throw new Exception("trap!");
SR ^= ReadOpWord(PC); PC += 2;
pendingCycles -= 20;
}
void ORI_SR()
{
if (S == false)
throw new Exception("trap!");
SR |= ReadOpWord(PC); PC += 2;
pendingCycles -= 20;
}
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 TRAP()
{
int vector = 32 + (op & 0x0F);
TrapVector(vector);
pendingCycles -= 4;
}
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,439 @@
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 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(EmuTimer.TIME_ACT.Cpuint_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]();
DoOpCode(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;
op = (ushort)ReadOpWord(PC); PC += 2;
//Opcodes[op]();
DoOpCode(op);
m68ki_check_interrupts();
int delta = prevCycles - pendingCycles;
totalExecutedCycles += (ulong)delta;
}
while (pendingCycles > 0);
pendingCycles -= 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,524 @@
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!");
}
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;
}
}
}

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,126 @@
namespace cpu.m68000
{
partial class MC68000
{
/// <summary>
/// 重写的68000指令调度
/// </summary>
/// <param name="op"></param>
void DoOpCode(ushort op)
{
MC68000Code opType = MC68000CodeArr[op];
switch (opType)
{
case MC68000Code.ORI: ORI(); return;
case MC68000Code.ILL: ILL(); return;
case MC68000Code.ORI_CCR: ORI_CCR(); return;
case MC68000Code.ORI_SR: ORI_SR(); return;
case MC68000Code.BTSTr: BTSTr(); return;
case MC68000Code.MOVEP: MOVEP(); return;
case MC68000Code.BCHGr: BCHGr(); return;
case MC68000Code.BCLRr: BCLRr(); return;
case MC68000Code.BSETr: BSETr(); return;
case MC68000Code.ANDI: ANDI(); return;
case MC68000Code.ANDI_CCR: ANDI_CCR(); return;
case MC68000Code.ANDI_SR: ANDI_SR(); return;
case MC68000Code.SUBI: SUBI(); return;
case MC68000Code.ADDI: ADDI(); return;
case MC68000Code.BTSTi: BTSTi(); return;
case MC68000Code.BCHGi: BCHGi(); return;
case MC68000Code.BCLRi: BCLRi(); return;
case MC68000Code.BSETi: BSETi(); return;
case MC68000Code.EORI: EORI(); return;
case MC68000Code.EORI_CCR: EORI_CCR(); return;
case MC68000Code.EORI_SR: EORI_SR(); return;
case MC68000Code.CMPI: CMPI(); return;
case MC68000Code.MOVE: MOVE(); return;
case MC68000Code.MOVEA: MOVEA(); return;
case MC68000Code.NEGX: NEGX(); return;
case MC68000Code.MOVEfSR: MOVEfSR(); return;
case MC68000Code.CHK: CHK(); return;
case MC68000Code.LEA: LEA(); return;
case MC68000Code.CLR: CLR(); return;
case MC68000Code.NEG: NEG(); return;
case MC68000Code.MOVECCR: MOVECCR(); return;
case MC68000Code.NOT: NOT(); return;
case MC68000Code.MOVEtSR: MOVEtSR(); return;
case MC68000Code.NBCD: NBCD(); return;
case MC68000Code.SWAP: SWAP(); return;
case MC68000Code.PEA: PEA(); return;
case MC68000Code.EXT: EXT(); return;
case MC68000Code.MOVEM0: MOVEM0(); return;
case MC68000Code.TST: TST(); return;
case MC68000Code.TAS: TAS(); return;
case MC68000Code.ILLEGAL: ILLEGAL(); return;
case MC68000Code.MOVEM1: MOVEM1(); return;
case MC68000Code.TRAP: TRAP(); return;
case MC68000Code.LINK: LINK(); return;
case MC68000Code.UNLK: UNLK(); return;
case MC68000Code.MOVEUSP: MOVEUSP(); return;
case MC68000Code.RESET: RESET(); return;
case MC68000Code.NOP: NOP(); return;
case MC68000Code.STOP: STOP(); return;
case MC68000Code.RTE: RTE(); return;
case MC68000Code.RTS: RTS(); return;
case MC68000Code.TRAPV: TRAPV(); return;
case MC68000Code.RTR: RTR(); return;
case MC68000Code.JSR: JSR(); return;
case MC68000Code.JMP: JMP(); return;
case MC68000Code.ADDQ: ADDQ(); return;
case MC68000Code.Scc: Scc(); return;
case MC68000Code.DBcc: DBcc(); return;
case MC68000Code.SUBQ: SUBQ(); return;
case MC68000Code.BRA: BRA(); return;
case MC68000Code.BSR: BSR(); return;
case MC68000Code.Bcc: Bcc(); return;
case MC68000Code.MOVEQ: MOVEQ(); return;
case MC68000Code.OR0: OR0(); return;
case MC68000Code.DIVU: DIVU(); return;
case MC68000Code.SBCD0: SBCD0(); return;
case MC68000Code.SBCD1: SBCD1(); return;
case MC68000Code.OR1: OR1(); return;
case MC68000Code.DIVS: DIVS(); return;
case MC68000Code.SUB0: SUB0(); return;
case MC68000Code.SUBA: SUBA(); return;
case MC68000Code.SUBX0: SUBX0(); return;
case MC68000Code.SUBX1: SUBX1(); return;
case MC68000Code.SUB1: SUB1(); return;
case MC68000Code.CMP: CMP(); return;
case MC68000Code.CMPA: CMPA(); return;
case MC68000Code.EOR: EOR(); return;
case MC68000Code.CMPM: CMPM(); return;
case MC68000Code.AND0: AND0(); return;
case MC68000Code.MULU: MULU(); return;
case MC68000Code.ABCD0: ABCD0(); return;
case MC68000Code.ABCD1: ABCD1(); return;
case MC68000Code.AND1: AND1(); return;
case MC68000Code.EXGdd: EXGdd(); return;
case MC68000Code.EXGaa: EXGaa(); return;
case MC68000Code.EXGda: EXGda(); return;
case MC68000Code.MULS: MULS(); return;
case MC68000Code.ADD0: ADD0(); return;
case MC68000Code.ADDA: ADDA(); return;
case MC68000Code.ADDX0: ADDX0(); return;
case MC68000Code.ADDX1: ADDX1(); return;
case MC68000Code.ADD1: ADD1(); return;
case MC68000Code.ASRd: ASRd(); return;
case MC68000Code.LSRd: LSRd(); return;
case MC68000Code.ROXRd: ROXRd(); return;
case MC68000Code.RORd: RORd(); return;
case MC68000Code.ASRd0: ASRd0(); return;
case MC68000Code.ASLd: ASLd(); return;
case MC68000Code.LSLd: LSLd(); return;
case MC68000Code.ROXLd: ROXLd(); return;
case MC68000Code.ROLd: ROLd(); return;
case MC68000Code.ASLd0: ASLd0(); return;
case MC68000Code.LSRd0: LSRd0(); return;
case MC68000Code.LSLd0: LSLd0(); return;
case MC68000Code.ROXRd0: ROXRd0(); return;
case MC68000Code.ROXLd0: ROXLd0(); return;
case MC68000Code.RORd0: RORd0(); return;
case MC68000Code.ROLd0: ROLd0(); return;
}
}
}
}

View File

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

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb52db132edb72746a600471b199d49b
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,910 @@
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(EmuTimer.TIME_ACT.Cpuint_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();
}
}
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,901 @@
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;
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(EmuTimer.TIME_ACT.Cpuint_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)
{
pendingCycles = 0;
}
else
{
do
{
int prevCycles = pendingCycles;
PPC = PC;
ireg = ReadOp(PC.LowWord);
PC.LowWord++;
insn[ireg]();
pendingCycles -= cycles_6809[ireg];
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();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 727532af9b9469442a63c74022c8905b
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: 2fd2fa6c87071aa4482ca5895aa105e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9712b77131e67e342acd3852569c6692
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: d3565408bc12d5c4eafb64846e799d0f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,170 @@
namespace cpu.nec
{
partial class Nec
{
static int EA;
static ushort EO;
static ushort E16;
int EA_000()
{
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + I.regs.b[12] + I.regs.b[13] * 0x100);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_001()
{
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + I.regs.b[14] + I.regs.b[15] * 0x100);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_002()
{
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + I.regs.b[12] + I.regs.b[13] * 0x100);
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_003()
{
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + I.regs.b[14] + I.regs.b[15] * 0x100);
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_004()
{
EO = (ushort)(I.regs.b[12] + I.regs.b[13] * 0x100);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_005()
{
EO = (ushort)(I.regs.b[14] + I.regs.b[15] * 0x100);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_006()
{
EO = FETCH();
EO += (ushort)(FETCH() << 8);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_007()
{
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_100()
{
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + I.regs.b[12] + I.regs.b[13] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_101()
{
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + I.regs.b[14] + I.regs.b[15] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_102()
{
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + I.regs.b[12] + I.regs.b[13] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_103()
{
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + I.regs.b[14] + I.regs.b[15] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_104()
{
EO = (ushort)(I.regs.b[12] + I.regs.b[13] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_105()
{
EO = (ushort)(I.regs.b[14] + I.regs.b[15] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_106()
{
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_107()
{
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + (sbyte)FETCH());
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_200()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + I.regs.b[12] + I.regs.b[13] * 0x100 + (short)E16);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_201()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + I.regs.b[14] + I.regs.b[15] * 0x100 + (short)E16);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_202()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + I.regs.b[12] + I.regs.b[13] * 0x100 + (short)E16);
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_203()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + I.regs.b[14] + I.regs.b[15] * 0x100 + (short)E16);
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_204()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[12] + I.regs.b[13] * 0x100 + (short)E16);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_205()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[14] + I.regs.b[15] * 0x100 + (short)E16);
EA = DefaultBase(3, I) + EO;
return EA;
}
int EA_206()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[10] + I.regs.b[11] * 0x100 + (short)E16);
EA = DefaultBase(2, I) + EO;
return EA;
}
int EA_207()
{
E16 = FETCH();
E16 += (ushort)(FETCH() << 8);
EO = (ushort)(I.regs.b[6] + I.regs.b[7] * 0x100 + (short)E16);
EA = DefaultBase(3, I) + EO;
return EA;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d5f27e4fff949a459570d38e744620f
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: 1dd5cd4e2bf67fa4b9221127b7fca5be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,138 @@
namespace cpu.nec
{
partial class Nec
{
ushort RegWord(int ModRM)
{
return (ushort)(I.regs.b[mod_RM.regw[ModRM] * 2] + I.regs.b[mod_RM.regw[ModRM] * 2 + 1] * 0x100);// I.regs.w[mod_RM.regw[ModRM]];
}
byte RegByte(int ModRM)
{
return I.regs.b[mod_RM.regb[ModRM]];
}
ushort GetRMWord(int ModRM)
{
return (ushort)(ModRM >= 0xc0 ? I.regs.b[mod_RM.RMw[ModRM] * 2] + I.regs.b[mod_RM.RMw[ModRM] * 2 + 1] * 0x100 : ReadWord(GetEA[ModRM]()));
}
void PutbackRMWord(int ModRM, ushort val)
{
if (ModRM >= 0xc0)
{
//I.regs.w[mod_RM.RMw[ModRM]] = val;
I.regs.b[mod_RM.RMw[ModRM] * 2] = (byte)(val % 0x100);
I.regs.b[mod_RM.RMw[ModRM] * 2 + 1] = (byte)(val / 0x100);
}
else
{
WriteWord(EA, val);
}
}
ushort GetnextRMWord()
{
return ReadWord((EA & 0xf0000) | ((EA + 2) & 0xffff));
}
void PutRMWord(int ModRM, ushort val)
{
if (ModRM >= 0xc0)
{
//I.regs.w[mod_RM.RMw[ModRM]] = val;
I.regs.b[mod_RM.RMw[ModRM] * 2] = (byte)(val % 0x100);
I.regs.b[mod_RM.RMw[ModRM] * 2 + 1] = (byte)(val / 0x100);
}
else
{
WriteWord(GetEA[ModRM](), val);
}
}
void PutImmRMWord(int ModRM)
{
ushort val;
if (ModRM >= 0xc0)
{
//I.regs.w[mod_RM.RMw[ModRM]] = FETCHWORD();
ushort w = FETCHWORD();
I.regs.b[mod_RM.RMw[ModRM] * 2] = (byte)(w % 0x100);
I.regs.b[mod_RM.RMw[ModRM] * 2 + 1] = (byte)(w / 0x100);
}
else
{
EA = GetEA[ModRM]();
val = FETCHWORD();
WriteWord(EA, val);
}
}
byte GetRMByte(int ModRM)
{
return ((ModRM) >= 0xc0 ? I.regs.b[mod_RM.RMb[ModRM]] : ReadByte(GetEA[ModRM]()));
}
void PutRMByte(int ModRM, byte val)
{
if (ModRM >= 0xc0)
{
I.regs.b[mod_RM.RMb[ModRM]] = val;
}
else
{
WriteByte(GetEA[ModRM](), val);
}
}
void PutImmRMByte(int ModRM)
{
if (ModRM >= 0xc0)
{
I.regs.b[mod_RM.RMb[ModRM]] = FETCH();
}
else
{
EA = GetEA[ModRM]();
WriteByte(EA, FETCH());
}
}
void PutbackRMByte(int ModRM, byte val)
{
if (ModRM >= 0xc0)
{
I.regs.b[mod_RM.RMb[ModRM]] = val;
}
else
{
WriteByte(EA, val);
}
}
void DEF_br8(out int ModRM, out byte src, out byte dst)
{
ModRM = FETCH();
src = RegByte(ModRM);
dst = GetRMByte(ModRM);
}
void DEF_wr16(out int ModRM, out ushort src, out ushort dst)
{
ModRM = FETCH();
src = RegWord(ModRM);
dst = GetRMWord(ModRM);
}
void DEF_r8b(out int ModRM, out byte src, out byte dst)
{
ModRM = FETCH();
dst = RegByte(ModRM);
src = GetRMByte(ModRM);
}
void DEF_r16w(out int ModRM, out ushort src, out ushort dst)
{
ModRM = FETCH();
dst = RegWord(ModRM);
src = GetRMWord(ModRM);
}
void DEF_ald8(out byte src, out byte dst)
{
src = FETCH();
dst = I.regs.b[0];
}
void DEF_axd16(out ushort src, out ushort dst)
{
src = FETCH();
dst = (ushort)(I.regs.b[0] + I.regs.b[1] * 0x100);// I.regs.w[0];
src += (ushort)(FETCH() << 8);
}
}
}

View File

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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 330693b766ebedc47a340cdcf561859d
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: 9c09602ef08e6484da16a66054f9fcbf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
using System;
namespace cpu.z80
{
public partial class Z80A
{
private bool iff1;
public bool IFF1 { get { return iff1; } set { iff1 = value; } }
private bool iff2;
public bool IFF2 { get { return iff2; } set { iff2 = value; } }
private bool interrupt;
public bool Interrupt { get { return interrupt; } set { interrupt = value; } }
private bool nonMaskableInterrupt;
public bool NonMaskableInterrupt
{
get { return nonMaskableInterrupt; }
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
}
private bool nonMaskableInterruptPending;
public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } }
private int interruptMode;
public int InterruptMode
{
get { return interruptMode; }
set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; }
}
private bool halted;
public bool Halted { get { return halted; } set { halted = value; } }
public Func<int> IRQCallback = delegate () { return 0; };
public Action NMICallback = delegate () { };
private void ResetInterrupts()
{
Interrupt = false;
NonMaskableInterrupt = false;
NonMaskableInterruptPending = false;
Interruptable = true;
IFF1 = IFF2 = false;
}
private void Halt()
{
RegPC.Word--;
Halted = true;
}
}
}

View File

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

View File

@ -0,0 +1,254 @@
using System;
using System.Runtime.InteropServices;
namespace cpu.z80
{
public partial class Z80A
{
[StructLayout(LayoutKind.Explicit)]
[Serializable()]
public struct RegisterPair
{
[FieldOffset(0)]
public ushort Word;
[FieldOffset(0)]
public byte Low;
[FieldOffset(1)]
public byte High;
public RegisterPair(ushort value)
{
Word = value;
Low = (byte)(Word);
High = (byte)(Word >> 8);
}
public static implicit operator ushort(RegisterPair rp)
{
return rp.Word;
}
public static implicit operator RegisterPair(ushort value)
{
return new RegisterPair(value);
}
}
public ushort PC
{
get
{
return RegPC.Word;
}
}
private bool RegFlagC
{
get { return (RegAF.Low & 0x01) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x01) | (value ? 0x01 : 0x00)); }
}
private bool RegFlagN
{
get { return (RegAF.Low & 0x02) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x02) | (value ? 0x02 : 0x00)); }
}
private bool RegFlagP
{
get { return (RegAF.Low & 0x04) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x04) | (value ? 0x04 : 0x00)); }
}
private bool RegFlag3
{
get { return (RegAF.Low & 0x08) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x08) | (value ? 0x08 : 0x00)); }
}
private bool RegFlagH
{
get { return (RegAF.Low & 0x10) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); }
}
private bool RegFlag5
{
get { return (RegAF.Low & 0x20) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); }
}
private bool RegFlagZ
{
get { return (RegAF.Low & 0x40) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); }
}
private bool RegFlagS
{
get { return (RegAF.Low & 0x80) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); }
}
private RegisterPair RegAF;
private RegisterPair RegBC;
private RegisterPair RegDE;
private RegisterPair RegHL;
private RegisterPair RegAltAF; // Shadow for A and F
private RegisterPair RegAltBC; // Shadow for B and C
private RegisterPair RegAltDE; // Shadow for D and E
private RegisterPair RegAltHL; // Shadow for H and L
private byte RegI; // I (interrupt vector)
private byte RegR; // R (memory refresh)
private byte RegR2;
private RegisterPair RegIX; // IX (index register x)
private RegisterPair RegIY; // IY (index register y)
private RegisterPair RegWZ; // WZ
private RegisterPair RegSP; // SP (stack pointer)
private RegisterPair RegPC; // PC (program counter)
private void ResetRegisters()
{
RegI = 0; RegR = 0; RegR2 = 0;
RegPC.Word = 0;
RegWZ.Word = 0;
}
public byte RegisterA
{
get { return RegAF.High; }
set { RegAF.High = value; }
}
public byte RegisterF
{
get { return RegAF.Low; }
set { RegAF.Low = value; }
}
public ushort RegisterAF
{
get { return RegAF.Word; }
set { RegAF.Word = value; }
}
public byte RegisterB
{
get { return RegBC.High; }
set { RegBC.High = value; }
}
public byte RegisterC
{
get { return RegBC.Low; }
set { RegBC.Low = value; }
}
public ushort RegisterBC
{
get { return RegBC.Word; }
set { RegBC.Word = value; }
}
public byte RegisterD
{
get { return RegDE.High; }
set { RegDE.High = value; }
}
public byte RegisterE
{
get { return RegDE.Low; }
set { RegDE.Low = value; }
}
public ushort RegisterDE
{
get { return RegDE.Word; }
set { RegDE.Word = value; }
}
public byte RegisterH
{
get { return RegHL.High; }
set { RegHL.High = value; }
}
public byte RegisterL
{
get { return RegHL.Low; }
set { RegHL.Low = value; }
}
public ushort RegisterHL
{
get { return RegHL.Word; }
set { RegHL.Word = value; }
}
public ushort RegisterPC
{
get { return RegPC.Word; }
set { RegPC.Word = value; }
}
public ushort RegisterSP
{
get { return RegSP.Word; }
set { RegSP.Word = value; }
}
public ushort RegisterIX
{
get { return RegIX.Word; }
set { RegIX.Word = value; }
}
public ushort RegisterIY
{
get { return RegIY.Word; }
set { RegIY.Word = value; }
}
public ushort RegisterWZ
{
get { return RegWZ.Word; }
set { RegWZ.Word = value; }
}
public byte RegisterI
{
get { return RegI; }
set { RegI = value; }
}
public byte RegisterR
{
get { return RegR; }
set { RegR = value; }
}
public byte RegisterR2
{
get { return RegR2; }
set { RegR2 = value; }
}
public ushort RegisterShadowAF
{
get { return RegAltAF.Word; }
set { RegAltAF.Word = value; }
}
public ushort RegisterShadowBC
{
get { return RegAltBC.Word; }
set { RegAltBC.Word = value; }
}
public ushort RegisterShadowDE
{
get { return RegAltDE.Word; }
set { RegAltDE.Word = value; }
}
public ushort RegisterShadowHL
{
get { return RegAltHL.Word; }
set { RegAltHL.Word = value; }
}
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More