forked from sin365/AxibugEmuOnline
进行一些内联优化,还有timer对象池优化
This commit is contained in:
parent
d2cc4fa05d
commit
200ee3830b
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<emu_timer> _readyToRelease = new Queue<emu_timer>();
|
||||
/// <summary>
|
||||
/// 线程安全队列(因为析构函数是额外线程来的)
|
||||
/// </summary>
|
||||
static Queue<emu_timer> _failedDeletions = new Queue<emu_timer>();
|
||||
static HashSet<emu_timer> _tempCheck = new HashSet<emu_timer>();
|
||||
static Queue<emu_timer> _timerPool = new Queue<emu_timer>();
|
||||
|
||||
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,表示创建时的引用
|
||||
|
||||
/// <summary>
|
||||
/// 增加引用计数
|
||||
/// </summary>
|
||||
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++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -205,14 +192,14 @@ namespace MAME.Core
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
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<emu_timer> 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<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)
|
||||
{
|
||||
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<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)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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())
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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++;
|
||||
}
|
||||
|
||||
@ -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 },
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user