summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2021-03-23 09:41:27 -0700
committer Aaron Giles <aaron@aarongiles.com>2021-03-23 09:41:27 -0700
commitc632b586f7627b4f2d880e1a114baded99911d77 (patch)
treeac2fbfda036c77444d837a4de84c032488645aac
parent690272e7fd9174983cdb17631ba28854473fb4a3 (diff)
First round of global synchronize removals.
-rw-r--r--src/devices/bus/hp9845_io/98046.cpp10
-rw-r--r--src/devices/bus/hp9845_io/98046.h2
-rw-r--r--src/devices/bus/mackbd/keyboard.cpp14
-rw-r--r--src/devices/bus/mackbd/pluskbd.cpp5
-rw-r--r--src/devices/bus/nes/mmc1.cpp4
-rw-r--r--src/devices/bus/nes/mmc1.h1
-rw-r--r--src/devices/bus/rs232/hlemouse.cpp6
-rw-r--r--src/devices/bus/rs232/hlemouse.h2
-rw-r--r--src/devices/bus/z29_kbd/he191_3425.cpp4
-rw-r--r--src/devices/bus/z29_kbd/he191_3425.h1
-rw-r--r--src/devices/bus/z29_kbd/md_kbd.cpp3
-rw-r--r--src/devices/bus/z29_kbd/md_kbd.h1
-rw-r--r--src/devices/cpu/m6502/m6500_1.cpp16
-rw-r--r--src/devices/cpu/m6502/m6500_1.h2
-rw-r--r--src/devices/cpu/mcs48/mcs48.cpp10
-rw-r--r--src/devices/cpu/mcs48/mcs48.h4
-rw-r--r--src/devices/cpu/tms34010/tms34010.cpp12
-rw-r--r--src/devices/cpu/tms34010/tms34010.h1
-rw-r--r--src/emu/attotime.h55
19 files changed, 129 insertions, 24 deletions
diff --git a/src/devices/bus/hp9845_io/98046.cpp b/src/devices/bus/hp9845_io/98046.cpp
index 8b7e601f0f4..cbf2edb3b4c 100644
--- a/src/devices/bus/hp9845_io/98046.cpp
+++ b/src/devices/bus/hp9845_io/98046.cpp
@@ -237,6 +237,8 @@ const tiny_rom_entry *hp98046_io_card_device::device_rom_region() const
void hp98046_io_card_device::device_start()
{
m_ram = std::make_unique<uint8_t[]>(1024);
+ m_sync_rx_im_w.enregister(*this, FUNC(hp98046_io_card_device::sync_rx_im_w));
+ m_sync_tx_im_w.enregister(*this, FUNC(hp98046_io_card_device::sync_tx_im_w));
save_pointer(NAME(m_ram) , 1024);
}
@@ -495,14 +497,14 @@ WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_cts_w)
WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_rxc_w)
{
if (!m_loopback) {
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_rx_im_w) , this) , state);
+ m_sync_rx_im_w.synchronize(state);
}
}
WRITE_LINE_MEMBER(hp98046_io_card_device::rs232_txc_w)
{
if (!m_loopback) {
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_tx_im_w) , this) , state);
+ m_sync_tx_im_w.synchronize(state);
}
}
@@ -636,7 +638,7 @@ WRITE_LINE_MEMBER(hp98046_io_card_device::rxc_w)
m_last_rxc = bool(state);
m_sio->rxca_w(m_last_rxc);
if (m_loopback) {
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_tx_im_w) , this) , state);
+ m_sync_tx_im_w.synchronize(state);
}
}
}
@@ -649,7 +651,7 @@ WRITE_LINE_MEMBER(hp98046_io_card_device::txc_w)
m_sio->txcb_w(m_last_txc);
m_sio->rxcb_w(m_last_txc);
if (m_loopback) {
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(hp98046_io_card_device::sync_rx_im_w) , this) , state);
+ m_sync_rx_im_w.synchronize(state);
}
}
}
diff --git a/src/devices/bus/hp9845_io/98046.h b/src/devices/bus/hp9845_io/98046.h
index 90debbb8c03..b3f9791e930 100644
--- a/src/devices/bus/hp9845_io/98046.h
+++ b/src/devices/bus/hp9845_io/98046.h
@@ -99,7 +99,9 @@ private:
DECLARE_WRITE_LINE_MEMBER(rxc_w);
DECLARE_WRITE_LINE_MEMBER(txc_w);
TIMER_CALLBACK_MEMBER(sync_rx_im_w);
+ emu_timer_cb m_sync_rx_im_w;
TIMER_CALLBACK_MEMBER(sync_tx_im_w);
+ emu_timer_cb m_sync_tx_im_w;
};
// device type definitions
diff --git a/src/devices/bus/mackbd/keyboard.cpp b/src/devices/bus/mackbd/keyboard.cpp
index 4f0de812c19..5857a807985 100644
--- a/src/devices/bus/mackbd/keyboard.cpp
+++ b/src/devices/bus/mackbd/keyboard.cpp
@@ -287,6 +287,8 @@ protected:
m_host_data_in = 0x01U;
m_watchdog_in = 1U;
+ m_update_host_data.enregister(*this, FUNC(peripheral_base::update_host_data));
+
save_item(NAME(m_row_drive));
save_item(NAME(m_host_clock_out));
save_item(NAME(m_host_data_out));
@@ -296,7 +298,7 @@ protected:
virtual DECLARE_WRITE_LINE_MEMBER(data_w) override
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(peripheral_base::update_host_data), this), state);
+ m_update_host_data.synchronize(state);
}
DECLARE_WRITE_LINE_MEMBER(watchdog_w)
@@ -351,6 +353,7 @@ private:
m_host_data_in = param ? 0x01U : 0x00U;
}
}
+ emu_timer_cb m_update_host_data;
TIMER_CALLBACK_MEMBER(watchdog_timeout)
{
@@ -443,6 +446,9 @@ protected:
{
peripheral_base<3>::device_start();
+ m_update_keyboard_clock.enregister(*this, FUNC(keypad_base::update_keyboard_clock));
+ m_update_keyboard_data.enregister(*this, FUNC(keypad_base::update_keyboard_data));
+
m_keyboard_data_out = 0x01U;
m_keyboard_clock_in = 0x01U;
m_keyboard_data_in = 0x01U;
@@ -466,23 +472,25 @@ private:
DECLARE_WRITE_LINE_MEMBER(keyboard_clock_in_w)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(keypad_base::update_keyboard_clock), this), state);
+ m_update_keyboard_clock.synchronize(state);
}
DECLARE_WRITE_LINE_MEMBER(keyboard_data_in_w)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(keypad_base::update_keyboard_data), this), state);
+ m_update_keyboard_data.synchronize(state);
}
TIMER_CALLBACK_MEMBER(update_keyboard_clock)
{
m_keyboard_clock_in = param ? 0x01U : 0x00U;
}
+ emu_timer_cb m_update_keyboard_clock;
TIMER_CALLBACK_MEMBER(update_keyboard_data)
{
m_keyboard_data_in = param ? 0x01U : 0x00U;
}
+ emu_timer_cb m_update_keyboard_data;
u8 m_keyboard_data_out = 0x01U; // data line drive to keyboard (idle high)
u8 m_keyboard_clock_in = 0x01U; // clock line driver from keyboard (idle high)
diff --git a/src/devices/bus/mackbd/pluskbd.cpp b/src/devices/bus/mackbd/pluskbd.cpp
index 6cc707607f4..520c509c3fc 100644
--- a/src/devices/bus/mackbd/pluskbd.cpp
+++ b/src/devices/bus/mackbd/pluskbd.cpp
@@ -144,6 +144,8 @@ protected:
m_host_data_out = 1U;
m_host_data_in = 0x01U;
+ m_update_host_data.enregister(*this, FUNC(keyboard_base::update_host_data));
+
save_item(NAME(m_row_drive));
save_item(NAME(m_host_clock_out));
save_item(NAME(m_host_data_out));
@@ -152,7 +154,7 @@ protected:
virtual DECLARE_WRITE_LINE_MEMBER(data_w) override
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(keyboard_base::update_host_data), this), state);
+ m_update_host_data.synchronize(state);
}
private:
@@ -207,6 +209,7 @@ private:
m_host_data_in = param ? 0x01U : 0x00U;
}
}
+ emu_timer_cb m_update_host_data;
required_device<mcs48_cpu_device> m_mpu;
required_ioport_array<10> m_rows;
diff --git a/src/devices/bus/nes/mmc1.cpp b/src/devices/bus/nes/mmc1.cpp
index 9a27c601b4c..9f7e695dd3b 100644
--- a/src/devices/bus/nes/mmc1.cpp
+++ b/src/devices/bus/nes/mmc1.cpp
@@ -73,6 +73,8 @@ void nes_sxrom_device::device_start()
save_item(NAME(m_count));
save_item(NAME(m_reg));
save_item(NAME(m_reg_write_enable));
+
+ m_resync_callback.enregister(*this, FUNC(nes_sxrom_device::resync_callback));
}
void nes_sxrom_device::pcb_reset()
@@ -235,7 +237,7 @@ void nes_sxrom_device::write_h(offs_t offset, uint8_t data)
else
{
m_reg_write_enable = 0;
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(nes_sxrom_device::resync_callback),this));
+ m_resync_callback.synchronize();
}
if (data & 0x80)
diff --git a/src/devices/bus/nes/mmc1.h b/src/devices/bus/nes/mmc1.h
index c8ccb835d76..368c757beba 100644
--- a/src/devices/bus/nes/mmc1.h
+++ b/src/devices/bus/nes/mmc1.h
@@ -29,6 +29,7 @@ protected:
virtual void device_start() override;
TIMER_CALLBACK_MEMBER(resync_callback);
+ emu_timer_cb m_resync_callback;
virtual void update_regs(int reg); // this is needed to simplify NES-EVENT pcb implementation, which handle differently some regs!
virtual void set_prg();
diff --git a/src/devices/bus/rs232/hlemouse.cpp b/src/devices/bus/rs232/hlemouse.cpp
index 599e0d77d14..1cd01b9384d 100644
--- a/src/devices/bus/rs232/hlemouse.cpp
+++ b/src/devices/bus/rs232/hlemouse.cpp
@@ -236,7 +236,8 @@ void hle_msmouse_device_base::device_start()
m_btn_val = m_btn_sent = 0x00U;
m_enable = 0U;
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(hle_msmouse_device_base::start_mouse), this));
+ m_start_mouse.enregister(*this, FUNC(hle_msmouse_device_base::start_mouse));
+ m_start_mouse.synchronize();
}
WRITE_LINE_MEMBER(hle_msmouse_device_base::input_dtr)
@@ -463,7 +464,8 @@ void hle_msystems_device_base::device_start()
m_phase = 0U;
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(hle_msystems_device_base::start_mouse), this));
+ m_start_mouse.enregister(*this, FUNC(hle_msystems_device_base::start_mouse));
+ m_start_mouse.synchronize();
}
void hle_msystems_device_base::tra_callback()
diff --git a/src/devices/bus/rs232/hlemouse.h b/src/devices/bus/rs232/hlemouse.h
index d2fae5bd4d1..a24d5396f18 100644
--- a/src/devices/bus/rs232/hlemouse.h
+++ b/src/devices/bus/rs232/hlemouse.h
@@ -44,6 +44,7 @@ protected:
private:
TIMER_CALLBACK_MEMBER(start_mouse);
+ emu_timer_cb m_start_mouse;
void check_enable();
void check_inputs();
@@ -138,6 +139,7 @@ protected:
private:
TIMER_CALLBACK_MEMBER(start_mouse);
+ emu_timer_cb m_start_mouse;
virtual bool read_inputs() = 0;
virtual uint8_t report_buttons() = 0;
diff --git a/src/devices/bus/z29_kbd/he191_3425.cpp b/src/devices/bus/z29_kbd/he191_3425.cpp
index 5a52f363590..555509a8a76 100644
--- a/src/devices/bus/z29_kbd/he191_3425.cpp
+++ b/src/devices/bus/z29_kbd/he191_3425.cpp
@@ -42,13 +42,15 @@ void he191_3425_device::device_start()
{
m_leds[0] = 1; // L1: Power
+ m_receive_data_synced.enregister(*this, FUNC(he191_3425_device::receive_data_synced));
+
save_item(NAME(m_select));
save_item(NAME(m_recv_data));
}
void he191_3425_device::receive_data(bool state)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(he191_3425_device::receive_data_synced), this), state);
+ m_receive_data_synced.synchronize(state);
}
TIMER_CALLBACK_MEMBER(he191_3425_device::receive_data_synced)
diff --git a/src/devices/bus/z29_kbd/he191_3425.h b/src/devices/bus/z29_kbd/he191_3425.h
index cf0129936fb..f7630fca636 100644
--- a/src/devices/bus/z29_kbd/he191_3425.h
+++ b/src/devices/bus/z29_kbd/he191_3425.h
@@ -39,6 +39,7 @@ private:
// misc. helpers
TIMER_CALLBACK_MEMBER(receive_data_synced);
+ emu_timer_cb m_receive_data_synced;
// object finders
required_device<cpu_device> m_mcu;
diff --git a/src/devices/bus/z29_kbd/md_kbd.cpp b/src/devices/bus/z29_kbd/md_kbd.cpp
index 1a313af10ce..a1f67753da6 100644
--- a/src/devices/bus/z29_kbd/md_kbd.cpp
+++ b/src/devices/bus/z29_kbd/md_kbd.cpp
@@ -49,6 +49,7 @@ void md_keyboard_device::device_resolve_objects()
void md_keyboard_device::device_start()
{
+ m_receive_data_synced.enregister(*this, FUNC(md_keyboard_device::receive_data_synced));
save_item(NAME(m_14515b_select));
save_item(NAME(m_ls175_clock));
save_item(NAME(m_recv_data));
@@ -61,7 +62,7 @@ void md_keyboard_device::device_reset()
void md_keyboard_device::receive_data(bool state)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(md_keyboard_device::receive_data_synced), this), state);
+ m_receive_data_synced.synchronize(state);
}
TIMER_CALLBACK_MEMBER(md_keyboard_device::receive_data_synced)
diff --git a/src/devices/bus/z29_kbd/md_kbd.h b/src/devices/bus/z29_kbd/md_kbd.h
index 8a81b9a461d..e99ba88a537 100644
--- a/src/devices/bus/z29_kbd/md_kbd.h
+++ b/src/devices/bus/z29_kbd/md_kbd.h
@@ -37,6 +37,7 @@ private:
// misc. helpers
TIMER_CALLBACK_MEMBER(receive_data_synced);
+ emu_timer_cb m_receive_data_synced;
void ls175_w(u8 data);
// address maps
diff --git a/src/devices/cpu/m6502/m6500_1.cpp b/src/devices/cpu/m6502/m6500_1.cpp
index aaede8b2bff..dd0578210b1 100644
--- a/src/devices/cpu/m6502/m6500_1.cpp
+++ b/src/devices/cpu/m6502/m6500_1.cpp
@@ -105,28 +105,28 @@ m6500_1_device::m6500_1_device(machine_config const &mconfig, char const *tag, d
void m6500_1_device::pa_w(uint8_t data)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<0>), this), unsigned(data));
+ m_set_port_in[0].synchronize(data);
}
void m6500_1_device::pb_w(u8 data)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<1>), this), unsigned(data));
+ m_set_port_in[1].synchronize(data);
}
void m6500_1_device::pc_w(u8 data)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<2>), this), unsigned(data));
+ m_set_port_in[2].synchronize(data);
}
void m6500_1_device::pd_w(u8 data)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_port_in<3>), this), unsigned(data));
+ m_set_port_in[3].synchronize(data);
}
WRITE_LINE_MEMBER(m6500_1_device::cntr_w)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(m6500_1_device::set_cntr_in), this), state);
+ m_set_cntr_in.synchronize(state);
}
@@ -145,6 +145,12 @@ void m6500_1_device::device_start()
m_counter_base = 0U;
+ m_set_port_in[0].enregister(*this, FUNC(m6500_1_device::set_port_in<0>));
+ m_set_port_in[1].enregister(*this, FUNC(m6500_1_device::set_port_in<1>));
+ m_set_port_in[2].enregister(*this, FUNC(m6500_1_device::set_port_in<2>));
+ m_set_port_in[3].enregister(*this, FUNC(m6500_1_device::set_port_in<3>));
+ m_set_cntr_in.enregister(*this, FUNC(m6500_1_device::set_cntr_in));
+
state_add(M6500_1_CR, "CR", m_cr).callimport().callexport();
state_add(M6500_1_UL, "UL", m_ul).callimport().callexport();
state_add(M6500_1_LL, "LL", m_ll).callimport().callexport();
diff --git a/src/devices/cpu/m6502/m6500_1.h b/src/devices/cpu/m6502/m6500_1.h
index 0a4a07a6ff9..c756da0cf2c 100644
--- a/src/devices/cpu/m6502/m6500_1.h
+++ b/src/devices/cpu/m6502/m6500_1.h
@@ -98,6 +98,7 @@ protected:
void write_port(offs_t offset, u8 data);
void clear_edge(offs_t offset, u8 data);
template <unsigned Port> TIMER_CALLBACK_MEMBER(set_port_in);
+ emu_timer_cb m_set_port_in[4];
u8 read_upper_count();
u8 read_lower_count();
@@ -108,6 +109,7 @@ protected:
bool pulse_generator_mode() const;
bool event_counter_mode() const;
TIMER_CALLBACK_MEMBER(set_cntr_in);
+ emu_timer_cb m_set_cntr_in;
void toggle_cntr();
void memory_map(address_map &map);
diff --git a/src/devices/cpu/mcs48/mcs48.cpp b/src/devices/cpu/mcs48/mcs48.cpp
index 34d89693bf2..fbda4a76657 100644
--- a/src/devices/cpu/mcs48/mcs48.cpp
+++ b/src/devices/cpu/mcs48/mcs48.cpp
@@ -1418,9 +1418,17 @@ TIMER_CALLBACK_MEMBER( upi41_cpu_device::master_callback )
void upi41_cpu_device::upi41_master_w(offs_t offset, uint8_t data)
{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(upi41_cpu_device::master_callback), this), (offset << 8) | data);
+ m_master_callback.synchronize((offset << 8) | data);
}
+void upi41_cpu_device::device_start()
+{
+ mcs48_cpu_device::device_start();
+
+ m_master_callback.enregister(*this, FUNC(upi41_cpu_device::master_callback));
+}
+
+
/***************************************************************************
GENERAL CONTEXT ACCESS
diff --git a/src/devices/cpu/mcs48/mcs48.h b/src/devices/cpu/mcs48/mcs48.h
index fa73d33e5b6..939bbc1b497 100644
--- a/src/devices/cpu/mcs48/mcs48.h
+++ b/src/devices/cpu/mcs48/mcs48.h
@@ -631,7 +631,11 @@ protected:
// construction/destruction
upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size);
+ // overrides
+ virtual void device_start() override;
+
TIMER_CALLBACK_MEMBER( master_callback );
+ emu_timer_cb m_master_callback;
};
class i8041a_device : public upi41_cpu_device
diff --git a/src/devices/cpu/tms34010/tms34010.cpp b/src/devices/cpu/tms34010/tms34010.cpp
index 6eaf63b96ae..8d4f78c2cb2 100644
--- a/src/devices/cpu/tms34010/tms34010.cpp
+++ b/src/devices/cpu/tms34010/tms34010.cpp
@@ -741,8 +741,10 @@ void tms340x0_device::device_start()
}
}
+ m_internal_interrupt_callback.enregister(*this, FUNC(tms340x0_device::internal_interrupt_callback));
+
/* allocate a scanline timer and set it to go off at the start */
- m_scantimer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tms340x0_device::scanline_callback), this));
+ m_scantimer = timer_alloc(*this, FUNC(tms340x0_device::scanline_callback));
m_scantimer->adjust(attotime::zero);
save_item(NAME(m_pc));
@@ -1286,7 +1288,7 @@ void tms34010_device::io_register_w(offs_t offset, u16 data, u16 mem_mask)
/* NMI issued? */
if (data & 0x0100)
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(tms340x0_device::internal_interrupt_callback), this), 0);
+ m_internal_interrupt_callback.synchronize(0);
}
break;
@@ -1324,7 +1326,7 @@ void tms34010_device::io_register_w(offs_t offset, u16 data, u16 mem_mask)
/* input interrupt? (should really be state-based, but the functions don't exist!) */
if (!(oldreg & 0x0008) && (newreg & 0x0008))
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(tms340x0_device::internal_interrupt_callback), this), TMS34010_HI);
+ m_internal_interrupt_callback.synchronize(TMS34010_HI);
else if ((oldreg & 0x0008) && !(newreg & 0x0008))
IOREG(REG_INTPEND) &= ~TMS34010_HI;
}
@@ -1441,7 +1443,7 @@ void tms34020_device::io_register_w(offs_t offset, u16 data, u16 mem_mask)
/* NMI issued? */
if (data & 0x0100)
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(tms340x0_device::internal_interrupt_callback), this), 0);
+ m_internal_interrupt_callback.synchronize(0);
break;
case REG020_HSTCTLL:
@@ -1476,7 +1478,7 @@ void tms34020_device::io_register_w(offs_t offset, u16 data, u16 mem_mask)
/* input interrupt? (should really be state-based, but the functions don't exist!) */
if (!(oldreg & 0x0008) && (newreg & 0x0008))
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(tms340x0_device::internal_interrupt_callback), this), TMS34010_HI);
+ m_internal_interrupt_callback.synchronize(TMS34010_HI);
else if ((oldreg & 0x0008) && !(newreg & 0x0008))
IOREG(REG020_INTPEND) &= ~TMS34010_HI;
break;
diff --git a/src/devices/cpu/tms34010/tms34010.h b/src/devices/cpu/tms34010/tms34010.h
index c3d639e3506..84499220929 100644
--- a/src/devices/cpu/tms34010/tms34010.h
+++ b/src/devices/cpu/tms34010/tms34010.h
@@ -177,6 +177,7 @@ public:
u16 host_r(offs_t offset);
TIMER_CALLBACK_MEMBER(internal_interrupt_callback);
+ emu_timer_cb m_internal_interrupt_callback;
TIMER_CALLBACK_MEMBER(scanline_callback);
protected:
diff --git a/src/emu/attotime.h b/src/emu/attotime.h
index 7b31362d7dc..ba801392b75 100644
--- a/src/emu/attotime.h
+++ b/src/emu/attotime.h
@@ -195,6 +195,61 @@ private:
/** @} */
+class precise_clock
+{
+public:
+ precise_clock(u32 rate = 1, u32 divider = 1) :
+ m_rate(rate),
+ m_divider(1),
+ m_period((rate == 0) ? ATTOSECONDS_PER_SECOND : ((ATTOSECONDS_PER_SECOND + rate - 1) / rate)),
+ m_base(attotime::zero),
+ m_tick_base(0)
+ {
+ }
+
+ void reset_tick_base() { m_tick_base = 0; }
+
+ void set_rate(attotime const &base, u32 rate, u32 divider = 0)
+ {
+ // remember the ticks at the old rate at the base time before setting it
+ m_tick_base = tick(base);
+ m_base = base;
+
+ // configure the new rate
+ m_rate = rate;
+ if (divider != 0)
+ m_divider = divider;
+ m_period = (rate == 0) ? ATTOSECONDS_PER_SECOND : ((ATTOSECONDS_PER_SECOND + rate - 1) / rate);
+ }
+
+ u64 tick(attotime const &time)
+ {
+ attotime delta = time - m_base;
+ u64 count = delta.seconds() * m_rate + delta.attoseconds() / m_period;
+ return m_tick_base + ((m_divider == 1) ? count : (count / m_divider));
+ }
+
+ attotime tick_time(u64 ticknum)
+ {
+ // can't get time of ticks prior to the last rate switch
+ if (ticknum < m_tick_base)
+ return attotime::zero;
+ ticknum = (ticknum - m_tick_base) * m_divider;
+
+ u64 seconds = ticknum / m_rate;
+ attotime delta(seconds, (ticknum - seconds * m_rate) * m_period);
+ return delta + m_base;
+ }
+
+private:
+ u32 m_rate; // integral rate in Hz
+ u32 m_divider; // clock divider (or 1 if no divider)
+ attoseconds_t m_period; // period, measured in attoseconds
+ attotime m_base; // time of last rate change
+ u64 m_tick_base; // ticks at last rate change
+};
+
+
//**************************************************************************
// INLINE FUNCTIONS
//**************************************************************************