From 200ee3830bc7434ac1b7d9b5524e76d4de1e0e48 Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Tue, 11 Nov 2025 17:55:44 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=B8=80=E4=BA=9B=E5=86=85?= =?UTF-8?q?=E8=81=94=E4=BC=98=E5=8C=96=EF=BC=8C=E8=BF=98=E6=9C=89timer?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E6=B1=A0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Plugins/Mame.Core/cpu/m6800/M6800.cs | 8 +- .../Plugins/Mame.Core/cpu/m6805/M6805.cs | 2 +- .../Plugins/Mame.Core/cpu/m6809/M6809.cs | 2 +- .../Assets/Plugins/Mame.Core/cpu/nec/Nec.cs | 4 +- .../Assets/Plugins/Mame.Core/emu/Crosshair.cs | 2 +- .../Assets/Plugins/Mame.Core/emu/EmuTimer.cs | 404 ++++++++++++++---- .../Mame.Core/mame/konami68000/Konamiic.cs | 38 +- .../Assets/Plugins/Mame.Core/mame/m72/M72.cs | 4 +- .../Plugins/Mame.Core/mame/m92/Drawgfx.cs | 149 ++++--- .../Plugins/Mame.Core/mame/namcos1/Video.cs | 10 +- .../Plugins/Mame.Core/mame/neogeo/Memory.cs | 136 ++++-- .../Plugins/Mame.Core/mame/neogeo/Neoprot.cs | 56 +-- .../Plugins/Mame.Core/mame/pgm/Machine.cs | 2 +- .../Plugins/Mame.Core/mame/taito/Bublbobl.cs | 6 +- .../Plugins/Mame.Core/mame/taito/Opwolf.cs | 49 ++- .../Assets/Plugins/Mame.Core/sound/AY8910.cs | 179 +++++++- .../Assets/Plugins/Mame.Core/sound/YM2413.cs | 2 +- 17 files changed, 801 insertions(+), 252 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800.cs index dbd25d5b..1edca5ea 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6800/M6800.cs @@ -32,7 +32,7 @@ namespace cpu.m6800 private ushort M6803_DDR1 = 0x00, M6803_DDR2 = 0x01, M6803_DDR3 = 0x04, M6803_DDR4 = 0x05, M6803_PORT1 = 0x100, M6803_PORT2 = 0x101, M6803_PORT3 = 0x102, M6803_PORT4 = 0x103; private byte M6800_RMCR_SS_MASK = 0x03, M6800_RMCR_SS_4096 = 0x03, M6800_RMCR_SS_1024 = 0x02, M6800_RMCR_SS_128 = 0x01, M6800_RMCR_SS_16 = 0x00, M6800_RMCR_CC_MASK = 0x0c; private byte M6800_TRCSR_RDRF = 0x80, M6800_TRCSR_ORFE = 0x40, M6800_TRCSR_TDRE = 0x20, M6800_TRCSR_RIE = 0x10, M6800_TRCSR_RE = 0x08, M6800_TRCSR_TIE = 0x04, M6800_TRCSR_TE = 0x02, M6800_TRCSR_WU = 0x01, M6800_PORT2_IO4 = 0x10, M6800_PORT2_IO3 = 0x08; - private int[] M6800_RMCR_SS = new int[] { 16, 128, 1024, 4096 }; + private static int[] M6800_RMCR_SS = new int[] { 16, 128, 1024, 4096 }; public enum M6800_TX_STATE { INIT = 0, @@ -64,7 +64,7 @@ namespace cpu.m6800 } } public uint timer_next; - public byte[] flags8i = new byte[256] /* increment */ + public readonly static byte[] flags8i = new byte[256] /* increment */ { 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, @@ -83,7 +83,7 @@ namespace cpu.m6800 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,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[] flags8d = new byte[256] /* decrement */ + private readonly static byte[] flags8d = new byte[256] /* decrement */ { 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, @@ -102,7 +102,7 @@ namespace cpu.m6800 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,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_6800 = new byte[] + private readonly static byte[] cycles_6800 = new byte[] { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /*0*/ 99, 2,99,99,99,99, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6805/M6805.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6805/M6805.cs index 58e1409e..6333a9b2 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6805/M6805.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6805/M6805.cs @@ -56,7 +56,7 @@ namespace cpu.m6805 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,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[] + public readonly static 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, diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6809/M6809.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6809/M6809.cs index 6cf16147..8e0a7103 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6809/M6809.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m6809/M6809.cs @@ -85,7 +85,7 @@ namespace cpu.m6809 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,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[] + private readonly static 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, diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/Nec.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/Nec.cs index e32950ed..1721176d 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/Nec.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/nec/Nec.cs @@ -449,7 +449,7 @@ namespace cpu.nec I.regs.b[Reg * 2 + 1] = (byte)((ushort)tmp1 / 0x100); } - static byte[] JMP_table = new byte[] { 3, 10, 10 }; + readonly static byte[] JMP_table = new byte[] { 3, 10, 10 }; //public void JMP(bool flag) //{ // int tmp = (int)((sbyte)FETCH()); @@ -732,7 +732,7 @@ namespace cpu.nec I.regs.b[5] = (byte)((ushort)result2 / 0x100); } } - static byte[] ADD4S_table = new byte[] { 18, 19, 19 }; + readonly static byte[] ADD4S_table = new byte[] { 18, 19, 19 }; public void ADD4S(ref int tmp, ref int tmp2) { int i, v1, v2, result; diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/Crosshair.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/Crosshair.cs index 98712800..5b08e0cf 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/Crosshair.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/Crosshair.cs @@ -15,7 +15,7 @@ public byte animation_counter; } public static crosshair_global global; - public static byte[] crosshair_raw_top = new byte[] + public readonly static byte[] crosshair_raw_top = new byte[] { 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, 0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/EmuTimer.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/EmuTimer.cs index 9fcb9402..b30758c6 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/EmuTimer.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/EmuTimer.cs @@ -1,10 +1,6 @@ using cpu.m6800; using System; -using System.Collections.Concurrent; using System.Collections.Generic; -using System.Runtime.ConstrainedExecution; -using System.Threading; -using System.Timers; using static MAME.Core.EmuTimer; namespace MAME.Core @@ -68,7 +64,6 @@ namespace MAME.Core { emu_timer.RemoveToList(ref timerlist, ref timer); } - public void Insert(int index, emu_timer timer) { emu_timer.InsertToList(ref timerlist, index, ref timer); @@ -78,6 +73,11 @@ namespace MAME.Core { return timerlist.IndexOf(timer); } + + public void RemoveAt(int index) + { + emu_timer.RemoveAtToList(ref timerlist, index); + } } public class EmuTimer @@ -117,6 +117,11 @@ namespace MAME.Core public Atime start; public Atime expire; + // 引用计数字段 + private int _refCount; + // 是否在检查池中 + private bool _inReadyQueue; + internal void reset() { action = default; @@ -126,27 +131,25 @@ namespace MAME.Core start = default; expire = default; _refCount = 0; + _inReadyQueue = false; } static Queue _readyToRelease = new Queue(); - /// - /// 线程安全队列(因为析构函数是额外线程来的) - /// - static Queue _failedDeletions = new Queue(); - static HashSet _tempCheck = new HashSet(); + static Queue _timerPool = new Queue(); static int outTimerAllCount = 0; static int newTimerCount = 0; public static emu_timer GetEmu_timerNoRef() { emu_timer obj; - if (!_failedDeletions.TryDequeue(out obj)) - { + if (!_timerPool.TryDequeue(out obj)) + { obj = new emu_timer(); newTimerCount++; } //这里引用计数为0,直接放入带Ready里,等待下一帧检测 obj.reset(); + obj._inReadyQueue = true; _readyToRelease.Enqueue(obj); outTimerAllCount++; return obj; @@ -157,47 +160,31 @@ namespace MAME.Core if (_readyToRelease.Count < 1) return; int checkcount = _readyToRelease.Count; - int beforpoolcount = _failedDeletions.Count; + int beforpoolcount = _timerPool.Count; int releaseCount = 0; - while(_readyToRelease.TryDequeue(out emu_timer ready)) + while (_readyToRelease.TryDequeue(out emu_timer ready)) { - if (_tempCheck.Contains(ready)) - continue; - _tempCheck.Add(ready); + ready._inReadyQueue = false; if (ready._refCount <= 0) { ready.ReturnToPool(); releaseCount++; } } - //UnityEngine.Debug.Log($"CheckReadyRelaseAfterRun 检查数量{checkcount}| 出池数量{outTimerAllCount},其中new创建的数量{newTimerCount} 回收数量{releaseCount} ,处理前池数量{beforpoolcount},处理后池数量{_failedDeletions.Count}"); + //UnityEngine.Debug.Log($"CheckReadyRelaseAfterRun 检查数量{checkcount}| 出池数量{outTimerAllCount},其中new创建的数量{newTimerCount} 回收数量{releaseCount} ,处理前池数量{beforpoolcount},处理后池数量{_timerPool.Count}"); outTimerAllCount = 0; newTimerCount = 0; - _readyToRelease.Clear(); - _tempCheck.Clear(); + //_readyToRelease.Clear(); } - // 引用计数字段(线程安全) - private int _refCount = 1; // 初始为1,表示创建时的引用 /// /// 增加引用计数 /// void AddRef() { - int newCount = Interlocked.Increment(ref _refCount); - - ////引用计数重新回到1时,移除。 - ////但是还是不在这里做把注释了,在每一帧开始之前统一检测 - //if (newCount == 1) - //{ - // UnityEngine.Debug.Log("CheckReadyRelaseAfterRun AddRef 复活"); - // //if (_readyToRelease.Contains(this)) - // //{ - // // //UnityEngine.Debug.Log("移除ReadyToRelease"); - // // _readyToRelease.Remove(this); - // //} - //} + //int newCount = Interlocked.Increment(ref _refCount); + _refCount++; } /// @@ -205,14 +192,14 @@ namespace MAME.Core /// void ReleaseRef() { - int newCount = Interlocked.Decrement(ref _refCount); - if (newCount == 0) + //int newCount = Interlocked.Decrement(ref _refCount); + _refCount--; + if (_refCount == 0) { - //UnityEngine.Debug.Log("CheckReadyRelaseAfterRun ReleaseRef 预回收"); // 引用计数为0,释放资源并回池 ReadyToRelease(); } - else if (newCount < 0) + else if (_refCount < 0) { // 引用计数异常,不应出现负数 throw new InvalidOperationException("引用计数出现负数"); @@ -221,7 +208,9 @@ namespace MAME.Core void ReadyToRelease() { + if (this._inReadyQueue) return; //UnityEngine.Debug.Log("ReadyToRelease"); + this._inReadyQueue = true; _readyToRelease.Enqueue(this); } @@ -230,7 +219,7 @@ namespace MAME.Core /// void ReturnToPool() { - _failedDeletions.Enqueue(this); + _timerPool.Enqueue(this); } #region 外部操作 间接影响引用计数 @@ -245,7 +234,6 @@ namespace MAME.Core } if (refattr != null) refattr.ReleaseRef(); - refattr = emu_timer; refattr.AddRef(); } @@ -278,6 +266,11 @@ namespace MAME.Core list[i].ReleaseRef(); list.Clear(); } + + internal static void RemoveAtToList(ref List list, int index) + { + list.RemoveAt(index); + } #endregion /* static void EnqueueObj(emu_timer obj) @@ -760,77 +753,340 @@ namespace MAME.Core } } + //static void timer_list_remove_and_insert(emu_timer timer) + //{ + // // 包一层引用避免引用计数中间丢失 + // { + // emu_timer tempref = null; + // emu_timer.SetRefUsed(ref tempref, ref timer); + + // // 内联移除逻辑 + // bool isSpecialAction = (timer.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || + // timer.action == TIME_ACT.setvector); + + // if (isSpecialAction) + // { + // // 优化:批量移除相同action和过期时间的定时器 + // for (int i = lt.Count - 1; i >= 0; i--) + // { + // emu_timer et = lt[i]; + // if (et.action == timer.action && + // Attotime.attotime_compare(et.expire, timer.expire) == 0) + // { + // lt.RemoveAt(i); // 直接从后往前移除,避免数组拷贝 + // } + // } + // } + // else + // { + // // 优化:只移除第一个匹配的定时器 + // int tempcount = lt.Count; + // for (int i = 0; i < tempcount; i++) + // { + // if (lt[i].action == timer.action) + // { + // lt.RemoveAt(i); + // break; // 找到第一个就退出 + // } + // } + // } + + // // 内联插入逻辑 + // int insertIndex = lt.Count; // 默认插入到最后 + + // // 优化:只有当定时器启用时才按时间排序插入 + // if (timer.enabled) + // { + // Atime expire = timer.expire; + + + // int tempcount = lt.Count; + // // 查找插入位置 + // for (int i = 0; i < tempcount; i++) + // { + // if (Attotime.attotime_compare(lt[i].expire, expire) > 0) + // { + // insertIndex = i; + // break; + // } + // } + // } + + // // 在找到的位置插入 + // if (insertIndex < lt.Count) + // { + // lt.Insert(insertIndex, timer); + // } + // else + // { + // lt.Add(timer); // 添加到末尾,比Insert性能更好[8](@ref) + // } + + // emu_timer.SetNull(ref tempref); + // } + //} + + //static void timer_list_remove_and_insert(emu_timer timer) + //{ + // { + // emu_timer tempref = null; + // emu_timer.SetRefUsed(ref tempref, ref timer); + + // List ltsrc = lt.GetSrcList(); + // // inline remove + // if (timer.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer.action == TIME_ACT.setvector) + // { + // int low = 0; + // int high = ltsrc.Count - 1; + // int start = -1; + // while (low <= high) + // { + // int mid = low + (high - low) / 2; + // int cmp = Attotime.attotime_compare(ltsrc[mid].expire, timer.expire); + // if (cmp < 0) + // low = mid + 1; + // else if (cmp > 0) + // high = mid - 1; + // else + // { + // start = mid; + // high = mid - 1; + // } + // } + // if (start == -1) start = low; + // int end = start; + // int tempcount = ltsrc.Count; + // while (end < tempcount && Attotime.attotime_compare(ltsrc[end].expire, timer.expire) == 0) + // end++; + // for (int j = end - 1; j >= start; j--) + // { + // if (ltsrc[j].action == timer.action) + // lt.RemoveAt(j); + // } + // } + // else + // { + // int tempcount = lt.Count; + // for (int j = 0; j < tempcount; j++) + // { + // if (lt[j].action == timer.action) + // { + // lt.RemoveAt(j); + // break; + // } + // } + // } + + // // inline insert + // int i1 = -1; + // if (timer.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer.action == TIME_ACT.setvector) + // { + // int tempcount = ltsrc.Count; + // for (int j = 0; j < tempcount; j++) + // { + // emu_timer temptimer = ltsrc[j]; + // if (temptimer.action == timer.action && Attotime.attotime_compare(temptimer.expire, global_basetime) <= 0) + // { + // i1 = j; + // break; + // } + // } + // } + // if (i1 == -1) + // { + // int low = 0; + // int high = ltsrc.Count - 1; + // int pos = ltsrc.Count; + // while (low <= high) + // { + // int mid = low + (high - low) / 2; + // if (Attotime.attotime_compare(ltsrc[mid].expire, timer.expire) > 0) + // { + // pos = mid; + // high = mid - 1; + // } + // else + // { + // low = mid + 1; + // } + // } + // lt.Insert(pos, timer); + // } + + // emu_timer.SetNull(ref tempref); + // } + //} + + //static void timer_list_insert(emu_timer timer1) + //{ + // int i; + // int i1 = -1; + // if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector) + // { + // //foreach (emu_timer et in lt) + // foreach (emu_timer et in lt.GetSrcList()) + // { + // if (et.action == timer1.action && Attotime.attotime_compare(et.expire, global_basetime) <= 0) + // { + // i1 = lt.IndexOf(et); + // break; + // } + // } + // } + // if (i1 == -1) + // { + // Atime expire = timer1.enabled ? timer1.expire : Attotime.ATTOTIME_NEVER; + // for (i = 0; i < lt.Count; i++) + // { + // if (Attotime.attotime_compare(lt[i].expire, expire) > 0) + // { + // break; + // } + // } + // lt.Insert(i, timer1); + // } + //} + + //手动优化 static void timer_list_insert(emu_timer timer1) { - int i; + TIME_ACT currAct = timer1.action; int i1 = -1; - if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector) + var tlist = lt.GetSrcList(); + int scanCount; + int tempMaxIdx = tlist.Count - 1; + if (currAct == TIME_ACT.Cpuint_cpunum_empty_event_queue || currAct == TIME_ACT.setvector) { //foreach (emu_timer et in lt) - foreach (emu_timer et in lt.GetSrcList()) + //foreach (emu_timer et in lt.GetSrcList()) + //{ + // if (et.action == currAct && Attotime.attotime_compare(et.expire, global_basetime) <= 0) + // { + // i1 = lt.IndexOf(et); + // break; + // } + //} + scanCount = 0; + while (scanCount >= tempMaxIdx) { - if (et.action == timer1.action && Attotime.attotime_compare(et.expire, global_basetime) <= 0) + emu_timer et = tlist[scanCount]; + if (et.action == currAct && Attotime.attotime_compare(et.expire, global_basetime) <= 0) { - i1 = lt.IndexOf(et); + i1 = scanCount; break; } + scanCount++; } } if (i1 == -1) { Atime expire = timer1.enabled ? timer1.expire : Attotime.ATTOTIME_NEVER; - for (i = 0; i < lt.Count; i++) + scanCount = 0; + while (scanCount <= tempMaxIdx) { - if (Attotime.attotime_compare(lt[i].expire, expire) > 0) - { - break; - } + emu_timer et = tlist[scanCount]; + if (Attotime.attotime_compare(et.expire, expire) > 0) + break; + scanCount++; } - lt.Insert(i, timer1); + lt.Insert(scanCount, timer1); } } static List timer_list_remove_lt1 = new List(); + //public static void timer_list_remove(emu_timer timer1) + //{ + // if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector) + // { + // timer_list_remove_lt1.Clear(); + // //foreach (emu_timer et in lt) + // foreach (emu_timer et in lt.GetSrcList()) + // { + // if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) == 0) + // { + // timer_list_remove_lt1.Add(et); + // //lt.Remove(et); + // //break; + // } + // else if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) < 0) + // { + // int i1 = 1; + // } + // else if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) > 0) + // { + // int i1 = 1; + // } + // } + // foreach (emu_timer et1 in timer_list_remove_lt1) + // { + // lt.Remove(et1); + // } + // } + // else + // { + // //TODO MAME.NET原来这么foreach写删除是有问题的 + + // //foreach (emu_timer et in lt) + // foreach (emu_timer et in lt.GetSrcList()) + // { + // if (et.action == timer1.action) + // { + // lt.Remove(et); + // break; + // } + // } + // } + //} + + //修改优化 public static void timer_list_remove(emu_timer timer1) { if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector) { - timer_list_remove_lt1.Clear(); - //foreach (emu_timer et in lt) - foreach (emu_timer et in lt.GetSrcList()) + //timer_list_remove_lt1.Clear(); + //foreach (emu_timer et in lt.GetSrcList()) + //{ + // if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) == 0) + // timer_list_remove_lt1.Add(et); + //} + //foreach (emu_timer et1 in timer_list_remove_lt1) + // lt.Remove(et1); + + var tlist = lt.GetSrcList(); + int tempMaxIdx = tlist.Count - 1; + while (tempMaxIdx >= 0) { + emu_timer et = tlist[tempMaxIdx]; if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) == 0) - { - timer_list_remove_lt1.Add(et); - //lt.Remove(et); - //break; - } - else if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) < 0) - { - int i1 = 1; - } - else if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) > 0) - { - int i1 = 1; - } - } - foreach (emu_timer et1 in timer_list_remove_lt1) - { - lt.Remove(et1); + lt.Remove(et); + tempMaxIdx--; } } else { //TODO MAME.NET原来这么foreach写删除是有问题的 - //foreach (emu_timer et in lt) - foreach (emu_timer et in lt.GetSrcList()) + //foreach (emu_timer et in lt.GetSrcList()) + //{ + // if (et.action == timer1.action) + // { + // lt.Remove(et); + // break; + // } + //} + + var tlist = lt.GetSrcList(); + int tempMaxIdx = tlist.Count - 1; + int scanCount = 0; + while (scanCount <= tempMaxIdx) { + emu_timer et = tlist[scanCount]; if (et.action == timer1.action) { lt.Remove(et); break; } + scanCount++; } } } diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/konami68000/Konamiic.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/konami68000/Konamiic.cs index c2de2ddf..29f23a94 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/konami68000/Konamiic.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/konami68000/Konamiic.cs @@ -544,18 +544,18 @@ } } + readonly static int[] K051960_sprites_draw_xoffset = new int[] { 0, 1, 4, 5, 16, 17, 20, 21 }; + readonly static int[] K051960_sprites_draw_yoffset = new int[] { 0, 2, 8, 10, 32, 34, 40, 42 }; + readonly static int[] K051960_sprites_draw_width = new int[] { 1, 2, 1, 2, 4, 2, 4, 8 }; + readonly static int[] K051960_sprites_draw_height = new int[] { 1, 1, 2, 2, 2, 4, 4, 8 }; + static int[] K051960_sprites_draw_sortedlist = new int[128]; public static void K051960_sprites_draw(RECT cliprect, int min_priority, int max_priority) { int ox, oy, code, color, pri, shadow, size, w, h, x, y, flipx, flipy, zoomx, zoomy, code2, color2, pri2; int offs, pri_code; - int[] sortedlist = new int[128]; - int[] xoffset = new int[] { 0, 1, 4, 5, 16, 17, 20, 21 }; - int[] yoffset = new int[] { 0, 2, 8, 10, 32, 34, 40, 42 }; - int[] width = new int[] { 1, 2, 1, 2, 4, 2, 4, 8 }; - int[] height = new int[] { 1, 1, 2, 2, 2, 4, 4, 8 }; for (offs = 0; offs < 128; offs++) { - sortedlist[offs] = -1; + K051960_sprites_draw_sortedlist[offs] = -1; } for (offs = 0; offs < 0x400; offs += 8) { @@ -563,17 +563,17 @@ { if (max_priority == -1) { - sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs; + K051960_sprites_draw_sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs; } else { - sortedlist[K051960_ram[offs] & 0x7f] = offs; + K051960_sprites_draw_sortedlist[K051960_ram[offs] & 0x7f] = offs; } } } for (pri_code = 0; pri_code < 128; pri_code++) { - offs = sortedlist[pri_code]; + offs = K051960_sprites_draw_sortedlist[pri_code]; if (offs == -1) { continue; @@ -594,8 +594,8 @@ } } size = (K051960_ram[offs + 1] & 0xe0) >> 5; - w = width[size]; - h = height[size]; + w = K051960_sprites_draw_width[size]; + h = K051960_sprites_draw_height[size]; if (w >= 2) code &= ~0x01; if (h >= 2) code &= ~0x02; if (w >= 4) code &= ~0x04; @@ -631,19 +631,19 @@ sx = ox + 16 * x; if (flipx != 0) { - c += xoffset[(w - 1 - x)]; + c += K051960_sprites_draw_xoffset[(w - 1 - x)]; } else { - c += xoffset[x]; + c += K051960_sprites_draw_xoffset[x]; } if (flipy != 0) { - c += yoffset[(h - 1 - y)]; + c += K051960_sprites_draw_yoffset[(h - 1 - y)]; } else { - c += yoffset[y]; + c += K051960_sprites_draw_yoffset[y]; } if (max_priority == -1) { @@ -682,16 +682,16 @@ zw = (ox + ((zoomx * (x + 1) + (1 << 11)) >> 12)) - sx; if (flipx != 0) { - c += xoffset[(w - 1 - x)]; + c += K051960_sprites_draw_xoffset[(w - 1 - x)]; } - else c += xoffset[x]; + else c += K051960_sprites_draw_xoffset[x]; if (flipy != 0) { - c += yoffset[(h - 1 - y)]; + c += K051960_sprites_draw_yoffset[(h - 1 - y)]; } else { - c += yoffset[y]; + c += K051960_sprites_draw_yoffset[y]; } if (max_priority == -1) { diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m72/M72.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m72/M72.cs index 239c88c5..832ace29 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m72/M72.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m72/M72.cs @@ -153,7 +153,7 @@ namespace MAME.Core #endregion - public static byte[] airduelm72_code = new byte[] { + public readonly static byte[] airduelm72_code = new byte[] { 0x68, 0x00, 0xd0, 0x1f, 0xc6, 0x06, 0xc0, 0x1c, 0x57, 0xea, 0x69, 0x0b, 0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -161,7 +161,7 @@ namespace MAME.Core 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - public static byte[] gunforce_decryption_table = new byte[256] { + public readonly static byte[] gunforce_decryption_table = new byte[256] { 0xff,0x90,0x90,0x2c,0x90,0x90,0x43,0x88, 0x90,0x13,0x0a,0xbd,0xba,0x60,0xea,0x90, /* 00 */ 0x90,0x90,0xf2,0x29,0xb3,0x22,0x90,0x0c, 0xa9,0x5f,0x9d,0x07,0x90,0x90,0x0b,0xbb, /* 10 */ 0x8a,0x90,0x90,0x90,0x3a,0x3c,0x5a,0x38, 0x99,0x90,0xf8,0x89,0x90,0x91,0x90,0x55, /* 20 */ diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m92/Drawgfx.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m92/Drawgfx.cs index 11c443ca..9d308db9 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m92/Drawgfx.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/m92/Drawgfx.cs @@ -1,66 +1,107 @@ -namespace MAME.Core +using System.Runtime.CompilerServices; + +namespace MAME.Core { public unsafe partial class Drawgfx { - public static void common_drawgfx_m92(byte* bb1, int code, int color, int flipx, int flipy, int sx, int sy, RECT clip, uint primask) + //public static void common_drawgfx_m92(byte* bb1, int code, int color, int flipx, int flipy, int sx, int sy, RECT clip, uint primask) + //{ + // int ox; + // int oy; + // int ex; + // int ey; + // ox = sx; + // oy = sy; + // ex = sx + 0x10 - 1; + // if (sx < 0) + // { + // sx = 0; + // } + // if (sx < clip.min_x) + // { + // sx = clip.min_x; + // } + // if (ex >= 0x200) + // { + // ex = 0x200 - 1; + // } + // if (ex > clip.max_x) + // { + // ex = clip.max_x; + // } + // if (sx > ex) + // { + // return; + // } + // ey = sy + 0x10 - 1; + // if (sy < 0) + // { + // sy = 0; + // } + // if (sy < clip.min_y) + // { + // sy = clip.min_y; + // } + // if (ey >= 0x100) + // { + // ey = 0x100 - 1; + // } + // if (ey > clip.max_y) + // { + // ey = clip.max_y; + // } + // if (sy > ey) + // { + // return; + // } + // int sw = 0x10; + // int sh = 0x10; + // int ls = sx - ox; + // int ts = sy - oy; + // int dw = ex - sx + 1; + // int dh = ey - sy + 1; + // int colorbase = 0x10 * color; + // blockmove_8toN_transpen_pri16_m92(bb1, code, sw, sh, 0x10, ls, ts, flipx, flipy, dw, dh, colorbase, sy, sx, primask); + //} + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void common_drawgfx_m92(byte* bb1, int code, int color, int flipx, int flipy, int sx, int sy, RECT clip, uint primask) { - int ox; - int oy; - int ex; - int ey; - ox = sx; - oy = sy; - ex = sx + 0x10 - 1; - if (sx < 0) - { - sx = 0; - } - if (sx < clip.min_x) - { - sx = clip.min_x; - } - if (ex >= 0x200) - { - ex = 0x200 - 1; - } - if (ex > clip.max_x) - { - ex = clip.max_x; - } - if (sx > ex) - { - return; - } - ey = sy + 0x10 - 1; - if (sy < 0) - { - sy = 0; - } - if (sy < clip.min_y) - { - sy = clip.min_y; - } - if (ey >= 0x100) - { - ey = 0x100 - 1; - } - if (ey > clip.max_y) - { - ey = clip.max_y; - } - if (sy > ey) - { - return; - } - int sw = 0x10; - int sh = 0x10; + // 使用常量折叠和预计算[5](@ref) + const int TEMP1 = 0x10 - 1; // 15 + const int TEMP3 = 0x100 - 1; // 255 + const int TEMP4 = 0x200 - 1; // 511 + + int ox = sx; + int oy = sy; + int ex = sx + TEMP1; + + // 边界检查优化:减少分支预测错误[5](@ref) + sx = sx < 0 ? 0 : sx; + sx = sx < clip.min_x ? clip.min_x : sx; + ex = ex >= 0x200 ? TEMP4 : ex; + ex = ex > clip.max_x ? clip.max_x : ex; + + if (sx > ex) return; + + int ey = sy + TEMP1; + sy = sy < 0 ? 0 : sy; + sy = sy < clip.min_y ? clip.min_y : sy; + ey = ey >= 0x100 ? TEMP3 : ey; + ey = ey > clip.max_y ? clip.max_y : ey; + + if (sy > ey) return; + + // 使用局部变量避免重复计算[2,4](@ref) int ls = sx - ox; int ts = sy - oy; int dw = ex - sx + 1; int dh = ey - sy + 1; - int colorbase = 0x10 * color; - blockmove_8toN_transpen_pri16_m92(bb1, code, sw, sh, 0x10, ls, ts, flipx, flipy, dw, dh, colorbase, sy, sx, primask); + int colorbase = color << 4; // 用移位代替乘法 0x10 * color + + // 内联关键函数调用 + blockmove_8toN_transpen_pri16_m92(bb1, code, 0x10, 0x10, 0x10, ls, ts, flipx, flipy, dw, dh, colorbase, sy, sx, primask); } + public unsafe static void blockmove_8toN_transpen_pri16_m92(byte* bb1, int code, int srcwidth, int srcheight, int srcmodulo, int leftskip, int topskip, int flipx, int flipy, int dstwidth, int dstheight, int colorbase, int sy, int sx, uint primask) { int ydir, xdir, col, i, j; diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/namcos1/Video.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/namcos1/Video.cs index a3f4c902..0f046aeb 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/namcos1/Video.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/namcos1/Video.cs @@ -125,6 +125,7 @@ namespace MAME.Core namcos1_playfield_control[offset & 0x1f] = data; } } + readonly static int[] draw_sprites_sprite_size = new int[] { 16, 8, 32, 4 }; public static void draw_sprites(int iBitmap, RECT cliprect) { int source_offset; @@ -132,14 +133,13 @@ namespace MAME.Core int sprite_yoffs = namcos1_spriteram[0x800 + 0x07f7]; for (source_offset = 0xfe0; source_offset >= 0x800; source_offset -= 0x10) { - int[] sprite_size = new int[] { 16, 8, 32, 4 }; int attr1 = namcos1_spriteram[source_offset + 10]; int attr2 = namcos1_spriteram[source_offset + 14]; int color = namcos1_spriteram[source_offset + 12]; int flipx = (attr1 & 0x20) >> 5; int flipy = (attr2 & 0x01); - int sizex = sprite_size[(attr1 & 0xc0) >> 6]; - int sizey = sprite_size[(attr2 & 0x06) >> 1]; + int sizex = draw_sprites_sprite_size[(attr1 & 0xc0) >> 6]; + int sizey = draw_sprites_sprite_size[(attr2 & 0x06) >> 1]; int tx = (attr1 & 0x18) & (~(sizex - 1)); int ty = (attr2 & 0x18) & (~(sizey - 1)); int sx = namcos1_spriteram[source_offset + 13] + ((color & 0x01) << 8); @@ -163,6 +163,7 @@ namespace MAME.Core Drawgfx.common_drawgfx_na(sizex, sizey, tx, ty, sprite, color, flipx, flipy, sx & 0x1ff, ((sy + 16) & 0xff) - 16, cliprect); } } + readonly static int[] video_update_namcos1_disp_x = new int[] { 25, 27, 28, 29 }; public static void video_update_namcos1() { int i, j, scrollx, scrolly; @@ -195,9 +196,8 @@ namespace MAME.Core } for (i = 0; i < 4; i++) { - int[] disp_x = new int[] { 25, 27, 28, 29 }; j = i << 2; - scrollx = (namcos1_playfield_control[j + 1] + (namcos1_playfield_control[j + 0] << 8)) - disp_x[i]; + scrollx = (namcos1_playfield_control[j + 1] + (namcos1_playfield_control[j + 0] << 8)) - video_update_namcos1_disp_x[i]; scrolly = (namcos1_playfield_control[j + 3] + (namcos1_playfield_control[j + 2] << 8)) + 8; if (Video.flip_screen_get()) { diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Memory.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Memory.cs index 36810907..9e9c9619 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Memory.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Memory.cs @@ -416,17 +416,94 @@ namespace MAME.Core } return result; } + //public static void MWriteByte(int address, sbyte value) + //{ + // address &= 0xffffff; + // if (address >= 0x100000 && address <= 0x1fffff) + // { + // if (address == 0x100d0b && value == 0x06)//&&MC68000.m1.TotalExecutedCycles>0x3F6FC8C) + // { + // ulong l1 = MC68000.m1.TotalExecutedCycles; + // int i2 = 1; + // //m68000Form.iStatus = 1; + // } + // Memory.mainram[address & 0xffff] = (byte)value; + // } + // else if (address >= 0x2ffff0 && address <= 0x2fffff) + // { + // main_cpu_bank_select_w(value); + // } + // else if (address >= 0x300000 && address <= 0x31ffff) + // { + // if ((address & 0x01) == 0) + // { + // int i1 = 1; + // } + // else if ((address & 0x01) == 1) + // { + // watchdog_w(); + // } + // } + // else if (address >= 0x320000 && address <= 0x33ffff) + // { + // if ((address & 0x01) == 0) + // { + // audio_command_w((byte)value); + // } + // else if ((address & 0x01) == 1) + // { + // int i1 = 1; + // } + // } + // else if (address >= 0x380000 && address <= 0x39ffff) + // { + // io_control_w((address & 0x7f) >> 1, (byte)value); + // } + // else if (address >= 0x3a0000 && address <= 0x3bffff) + // { + // if ((address & 0x01) == 1) + // { + // system_control_w((address & 0x1f) >> 1); + // } + // } + // else if (address >= 0x3c0000 && address <= 0x3dffff) + // { + // if ((address & 0x01) == 0) + // { + // neogeo_video_register_w((address & 0x0f) >> 1, (ushort)((value << 8) | (byte)value)); + // } + // else if ((address & 0x01) == 1) + // { + // int i1 = 1; + // } + // } + // else if (address >= 0x400000 && address <= 0x7fffff) + // { + // int i1 = 1; + // //neogeo_paletteram_w((address - 0x400000) >> 1, data, mem_mask); + // } + // else if (address >= 0xd00000 && address <= 0xdfffff) + // { + // save_ram_w(address & 0xffff, (byte)value); + // } + // else + // { + // int i1 = 1; + // } + //} + + //手动优化 public static void MWriteByte(int address, sbyte value) { address &= 0xffffff; if (address >= 0x100000 && address <= 0x1fffff) { - if (address == 0x100d0b && value == 0x06)//&&MC68000.m1.TotalExecutedCycles>0x3F6FC8C) - { - ulong l1 = MC68000.m1.TotalExecutedCycles; - int i2 = 1; - //m68000Form.iStatus = 1; - } + //if (address == 0x100d0b && value == 0x06)//&&MC68000.m1.TotalExecutedCycles>0x3F6FC8C) + //{ + // ulong l1 = MC68000.m1.TotalExecutedCycles; + // int i2 = 1; + // //m68000Form.iStatus = 1; + //} Memory.mainram[address & 0xffff] = (byte)value; } else if (address >= 0x2ffff0 && address <= 0x2fffff) @@ -435,13 +512,15 @@ namespace MAME.Core } else if (address >= 0x300000 && address <= 0x31ffff) { - if ((address & 0x01) == 0) + /*if ((address & 0x01) == 0) { int i1 = 1; } - else if ((address & 0x01) == 1) + else */if ((address & 0x01) == 1) { - watchdog_w(); + //watchdog_w(); + //减少一次堆栈 无意义套娃 + Watchdog.watchdog_reset(); } } else if (address >= 0x320000 && address <= 0x33ffff) @@ -450,10 +529,11 @@ namespace MAME.Core { audio_command_w((byte)value); } - else if ((address & 0x01) == 1) - { - int i1 = 1; - } + //无意义 + //else if ((address & 0x01) == 1) + //{ + // int i1 = 1; + //} } else if (address >= 0x380000 && address <= 0x39ffff) { @@ -472,24 +552,28 @@ namespace MAME.Core { neogeo_video_register_w((address & 0x0f) >> 1, (ushort)((value << 8) | (byte)value)); } - else if ((address & 0x01) == 1) - { - int i1 = 1; - } - } - else if (address >= 0x400000 && address <= 0x7fffff) - { - int i1 = 1; - //neogeo_paletteram_w((address - 0x400000) >> 1, data, mem_mask); + //无意义 + //else if ((address & 0x01) == 1) + //{ + // int i1 = 1; + //} } + + //无意义 + //else if (address >= 0x400000 && address <= 0x7fffff) + //{ + // int i1 = 1; + // //neogeo_paletteram_w((address - 0x400000) >> 1, data, mem_mask); + //} else if (address >= 0xd00000 && address <= 0xdfffff) { save_ram_w(address & 0xffff, (byte)value); } - else - { - int i1 = 1; - } + //无意义 + //else + //{ + // int i1 = 1; + //} } public static void MWriteWord(int address, short value) { diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Neoprot.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Neoprot.cs index c0338a25..ed12435d 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Neoprot.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/neogeo/Neoprot.cs @@ -96,10 +96,7 @@ namespace MAME.Core neogeo_rng = (ushort)((neogeo_rng << 1) | newbit); return old; } - public static void kof99_bankswitch_w(int data) - { - int bankaddress; - int[] bankoffset = new int[] + readonly static int[] kof99_bankswitch_w_bankoffset = new int[] { 0x000000, 0x100000, 0x200000, 0x300000, 0x3cc000, 0x4cc000, 0x3f2000, 0x4f2000, @@ -111,6 +108,10 @@ namespace MAME.Core 0x588800, 0x581800, 0x599800, 0x594800, 0x598000 }; + public static void kof99_bankswitch_w(int data) + { + int bankaddress; + data = (((data >> 14) & 1) << 0) + (((data >> 6) & 1) << 1) + @@ -118,13 +119,10 @@ namespace MAME.Core (((data >> 10) & 1) << 3) + (((data >> 12) & 1) << 4) + (((data >> 5) & 1) << 5); - bankaddress = 0x100000 + bankoffset[data]; + bankaddress = 0x100000 + kof99_bankswitch_w_bankoffset[data]; main_cpu_bank_address = bankaddress; } - public static void garou_bankswitch_w(int data) - { - int bankaddress; - int[] bankoffset = new int[] + readonly static int[] garou_bankswitch_w_bankoffset = new int[] { 0x000000, 0x100000, 0x200000, 0x300000, // 00 0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04 @@ -141,6 +139,10 @@ namespace MAME.Core 0x5d0000, 0x5d8000, 0x5e0000, 0x5e8000, // 48 0x5f0000, 0x5f8000, 0x600000 }; + public static void garou_bankswitch_w(int data) + { + int bankaddress; + data = (((data >> 5) & 1) << 0) + (((data >> 9) & 1) << 1) + @@ -148,13 +150,10 @@ namespace MAME.Core (((data >> 6) & 1) << 3) + (((data >> 14) & 1) << 4) + (((data >> 12) & 1) << 5); - bankaddress = 0x100000 + bankoffset[data]; + bankaddress = 0x100000 + garou_bankswitch_w_bankoffset[data]; main_cpu_bank_address = bankaddress; } - public static void garouh_bankswitch_w(int data) - { - int bankaddress; - int[] bankoffset = new int[] + readonly static int[] garouh_bankswitch_w_bankoffset = new int[] { 0x000000, 0x100000, 0x200000, 0x300000, // 00 0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04 @@ -173,6 +172,10 @@ namespace MAME.Core 0x000000, 0x000000, 0x000000, 0x000000, // 56 0x000000, 0x000000, 0x000000, 0x000000 // 60 }; + public static void garouh_bankswitch_w(int data) + { + int bankaddress; + data = (((data >> 4) & 1) << 0) + (((data >> 8) & 1) << 1) + @@ -180,14 +183,11 @@ namespace MAME.Core (((data >> 2) & 1) << 3) + (((data >> 11) & 1) << 4) + (((data >> 13) & 1) << 5); - bankaddress = 0x100000 + bankoffset[data]; + bankaddress = 0x100000 + garouh_bankswitch_w_bankoffset[data]; main_cpu_bank_address = bankaddress; } - public static void mslug3_bankswitch_w(int data) + readonly static int[] mslug3_bankswitch_w_bankoffset = new int[] { - int bankaddress; - int[] bankoffset = new int[] - { 0x000000, 0x020000, 0x040000, 0x060000, // 00 0x070000, 0x090000, 0x0b0000, 0x0d0000, // 04 0x0e0000, 0x0f0000, 0x120000, 0x130000, // 08 @@ -201,7 +201,10 @@ namespace MAME.Core 0x400000, 0x410000, 0x440000, 0x450000, // 40 0x460000, 0x470000, 0x4a0000, 0x4b0000, // 44 0x4c0000 - }; + }; + public static void mslug3_bankswitch_w(int data) + { + int bankaddress; data = (((data >> 14) & 1) << 0) + (((data >> 12) & 1) << 1) + @@ -209,13 +212,10 @@ namespace MAME.Core (((data >> 6) & 1) << 3) + (((data >> 3) & 1) << 4) + (((data >> 9) & 1) << 5); - bankaddress = 0x100000 + bankoffset[data]; + bankaddress = 0x100000 + mslug3_bankswitch_w_bankoffset[data]; main_cpu_bank_address = bankaddress; } - public static void kof2000_bankswitch_w(int data) - { - int bankaddress; - int[] bankoffset = new int[] + readonly static int[] kof2000_bankswitch_w_bankoffset = new int[] { 0x000000, 0x100000, 0x200000, 0x300000, // 00 0x3f7800, 0x4f7800, 0x3ff800, 0x4ff800, // 04 @@ -227,6 +227,10 @@ namespace MAME.Core 0x52d000, 0x62d000, 0x52e800, 0x62e800, // 28 0x618000, 0x619000, 0x61a000, 0x61a800, // 32 }; + public static void kof2000_bankswitch_w(int data) + { + int bankaddress; + data = (((data >> 15) & 1) << 0) + (((data >> 14) & 1) << 1) + @@ -234,7 +238,7 @@ namespace MAME.Core (((data >> 3) & 1) << 3) + (((data >> 10) & 1) << 4) + (((data >> 5) & 1) << 5); - bankaddress = 0x100000 + bankoffset[data]; + bankaddress = 0x100000 + kof2000_bankswitch_w_bankoffset[data]; main_cpu_bank_address = bankaddress; } public static void pvc_prot1() diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/pgm/Machine.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/pgm/Machine.cs index 96bbee12..b40b84fb 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/pgm/Machine.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/pgm/Machine.cs @@ -8,7 +8,7 @@ public static byte kb_swap; public static ushort olds_bs, kb_cmd3; public static byte[][] kb_source_data; - public static byte[][] drgw2_source_data = new byte[0x08][]//[0xec] + public readonly static byte[][] drgw2_source_data = new byte[0x08][]//[0xec] { new byte[]{ 0, }, // Region 0, not used new byte[]{ // Region 1, $13A886 diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Bublbobl.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Bublbobl.cs index 360143be..691cbc8c 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Bublbobl.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Bublbobl.cs @@ -11,7 +11,7 @@ public static byte port1_out, port2_out, port3_out, port4_out; public static byte portA_in, portA_out, ddrA, portB_in, portB_out, ddrB; public static int ic43_a, ic43_b; - public static byte[] tokio_prot_data = new byte[] + public readonly static byte[] tokio_prot_data = new byte[] { 0x6c, 0x7f,0x5f,0x7f,0x6f,0x5f,0x77,0x5f,0x7f,0x5f,0x7f,0x5f,0x7f,0x5b,0x7f,0x5f,0x7f, @@ -295,10 +295,10 @@ } ic43_a = res; } + readonly static int[] boblbobl_ic43_b_w_xor = new int[] { 4, 1, 8, 2 }; public static void boblbobl_ic43_b_w(int offset, byte data) { - int[] xor = new int[] { 4, 1, 8, 2 }; - ic43_b = (data >> 4) ^ xor[offset]; + ic43_b = (data >> 4) ^ boblbobl_ic43_b_w_xor[offset]; } public static byte boblbobl_ic43_b_r(int offset) { diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Opwolf.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Opwolf.cs index 905e2943..679da6e0 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Opwolf.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/mame/taito/Opwolf.cs @@ -671,6 +671,9 @@ namespace MAME.Core { current_bank = (byte)(data & 7); } + + static int[] opwolf_cchip_data_w_coin_table = new int[] { 0, 0 }; + static byte[] opwolf_cchip_data_w_coin_offset = new byte[2]; public static void opwolf_cchip_data_w(int offset, ushort data) { cchip_ram[(current_bank * 0x400) + offset] = (byte)(data & 0xff); @@ -680,28 +683,28 @@ namespace MAME.Core // Shouldn't we directly read the values from the ROM area ? if (offset == 0x14) { - int[] coin_table = new int[] { 0, 0 }; - byte[] coin_offset = new byte[2]; + //int[] coin_table = new int[] { 0, 0 }; + //byte[] coin_offset = new byte[2]; int slot; if ((opwolf_region == 1) || (opwolf_region == 2)) { - coin_table[0] = 0x03ffce; - coin_table[1] = 0x03ffce; + opwolf_cchip_data_w_coin_table[0] = 0x03ffce; + opwolf_cchip_data_w_coin_table[1] = 0x03ffce; } if ((opwolf_region == 3) || (opwolf_region == 4)) { - coin_table[0] = 0x03ffde; - coin_table[1] = 0x03ffee; + opwolf_cchip_data_w_coin_table[0] = 0x03ffde; + opwolf_cchip_data_w_coin_table[1] = 0x03ffee; } - coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4))); - coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6))); + opwolf_cchip_data_w_coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4))); + opwolf_cchip_data_w_coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6))); for (slot = 0; slot < 2; slot++) { - if (coin_table[slot] != 0) + if (opwolf_cchip_data_w_coin_table[slot] != 0) { - cchip_coins_for_credit[slot] = (byte)((Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 0) / 2 * 2] * 0x100 + Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 0) / 2 * 2 + 1]) & 0xff); - cchip_credits_for_coin[slot] = (byte)((Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 2) / 2 * 2] * 0x100 + Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 2) / 2 * 2 + 1]) & 0xff); + cchip_coins_for_credit[slot] = (byte)((Memory.mainrom[(opwolf_cchip_data_w_coin_table[slot] + opwolf_cchip_data_w_coin_offset[slot] + 0) / 2 * 2] * 0x100 + Memory.mainrom[(opwolf_cchip_data_w_coin_table[slot] + opwolf_cchip_data_w_coin_offset[slot] + 0) / 2 * 2 + 1]) & 0xff); + cchip_credits_for_coin[slot] = (byte)((Memory.mainrom[(opwolf_cchip_data_w_coin_table[slot] + opwolf_cchip_data_w_coin_offset[slot] + 2) / 2 * 2] * 0x100 + Memory.mainrom[(opwolf_cchip_data_w_coin_table[slot] + opwolf_cchip_data_w_coin_offset[slot] + 2) / 2 * 2 + 1]) & 0xff); } } } @@ -712,6 +715,8 @@ namespace MAME.Core } } } + static int[] opwolf_cchip_data_w2_coin_table = new int[] { 0, 0 }; + static byte[] opwolf_cchip_data_w2_coin_offset = new byte[2]; public static void opwolf_cchip_data_w2(int offset, byte data) { cchip_ram[(current_bank * 0x400) + offset] = (byte)(data & 0xff); @@ -721,28 +726,28 @@ namespace MAME.Core // Shouldn't we directly read the values from the ROM area ? if (offset == 0x14) { - int[] coin_table = new int[] { 0, 0 }; - byte[] coin_offset = new byte[2]; + //int[] coin_table = new int[] { 0, 0 }; + //byte[] coin_offset = new byte[2]; int slot; if ((opwolf_region == 1) || (opwolf_region == 2)) { - coin_table[0] = 0x03ffce; - coin_table[1] = 0x03ffce; + opwolf_cchip_data_w2_coin_table[0] = 0x03ffce; + opwolf_cchip_data_w2_coin_table[1] = 0x03ffce; } if ((opwolf_region == 3) || (opwolf_region == 4)) { - coin_table[0] = 0x03ffde; - coin_table[1] = 0x03ffee; + opwolf_cchip_data_w2_coin_table[0] = 0x03ffde; + opwolf_cchip_data_w2_coin_table[1] = 0x03ffee; } - coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4))); - coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6))); + opwolf_cchip_data_w2_coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4))); + opwolf_cchip_data_w2_coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6))); for (slot = 0; slot < 2; slot++) { - if (coin_table[slot] != 0) + if (opwolf_cchip_data_w2_coin_table[slot] != 0) { - cchip_coins_for_credit[slot] = (byte)((Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 0) / 2 * 2] * 0x100 + Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 0) / 2 * 2 + 1]) & 0xff); - cchip_credits_for_coin[slot] = (byte)((Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 2) / 2 * 2] * 0x100 + Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 2) / 2 * 2 + 1]) & 0xff); + cchip_coins_for_credit[slot] = (byte)((Memory.mainrom[(opwolf_cchip_data_w2_coin_table[slot] + opwolf_cchip_data_w2_coin_offset[slot] + 0) / 2 * 2] * 0x100 + Memory.mainrom[(opwolf_cchip_data_w2_coin_table[slot] + opwolf_cchip_data_w2_coin_offset[slot] + 0) / 2 * 2 + 1]) & 0xff); + cchip_credits_for_coin[slot] = (byte)((Memory.mainrom[(opwolf_cchip_data_w2_coin_table[slot] + opwolf_cchip_data_w2_coin_offset[slot] + 2) / 2 * 2] * 0x100 + Memory.mainrom[(opwolf_cchip_data_w2_coin_table[slot] + opwolf_cchip_data_w2_coin_offset[slot] + 2) / 2 * 2 + 1]) & 0xff); } } } diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/AY8910.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/AY8910.cs index 2bb8a27e..cdc092fe 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/AY8910.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/AY8910.cs @@ -286,18 +286,41 @@ namespace MAME.Core } } } + //private int mix_3D() + //{ + // int indx = 0, chan; + // for (chan = 0; chan < 3; chan++) + // { + // if (TONE_ENVELOPE(chan) != 0) + // { + // indx |= ((1 << (chan + 15)) | ((ay8910info.vol_enabled[chan] != 0) ? ay8910info.env_volume << (chan * 5) : 0)); + // } + // else + // { + // indx |= ((ay8910info.vol_enabled[chan] != 0) ? TONE_VOLUME(chan) << (chan * 5) : 0); + // } + // } + // return ay8910info.vol3d_table[indx]; + //} + + //手动内联 private int mix_3D() { int indx = 0, chan; for (chan = 0; chan < 3; chan++) { - if (TONE_ENVELOPE(chan) != 0) + //if (TONE_ENVELOPE(chan) != 0) + if(((ay8910info.regs[TONE_ENVELOPE_REG_OFFSET + chan] >> TONE_ENVELOPE_MOVE) & TONE_ENVELOPE_VOLUME_MASK)!=0) { indx |= ((1 << (chan + 15)) | ((ay8910info.vol_enabled[chan] != 0) ? ay8910info.env_volume << (chan * 5) : 0)); } else { - indx |= ((ay8910info.vol_enabled[chan] != 0) ? TONE_VOLUME(chan) << (chan * 5) : 0); + indx |= ((ay8910info.vol_enabled[chan] != 0) ? + //TONE_VOLUME(chan) + (ay8910info.regs[TONE_VOLUME_REG_OFFSET + chan] & TONE_VOLUME_VOLUME_MASK) + << (chan * 5) + : 0); } } return ay8910info.vol3d_table[indx]; @@ -373,6 +396,104 @@ namespace MAME.Core break; } } + //public void ay8910_update(int offset, int length) + //{ + // int chan, i, j; + // if (ay8910info.ready == 0) + // { + // for (chan = 0; chan < ay8910info.streams; chan++) + // { + // for (j = 0; j < length; j++) + // { + // stream.streamoutput_Ptrs[chan][offset + j] = 0; + // } + // } + // } + // for (i = 0; i < length; i++) + // { + // for (chan = 0; chan < 3; chan++) + // { + // ay8910info.count[chan]++; + // if (ay8910info.count[chan] >= TONE_PERIOD(chan)) + // { + // ay8910info.output[chan] ^= 1; + // ay8910info.count[chan] = 0; ; + // } + // } + // ay8910info.count_noise++; + // if (ay8910info.count_noise >= NOISE_PERIOD()) + // { + // if (((ay8910info.rng + 1) & 2) != 0) + // { + // ay8910info.output_noise ^= 1; + // } + // if ((ay8910info.rng & 1) != 0) + // { + // ay8910info.rng ^= 0x24000; + // } + // ay8910info.rng >>= 1; + // ay8910info.count_noise = 0; + // } + // for (chan = 0; chan < 3; chan++) + // { + // ay8910info.vol_enabled[chan] = (byte)((ay8910info.output[chan] | TONE_ENABLEQ(chan)) & (ay8910info.output_noise | NOISE_ENABLEQ(chan))); + // } + // if (ay8910info.holding == 0) + // { + // ay8910info.count_env++; + // if (ay8910info.count_env >= ENVELOPE_PERIOD() * ay8910info.step) + // { + // ay8910info.count_env = 0; + // ay8910info.env_step--; + // if (ay8910info.env_step < 0) + // { + // if (ay8910info.hold != 0) + // { + // if (ay8910info.alternate != 0) + // { + // ay8910info.attack ^= ay8910info.env_step_mask; + // } + // ay8910info.holding = 1; + // ay8910info.env_step = 0; + // } + // else + // { + // if (ay8910info.alternate != 0 && (ay8910info.env_step & (ay8910info.env_step_mask + 1)) != 0) + // { + // ay8910info.attack ^= ay8910info.env_step_mask; + // } + // ay8910info.env_step &= (sbyte)ay8910info.env_step_mask; + // } + // } + // } + // } + // ay8910info.env_volume = (ay8910info.env_step ^ ay8910info.attack); + // if (ay8910info.streams == 3) + // { + // for (chan = 0; chan < 3; chan++) + // { + // if (TONE_ENVELOPE(chan) != 0) + // { + // int i1 = ay8910info.env_table[chan][ay8910info.vol_enabled[chan] != 0 ? ay8910info.env_volume : 0]; + // stream.streamoutput_Ptrs[chan][offset] = ay8910info.env_table[chan][ay8910info.vol_enabled[chan] != 0 ? ay8910info.env_volume : 0]; + // } + // else + // { + // int i1 = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? TONE_VOLUME(chan) : 0]; + // stream.streamoutput_Ptrs[chan][offset] = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? TONE_VOLUME(chan) : 0]; + // } + // } + // } + // else + // { + // stream.streamoutput_Ptrs[0][offset] = mix_3D(); + // } + // offset++; + // } + //} + + + //手动内联优化 public void ay8910_update(int offset, int length) { int chan, i, j; @@ -391,14 +512,16 @@ namespace MAME.Core for (chan = 0; chan < 3; chan++) { ay8910info.count[chan]++; - if (ay8910info.count[chan] >= TONE_PERIOD(chan)) + //if (ay8910info.count[chan] >= TONE_PERIOD(chan)) + if (ay8910info.count[chan] >= (ay8910info.regs[chan << 1] | ((ay8910info.regs[(chan << 1) | 1] & 0x0f) << 8))) { ay8910info.output[chan] ^= 1; ay8910info.count[chan] = 0; ; } } ay8910info.count_noise++; - if (ay8910info.count_noise >= NOISE_PERIOD()) + //if (ay8910info.count_noise >= NOISE_PERIOD()) + if (ay8910info.count_noise >= (ay8910info.regs[6] & 0x1f)) { if (((ay8910info.rng + 1) & 2) != 0) { @@ -413,12 +536,23 @@ namespace MAME.Core } for (chan = 0; chan < 3; chan++) { - ay8910info.vol_enabled[chan] = (byte)((ay8910info.output[chan] | TONE_ENABLEQ(chan)) & (ay8910info.output_noise | NOISE_ENABLEQ(chan))); + //ay8910info.vol_enabled[chan] = (byte)((ay8910info.output[chan] | TONE_ENABLEQ(chan)) & (ay8910info.output_noise | NOISE_ENABLEQ(chan))); + ay8910info.vol_enabled[chan] = (byte)((ay8910info.output[chan] | + //TONE_ENABLEQ(chan) + ((ay8910info.regs[7] >> chan) & 1) + ) & (ay8910info.output_noise | + //NOISE_ENABLEQ(chan) + ((ay8910info.regs[7] >> (3 + chan)) & 1) + )); } if (ay8910info.holding == 0) { ay8910info.count_env++; - if (ay8910info.count_env >= ENVELOPE_PERIOD() * ay8910info.step) + //if (ay8910info.count_env >= ENVELOPE_PERIOD() * ay8910info.step) + if (ay8910info.count_env >= + //ENVELOPE_PERIOD() + (ay8910info.regs[11] | (ay8910info.regs[12] << 8)) + * ay8910info.step) { ay8910info.count_env = 0; ay8910info.env_step--; @@ -449,21 +583,46 @@ namespace MAME.Core { for (chan = 0; chan < 3; chan++) { - if (TONE_ENVELOPE(chan) != 0) + //if (TONE_ENVELOPE(chan) != 0) + if(((ay8910info.regs[TONE_ENVELOPE_REG_OFFSET + chan] >> TONE_ENVELOPE_MOVE) & TONE_ENVELOPE_VOLUME_MASK) != 0) { int i1 = ay8910info.env_table[chan][ay8910info.vol_enabled[chan] != 0 ? ay8910info.env_volume : 0]; stream.streamoutput_Ptrs[chan][offset] = ay8910info.env_table[chan][ay8910info.vol_enabled[chan] != 0 ? ay8910info.env_volume : 0]; } else { - int i1 = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? TONE_VOLUME(chan) : 0]; - stream.streamoutput_Ptrs[chan][offset] = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? TONE_VOLUME(chan) : 0]; + int i1 = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? + //TONE_VOLUME(chan) + ay8910info.regs[TONE_VOLUME_REG_OFFSET + chan] & TONE_VOLUME_VOLUME_MASK + : 0]; + stream.streamoutput_Ptrs[chan][offset] = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? + //TONE_VOLUME(chan) + ay8910info.regs[TONE_VOLUME_REG_OFFSET + chan] & TONE_VOLUME_VOLUME_MASK + : 0]; } } } else { - stream.streamoutput_Ptrs[0][offset] = mix_3D(); + //stream.streamoutput_Ptrs[0][offset] = mix_3D(); + { + int indx = 0, tempchan; + for (tempchan = 0; tempchan < 3; tempchan++) + { + if (((ay8910info.regs[TONE_ENVELOPE_REG_OFFSET + tempchan] >> TONE_ENVELOPE_MOVE) & TONE_ENVELOPE_VOLUME_MASK) != 0) + { + indx |= ((1 << (tempchan + 15)) | ((ay8910info.vol_enabled[tempchan] != 0) ? ay8910info.env_volume << (tempchan * 5) : 0)); + } + else + { + indx |= ((ay8910info.vol_enabled[tempchan] != 0) ? + (ay8910info.regs[TONE_VOLUME_REG_OFFSET + tempchan] & TONE_VOLUME_VOLUME_MASK) + << (tempchan * 5) + : 0); + } + } + stream.streamoutput_Ptrs[0][offset] = ay8910info.vol3d_table[indx]; + } } offset++; } diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2413.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2413.cs index ac69dfbc..a0d47aff 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2413.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2413.cs @@ -287,7 +287,7 @@ namespace MAME.Core 6, 3, 0,-3,-6,-3, 0, 3, 7, 3, 0,-3,-7,-3, 0, 3, }; - private static byte[][] table = new byte[19][] + private readonly static byte[][] table = new byte[19][] { new byte[]{0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 },