public static Atime attotime_add_attoseconds(Atime _time1, long _attoseconds) { Atime result; /* if one of the items is attotime_never, return attotime_never */ if (_time1.seconds >= ATTOTIME_MAX_SECONDS) { return(ATTOTIME_NEVER); } /* add the seconds and attoseconds */ result.attoseconds = _time1.attoseconds + _attoseconds; result.seconds = _time1.seconds; /* normalize and return */ if (result.attoseconds >= ATTOSECONDS_PER_SECOND) { result.attoseconds -= ATTOSECONDS_PER_SECOND; result.seconds++; } /* overflow */ if (result.seconds >= ATTOTIME_MAX_SECONDS) { return(ATTOTIME_NEVER); } return(result); }
/*public static void scanline_update_callback() * { * int scanline = scanline_param; * video_screen_update_partial(scanline); * scanline++; * if (scanline > screenstate.visarea.max_y) * { * scanline = screenstate.visarea.min_y; * } * scanline_param=scanline; * Timer.timer_adjust_periodic(scanline_timer, video_screen_get_time_until_pos(scanline, 0), Attotime.ATTOTIME_NEVER); * }*/ public static void video_frame_update() { Mame.paused = false; Atime current_time = Timer.global_basetime; if (!Mame.paused) { finish_screen_updates(); } //Keyboard.Update(); //Inptport.frame_update_callback(); //UI.ui_update_and_render(); /*if(Machine.FORM.cheatform.lockState == ui.cheatForm.LockState.LOCK_FRAME) * { * Machine.FORM.cheatform.ApplyCheat(); * }*/ //GDIDraw(); if (effective_throttle()) { update_throttle(current_time); } recompute_speed(current_time); if (Mame.paused) { //Thread.Sleep(5); } else { video_eof_callback(); } }
private static void recompute_speed(Atime emutime) { long delta_emutime; if (speed_last_realtime == 0 || Mame.mame_is_paused()) { speed_last_realtime = Wintime.osd_ticks(); speed_last_emutime = emutime; } delta_emutime = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(emutime, speed_last_emutime)); if (delta_emutime > Attotime.ATTOSECONDS_PER_SECOND / 4) { long realtime = Wintime.osd_ticks(); long delta_realtime = realtime - speed_last_realtime; long tps = Wintime.ticks_per_second; speed_percent = (double)delta_emutime * (double)tps / ((double)delta_realtime * (double)Attotime.ATTOSECONDS_PER_SECOND); speed_last_realtime = realtime; speed_last_emutime = emutime; overall_valid_counter++; if (overall_valid_counter >= 4) { overall_real_ticks += delta_realtime; while (overall_real_ticks >= tps) { overall_real_ticks -= tps; overall_real_seconds++; } overall_emutime = Attotime.attotime_add_attoseconds(overall_emutime, delta_emutime); } } }
public irq(int i1, int i2, LineState s1, Atime t1) { cpunum = i1; line = i2; state = s1; time = t1; }
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); if (which.expire.attoseconds == 0x003be7e176706f58) { int i1 = 1; } which.period = period; timer_list_remove(which); timer_list_insert(which); if (lt.IndexOf(which) == 0) { if (Cpuexec.activecpu >= 0 && Cpuexec.activecpu < Cpuexec.ncpu) { Cpuexec.activecpu_abort_timeslice(Cpuexec.activecpu); } } }
public static void timer_list_insert(emu_timer timer1) { int i; int i1 = -1; if (timer1.func == "latch_callback") { int i2 = 1; } if (timer1.func == "cpunum_empty_event_queue") { foreach (emu_timer et in lt) { if (et.func == timer1.func && 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); } }
public irq(int _cpunum, int _line, LineState _state, int _vector, Atime _time) { cpunum = _cpunum; line = _line; state = _state; vector = _vector; time = _time; }
private static void adjust_display_position_interrupt_timer() { if ((display_counter + 1) != 0) { Atime period = Attotime.attotime_mul(new Atime(0, Attotime.ATTOSECONDS_PER_SECOND / 6000000), display_counter + 1); Timer.timer_adjust_periodic(display_position_interrupt_timer, period, Attotime.ATTOTIME_NEVER); } }
private static void TimerHandler_3812(int c, Atime period) { if (Attotime.attotime_compare(period, Attotime.ATTOTIME_ZERO) == 0) { Timer.timer_enable(timer[c], false); } else { Timer.timer_adjust_periodic(timer[c], period, Attotime.ATTOTIME_NEVER); } }
public static void cpu_boost_interleave(Atime timeslice_time, Atime boost_duration) { if (Attotime.attotime_compare(timeslice_time, perfect_interleave) < 0) { timeslice_time = perfect_interleave; } Timer.timer_adjust_periodic(interleave_boost_timer, timeslice_time, timeslice_time); if (!Timer.timer_enabled(interleave_boost_timer_end) || Attotime.attotime_compare(Timer.timer_timeleft(interleave_boost_timer_end), boost_duration) < 0) { Timer.timer_adjust_periodic(interleave_boost_timer_end, boost_duration, Attotime.ATTOTIME_NEVER); } }
private static void streams_updatePGM() { Atime curtime = Timer.global_basetime; bool second_tick = false; if (curtime.seconds != last_update_second) { second_tick = true; } ics2115stream.adjuststream(second_tick); mixerstream.adjuststream(second_tick); last_update_second = curtime.seconds; }
public static void streams_updateC() { Atime curtime = Timer.global_basetime; bool second_tick = false; if (curtime.seconds != last_update_second) { second_tick = true; } ym2151stream.adjuststream(second_tick); okistream.adjuststream(second_tick); mixerstream.adjuststream(second_tick); last_update_second = curtime.seconds; }
private static void update_throttle(Atime emutime) { long real_delta_attoseconds; long emu_delta_attoseconds; long real_is_ahead_attoseconds; long attoseconds_per_tick; long ticks_per_second; long target_ticks; long diff_ticks; ticks_per_second = Wintime.ticks_per_second; attoseconds_per_tick = Attotime.ATTOSECONDS_PER_SECOND / ticks_per_second; if (Mame.mame_is_paused()) { throttle_emutime = Attotime.attotime_sub_attoseconds(emutime, Attotime.ATTOSECONDS_PER_SECOND / PAUSED_REFRESH_RATE); throttle_realtime = throttle_emutime; } emu_delta_attoseconds = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(emutime, throttle_emutime)); if (emu_delta_attoseconds < 0 || emu_delta_attoseconds > Attotime.ATTOSECONDS_PER_SECOND / 10) { goto resync; } diff_ticks = Wintime.osd_ticks() - throttle_last_ticks; throttle_last_ticks += diff_ticks; if (diff_ticks >= ticks_per_second) { goto resync; } real_delta_attoseconds = diff_ticks * attoseconds_per_tick; throttle_emutime = emutime; throttle_realtime = Attotime.attotime_add_attoseconds(throttle_realtime, real_delta_attoseconds); throttle_history = (throttle_history << 1) | Convert.ToUInt32(emu_delta_attoseconds > real_delta_attoseconds); real_is_ahead_attoseconds = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(throttle_emutime, throttle_realtime)); if ((real_is_ahead_attoseconds < -Attotime.ATTOSECONDS_PER_SECOND / 10) || (real_is_ahead_attoseconds < 0 && popcount[throttle_history & 0xff] < 6)) { goto resync; } if (real_is_ahead_attoseconds < 0) { return; } target_ticks = throttle_last_ticks + real_is_ahead_attoseconds / attoseconds_per_tick; diff_ticks = throttle_until_ticks(target_ticks) - throttle_last_ticks; throttle_last_ticks += diff_ticks; throttle_realtime = Attotime.attotime_add_attoseconds(throttle_realtime, diff_ticks * attoseconds_per_tick); return; resync: throttle_realtime = throttle_emutime = emutime; }
private static void streams_updateM92() { Atime curtime = Timer.global_basetime; bool second_tick = false; if (curtime.seconds != last_update_second) { second_tick = true; } ym2151stream.adjuststream(second_tick); iremga20stream.adjuststream(second_tick); mixerstream.adjuststream(second_tick); last_update_second = curtime.seconds; }
private int time_to_sampindex(Atime time) { int sample = (int)(time.attoseconds / attoseconds_per_sample); if (time.seconds > Sound.last_update_second) { sample += sample_rate; } if (time.seconds < Sound.last_update_second) { sample -= sample_rate; } return(sample); }
private static void streams_updateIGS011() { Atime curtime = Timer.global_basetime; bool second_tick = false; if (curtime.seconds != last_update_second) { second_tick = true; } okistream.adjuststream(second_tick); ym3812stream.adjuststream(second_tick); mixerstream.adjuststream(second_tick); last_update_second = curtime.seconds; }
public static void timer_handler1(int count) { if (count == 0) { /* Reset FM Timer */ Timer.timer_enable(timer1, false); } else { /* Start FM Timer */ Atime period = Attotime.attotime_mul(new Atime(0, Attotime.ATTOSECONDS_PER_SECOND / 8000000), (uint)count); if (!Timer.timer_enable(timer1, true)) { Timer.timer_adjust_periodic(timer1, period, Attotime.ATTOTIME_NEVER); } } }
public static emu_timer timer_alloc_common(Action action, string func, bool temp) { Atime time = get_current_time(); emu_timer timer = new emu_timer(); 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 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(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.timer_callback_0, "timer_callback_0")); lt2.Add(new emu_timer2(30, YM2610.timer_callback_1, "timer_callback_1")); 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")); }
public static Atime attotime_div(Atime _time1, uint factor) { uint attolo, attohi, reshi, reslo, remainder; Atime result; ulong temp; /* if one of the items is attotime_never, return attotime_never */ if (_time1.seconds >= ATTOTIME_MAX_SECONDS) { return(new Atime(ATTOTIME_MAX_SECONDS, 0)); } /* ignore divide by zero */ if (factor == 0) { return(_time1); } /* split attoseconds into upper and lower halves which fit into 32 bits */ attohi = divu_64x32_rem((ulong)_time1.attoseconds, 1000000000, out attolo); /* divide the seconds and get the remainder */ result.seconds = (int)divu_64x32_rem((ulong)_time1.seconds, factor, out remainder); /* combine the upper half of attoseconds with the remainder and divide that */ temp = (ulong)attohi + mulu_32x32(remainder, 1000000000); reshi = divu_64x32_rem(temp, factor, out remainder); /* combine the lower half of attoseconds with the remainder and divide that */ temp = attolo + mulu_32x32(remainder, 1000000000); reslo = divu_64x32_rem(temp, factor, out remainder); /* round based on the remainder */ result.attoseconds = (long)reslo + (long)mulu_32x32(reshi, 1000000000); if (remainder >= factor / 2) { if (++result.attoseconds >= ATTOSECONDS_PER_SECOND) { result.attoseconds = 0; result.seconds++; } } return(result); }
public static long attotime_to_attoseconds(Atime _time) { if (_time.seconds == 0) { return(_time.attoseconds); } else if (_time.seconds == -1) { return(_time.attoseconds - Attotime.ATTOSECONDS_PER_SECOND); } else if (_time.seconds > 0) { return(Attotime.ATTOSECONDS_PER_SECOND); } else { return(-Attotime.ATTOSECONDS_PER_SECOND); } }
public static int attotime_compare(Atime _time1, Atime _time2) { if (_time1.seconds > _time2.seconds) { return(1); } if (_time1.seconds < _time2.seconds) { return(-1); } if (_time1.attoseconds > _time2.attoseconds) { return(1); } if (_time1.attoseconds < _time2.attoseconds) { return(-1); } return(0); }
private static void frame_update() { Atime curtime = Timer.get_current_time(); portdata.last_delta_nsec = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(curtime, portdata.last_frame_time)) / Attotime.ATTOSECONDS_PER_NANOSECOND; portdata.last_frame_time = curtime; if (Mame.playState != Mame.PlayState.PLAY_REPLAYRUNNING) { if (Mame.is_foreground) { loop_inputports_callback(); } /*int i1 = (int)(Video.screenstate.frame_number % 4); * if (i1 == 0) * { * CPS.short1 = unchecked((short)0xfffb); * } * else if (i1 == 1) * { * CPS.short1 = unchecked((short)0xffce); * } * else if (i1 == 2) * { * CPS.short1 = unchecked((short)0xfff7); * } * else if (i1 == 3) * { * CPS.short1 = unchecked((short)0xffcd); * }*/ } if (Mame.playState == Mame.PlayState.PLAY_RECORDRUNNING) { record_port_callback(); } else if (Mame.playState == Mame.PlayState.PLAY_REPLAYRUNNING) { replay_port_callback(); } }
private static void frame_update() { Atime curtime = Timer.get_current_time(); portdata.last_delta_nsec = Attotime.attotime_to_attoseconds(Attotime.attotime_sub(curtime, portdata.last_frame_time)) / Attotime.ATTOSECONDS_PER_NANOSECOND; portdata.last_frame_time = curtime; if (Mame.playState != Mame.PlayState.PLAY_REPLAYRUNNING) { if (Mame.is_foreground) { loop_inputports_callback(); } } if (Mame.playState == Mame.PlayState.PLAY_RECORDRUNNING) { record_port_callback(); } else if (Mame.playState == Mame.PlayState.PLAY_REPLAYRUNNING) { replay_port_callback(); } }
public static void watchdog_init() { watchdog_timer = Timer.timer_alloc_common(watchdog_callback, "watchdog_callback", false); switch (Machine.sBoard) { case "CPS-1": case "CPS-1(QSound)": case "CPS2": watchdog_time = Attotime.ATTOTIME_ZERO; break; case "Neo Geo": watchdog_time = new Atime(0, (long)128762e12); break; case "Namco System 1": case "IGS011": case "PGM": watchdog_time = Attotime.ATTOTIME_ZERO; break; } }
public static Atime attotime_sub_attoseconds(Atime _time1, long _attoseconds) { Atime result; /* if time1 is attotime_never, return attotime_never */ if (_time1.seconds >= ATTOTIME_MAX_SECONDS) { return(ATTOTIME_NEVER); } /* add the seconds and attoseconds */ result.attoseconds = _time1.attoseconds - _attoseconds; result.seconds = _time1.seconds; /* normalize and return */ if (result.attoseconds < 0) { result.attoseconds += ATTOSECONDS_PER_SECOND; result.seconds--; } return(result); }
public static Atime attotime_mul(Atime _time1, uint factor) { uint attolo, attohi, reslo, reshi; ulong temp; /* if one of the items is attotime_never, return attotime_never */ if (_time1.seconds >= ATTOTIME_MAX_SECONDS) { return(ATTOTIME_NEVER); } /* 0 times anything is zero */ if (factor == 0) { return(ATTOTIME_ZERO); } /* split attoseconds into upper and lower halves which fit into 32 bits */ attohi = divu_64x32_rem((ulong)_time1.attoseconds, 1000000000, out attolo); /* scale the lower half, then split into high/low parts */ temp = mulu_32x32(attolo, factor); temp = divu_64x32_rem(temp, 1000000000, out reslo); /* scale the upper half, then split into high/low parts */ temp += mulu_32x32(attohi, factor); temp = divu_64x32_rem(temp, 1000000000, out reshi); /* scale the seconds */ temp += mulu_32x32((uint)_time1.seconds, factor); if (temp >= 1000000000) { return(ATTOTIME_NEVER); } /* build the result */ return(new Atime((int)temp, (long)reslo + mul_32x32((int)reshi, 1000000000))); }
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)) { 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(timer); timer_list_insert(timer); } } } }
public static void compute_perfect_interleave() { long smallest = cpu[0].attoseconds_per_cycle; int cpunum; perfect_interleave = Attotime.ATTOTIME_ZERO; perfect_interleave.attoseconds = Attotime.ATTOSECONDS_PER_SECOND - 1; for (cpunum = 1; cpunum < ncpu; cpunum++) { if (cpu[cpunum].attoseconds_per_cycle < smallest) { perfect_interleave.attoseconds = smallest; smallest = cpu[cpunum].attoseconds_per_cycle; } else if (cpu[cpunum].attoseconds_per_cycle < perfect_interleave.attoseconds) { perfect_interleave.attoseconds = cpu[cpunum].attoseconds_per_cycle; } } if (perfect_interleave.attoseconds == Attotime.ATTOSECONDS_PER_SECOND - 1) { perfect_interleave.attoseconds = cpu[0].attoseconds_per_cycle; } }
private static void cpu_inittimers() { switch (Machine.sBoard) { case "CPS-1(QSound)": case "CPS2": timedint_period = new Atime(0, (long)(1e18 / 250)); timedint_timer = Timer.timer_alloc_common(Generic.irq_1_0_line_hold, "irq_1_0_line_hold", false); Timer.timer_adjust_periodic(timedint_timer, timedint_period, timedint_period); break; /*case "Neo Geo": * interleave_boost_timer = Timer.timer_alloc_common(null_callback, "boost_callback", false); * interleave_boost_timer_end = Timer.timer_alloc_common(end_interleave_boost, "end_interleave_boost", false); * break; * case "CPS1": * case "Namco System 1": * case "IGS011": * case "PGM": * case "M72": * case "M92": * break;*/ } }