进行一些内联优化,还有timer对象池优化

This commit is contained in:
sin365 2025-11-11 17:55:44 +08:00
parent d2cc4fa05d
commit 200ee3830b
17 changed files with 801 additions and 252 deletions

View File

@ -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 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_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 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 public enum M6800_TX_STATE
{ {
INIT = 0, INIT = 0,
@ -64,7 +64,7 @@ namespace cpu.m6800
} }
} }
public uint timer_next; 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, 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,
@ -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,
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,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, 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,
@ -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,
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,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 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, /*0*/ 99, 2,99,99,99,99, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2,

View File

@ -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,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,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 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, /*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,

View File

@ -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,
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,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, 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, 0x00,0x00,0x02,0x04,0x02,0x02,0x05,0x09,0x02,0x02,0x03,0x02,0x03,0x02,0x08,0x06,

View File

@ -449,7 +449,7 @@ namespace cpu.nec
I.regs.b[Reg * 2 + 1] = (byte)((ushort)tmp1 / 0x100); 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) //public void JMP(bool flag)
//{ //{
// int tmp = (int)((sbyte)FETCH()); // int tmp = (int)((sbyte)FETCH());
@ -732,7 +732,7 @@ namespace cpu.nec
I.regs.b[5] = (byte)((ushort)result2 / 0x100); 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) public void ADD4S(ref int tmp, ref int tmp2)
{ {
int i, v1, v2, result; int i, v1, v2, result;

View File

@ -15,7 +15,7 @@
public byte animation_counter; public byte animation_counter;
} }
public static crosshair_global global; 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,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, 0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,

View File

@ -1,10 +1,6 @@
using cpu.m6800; using cpu.m6800;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.ConstrainedExecution;
using System.Threading;
using System.Timers;
using static MAME.Core.EmuTimer; using static MAME.Core.EmuTimer;
namespace MAME.Core namespace MAME.Core
@ -68,7 +64,6 @@ namespace MAME.Core
{ {
emu_timer.RemoveToList(ref timerlist, ref timer); emu_timer.RemoveToList(ref timerlist, ref timer);
} }
public void Insert(int index, emu_timer timer) public void Insert(int index, emu_timer timer)
{ {
emu_timer.InsertToList(ref timerlist, index, ref timer); emu_timer.InsertToList(ref timerlist, index, ref timer);
@ -78,6 +73,11 @@ namespace MAME.Core
{ {
return timerlist.IndexOf(timer); return timerlist.IndexOf(timer);
} }
public void RemoveAt(int index)
{
emu_timer.RemoveAtToList(ref timerlist, index);
}
} }
public class EmuTimer public class EmuTimer
@ -117,6 +117,11 @@ namespace MAME.Core
public Atime start; public Atime start;
public Atime expire; public Atime expire;
// 引用计数字段
private int _refCount;
// 是否在检查池中
private bool _inReadyQueue;
internal void reset() internal void reset()
{ {
action = default; action = default;
@ -126,27 +131,25 @@ namespace MAME.Core
start = default; start = default;
expire = default; expire = default;
_refCount = 0; _refCount = 0;
_inReadyQueue = false;
} }
static Queue<emu_timer> _readyToRelease = new Queue<emu_timer>(); static Queue<emu_timer> _readyToRelease = new Queue<emu_timer>();
/// <summary> static Queue<emu_timer> _timerPool = new Queue<emu_timer>();
/// 线程安全队列(因为析构函数是额外线程来的)
/// </summary>
static Queue<emu_timer> _failedDeletions = new Queue<emu_timer>();
static HashSet<emu_timer> _tempCheck = new HashSet<emu_timer>();
static int outTimerAllCount = 0; static int outTimerAllCount = 0;
static int newTimerCount = 0; static int newTimerCount = 0;
public static emu_timer GetEmu_timerNoRef() public static emu_timer GetEmu_timerNoRef()
{ {
emu_timer obj; emu_timer obj;
if (!_failedDeletions.TryDequeue(out obj)) if (!_timerPool.TryDequeue(out obj))
{ {
obj = new emu_timer(); obj = new emu_timer();
newTimerCount++; newTimerCount++;
} }
//这里引用计数为0直接放入带Ready里等待下一帧检测 //这里引用计数为0直接放入带Ready里等待下一帧检测
obj.reset(); obj.reset();
obj._inReadyQueue = true;
_readyToRelease.Enqueue(obj); _readyToRelease.Enqueue(obj);
outTimerAllCount++; outTimerAllCount++;
return obj; return obj;
@ -157,47 +160,31 @@ namespace MAME.Core
if (_readyToRelease.Count < 1) if (_readyToRelease.Count < 1)
return; return;
int checkcount = _readyToRelease.Count; int checkcount = _readyToRelease.Count;
int beforpoolcount = _failedDeletions.Count; int beforpoolcount = _timerPool.Count;
int releaseCount = 0; int releaseCount = 0;
while(_readyToRelease.TryDequeue(out emu_timer ready)) while (_readyToRelease.TryDequeue(out emu_timer ready))
{ {
if (_tempCheck.Contains(ready)) ready._inReadyQueue = false;
continue;
_tempCheck.Add(ready);
if (ready._refCount <= 0) if (ready._refCount <= 0)
{ {
ready.ReturnToPool(); ready.ReturnToPool();
releaseCount++; 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; outTimerAllCount = 0;
newTimerCount = 0; newTimerCount = 0;
_readyToRelease.Clear(); //_readyToRelease.Clear();
_tempCheck.Clear();
} }
// 引用计数字段(线程安全)
private int _refCount = 1; // 初始为1表示创建时的引用
/// <summary> /// <summary>
/// 增加引用计数 /// 增加引用计数
/// </summary> /// </summary>
void AddRef() void AddRef()
{ {
int newCount = Interlocked.Increment(ref _refCount); //int newCount = Interlocked.Increment(ref _refCount);
_refCount++;
////引用计数重新回到1时移除。
////但是还是不在这里做把注释了,在每一帧开始之前统一检测
//if (newCount == 1)
//{
// UnityEngine.Debug.Log("CheckReadyRelaseAfterRun AddRef 复活");
// //if (_readyToRelease.Contains(this))
// //{
// // //UnityEngine.Debug.Log("移除ReadyToRelease");
// // _readyToRelease.Remove(this);
// //}
//}
} }
/// <summary> /// <summary>
@ -205,14 +192,14 @@ namespace MAME.Core
/// </summary> /// </summary>
void ReleaseRef() void ReleaseRef()
{ {
int newCount = Interlocked.Decrement(ref _refCount); //int newCount = Interlocked.Decrement(ref _refCount);
if (newCount == 0) _refCount--;
if (_refCount == 0)
{ {
//UnityEngine.Debug.Log("CheckReadyRelaseAfterRun ReleaseRef 预回收");
// 引用计数为0释放资源并回池 // 引用计数为0释放资源并回池
ReadyToRelease(); ReadyToRelease();
} }
else if (newCount < 0) else if (_refCount < 0)
{ {
// 引用计数异常,不应出现负数 // 引用计数异常,不应出现负数
throw new InvalidOperationException("引用计数出现负数"); throw new InvalidOperationException("引用计数出现负数");
@ -221,7 +208,9 @@ namespace MAME.Core
void ReadyToRelease() void ReadyToRelease()
{ {
if (this._inReadyQueue) return;
//UnityEngine.Debug.Log("ReadyToRelease"); //UnityEngine.Debug.Log("ReadyToRelease");
this._inReadyQueue = true;
_readyToRelease.Enqueue(this); _readyToRelease.Enqueue(this);
} }
@ -230,7 +219,7 @@ namespace MAME.Core
/// </summary> /// </summary>
void ReturnToPool() void ReturnToPool()
{ {
_failedDeletions.Enqueue(this); _timerPool.Enqueue(this);
} }
#region #region
@ -245,7 +234,6 @@ namespace MAME.Core
} }
if (refattr != null) if (refattr != null)
refattr.ReleaseRef(); refattr.ReleaseRef();
refattr = emu_timer; refattr = emu_timer;
refattr.AddRef(); refattr.AddRef();
} }
@ -278,6 +266,11 @@ namespace MAME.Core
list[i].ReleaseRef(); list[i].ReleaseRef();
list.Clear(); list.Clear();
} }
internal static void RemoveAtToList(ref List<emu_timer> list, int index)
{
list.RemoveAt(index);
}
#endregion #endregion
/* /*
static void EnqueueObj(emu_timer obj) 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<emu_timer> 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) static void timer_list_insert(emu_timer timer1)
{ {
int i; TIME_ACT currAct = timer1.action;
int i1 = -1; 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)
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; break;
} }
scanCount++;
} }
} }
if (i1 == -1) if (i1 == -1)
{ {
Atime expire = timer1.enabled ? timer1.expire : Attotime.ATTOTIME_NEVER; 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) emu_timer et = tlist[scanCount];
{ if (Attotime.attotime_compare(et.expire, expire) > 0)
break; break;
} scanCount++;
} }
lt.Insert(i, timer1); lt.Insert(scanCount, timer1);
} }
} }
static List<emu_timer> timer_list_remove_lt1 = new List<emu_timer>(); static List<emu_timer> timer_list_remove_lt1 = new List<emu_timer>();
//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) public static void timer_list_remove(emu_timer timer1)
{ {
if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector) if (timer1.action == TIME_ACT.Cpuint_cpunum_empty_event_queue || timer1.action == TIME_ACT.setvector)
{ {
timer_list_remove_lt1.Clear(); //timer_list_remove_lt1.Clear();
//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 && 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) if (et.action == timer1.action && Attotime.attotime_compare(et.expire, timer1.expire) == 0)
{ lt.Remove(et);
timer_list_remove_lt1.Add(et); tempMaxIdx--;
//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 else
{ {
//TODO MAME.NET原来这么foreach写删除是有问题的 //TODO MAME.NET原来这么foreach写删除是有问题的
//foreach (emu_timer et in lt) //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) if (et.action == timer1.action)
{ {
lt.Remove(et); lt.Remove(et);
break; break;
} }
scanCount++;
} }
} }
} }

View File

@ -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) 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 ox, oy, code, color, pri, shadow, size, w, h, x, y, flipx, flipy, zoomx, zoomy, code2, color2, pri2;
int offs, pri_code; 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++) for (offs = 0; offs < 128; offs++)
{ {
sortedlist[offs] = -1; K051960_sprites_draw_sortedlist[offs] = -1;
} }
for (offs = 0; offs < 0x400; offs += 8) for (offs = 0; offs < 0x400; offs += 8)
{ {
@ -563,17 +563,17 @@
{ {
if (max_priority == -1) if (max_priority == -1)
{ {
sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs; K051960_sprites_draw_sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs;
} }
else 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++) for (pri_code = 0; pri_code < 128; pri_code++)
{ {
offs = sortedlist[pri_code]; offs = K051960_sprites_draw_sortedlist[pri_code];
if (offs == -1) if (offs == -1)
{ {
continue; continue;
@ -594,8 +594,8 @@
} }
} }
size = (K051960_ram[offs + 1] & 0xe0) >> 5; size = (K051960_ram[offs + 1] & 0xe0) >> 5;
w = width[size]; w = K051960_sprites_draw_width[size];
h = height[size]; h = K051960_sprites_draw_height[size];
if (w >= 2) code &= ~0x01; if (w >= 2) code &= ~0x01;
if (h >= 2) code &= ~0x02; if (h >= 2) code &= ~0x02;
if (w >= 4) code &= ~0x04; if (w >= 4) code &= ~0x04;
@ -631,19 +631,19 @@
sx = ox + 16 * x; sx = ox + 16 * x;
if (flipx != 0) if (flipx != 0)
{ {
c += xoffset[(w - 1 - x)]; c += K051960_sprites_draw_xoffset[(w - 1 - x)];
} }
else else
{ {
c += xoffset[x]; c += K051960_sprites_draw_xoffset[x];
} }
if (flipy != 0) if (flipy != 0)
{ {
c += yoffset[(h - 1 - y)]; c += K051960_sprites_draw_yoffset[(h - 1 - y)];
} }
else else
{ {
c += yoffset[y]; c += K051960_sprites_draw_yoffset[y];
} }
if (max_priority == -1) if (max_priority == -1)
{ {
@ -682,16 +682,16 @@
zw = (ox + ((zoomx * (x + 1) + (1 << 11)) >> 12)) - sx; zw = (ox + ((zoomx * (x + 1) + (1 << 11)) >> 12)) - sx;
if (flipx != 0) 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) if (flipy != 0)
{ {
c += yoffset[(h - 1 - y)]; c += K051960_sprites_draw_yoffset[(h - 1 - y)];
} }
else else
{ {
c += yoffset[y]; c += K051960_sprites_draw_yoffset[y];
} }
if (max_priority == -1) if (max_priority == -1)
{ {

View File

@ -153,7 +153,7 @@ namespace MAME.Core
#endregion #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, 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,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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 */ 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 */ 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 */ 0x8a,0x90,0x90,0x90,0x3a,0x3c,0x5a,0x38, 0x99,0x90,0xf8,0x89,0x90,0x91,0x90,0x55, /* 20 */

View File

@ -1,66 +1,107 @@
namespace MAME.Core using System.Runtime.CompilerServices;
namespace MAME.Core
{ {
public unsafe partial class Drawgfx 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; // 使用常量折叠和预计算[5](@ref)
int oy; const int TEMP1 = 0x10 - 1; // 15
int ex; const int TEMP3 = 0x100 - 1; // 255
int ey; const int TEMP4 = 0x200 - 1; // 511
ox = sx;
oy = sy; int ox = sx;
ex = sx + 0x10 - 1; int oy = sy;
if (sx < 0) int ex = sx + TEMP1;
{
sx = 0; // 边界检查优化:减少分支预测错误[5](@ref)
} sx = sx < 0 ? 0 : sx;
if (sx < clip.min_x) sx = sx < clip.min_x ? clip.min_x : sx;
{ ex = ex >= 0x200 ? TEMP4 : ex;
sx = clip.min_x; ex = ex > clip.max_x ? clip.max_x : ex;
}
if (ex >= 0x200) if (sx > ex) return;
{
ex = 0x200 - 1; int ey = sy + TEMP1;
} sy = sy < 0 ? 0 : sy;
if (ex > clip.max_x) sy = sy < clip.min_y ? clip.min_y : sy;
{ ey = ey >= 0x100 ? TEMP3 : ey;
ex = clip.max_x; ey = ey > clip.max_y ? clip.max_y : ey;
}
if (sx > ex) if (sy > ey) return;
{
return; // 使用局部变量避免重复计算[2,4](@ref)
}
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 ls = sx - ox;
int ts = sy - oy; int ts = sy - oy;
int dw = ex - sx + 1; int dw = ex - sx + 1;
int dh = ey - sy + 1; int dh = ey - sy + 1;
int colorbase = 0x10 * color; int colorbase = color << 4; // 用移位代替乘法 0x10 * color
blockmove_8toN_transpen_pri16_m92(bb1, code, sw, sh, 0x10, ls, ts, flipx, flipy, dw, dh, colorbase, sy, sx, primask);
// 内联关键函数调用
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) 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; int ydir, xdir, col, i, j;

View File

@ -125,6 +125,7 @@ namespace MAME.Core
namcos1_playfield_control[offset & 0x1f] = data; 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) public static void draw_sprites(int iBitmap, RECT cliprect)
{ {
int source_offset; int source_offset;
@ -132,14 +133,13 @@ namespace MAME.Core
int sprite_yoffs = namcos1_spriteram[0x800 + 0x07f7]; int sprite_yoffs = namcos1_spriteram[0x800 + 0x07f7];
for (source_offset = 0xfe0; source_offset >= 0x800; source_offset -= 0x10) 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 attr1 = namcos1_spriteram[source_offset + 10];
int attr2 = namcos1_spriteram[source_offset + 14]; int attr2 = namcos1_spriteram[source_offset + 14];
int color = namcos1_spriteram[source_offset + 12]; int color = namcos1_spriteram[source_offset + 12];
int flipx = (attr1 & 0x20) >> 5; int flipx = (attr1 & 0x20) >> 5;
int flipy = (attr2 & 0x01); int flipy = (attr2 & 0x01);
int sizex = sprite_size[(attr1 & 0xc0) >> 6]; int sizex = draw_sprites_sprite_size[(attr1 & 0xc0) >> 6];
int sizey = sprite_size[(attr2 & 0x06) >> 1]; int sizey = draw_sprites_sprite_size[(attr2 & 0x06) >> 1];
int tx = (attr1 & 0x18) & (~(sizex - 1)); int tx = (attr1 & 0x18) & (~(sizex - 1));
int ty = (attr2 & 0x18) & (~(sizey - 1)); int ty = (attr2 & 0x18) & (~(sizey - 1));
int sx = namcos1_spriteram[source_offset + 13] + ((color & 0x01) << 8); 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); 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() public static void video_update_namcos1()
{ {
int i, j, scrollx, scrolly; int i, j, scrollx, scrolly;
@ -195,9 +196,8 @@ namespace MAME.Core
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
int[] disp_x = new int[] { 25, 27, 28, 29 };
j = i << 2; 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; scrolly = (namcos1_playfield_control[j + 3] + (namcos1_playfield_control[j + 2] << 8)) + 8;
if (Video.flip_screen_get()) if (Video.flip_screen_get())
{ {

View File

@ -416,17 +416,94 @@ namespace MAME.Core
} }
return result; 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) public static void MWriteByte(int address, sbyte value)
{ {
address &= 0xffffff; address &= 0xffffff;
if (address >= 0x100000 && address <= 0x1fffff) if (address >= 0x100000 && address <= 0x1fffff)
{ {
if (address == 0x100d0b && value == 0x06)//&&MC68000.m1.TotalExecutedCycles>0x3F6FC8C) //if (address == 0x100d0b && value == 0x06)//&&MC68000.m1.TotalExecutedCycles>0x3F6FC8C)
{ //{
ulong l1 = MC68000.m1.TotalExecutedCycles; // ulong l1 = MC68000.m1.TotalExecutedCycles;
int i2 = 1; // int i2 = 1;
//m68000Form.iStatus = 1; // //m68000Form.iStatus = 1;
} //}
Memory.mainram[address & 0xffff] = (byte)value; Memory.mainram[address & 0xffff] = (byte)value;
} }
else if (address >= 0x2ffff0 && address <= 0x2fffff) else if (address >= 0x2ffff0 && address <= 0x2fffff)
@ -435,13 +512,15 @@ namespace MAME.Core
} }
else if (address >= 0x300000 && address <= 0x31ffff) else if (address >= 0x300000 && address <= 0x31ffff)
{ {
if ((address & 0x01) == 0) /*if ((address & 0x01) == 0)
{ {
int i1 = 1; 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) else if (address >= 0x320000 && address <= 0x33ffff)
@ -450,10 +529,11 @@ namespace MAME.Core
{ {
audio_command_w((byte)value); audio_command_w((byte)value);
} }
else if ((address & 0x01) == 1) //无意义
{ //else if ((address & 0x01) == 1)
int i1 = 1; //{
} // int i1 = 1;
//}
} }
else if (address >= 0x380000 && address <= 0x39ffff) 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)); neogeo_video_register_w((address & 0x0f) >> 1, (ushort)((value << 8) | (byte)value));
} }
else if ((address & 0x01) == 1) //无意义
{ //else if ((address & 0x01) == 1)
int i1 = 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 >= 0x400000 && address <= 0x7fffff)
//{
// int i1 = 1;
// //neogeo_paletteram_w((address - 0x400000) >> 1, data, mem_mask);
//}
else if (address >= 0xd00000 && address <= 0xdfffff) else if (address >= 0xd00000 && address <= 0xdfffff)
{ {
save_ram_w(address & 0xffff, (byte)value); save_ram_w(address & 0xffff, (byte)value);
} }
else //无意义
{ //else
int i1 = 1; //{
} // int i1 = 1;
//}
} }
public static void MWriteWord(int address, short value) public static void MWriteWord(int address, short value)
{ {

View File

@ -96,10 +96,7 @@ namespace MAME.Core
neogeo_rng = (ushort)((neogeo_rng << 1) | newbit); neogeo_rng = (ushort)((neogeo_rng << 1) | newbit);
return old; return old;
} }
public static void kof99_bankswitch_w(int data) readonly static int[] kof99_bankswitch_w_bankoffset = new int[]
{
int bankaddress;
int[] bankoffset = new int[]
{ {
0x000000, 0x100000, 0x200000, 0x300000, 0x000000, 0x100000, 0x200000, 0x300000,
0x3cc000, 0x4cc000, 0x3f2000, 0x4f2000, 0x3cc000, 0x4cc000, 0x3f2000, 0x4f2000,
@ -111,6 +108,10 @@ namespace MAME.Core
0x588800, 0x581800, 0x599800, 0x594800, 0x588800, 0x581800, 0x599800, 0x594800,
0x598000 0x598000
}; };
public static void kof99_bankswitch_w(int data)
{
int bankaddress;
data = data =
(((data >> 14) & 1) << 0) + (((data >> 14) & 1) << 0) +
(((data >> 6) & 1) << 1) + (((data >> 6) & 1) << 1) +
@ -118,13 +119,10 @@ namespace MAME.Core
(((data >> 10) & 1) << 3) + (((data >> 10) & 1) << 3) +
(((data >> 12) & 1) << 4) + (((data >> 12) & 1) << 4) +
(((data >> 5) & 1) << 5); (((data >> 5) & 1) << 5);
bankaddress = 0x100000 + bankoffset[data]; bankaddress = 0x100000 + kof99_bankswitch_w_bankoffset[data];
main_cpu_bank_address = bankaddress; main_cpu_bank_address = bankaddress;
} }
public static void garou_bankswitch_w(int data) readonly static int[] garou_bankswitch_w_bankoffset = new int[]
{
int bankaddress;
int[] bankoffset = new int[]
{ {
0x000000, 0x100000, 0x200000, 0x300000, // 00 0x000000, 0x100000, 0x200000, 0x300000, // 00
0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04 0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04
@ -141,6 +139,10 @@ namespace MAME.Core
0x5d0000, 0x5d8000, 0x5e0000, 0x5e8000, // 48 0x5d0000, 0x5d8000, 0x5e0000, 0x5e8000, // 48
0x5f0000, 0x5f8000, 0x600000 0x5f0000, 0x5f8000, 0x600000
}; };
public static void garou_bankswitch_w(int data)
{
int bankaddress;
data = data =
(((data >> 5) & 1) << 0) + (((data >> 5) & 1) << 0) +
(((data >> 9) & 1) << 1) + (((data >> 9) & 1) << 1) +
@ -148,13 +150,10 @@ namespace MAME.Core
(((data >> 6) & 1) << 3) + (((data >> 6) & 1) << 3) +
(((data >> 14) & 1) << 4) + (((data >> 14) & 1) << 4) +
(((data >> 12) & 1) << 5); (((data >> 12) & 1) << 5);
bankaddress = 0x100000 + bankoffset[data]; bankaddress = 0x100000 + garou_bankswitch_w_bankoffset[data];
main_cpu_bank_address = bankaddress; main_cpu_bank_address = bankaddress;
} }
public static void garouh_bankswitch_w(int data) readonly static int[] garouh_bankswitch_w_bankoffset = new int[]
{
int bankaddress;
int[] bankoffset = new int[]
{ {
0x000000, 0x100000, 0x200000, 0x300000, // 00 0x000000, 0x100000, 0x200000, 0x300000, // 00
0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04 0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04
@ -173,6 +172,10 @@ namespace MAME.Core
0x000000, 0x000000, 0x000000, 0x000000, // 56 0x000000, 0x000000, 0x000000, 0x000000, // 56
0x000000, 0x000000, 0x000000, 0x000000 // 60 0x000000, 0x000000, 0x000000, 0x000000 // 60
}; };
public static void garouh_bankswitch_w(int data)
{
int bankaddress;
data = data =
(((data >> 4) & 1) << 0) + (((data >> 4) & 1) << 0) +
(((data >> 8) & 1) << 1) + (((data >> 8) & 1) << 1) +
@ -180,14 +183,11 @@ namespace MAME.Core
(((data >> 2) & 1) << 3) + (((data >> 2) & 1) << 3) +
(((data >> 11) & 1) << 4) + (((data >> 11) & 1) << 4) +
(((data >> 13) & 1) << 5); (((data >> 13) & 1) << 5);
bankaddress = 0x100000 + bankoffset[data]; bankaddress = 0x100000 + garouh_bankswitch_w_bankoffset[data];
main_cpu_bank_address = bankaddress; 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 0x000000, 0x020000, 0x040000, 0x060000, // 00
0x070000, 0x090000, 0x0b0000, 0x0d0000, // 04 0x070000, 0x090000, 0x0b0000, 0x0d0000, // 04
0x0e0000, 0x0f0000, 0x120000, 0x130000, // 08 0x0e0000, 0x0f0000, 0x120000, 0x130000, // 08
@ -201,7 +201,10 @@ namespace MAME.Core
0x400000, 0x410000, 0x440000, 0x450000, // 40 0x400000, 0x410000, 0x440000, 0x450000, // 40
0x460000, 0x470000, 0x4a0000, 0x4b0000, // 44 0x460000, 0x470000, 0x4a0000, 0x4b0000, // 44
0x4c0000 0x4c0000
}; };
public static void mslug3_bankswitch_w(int data)
{
int bankaddress;
data = data =
(((data >> 14) & 1) << 0) + (((data >> 14) & 1) << 0) +
(((data >> 12) & 1) << 1) + (((data >> 12) & 1) << 1) +
@ -209,13 +212,10 @@ namespace MAME.Core
(((data >> 6) & 1) << 3) + (((data >> 6) & 1) << 3) +
(((data >> 3) & 1) << 4) + (((data >> 3) & 1) << 4) +
(((data >> 9) & 1) << 5); (((data >> 9) & 1) << 5);
bankaddress = 0x100000 + bankoffset[data]; bankaddress = 0x100000 + mslug3_bankswitch_w_bankoffset[data];
main_cpu_bank_address = bankaddress; main_cpu_bank_address = bankaddress;
} }
public static void kof2000_bankswitch_w(int data) readonly static int[] kof2000_bankswitch_w_bankoffset = new int[]
{
int bankaddress;
int[] bankoffset = new int[]
{ {
0x000000, 0x100000, 0x200000, 0x300000, // 00 0x000000, 0x100000, 0x200000, 0x300000, // 00
0x3f7800, 0x4f7800, 0x3ff800, 0x4ff800, // 04 0x3f7800, 0x4f7800, 0x3ff800, 0x4ff800, // 04
@ -227,6 +227,10 @@ namespace MAME.Core
0x52d000, 0x62d000, 0x52e800, 0x62e800, // 28 0x52d000, 0x62d000, 0x52e800, 0x62e800, // 28
0x618000, 0x619000, 0x61a000, 0x61a800, // 32 0x618000, 0x619000, 0x61a000, 0x61a800, // 32
}; };
public static void kof2000_bankswitch_w(int data)
{
int bankaddress;
data = data =
(((data >> 15) & 1) << 0) + (((data >> 15) & 1) << 0) +
(((data >> 14) & 1) << 1) + (((data >> 14) & 1) << 1) +
@ -234,7 +238,7 @@ namespace MAME.Core
(((data >> 3) & 1) << 3) + (((data >> 3) & 1) << 3) +
(((data >> 10) & 1) << 4) + (((data >> 10) & 1) << 4) +
(((data >> 5) & 1) << 5); (((data >> 5) & 1) << 5);
bankaddress = 0x100000 + bankoffset[data]; bankaddress = 0x100000 + kof2000_bankswitch_w_bankoffset[data];
main_cpu_bank_address = bankaddress; main_cpu_bank_address = bankaddress;
} }
public static void pvc_prot1() public static void pvc_prot1()

View File

@ -8,7 +8,7 @@
public static byte kb_swap; public static byte kb_swap;
public static ushort olds_bs, kb_cmd3; public static ushort olds_bs, kb_cmd3;
public static byte[][] kb_source_data; 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[]{ 0, }, // Region 0, not used
new byte[]{ // Region 1, $13A886 new byte[]{ // Region 1, $13A886

View File

@ -11,7 +11,7 @@
public static byte port1_out, port2_out, port3_out, port4_out; 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 byte portA_in, portA_out, ddrA, portB_in, portB_out, ddrB;
public static int ic43_a, ic43_b; 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, 0x6c,
0x7f,0x5f,0x7f,0x6f,0x5f,0x77,0x5f,0x7f,0x5f,0x7f,0x5f,0x7f,0x5b,0x7f,0x5f,0x7f, 0x7f,0x5f,0x7f,0x6f,0x5f,0x77,0x5f,0x7f,0x5f,0x7f,0x5f,0x7f,0x5b,0x7f,0x5f,0x7f,
@ -295,10 +295,10 @@
} }
ic43_a = res; 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) public static void boblbobl_ic43_b_w(int offset, byte data)
{ {
int[] xor = new int[] { 4, 1, 8, 2 }; ic43_b = (data >> 4) ^ boblbobl_ic43_b_w_xor[offset];
ic43_b = (data >> 4) ^ xor[offset];
} }
public static byte boblbobl_ic43_b_r(int offset) public static byte boblbobl_ic43_b_r(int offset)
{ {

View File

@ -671,6 +671,9 @@ namespace MAME.Core
{ {
current_bank = (byte)(data & 7); 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) public static void opwolf_cchip_data_w(int offset, ushort data)
{ {
cchip_ram[(current_bank * 0x400) + offset] = (byte)(data & 0xff); 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 ? // Shouldn't we directly read the values from the ROM area ?
if (offset == 0x14) if (offset == 0x14)
{ {
int[] coin_table = new int[] { 0, 0 }; //int[] coin_table = new int[] { 0, 0 };
byte[] coin_offset = new byte[2]; //byte[] coin_offset = new byte[2];
int slot; int slot;
if ((opwolf_region == 1) || (opwolf_region == 2)) if ((opwolf_region == 1) || (opwolf_region == 2))
{ {
coin_table[0] = 0x03ffce; opwolf_cchip_data_w_coin_table[0] = 0x03ffce;
coin_table[1] = 0x03ffce; opwolf_cchip_data_w_coin_table[1] = 0x03ffce;
} }
if ((opwolf_region == 3) || (opwolf_region == 4)) if ((opwolf_region == 3) || (opwolf_region == 4))
{ {
coin_table[0] = 0x03ffde; opwolf_cchip_data_w_coin_table[0] = 0x03ffde;
coin_table[1] = 0x03ffee; opwolf_cchip_data_w_coin_table[1] = 0x03ffee;
} }
coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4))); opwolf_cchip_data_w_coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4)));
coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6))); opwolf_cchip_data_w_coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6)));
for (slot = 0; slot < 2; slot++) 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_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[(coin_table[slot] + coin_offset[slot] + 2) / 2 * 2] * 0x100 + Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 2) / 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) public static void opwolf_cchip_data_w2(int offset, byte data)
{ {
cchip_ram[(current_bank * 0x400) + offset] = (byte)(data & 0xff); 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 ? // Shouldn't we directly read the values from the ROM area ?
if (offset == 0x14) if (offset == 0x14)
{ {
int[] coin_table = new int[] { 0, 0 }; //int[] coin_table = new int[] { 0, 0 };
byte[] coin_offset = new byte[2]; //byte[] coin_offset = new byte[2];
int slot; int slot;
if ((opwolf_region == 1) || (opwolf_region == 2)) if ((opwolf_region == 1) || (opwolf_region == 2))
{ {
coin_table[0] = 0x03ffce; opwolf_cchip_data_w2_coin_table[0] = 0x03ffce;
coin_table[1] = 0x03ffce; opwolf_cchip_data_w2_coin_table[1] = 0x03ffce;
} }
if ((opwolf_region == 3) || (opwolf_region == 4)) if ((opwolf_region == 3) || (opwolf_region == 4))
{ {
coin_table[0] = 0x03ffde; opwolf_cchip_data_w2_coin_table[0] = 0x03ffde;
coin_table[1] = 0x03ffee; opwolf_cchip_data_w2_coin_table[1] = 0x03ffee;
} }
coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4))); opwolf_cchip_data_w2_coin_offset[0] = (byte)(12 - (4 * ((data & 0x30) >> 4)));
coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6))); opwolf_cchip_data_w2_coin_offset[1] = (byte)(12 - (4 * ((data & 0xc0) >> 6)));
for (slot = 0; slot < 2; slot++) 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_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[(coin_table[slot] + coin_offset[slot] + 2) / 2 * 2] * 0x100 + Memory.mainrom[(coin_table[slot] + coin_offset[slot] + 2) / 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);
} }
} }
} }

View File

@ -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() private int mix_3D()
{ {
int indx = 0, chan; int indx = 0, chan;
for (chan = 0; chan < 3; 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)); indx |= ((1 << (chan + 15)) | ((ay8910info.vol_enabled[chan] != 0) ? ay8910info.env_volume << (chan * 5) : 0));
} }
else 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]; return ay8910info.vol3d_table[indx];
@ -373,6 +396,104 @@ namespace MAME.Core
break; 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) public void ay8910_update(int offset, int length)
{ {
int chan, i, j; int chan, i, j;
@ -391,14 +512,16 @@ namespace MAME.Core
for (chan = 0; chan < 3; chan++) for (chan = 0; chan < 3; chan++)
{ {
ay8910info.count[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.output[chan] ^= 1;
ay8910info.count[chan] = 0; ; ay8910info.count[chan] = 0; ;
} }
} }
ay8910info.count_noise++; 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) if (((ay8910info.rng + 1) & 2) != 0)
{ {
@ -413,12 +536,23 @@ namespace MAME.Core
} }
for (chan = 0; chan < 3; chan++) 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) if (ay8910info.holding == 0)
{ {
ay8910info.count_env++; 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.count_env = 0;
ay8910info.env_step--; ay8910info.env_step--;
@ -449,21 +583,46 @@ namespace MAME.Core
{ {
for (chan = 0; chan < 3; 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)
{ {
int i1 = ay8910info.env_table[chan][ay8910info.vol_enabled[chan] != 0 ? ay8910info.env_volume : 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]; stream.streamoutput_Ptrs[chan][offset] = ay8910info.env_table[chan][ay8910info.vol_enabled[chan] != 0 ? ay8910info.env_volume : 0];
} }
else else
{ {
int i1 = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? TONE_VOLUME(chan) : 0]; int i1 = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ?
stream.streamoutput_Ptrs[chan][offset] = ay8910info.vol_table[chan][ay8910info.vol_enabled[chan] != 0 ? TONE_VOLUME(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 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++; offset++;
} }

View File

@ -287,7 +287,7 @@ namespace MAME.Core
6, 3, 0,-3,-6,-3, 0, 3, 6, 3, 0,-3,-6,-3, 0, 3,
7, 3, 0,-3,-7,-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 }, new byte[]{0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 },