AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/emu/EmuTimer.cs

1354 lines
59 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
public class EmuTimerLister
{
public emu_timer this[int index]
{
get { return timerlist[index]; }
set { timerlist[index] = value; } // 如果需要设置的话
}
public static void GetNewTimerLister(ref EmuTimerLister tlistObj)
{
//如果新旧值替换
if (tlistObj != null)
{
tlistObj.ReleaseLister();
ObjectPoolAuto.Release(tlistObj);
tlistObj = null;
}
tlistObj = ObjectPoolAuto.Acquire<EmuTimerLister>();
tlistObj.InitLister();
}
List<emu_timer> timerlist;
public List<emu_timer> GetSrcList()
{
return timerlist;
}
public int Count
{
get { return timerlist.Count; }
}
void InitLister()
{
ReleaseLister();
timerlist = ObjectPoolAuto.AcquireList<emu_timer>();
}
void ReleaseLister()
{
if (timerlist != null)
{
Clear();
ObjectPoolAuto.Release(timerlist);
timerlist = null;
}
}
public void Clear()
{
emu_timer.ClearList(ref timerlist);
}
public void Add(emu_timer timer)
{
emu_timer.AddList(ref timerlist, ref timer);
}
public void Remove(emu_timer timer)
{
emu_timer.RemoveToList(ref timerlist, ref timer);
}
public void Insert(int index, emu_timer timer)
{
emu_timer.InsertToList(ref timerlist, index, ref timer);
}
public int IndexOf(emu_timer timer)
{
return timerlist.IndexOf(timer);
}
}
public class EmuTimer
{
public static EmuTimerLister lt;
private static List<emu_timer2> lt2;
public static Atime global_basetime;
public static Atime global_basetime_obj;
private static bool callback_timer_modified;
private static emu_timer callback_timer;
private static Atime callback_timer_expire_time;
public delegate void timer_fired_func();
public static Action setvector;
/*public class emu_timer
{
public TIME_ACT action;
//public string func;
public bool enabled;
public bool temporary;
public Atime period;
public Atime start;
public Atime expire;
}*/
public static void instancingTimerList()
{
//lt = new List<emu_timer>();
EmuTimerLister.GetNewTimerLister(ref lt);
}
public class emu_timer
{
public TIME_ACT action;
public bool enabled;
public bool temporary;
public Atime period;
public Atime start;
public Atime expire;
internal void reset()
{
action = default;
enabled = default;
temporary = default;
period = default;
start = default;
expire = default;
_refCount = 0;
}
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 int outTimerAllCount = 0;
static int newTimerCount = 0;
public static emu_timer GetEmu_timerNoRef()
{
emu_timer obj;
if (!_failedDeletions.TryDequeue(out obj))
{
obj = new emu_timer();
newTimerCount++;
}
//这里引用计数为0直接放入带Ready里等待下一帧检测
obj.reset();
_readyToRelease.Enqueue(obj);
outTimerAllCount++;
return obj;
}
public static void CheckReadyRelaseBeforeFrameRun()
{
if (_readyToRelease.Count < 1)
return;
int checkcount = _readyToRelease.Count;
int beforpoolcount = _failedDeletions.Count;
int releaseCount = 0;
while(_readyToRelease.TryDequeue(out emu_timer ready))
{
if (_tempCheck.Contains(ready))
continue;
_tempCheck.Add(ready);
if (ready._refCount <= 0)
{
ready.ReturnToPool();
releaseCount++;
}
}
//UnityEngine.Debug.Log($"CheckReadyRelaseAfterRun 检查数量{checkcount}| 出池数量{outTimerAllCount}其中new创建的数量{newTimerCount} 回收数量{releaseCount} ,处理前池数量{beforpoolcount},处理后池数量{_failedDeletions.Count}");
outTimerAllCount = 0;
newTimerCount = 0;
_readyToRelease.Clear();
_tempCheck.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);
// //}
//}
}
/// <summary>
/// 减少引用计数当计数为0时释放对象回池
/// </summary>
void ReleaseRef()
{
int newCount = Interlocked.Decrement(ref _refCount);
if (newCount == 0)
{
//UnityEngine.Debug.Log("CheckReadyRelaseAfterRun ReleaseRef 预回收");
// 引用计数为0释放资源并回池
ReadyToRelease();
}
else if (newCount < 0)
{
// 引用计数异常,不应出现负数
throw new InvalidOperationException("引用计数出现负数");
}
}
void ReadyToRelease()
{
//UnityEngine.Debug.Log("ReadyToRelease");
_readyToRelease.Enqueue(this);
}
/// <summary>
/// 释放资源并回池
/// </summary>
void ReturnToPool()
{
_failedDeletions.Enqueue(this);
}
#region
public static void SetRefUsed(ref emu_timer refattr, ref emu_timer emu_timer)
{
if (refattr == emu_timer)
return;
if (emu_timer == null)
{
SetNull(ref refattr);
return;
}
if (refattr != null)
refattr.ReleaseRef();
refattr = emu_timer;
refattr.AddRef();
}
public static void SetNull(ref emu_timer timer)
{
if (timer != null)
{
timer.ReleaseRef();
timer = null;
}
}
public static void AddList(ref List<emu_timer> list, ref emu_timer timer)
{
list.Add(timer);
timer.AddRef();
}
internal static void InsertToList(ref List<emu_timer> list, int index, ref emu_timer timer)
{
list.Insert(index, timer);
timer.AddRef();
}
public static void RemoveToList(ref List<emu_timer> list, ref emu_timer timer)
{
list.Remove(timer);
timer.ReleaseRef();
}
internal static void ClearList(ref List<emu_timer> list)
{
for (int i = 0; i < list.Count; i++)
list[i].ReleaseRef();
list.Clear();
}
#endregion
/*
static void EnqueueObj(emu_timer obj)
{
_failedDeletions.Enqueue(obj);
}
~emu_timer()
{
//咱也没办法这样子来实现emu_timer的回收到对象池。只能这样实现MAME里面对于emu_timer持有引用比较混沌在确保没有引用计数时再安全回池。
//回池,引用计数+1使其不被回收。相当于打断CG回收
//原本没有析构函数时GC是直接回收有析构时则调用后下一次GC再回收但是这就有操作空间了。这里引用计数+1
//GC回收但是不回收请回对象池
//说人话,就是用析构驱动回池,而不破坏现有代码
EnqueueObj(this);
GC.ReRegisterForFinalize(this);//手动注册,否则析构函数再也不会回调
}*/
}
public class emu_timer2
{
public int index;
public TIME_ACT action;
public string func;
public emu_timer2(int i1, TIME_ACT ac1)
{
index = i1;
action = ac1;
//func = func1;
}
}
//public static Action getactionbyindex(int index)
public static TIME_ACT getactionbyindex(int index)
{
TIME_ACT action = TIME_ACT.NoneAct;
foreach (emu_timer2 timer in lt2)
{
if (timer.index == index)
{
action = timer.action;
if (index == 4)
{
action = TIME_ACT.Sound_sound_update;
}
else if (index == 32)
{
action = TIME_ACT.M6800_action_rx;
}
else if (index == 33)
{
action = TIME_ACT.M6800_action_tx;
}
else if (index == 39)
{
action = TIME_ACT.setvector;
}
else if (index == 42)
{
action = TIME_ACT.Cpuexec_vblank_interrupt2;
}
}
}
return action;
}
//{
// Action action = null;
// foreach (emu_timer2 timer in lt2)
// {
// if (timer.index == index)
// {
// action = timer.action;
// if (index == 4)
// {
// action = Sound.sound_update;
// }
// else if (index == 32)
// {
// action = M6800.action_rx;
// }
// else if (index == 33)
// {
// action = M6800.action_tx;
// }
// else if (index == 39)
// {
// action = setvector;
// }
// else if (index == 42)
// {
// action = Cpuexec.vblank_interrupt2;
// }
// }
// }
// return action;
//}
public static string getfuncbyindex(int index)
{
string func = "";
foreach (emu_timer2 timer in lt2)
{
if (timer.index == index)
{
func = timer.func;
break;
}
}
return func;
}
//public static int getindexbyfunc(string func)
//{
// int index = 0;
// foreach (emu_timer2 timer in lt2)
// {
// if (timer.func == func)
// {
// index = timer.index;
// break;
// }
// }
// return index;
//}
public static int getindexbyaction(TIME_ACT act)
{
int index = 0;
foreach (emu_timer2 timer in lt2)
{
if (timer.action == act)
{
index = timer.index;
break;
}
}
return index;
}
//public static void timer_init()
//{
// global_basetime = Attotime.ATTOTIME_ZERO;
// lt = new List<emu_timer>();
// lt2 = new List<emu_timer2>();
// lt2.Add(new emu_timer2(1, Video.vblank_begin_callback, "vblank_begin_callback"));
// lt2.Add(new emu_timer2(2, Mame.soft_reset, "soft_reset"));
// lt2.Add(new emu_timer2(3, Cpuint.cpunum_empty_event_queue, "cpunum_empty_event_queue"));
// lt2.Add(new emu_timer2(4, Sound.sound_update, "sound_update"));
// lt2.Add(new emu_timer2(5, Watchdog.watchdog_callback, "watchdog_callback"));
// lt2.Add(new emu_timer2(6, Generic.irq_1_0_line_hold, "irq_1_0_line_hold"));
// lt2.Add(new emu_timer2(7, Video.vblank_end_callback, "vblank_end_callback"));
// lt2.Add(new emu_timer2(10, YM2151.irqAon_callback, "irqAon_callback"));
// lt2.Add(new emu_timer2(11, YM2151.irqBon_callback, "irqBon_callback"));
// lt2.Add(new emu_timer2(12, YM2151.irqAoff_callback, "irqAoff_callback"));
// lt2.Add(new emu_timer2(13, YM2151.irqBoff_callback, "irqBoff_callback"));
// lt2.Add(new emu_timer2(14, YM2151.timer_callback_a, "timer_callback_a"));
// lt2.Add(new emu_timer2(15, YM2151.timer_callback_b, "timer_callback_b"));
// lt2.Add(new emu_timer2(16, Cpuexec.trigger_partial_frame_interrupt, "trigger_partial_frame_interrupt"));
// lt2.Add(new emu_timer2(17, Cpuexec.null_callback, "boost_callback"));
// lt2.Add(new emu_timer2(18, Cpuexec.end_interleave_boost, "end_interleave_boost"));
// lt2.Add(new emu_timer2(19, Video.scanline0_callback, "scanline0_callback"));
// lt2.Add(new emu_timer2(20, Sound.latch_callback, "latch_callback"));
// lt2.Add(new emu_timer2(21, Sound.latch_callback2, "latch_callback2"));
// lt2.Add(new emu_timer2(22, Sound.latch_callback3, "latch_callback3"));
// lt2.Add(new emu_timer2(23, Sound.latch_callback4, "latch_callback4"));
// lt2.Add(new emu_timer2(24, Neogeo.display_position_interrupt_callback, "display_position_interrupt_callback"));
// lt2.Add(new emu_timer2(25, Neogeo.display_position_vblank_callback, "display_position_vblank_callback"));
// lt2.Add(new emu_timer2(26, Neogeo.vblank_interrupt_callback, "vblank_interrupt_callback"));
// lt2.Add(new emu_timer2(27, Neogeo.auto_animation_timer_callback, "auto_animation_timer_callback"));
// lt2.Add(new emu_timer2(29, YM2610.F2610.timer_callback_0, "timer_callback_0"));
// lt2.Add(new emu_timer2(30, YM2610.F2610.timer_callback_1, "timer_callback_1"));
// lt2.Add(new emu_timer2(31, Neogeo.sprite_line_timer_callback, "sprite_line_timer_callback"));
// lt2.Add(new emu_timer2(32, M6800.action_rx, "m6800_rx_tick"));
// lt2.Add(new emu_timer2(33, M6800.action_tx, "m6800_tx_tick"));
// lt2.Add(new emu_timer2(34, YM3812.timer_callback_3812_0, "timer_callback_3812_0"));
// lt2.Add(new emu_timer2(35, YM3812.timer_callback_3812_1, "timer_callback_3812_1"));
// lt2.Add(new emu_timer2(36, ICS2115.timer_cb_0, "timer_cb_0"));
// lt2.Add(new emu_timer2(37, ICS2115.timer_cb_1, "timer_cb_1"));
// lt2.Add(new emu_timer2(38, M72.m72_scanline_interrupt, "m72_scanline_interrupt"));
// lt2.Add(new emu_timer2(39, setvector, "setvector_callback"));
// lt2.Add(new emu_timer2(40, M92.m92_scanline_interrupt, "m92_scanline_interrupt"));
// lt2.Add(new emu_timer2(41, Cpuexec.cpu_timeslicecallback, "cpu_timeslicecallback"));
// lt2.Add(new emu_timer2(42, Cpuexec.vblank_interrupt2, "vblank_interrupt2"));
// lt2.Add(new emu_timer2(43, Konami68000.nmi_callback, "nmi_callback"));
// lt2.Add(new emu_timer2(44, Upd7759.upd7759_slave_update, "upd7759_slave_update"));
// lt2.Add(new emu_timer2(45, Generic.irq_2_0_line_hold, "irq_2_0_line_hold"));
// lt2.Add(new emu_timer2(46, MSM5205.MSM5205_vclk_callback0, "msm5205_vclk_callback0"));
// lt2.Add(new emu_timer2(47, MSM5205.MSM5205_vclk_callback1, "msm5205_vclk_callback1"));
// lt2.Add(new emu_timer2(48, YM2203.timer_callback_2203_0_0, "timer_callback_2203_0_0"));
// lt2.Add(new emu_timer2(49, YM2203.timer_callback_2203_0_1, "timer_callback_2203_0_1"));
// lt2.Add(new emu_timer2(50, YM2203.timer_callback_2203_1_0, "timer_callback_2203_1_0"));
// lt2.Add(new emu_timer2(51, YM2203.timer_callback_2203_1_1, "timer_callback_2203_1_1"));
// lt2.Add(new emu_timer2(52, YM3812.timer_callback_3526_0, "timer_callback_3526_0"));
// lt2.Add(new emu_timer2(53, YM3812.timer_callback_3526_1, "timer_callback_3526_1"));
// lt2.Add(new emu_timer2(54, K054539.k054539_irq, "k054539_irq"));
// lt2.Add(new emu_timer2(55, Taito.cchip_timer, "cchip_timer"));
//}
public static void timer_init()
{
global_basetime = Attotime.ATTOTIME_ZERO;
//lt = new List<emu_timer>();
EmuTimerLister.GetNewTimerLister(ref lt);
lt2 = new List<emu_timer2>();
lt2.Add(new emu_timer2(1, TIME_ACT.Video_vblank_begin_callback));
lt2.Add(new emu_timer2(2, TIME_ACT.Mame_soft_reset));
lt2.Add(new emu_timer2(3, TIME_ACT.Cpuint_cpunum_empty_event_queue));
lt2.Add(new emu_timer2(4, TIME_ACT.Sound_sound_update));
lt2.Add(new emu_timer2(5, TIME_ACT.Watchdog_watchdog_callback));
lt2.Add(new emu_timer2(6, TIME_ACT.Generic_irq_1_0_line_hold));
lt2.Add(new emu_timer2(7, TIME_ACT.Video_vblank_end_callback));
lt2.Add(new emu_timer2(10, TIME_ACT.YM2151_irqAon_callback));
lt2.Add(new emu_timer2(11, TIME_ACT.YM2151_irqBon_callback));
lt2.Add(new emu_timer2(12, TIME_ACT.YM2151_irqAoff_callback));
lt2.Add(new emu_timer2(13, TIME_ACT.YM2151_irqBoff_callback));
lt2.Add(new emu_timer2(14, TIME_ACT.YM2151_timer_callback_a));
lt2.Add(new emu_timer2(15, TIME_ACT.YM2151_timer_callback_b));
lt2.Add(new emu_timer2(16, TIME_ACT.Cpuexec_trigger_partial_frame_interrupt));
lt2.Add(new emu_timer2(17, TIME_ACT.Cpuexec_null_callback));
lt2.Add(new emu_timer2(18, TIME_ACT.Cpuexec_end_interleave_boost));
lt2.Add(new emu_timer2(19, TIME_ACT.Video_scanline0_callback));
lt2.Add(new emu_timer2(20, TIME_ACT.Sound_latch_callback));
lt2.Add(new emu_timer2(21, TIME_ACT.Sound_latch_callback2));
lt2.Add(new emu_timer2(22, TIME_ACT.Sound_latch_callback3));
lt2.Add(new emu_timer2(23, TIME_ACT.Sound_latch_callback4));
lt2.Add(new emu_timer2(24, TIME_ACT.Neogeo_display_position_interrupt_callback));
lt2.Add(new emu_timer2(25, TIME_ACT.Neogeo_display_position_vblank_callback));
lt2.Add(new emu_timer2(26, TIME_ACT.Neogeo_vblank_interrupt_callback));
lt2.Add(new emu_timer2(27, TIME_ACT.Neogeo_auto_animation_timer_callback));
lt2.Add(new emu_timer2(29, TIME_ACT.YM2610_F2610_timer_callback_0));
lt2.Add(new emu_timer2(30, TIME_ACT.YM2610_F2610_timer_callback_1));
lt2.Add(new emu_timer2(31, TIME_ACT.Neogeo_sprite_line_timer_callback));
lt2.Add(new emu_timer2(32, TIME_ACT.M6800_action_rx));
lt2.Add(new emu_timer2(33, TIME_ACT.M6800_action_tx));
lt2.Add(new emu_timer2(34, TIME_ACT.YM3812_timer_callback_3812_0));
lt2.Add(new emu_timer2(35, TIME_ACT.YM3812_timer_callback_3812_1));
lt2.Add(new emu_timer2(36, TIME_ACT.ICS2115_timer_cb_0));
lt2.Add(new emu_timer2(37, TIME_ACT.ICS2115_timer_cb_1));
lt2.Add(new emu_timer2(38, TIME_ACT.M72_m72_scanline_interrupt));
lt2.Add(new emu_timer2(39, TIME_ACT.setvector));
lt2.Add(new emu_timer2(40, TIME_ACT.M92_m92_scanline_interrupt));
lt2.Add(new emu_timer2(41, TIME_ACT.Cpuexec_cpu_timeslicecallback));
lt2.Add(new emu_timer2(42, TIME_ACT.Cpuexec_vblank_interrupt2));
lt2.Add(new emu_timer2(43, TIME_ACT.Konami68000_nmi_callback));
lt2.Add(new emu_timer2(44, TIME_ACT.Upd7759_upd7759_slave_update));
lt2.Add(new emu_timer2(45, TIME_ACT.Generic_irq_2_0_line_hold));
lt2.Add(new emu_timer2(46, TIME_ACT.MSM5205_MSM5205_vclk_callback0));
lt2.Add(new emu_timer2(47, TIME_ACT.MSM5205_MSM5205_vclk_callback1));
lt2.Add(new emu_timer2(48, TIME_ACT.YM2203_timer_callback_2203_0_0));
lt2.Add(new emu_timer2(49, TIME_ACT.YM2203_timer_callback_2203_0_1));
lt2.Add(new emu_timer2(50, TIME_ACT.YM2203_timer_callback_2203_1_0));
lt2.Add(new emu_timer2(51, TIME_ACT.YM2203_timer_callback_2203_1_1));
lt2.Add(new emu_timer2(52, TIME_ACT.YM3812_timer_callback_3526_0));
lt2.Add(new emu_timer2(53, TIME_ACT.YM3812_timer_callback_3526_1));
lt2.Add(new emu_timer2(54, TIME_ACT.K054539_k054539_irq));
lt2.Add(new emu_timer2(55, TIME_ACT.Taito_cchip_timer));
}
#region
public enum TIME_ACT : byte
{
NoneAct = 0,
Video_vblank_begin_callback,
Mame_soft_reset,
Cpuint_cpunum_empty_event_queue,
Sound_sound_update,
Watchdog_watchdog_callback,
Generic_irq_1_0_line_hold,
Video_vblank_end_callback,
YM2151_irqAon_callback,
YM2151_irqBon_callback,
YM2151_irqAoff_callback,
YM2151_irqBoff_callback,
YM2151_timer_callback_a,
YM2151_timer_callback_b,
Cpuexec_trigger_partial_frame_interrupt,
Cpuexec_null_callback,
Cpuexec_end_interleave_boost,
Video_scanline0_callback,
Sound_latch_callback,
Sound_latch_callback2,
Sound_latch_callback3,
Sound_latch_callback4,
Neogeo_display_position_interrupt_callback,
Neogeo_display_position_vblank_callback,
Neogeo_vblank_interrupt_callback,
Neogeo_auto_animation_timer_callback,
YM2610_F2610_timer_callback_0,
YM2610_F2610_timer_callback_1,
Neogeo_sprite_line_timer_callback,
M6800_action_rx,
M6800_action_tx,
YM3812_timer_callback_3812_0,
YM3812_timer_callback_3812_1,
ICS2115_timer_cb_0,
ICS2115_timer_cb_1,
M72_m72_scanline_interrupt,
setvector,
M92_m92_scanline_interrupt,
Cpuexec_cpu_timeslicecallback,
Cpuexec_vblank_interrupt2,
Konami68000_nmi_callback,
Upd7759_upd7759_slave_update,
Generic_irq_2_0_line_hold,
MSM5205_MSM5205_vclk_callback0,
MSM5205_MSM5205_vclk_callback1,
YM2203_timer_callback_2203_0_0,
YM2203_timer_callback_2203_0_1,
YM2203_timer_callback_2203_1_0,
YM2203_timer_callback_2203_1_1,
YM3812_timer_callback_3526_0,
YM3812_timer_callback_3526_1,
K054539_k054539_irq,
Taito_cchip_timer,
Cpuexec_trigger2,
Taitob_rsaga2_interrupt2,
Taitob_crimec_interrupt3,
Taitob_hitice_interrupt6,
Taitob_rambo3_interrupt1,
Taitob_pbobble_interrupt5,
Taitob_viofight_interrupt1,
Taitob_masterw_interrupt4,
Taitob_silentd_interrupt4,
Taitob_selfeena_interrupt4,
Taitob_sbm_interrupt5,
Generic_clear_all_lines,
M92_spritebuffer_callback,
Taito_opwolf_timer_callback,
Taito_nmi_callback,
}
public static void DoAct(TIME_ACT act)
{
switch (act)
{
case TIME_ACT.Video_vblank_begin_callback: Video.vblank_begin_callback(); break;
case TIME_ACT.Mame_soft_reset: Mame.soft_reset(); break;
case TIME_ACT.Cpuint_cpunum_empty_event_queue: Cpuint.cpunum_empty_event_queue(); break;
case TIME_ACT.Sound_sound_update: Sound.sound_update(); break;
case TIME_ACT.Watchdog_watchdog_callback: Watchdog.watchdog_callback(); break;
case TIME_ACT.Generic_irq_1_0_line_hold: Generic.irq_1_0_line_hold(); break;
case TIME_ACT.Video_vblank_end_callback: Video.vblank_end_callback(); break;
case TIME_ACT.YM2151_irqAon_callback: YM2151.irqAon_callback(); break;
case TIME_ACT.YM2151_irqBon_callback: YM2151.irqBon_callback(); break;
case TIME_ACT.YM2151_irqAoff_callback: YM2151.irqAoff_callback(); break;
case TIME_ACT.YM2151_irqBoff_callback: YM2151.irqBoff_callback(); break;
case TIME_ACT.YM2151_timer_callback_a: YM2151.timer_callback_a(); break;
case TIME_ACT.YM2151_timer_callback_b: YM2151.timer_callback_b(); break;
case TIME_ACT.Cpuexec_trigger_partial_frame_interrupt: Cpuexec.trigger_partial_frame_interrupt(); break;
case TIME_ACT.Cpuexec_null_callback: Cpuexec.null_callback(); break;
case TIME_ACT.Cpuexec_end_interleave_boost: Cpuexec.end_interleave_boost(); break;
case TIME_ACT.Video_scanline0_callback: Video.scanline0_callback(); break;
case TIME_ACT.Sound_latch_callback: Sound.latch_callback(); break;
case TIME_ACT.Sound_latch_callback2: Sound.latch_callback2(); break;
case TIME_ACT.Sound_latch_callback3: Sound.latch_callback3(); break;
case TIME_ACT.Sound_latch_callback4: Sound.latch_callback4(); break;
case TIME_ACT.Neogeo_display_position_interrupt_callback: Neogeo.display_position_interrupt_callback(); break;
case TIME_ACT.Neogeo_display_position_vblank_callback: Neogeo.display_position_vblank_callback(); break;
case TIME_ACT.Neogeo_vblank_interrupt_callback: Neogeo.vblank_interrupt_callback(); break;
case TIME_ACT.Neogeo_auto_animation_timer_callback: Neogeo.auto_animation_timer_callback(); break;
case TIME_ACT.YM2610_F2610_timer_callback_0: YM2610.F2610.timer_callback_0(); break;
case TIME_ACT.YM2610_F2610_timer_callback_1: YM2610.F2610.timer_callback_1(); break;
case TIME_ACT.Neogeo_sprite_line_timer_callback: Neogeo.sprite_line_timer_callback(); break;
case TIME_ACT.M6800_action_rx: M6800.action_rx(); break;
case TIME_ACT.M6800_action_tx: M6800.action_tx(); break;
case TIME_ACT.YM3812_timer_callback_3812_0: YM3812.timer_callback_3812_0(); break;
case TIME_ACT.YM3812_timer_callback_3812_1: YM3812.timer_callback_3812_1(); break;
case TIME_ACT.ICS2115_timer_cb_0: ICS2115.timer_cb_0(); break;
case TIME_ACT.ICS2115_timer_cb_1: ICS2115.timer_cb_1(); break;
case TIME_ACT.M72_m72_scanline_interrupt: M72.m72_scanline_interrupt(); break;
case TIME_ACT.setvector: setvector(); break;
case TIME_ACT.M92_m92_scanline_interrupt: M92.m92_scanline_interrupt(); break;
case TIME_ACT.Cpuexec_cpu_timeslicecallback: Cpuexec.cpu_timeslicecallback(); break;
case TIME_ACT.Cpuexec_vblank_interrupt2: Cpuexec.vblank_interrupt2(); break;
case TIME_ACT.Konami68000_nmi_callback: Konami68000.nmi_callback(); break;
case TIME_ACT.Upd7759_upd7759_slave_update: Upd7759.upd7759_slave_update(); break;
case TIME_ACT.Generic_irq_2_0_line_hold: Generic.irq_2_0_line_hold(); break;
case TIME_ACT.MSM5205_MSM5205_vclk_callback0: MSM5205.MSM5205_vclk_callback0(); break;
case TIME_ACT.MSM5205_MSM5205_vclk_callback1: MSM5205.MSM5205_vclk_callback1(); break;
case TIME_ACT.YM2203_timer_callback_2203_0_0: YM2203.timer_callback_2203_0_0(); break;
case TIME_ACT.YM2203_timer_callback_2203_0_1: YM2203.timer_callback_2203_0_1(); break;
case TIME_ACT.YM2203_timer_callback_2203_1_0: YM2203.timer_callback_2203_1_0(); break;
case TIME_ACT.YM2203_timer_callback_2203_1_1: YM2203.timer_callback_2203_1_1(); break;
case TIME_ACT.YM3812_timer_callback_3526_0: YM3812.timer_callback_3526_0(); break;
case TIME_ACT.YM3812_timer_callback_3526_1: YM3812.timer_callback_3526_1(); break;
case TIME_ACT.K054539_k054539_irq: K054539.k054539_irq(); break;
case TIME_ACT.Taito_cchip_timer: Taito.cchip_timer(); break;
case TIME_ACT.Cpuexec_trigger2: Cpuexec.trigger2(); break;
case TIME_ACT.Taitob_rsaga2_interrupt2: Taitob.rsaga2_interrupt2(); break;
case TIME_ACT.Taitob_crimec_interrupt3: Taitob.crimec_interrupt3(); break;
case TIME_ACT.Taitob_hitice_interrupt6: Taitob.hitice_interrupt6(); break;
case TIME_ACT.Taitob_rambo3_interrupt1: Taitob.rambo3_interrupt1(); break;
case TIME_ACT.Taitob_pbobble_interrupt5: Taitob.pbobble_interrupt5(); break;
case TIME_ACT.Taitob_viofight_interrupt1: Taitob.viofight_interrupt1(); break;
case TIME_ACT.Taitob_masterw_interrupt4: Taitob.masterw_interrupt4(); break;
case TIME_ACT.Taitob_silentd_interrupt4: Taitob.silentd_interrupt4(); break;
case TIME_ACT.Taitob_selfeena_interrupt4: Taitob.selfeena_interrupt4(); break;
case TIME_ACT.Taitob_sbm_interrupt5: Taitob.sbm_interrupt5(); break;
case TIME_ACT.Generic_clear_all_lines: Generic.clear_all_lines(); break;
case TIME_ACT.M92_spritebuffer_callback: M92.spritebuffer_callback(); break;//!!
case TIME_ACT.Taito_opwolf_timer_callback: Taito.opwolf_timer_callback(); break;
case TIME_ACT.Taito_nmi_callback: Taito.nmi_callback(); break;
}
}
#endregion
public static Atime get_current_time()
{
if (callback_timer != null)
{
return callback_timer_expire_time;
}
if (Cpuexec.activecpu >= 0 && Cpuexec.activecpu < Cpuexec.ncpu)
{
return Cpuexec.cpunum_get_localtime(Cpuexec.activecpu);
}
return global_basetime;
}
/*public static void timer_remove(emu_timer timer1)
{
if (timer1 == callback_timer)
{
callback_timer_modified = true;
}
timer_list_remove(timer1);
}*/
public static void timer_adjust_periodic(emu_timer which, Atime start_delay, Atime period)
{
Atime time = get_current_time();
if (which == callback_timer)
{
callback_timer_modified = true;
}
which.enabled = true;
if (start_delay.seconds < 0)
{
start_delay = Attotime.ATTOTIME_ZERO;
}
which.start = time;
which.expire = Attotime.attotime_add(time, start_delay);
which.period = period;
timer_list_remove_and_insert(which);
//timer_list_remove(which);
//timer_list_insert(which);
//if (lt.IndexOf(which) == 0)
if (lt[0] == which)
{
if (Cpuexec.activecpu >= 0 && Cpuexec.activecpu < Cpuexec.ncpu)
{
Cpuexec.activecpu_abort_timeslice(Cpuexec.activecpu);
}
}
}
public static void timer_pulse_internal(Atime period, TIME_ACT action)
{
//emu_timer timer = timer_alloc_common(action, false);
emu_timer timer = timer_alloc_common_NoRef(action, false);
timer_adjust_periodic(timer, period, period);
}
public static void timer_set_internal(TIME_ACT action)
{
//emu_timer timer = timer_alloc_common(action, true);
emu_timer timer = timer_alloc_common_NoRef(action, true);
timer_adjust_periodic(timer, Attotime.ATTOTIME_ZERO, Attotime.ATTOTIME_NEVER);
}
static void timer_list_remove_and_insert(emu_timer timer)
{
//包一层引用避免引用计数中间丢失,进等待检测队列(减少这样的情况)
{
emu_timer tempref = null;
emu_timer.SetRefUsed(ref tempref, ref timer);
timer_list_remove(timer);
timer_list_insert(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 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 sort()
{
int i1, i2, n1;
Atime expire1, expire2;
n1 = lt.Count;
for (i2 = 1; i2 < n1; i2++)
{
for (i1 = 0; i1 < i2; i1++)
{
if (lt[i1].enabled ==true)
{
expire1 = lt[i1].expire;
}
else
{
expire1 = Attotime.ATTOTIME_NEVER;
}
if (lt[i2].enabled == true)
{
expire2 = lt[i2].expire;
}
else
{
expire2 = Attotime.ATTOTIME_NEVER;
}
if (Attotime.attotime_compare(expire1, expire2) > 0)
{
var temp = lt[i1];
lt[i1] = lt[i2];
lt[i2] = temp;
}
}
}
}*/
public static void timer_set_global_time(Atime newbase)
{
emu_timer timer;
global_basetime = newbase;
while (Attotime.attotime_compare(lt[0].expire, global_basetime) <= 0)
{
bool was_enabled = lt[0].enabled;
timer = lt[0];
if (Attotime.attotime_compare(timer.period, Attotime.ATTOTIME_ZERO) == 0 || Attotime.attotime_compare(timer.period, Attotime.ATTOTIME_NEVER) == 0)
{
timer.enabled = false;
}
callback_timer_modified = false;
callback_timer = timer;
callback_timer_expire_time = timer.expire;
//if (was_enabled && (timer.action != null && timer.action != Cpuexec.null_callback))
if (was_enabled && (timer.action != TIME_ACT.NoneAct && timer.action != TIME_ACT.Cpuexec_null_callback))
{
//timer.action();
DoAct(timer.action);
}
callback_timer = null;
if (callback_timer_modified == false)
{
if (timer.temporary)
{
timer_list_remove(timer);
}
else
{
timer.start = timer.expire;
timer.expire = Attotime.attotime_add(timer.expire, timer.period);
timer_list_remove_and_insert(timer);
//timer_list_remove(timer);
//timer_list_insert(timer);
}
}
}
}
//public static emu_timer timer_alloc_common(TIME_ACT action, bool temp)
//{
// Atime time = get_current_time();
// //emu_timer timer = new emu_timer();
// emu_timer timer = emu_timer.GetEmu_timerNoRef();
// timer.action = action;
// timer.enabled = false;
// timer.temporary = temp;
// timer.period = Attotime.ATTOTIME_ZERO;
// //timer.func = func;
// timer.start = time;
// timer.expire = Attotime.ATTOTIME_NEVER;
// timer_list_insert(timer);
// return timer;
//}
/// <summary>
/// 申请新的timer且直接操作引用计数
/// </summary>
/// <param name="refattr"></param>
/// <param name="action"></param>
/// <param name="temp"></param>
public static void timer_alloc_common(ref emu_timer refattr, TIME_ACT action, bool temp)
{
//Atime time = get_current_time();
//emu_timer timer = emu_timer.GetEmu_timerNoRef();
//timer.action = action;
//timer.enabled = false;
//timer.temporary = temp;
//timer.period = Attotime.ATTOTIME_ZERO;
////timer.func = func;
//timer.start = time;
//timer.expire = Attotime.ATTOTIME_NEVER;
//timer_list_insert(timer);
emu_timer timer = timer_alloc_common_NoRef(action, temp);
emu_timer.SetRefUsed(ref refattr, ref timer);
}
/// <summary>
/// 申请新的timer不操作额外引用计数用于外部中间传递
/// </summary>
/// <param name="action"></param>
/// <param name="temp"></param>
/// <returns></returns>
public static emu_timer timer_alloc_common_NoRef(TIME_ACT action, bool temp)
{
Atime time = get_current_time();
//创建一个timer
emu_timer timer = emu_timer.GetEmu_timerNoRef();
timer.action = action;
timer.enabled = false;
timer.temporary = temp;
timer.period = Attotime.ATTOTIME_ZERO;
//timer.func = func;
timer.start = time;
timer.expire = Attotime.ATTOTIME_NEVER;
timer_list_insert(timer);
return timer;
}
public static bool timer_enable(emu_timer which, bool enable)
{
bool old;
old = which.enabled;
which.enabled = enable;
timer_list_remove_and_insert(which);
//timer_list_remove(which);
//timer_list_insert(which);
return old;
}
public static bool timer_enabled(emu_timer which)
{
return which.enabled;
}
public static Atime timer_timeleft(emu_timer which)
{
return Attotime.attotime_sub(which.expire, get_current_time());
}
public static void SaveStateBinary(System.IO.BinaryWriter writer)
{
int i, i1, n;
n = lt.Count;
writer.Write(n);
for (i = 0; i < n; i++)
{
i1 = getindexbyaction(lt[i].action);
writer.Write(i1);
writer.Write(lt[i].enabled);
writer.Write(lt[i].temporary);
writer.Write(lt[i].period.seconds);
writer.Write(lt[i].period.attoseconds);
writer.Write(lt[i].start.seconds);
writer.Write(lt[i].start.attoseconds);
writer.Write(lt[i].expire.seconds);
writer.Write(lt[i].expire.attoseconds);
}
for (i = n; i < 32; i++)
{
writer.Write(0);
writer.Write(false);
writer.Write(false);
writer.Write(0);
writer.Write((long)0);
writer.Write(0);
writer.Write((long)0);
writer.Write(0);
writer.Write((long)0);
}
}
public static void LoadStateBinary(System.IO.BinaryReader reader)
{
int i, i1, n;
n = reader.ReadInt32();
//lt = new List<emu_timer>();
EmuTimerLister.GetNewTimerLister(ref lt);
for (i = 0; i < n; i++)
{
emu_timer etimer = emu_timer.GetEmu_timerNoRef();
#region
lt.Add(etimer);
i1 = reader.ReadInt32();
etimer.action = getactionbyindex(i1);
//etimer.func = getfuncbyindex(i1);
etimer.enabled = reader.ReadBoolean();
etimer.temporary = reader.ReadBoolean();
etimer.period.seconds = reader.ReadInt32();
etimer.period.attoseconds = reader.ReadInt64();
etimer.start.seconds = reader.ReadInt32();
etimer.start.attoseconds = reader.ReadInt64();
etimer.expire.seconds = reader.ReadInt32();
etimer.expire.attoseconds = reader.ReadInt64();
//if (etimer.func == "vblank_begin_callback")
if (etimer.action == TIME_ACT.Video_vblank_begin_callback)
{
emu_timer.SetRefUsed(ref Video.vblank_begin_timer, ref etimer);//Video.vblank_begin_timer = etimer;
lt.Remove(etimer);
lt.Add(Video.vblank_begin_timer);
}
else if (etimer.action == TIME_ACT.Video_vblank_end_callback)
{
//Video.vblank_end_timer = etimer;
emu_timer.SetRefUsed(ref Video.vblank_end_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Video.vblank_end_timer);
}
else if (etimer.action == TIME_ACT.Mame_soft_reset)
{
//Mame.soft_reset_timer = etimer;
emu_timer.SetRefUsed(ref Mame.soft_reset_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Mame.soft_reset_timer);
}
else if (etimer.action == TIME_ACT.Watchdog_watchdog_callback)
{
//Watchdog.watchdog_timer = etimer;
emu_timer.SetRefUsed(ref Watchdog.watchdog_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Watchdog.watchdog_timer);
}
else if (etimer.action == TIME_ACT.Generic_irq_1_0_line_hold)
{
//Cpuexec.timedint_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.timedint_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.timedint_timer);
}
else if (etimer.action == TIME_ACT.YM2151_timer_callback_a)
{
//YM2151.PSG.timer_A = etimer;
emu_timer.SetRefUsed(ref YM2151.PSG.timer_A, ref etimer);
lt.Remove(etimer);
lt.Add(YM2151.PSG.timer_A);
}
else if (etimer.action == TIME_ACT.YM2151_timer_callback_b)
{
//YM2151.PSG.timer_B = etimer;
emu_timer.SetRefUsed(ref YM2151.PSG.timer_B, ref etimer);
lt.Remove(etimer);
lt.Add(YM2151.PSG.timer_B);
}
else if (etimer.action == TIME_ACT.Cpuexec_trigger_partial_frame_interrupt)
{
switch (Machine.sBoard)
{
case "CPS2":
case "IGS011":
case "Konami68000":
//Cpuexec.cpu[0].partial_frame_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.cpu[0].partial_frame_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.cpu[0].partial_frame_timer);
break;
case "M72":
//Cpuexec.cpu[1].partial_frame_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.cpu[1].partial_frame_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.cpu[1].partial_frame_timer);
break;
case "Capcom":
switch (Machine.sName)
{
case "gng":
case "gnga":
case "gngbl":
case "gngprot":
case "gngblita":
case "gngc":
case "gngt":
case "makaimur":
case "makaimurc":
case "makaimurg":
case "diamond":
//Cpuexec.cpu[1].partial_frame_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.cpu[1].partial_frame_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.cpu[1].partial_frame_timer);
break;
}
break;
}
}
else if (etimer.action == TIME_ACT.Cpuexec_null_callback)
{
//Cpuexec.interleave_boost_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.interleave_boost_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.interleave_boost_timer);
}
else if (etimer.action == TIME_ACT.Cpuexec_end_interleave_boost)
{
//Cpuexec.interleave_boost_timer_end = etimer;
emu_timer.SetRefUsed(ref Cpuexec.interleave_boost_timer_end, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.interleave_boost_timer_end);
}
else if (etimer.action == TIME_ACT.Video_scanline0_callback)
{
//Video.scanline0_timer = etimer;
emu_timer.SetRefUsed(ref Video.scanline0_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Video.scanline0_timer);
}
else if (etimer.action == TIME_ACT.Neogeo_display_position_interrupt_callback)
{
//Neogeo.display_position_interrupt_timer = etimer;
emu_timer.SetRefUsed(ref Neogeo.display_position_interrupt_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Neogeo.display_position_interrupt_timer);
}
else if (etimer.action == TIME_ACT.Neogeo_display_position_vblank_callback)
{
//Neogeo.display_position_vblank_timer = etimer;
emu_timer.SetRefUsed(ref Neogeo.display_position_vblank_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Neogeo.display_position_vblank_timer);
}
else if (etimer.action == TIME_ACT.Neogeo_vblank_interrupt_callback)
{
//Neogeo.vblank_interrupt_timer = etimer;
emu_timer.SetRefUsed(ref Neogeo.vblank_interrupt_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Neogeo.vblank_interrupt_timer);
}
else if (etimer.action == TIME_ACT.Neogeo_auto_animation_timer_callback)
{
//Neogeo.auto_animation_timer = etimer;
emu_timer.SetRefUsed(ref Neogeo.auto_animation_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Neogeo.auto_animation_timer);
}
else if (etimer.action == TIME_ACT.Neogeo_sprite_line_timer_callback)
{
//Neogeo.sprite_line_timer = etimer;
emu_timer.SetRefUsed(ref Neogeo.sprite_line_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Neogeo.sprite_line_timer);
}
else if (etimer.action == TIME_ACT.YM2610_F2610_timer_callback_0)
{
//YM2610.timer[0] = etimer;
emu_timer.SetRefUsed(ref YM2610.timer[0], ref etimer);
lt.Remove(etimer);
lt.Add(YM2610.timer[0]);
}
else if (etimer.action == TIME_ACT.YM2610_F2610_timer_callback_1)
{
//YM2610.timer[1] = etimer;
emu_timer.SetRefUsed(ref YM2610.timer[1], ref etimer);
lt.Remove(etimer);
lt.Add(YM2610.timer[1]);
}
else if (etimer.action == TIME_ACT.M6800_action_rx)
{
//M6800.m1.m6800_rx_timer = etimer;
emu_timer.SetRefUsed(ref M6800.m1.m6800_rx_timer, ref etimer);
lt.Remove(etimer);
lt.Add(M6800.m1.m6800_rx_timer);
}
else if (etimer.action == TIME_ACT.M6800_action_tx)
{
//M6800.m1.m6800_tx_timer = etimer;
emu_timer.SetRefUsed(ref M6800.m1.m6800_tx_timer, ref etimer);
lt.Remove(etimer);
lt.Add(M6800.m1.m6800_tx_timer);
}
else if (etimer.action == TIME_ACT.YM3812_timer_callback_3812_0)
{
//YM3812.timer[0] = etimer;
emu_timer.SetRefUsed(ref YM3812.timer[0], ref etimer);
lt.Remove(etimer);
lt.Add(YM3812.timer[0]);
}
else if (etimer.action == TIME_ACT.YM3812_timer_callback_3812_1)
{
//YM3812.timer[1] = etimer;
emu_timer.SetRefUsed(ref YM3812.timer[1], ref etimer);
lt.Remove(etimer);
lt.Add(YM3812.timer[1]);
}
else if (etimer.action == TIME_ACT.ICS2115_timer_cb_0)
{
//ICS2115.timer[0].timer = etimer;
emu_timer.SetRefUsed(ref ICS2115.timer[0].timer, ref etimer);
lt.Remove(etimer);
lt.Add(ICS2115.timer[0].timer);
}
else if (etimer.action == TIME_ACT.ICS2115_timer_cb_1)
{
//ICS2115.timer[1].timer = etimer;
emu_timer.SetRefUsed(ref ICS2115.timer[1].timer, ref etimer);
lt.Remove(etimer);
lt.Add(ICS2115.timer[1].timer);
}
else if (etimer.action == TIME_ACT.M72_m72_scanline_interrupt)
{
//M72.scanline_timer = etimer;
emu_timer.SetRefUsed(ref M72.scanline_timer, ref etimer);
lt.Remove(etimer);
lt.Add(M72.scanline_timer);
}
else if (etimer.action == TIME_ACT.M92_m92_scanline_interrupt)
{
//M92.scanline_timer = etimer;
emu_timer.SetRefUsed(ref M72.scanline_timer, ref etimer);
lt.Remove(etimer);
lt.Add(M92.scanline_timer);
}
else if (etimer.action == TIME_ACT.Cpuexec_cpu_timeslicecallback)
{
//Cpuexec.timeslice_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.timeslice_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.timeslice_timer);
}
else if (etimer.action == TIME_ACT.Upd7759_upd7759_slave_update)
{
//Upd7759.chip.timer = etimer;
emu_timer.SetRefUsed(ref Upd7759.chip.timer, ref etimer);
lt.Remove(etimer);
lt.Add(Upd7759.chip.timer);
}
else if (etimer.action == TIME_ACT.Generic_irq_2_0_line_hold)
{
//Cpuexec.timedint_timer = etimer;
emu_timer.SetRefUsed(ref Cpuexec.timedint_timer, ref etimer);
lt.Remove(etimer);
lt.Add(Cpuexec.timedint_timer);
}
else if (etimer.action == TIME_ACT.MSM5205_MSM5205_vclk_callback0)
{
//MSM5205.timer[0] = etimer;
emu_timer.SetRefUsed(ref MSM5205.timer[0], ref etimer);
lt.Remove(etimer);
lt.Add(MSM5205.timer[0]);
}
else if (etimer.action == TIME_ACT.MSM5205_MSM5205_vclk_callback1)
{
//MSM5205.timer[1] = etimer;
emu_timer.SetRefUsed(ref MSM5205.timer[1], ref etimer);
lt.Remove(etimer);
lt.Add(MSM5205.timer[1]);
}
else if (etimer.action == TIME_ACT.YM2203_timer_callback_2203_0_0)
{
//YM2203.FF2203[0].timer[0] = etimer;
emu_timer.SetRefUsed(ref YM2203.FF2203[0].timer[0], ref etimer);
lt.Remove(etimer);
lt.Add(YM2203.FF2203[0].timer[0]);
}
else if (etimer.action == TIME_ACT.YM2203_timer_callback_2203_0_1)
{
//YM2203.FF2203[0].timer[1] = etimer;
emu_timer.SetRefUsed(ref YM2203.FF2203[0].timer[1], ref etimer);
lt.Remove(etimer);
lt.Add(YM2203.FF2203[0].timer[1]);
}
else if (etimer.action == TIME_ACT.YM2203_timer_callback_2203_1_0)
{
//YM2203.FF2203[1].timer[0] = etimer;
emu_timer.SetRefUsed(ref YM2203.FF2203[1].timer[0], ref etimer);
lt.Remove(etimer);
lt.Add(YM2203.FF2203[1].timer[0]);
}
else if (etimer.action == TIME_ACT.YM2203_timer_callback_2203_1_1)
{
//YM2203.FF2203[1].timer[1] = etimer;
emu_timer.SetRefUsed(ref YM2203.FF2203[1].timer[1], ref etimer);
lt.Remove(etimer);
lt.Add(YM2203.FF2203[1].timer[1]);
}
else if (etimer.action == TIME_ACT.YM3812_timer_callback_3526_0)
{
//YM3812.timer[0] = etimer;
emu_timer.SetRefUsed(ref YM3812.timer[0], ref etimer);
lt.Remove(etimer);
lt.Add(YM3812.timer[0]);
}
else if (etimer.action == TIME_ACT.YM3812_timer_callback_3526_1)
{
//YM3812.timer[1] = etimer;
emu_timer.SetRefUsed(ref YM3812.timer[1], ref etimer);
lt.Remove(etimer);
lt.Add(YM3812.timer[1]);
}
#endregion
}
for (i = n; i < 32; i++)
{
reader.ReadInt32();
reader.ReadBoolean();
reader.ReadBoolean();
reader.ReadInt32();
reader.ReadInt64();
reader.ReadInt32();
reader.ReadInt64();
reader.ReadInt32();
reader.ReadInt64();
}
}
}
}