Skip to content

Potential emu_timer::enable issues/cleanup #10071

@MooglyGuy

Description

@MooglyGuy

The behavior of emu_timer::enable is to unschedule the timer if called with false, and to re-schedule the timer if called with true, albeit with the originally-set expiration time. This means, for example, if the following sequence occurs:

  • adjust(attotime::from_seconds(1));
  • enable(false);
  • 5 seconds elapse
  • enable(true);
    The timer will fire instantly, rather than 1 second after the timer is re-enabled.

The following drivers and devices all make calls to emu_timer::enable with a value of either true or 1, and are grouped based on observed behavior:

Unnecessary calls to enable(true) due to an immediately preceding (or following) call to adjust or reset, or due to the timer never being disabled in the first place:

  • src/devices/bus/ata/atahle.cpp
  • src/devices/bus/ss50/mp4.cpp
  • src/devices/bus/ti99/joyport/handset.cpp
  • src/devices/bus/ti99/joyport/mecmouse.cpp
  • src/devices/machine/corvushd.cpp
  • src/mame/bitcorp/gamate.cpp
  • src/mame/ensoniq/esqpanel.cpp
  • src/mame/skeleton/gameking.cpp
  • src/mame/svision/svision.cpp
  • src/mame/ti/ti85_m.cpp
  • src/mame/usp/patinho_feio.cpp
  • src/mame/shared/xbox_nv2a.cpp
  • src/mame/shared/xbox_pci.cpp
  • src/mame/shared/xbox_usb.cpp

Devices or drivers which have a periodic timer that can be temporarily suspended, which may result in the timer spuriously firing on re-enable, regardless of periodicity, if a full timer period has elapsed since it was disabled:

  • src/devices/bus/vip/vp550.cpp
  • src/devices/imagedev/microdrv.cpp
  • src/devices/machine/icm7170.cpp
  • src/devices/machine/mccs1850.cpp
  • src/devices/machine/rtc4543.cpp
  • src/devices/machine/upd4992.cpp
  • src/mame/act/victor9k_fdc.cpp
  • src/mame/pdp1/pdp1.cpp

Devices or drivers which appear to erroneously assume that a timer, when re-enabled, will have the same remaining duration as when it was disabled:

  • src/devices/machine/6840ptm.cpp
  • src/devices/machine/mc68901.cpp
  • src/devices/machine/upd1990a.cpp
  • src/mame/aviion/aviion88k.cpp
  • src/mame/konami/gticlub.cpp
  • src/mame/konami/hornet.cpp
  • src/mame/konami/nwk-tr.cpp
  • src/mame/nintendo/pokemini.cpp

src/devices/machine/am9513.cpp is a special case as the current behavior is correct, but the code itself could be changed for clarity. The case where m_freq_timer_selected[f] is non-zero is meaningless as the timer will have been adjusted (and therefore enabled) immediately prior, and there is no point in adjusting the timer if m_freq_timer_selected[f] is zero as it is never enabled outside of the relevant function.

I'll remove the unnecessary enable calls from the first group myself, and will be trying to fix up the latter two groups of devices and drivers as well. However, I'd feel more comfortable if the relevant owners of the latter two groups would take point, so tagging in @curt-coder, @angelosa, @happppp, @rb6502, @wilbertpol, and @villedevs if any of you want to take a stab at it yourselves. For the drivers and devices in the final group (incorrect assumption of timer suspension), the solution I've implemented for 6840ptm.cpp in my local tree is:

  • When disabling a timer, take note of remaining(), stash it in a member variable, then call adjust(attotime::never) on the timer.
  • When calling adjust on the timer with some non-never value, clear the stashed value to attotime::never
  • When re-enabling a timer, use the stashed value (if the timer is not already running and enabled).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions