forked from sin365/AxibugEmuOnline
使用MAME新的motionkey定义,debug,更新协议
This commit is contained in:
parent
912468b674
commit
21468a6397
8
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/Log.meta
Normal file
8
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/Log.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19fb05683c89f9d438ce6cb7e65de2ec
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 152466b6f17e41244be3f9dd18aee4e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 271a8a6401146c04ab5fb754032a2dd5
|
@ -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 }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22cdf3c2148e1a24ca9353926f553d77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
75
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/MAMEEmu.cs
Normal file
75
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/MAMEEmu.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35d7d011a9c354848a421281c06f5f8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Mame.Core",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cfb12a06e639a448b797cd60959004e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebd8f2e90f8767b498f2431f7394ede9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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 宽高
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eacdf053bdef1934d8cdec1c463f8847
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
namespace MAME.Core
|
||||
{
|
||||
public partial class CpsMotion
|
||||
{
|
||||
public CpsMotion()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08bc0c1fe9979244e872263dfe2c09b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
namespace MAME.Core
|
||||
{
|
||||
public class Konami68000Motion
|
||||
{
|
||||
public Konami68000Motion()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85d3575e43093a54f82622b4c53c1a40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
using cpu.m68000;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public class M68000Motion
|
||||
{
|
||||
public M68000Motion()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43abb82203533b94fa07632370f6ca15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
using cpu.m6809;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
|
||||
public partial class M6809Motion
|
||||
{
|
||||
public M6809Motion()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c291a8abf15d254596af257bb937441
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public partial class NeogeoMotion
|
||||
{
|
||||
public NeogeoMotion()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1dce3116faca2f43a19f5e965e245e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,14 @@
|
||||
using cpu.z80;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MAME.Core
|
||||
{
|
||||
public partial class Z80Motion
|
||||
{
|
||||
|
||||
public Z80Motion()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cb936512a0186e449fa3a9053127b42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f22c2fa157c9e6045ad5307124c8a365
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0f2056e5d40c9e4b87a70bb42c0665d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87f805602538c22479c796f78f64b052
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\netstandard2.0\publish\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e66dd647cf36e64eba535a9422b5dfd
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2024-08-30T07:41:53.2597006Z||;True|2024-08-29T17:00:35.4694695+08:00||;True|2024-08-29T16:40:23.7314446+08:00||;True|2024-08-29T16:17:16.6219882+08:00||;False|2024-08-29T15:55:34.5778980+08:00||;True|2024-08-29T15:34:15.1410739+08:00||;False|2024-08-29T15:31:15.0815441+08:00||;False|2024-08-29T15:29:46.6749330+08:00||;False|2024-08-29T15:27:48.9116490+08:00||;False|2024-08-29T15:27:23.2208875+08:00||;True|2024-08-28T16:12:23.3416224+08:00||;True|2024-08-28T13:18:21.7983285+08:00||;True|2024-08-28T12:54:14.9742502+08:00||;True|2024-08-28T12:09:37.5280942+08:00||;True|2024-08-28T12:07:03.6717540+08:00||;True|2024-08-07T18:02:59.4096796+08:00||;False|2024-08-07T18:02:44.0239078+08:00||;True|2024-07-31T17:00:23.0585720+08:00||;True|2024-07-31T17:00:19.8123170+08:00||;True|2024-07-30T20:51:40.9773933+08:00||;True|2024-07-30T17:04:12.3440051+08:00||;True|2024-07-30T17:01:28.0849009+08:00||;True|2024-07-30T10:36:57.5301145+08:00||;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5cd247a5a04ff44bbdce6ed08ab6ccb
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69d9e952f0a1b3349b7127b9f01238f3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13fc2a860c40ef54b917a94ebf44f187
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu.meta
Normal file
8
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5256a2747754bc84095436214447d27b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efa49c62f62f6f048a465cb5e940eeae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f888c964f0338f48a49e0eaedeb54ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e27c96a34afca8c4f991cc6209a8895e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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); }
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb223c61fecbecc4fb762d9ebe649194
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df989ce237c20a84aa97ead349d2093e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 317be4f8630ce90409e488310814c936
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1386
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800.cs
Normal file
1386
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b048d365a2726014e8b35b00934ba716
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1889
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800op.cs
Normal file
1889
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800op.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ac480a98cd915a488d75cf520ceeb12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5363a2171a5a06e458069790876245da
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae3b5a67d5c131646a72ea967ddd303f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d595cf6577109d144b95da9cb77cfdd9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b9a46ea2abd2a04b88ef2ad2aa34650
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f00bdfe992953ee40bfa6536dcda1148
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2095e1daba88c5b4b935aaa55d3ed2e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8ae0dd765643d44da568a00571a176e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cde299f017f5c6c4d83cb4a8e4cfe543
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ca60a438b9bb004189843e1d4dad73c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb52db132edb72746a600471b199d49b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd115883ec0396d42abef36787464a37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cec51d80caf2184681dc0898d9dec38
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84fc920b98828f14c8f326b4f1520eb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1896
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6805/M6805op.cs
Normal file
1896
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6805/M6805op.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0c310d005b3a9f4d8861c58a32603b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24967d13608942c4289d335114c41269
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 727532af9b9469442a63c74022c8905b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
2394
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6809/M6809op.cs
Normal file
2394
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6809/M6809op.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fd2fa6c87071aa4482ca5895aa105e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9712b77131e67e342acd3852569c6692
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1334
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/Nec.cs
Normal file
1334
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/Nec.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3565408bc12d5c4eafb64846e799d0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
170
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/NecEa.cs
Normal file
170
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/NecEa.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d5f27e4fff949a459570d38e744620f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
2472
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/NecInstr.cs
Normal file
2472
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/NecInstr.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dd5cd4e2bf67fa4b9221127b7fca5be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20de18d94833a3f43bbeceac70edcc66
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 330693b766ebedc47a340cdcf561859d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
11707
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/z80/Execute.cs
Normal file
11707
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/z80/Execute.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c09602ef08e6484da16a66054f9fcbf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c96c195554ad5940b560fc6284134f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user