diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index 4e916321f0d..f0663e66989 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -140,6 +140,10 @@ ADDRESS_MAP_END netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, NETLIST_CORE, "Netlist core device", tag, owner, clock, "netlist_core", __FILE__), + m_icount(0), + m_div(0), + m_rem(0), + m_old(netlist_time::zero), m_netlist(NULL), m_setup(NULL), m_setup_func(NULL) @@ -148,6 +152,10 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, cons netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *file) : device_t(mconfig, type, name, tag, owner, clock, shortname, file), + m_icount(0), + m_div(0), + m_rem(0), + m_old(netlist_time::zero), m_netlist(NULL), m_setup(NULL), m_setup_func(NULL) @@ -170,13 +178,13 @@ void netlist_mame_device_t::device_start() { LOG_DEV_CALLS(("device_start %s\n", tag())); + printf("clock is %d\n", clock()); + m_netlist = global_alloc_clear(netlist_mame_t(*this)); m_setup = global_alloc_clear(netlist_setup_t(*m_netlist)); netlist().init_object(*m_netlist, "netlist"); m_setup->init(); - netlist().set_clock_freq(this->clock()); - // register additional devices m_setup->factory().register_device( "NETDEV_CALLBACK", "nld_analog_callback"); @@ -197,13 +205,32 @@ void netlist_mame_device_t::device_start() m_setup->start_devices(); m_setup->resolve_inputs(); + netlist().save(NAME(m_rem)); + netlist().save(NAME(m_div)); + netlist().save(NAME(m_old)); + save_state(); + m_old = netlist_time::zero; + m_rem = 0; + } +void netlist_mame_device_t::device_clock_changed() +{ + //printf("device_clock_changed\n"); + m_div = netlist_time::from_hz(clock()).as_raw(); + //m_rem = 0; + NL_VERBOSE_OUT(("Setting clock %" I64FMT "d and divisor %d\n", clockfreq, m_div)); + //printf("Setting clock %d and divisor %d\n", clock(), m_div); +} + + void netlist_mame_device_t::device_reset() { LOG_DEV_CALLS(("device_reset\n")); + m_old = netlist_time::zero; + m_rem = 0; netlist().reset(); } @@ -236,6 +263,19 @@ void netlist_mame_device_t::device_timer(emu_timer &timer, device_timer_id id, i { } +ATTR_HOT ATTR_ALIGN void netlist_mame_device_t::update_time_x() +{ + const netlist_time delta = netlist().time() - m_old + netlist_time::from_raw(m_rem); + m_old = netlist().time(); + m_icount -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem); +} + +ATTR_HOT ATTR_ALIGN void netlist_mame_device_t::check_mame_abort_slice() +{ + if (m_icount <= 0) + netlist().abort_current_queue_slice(); +} + ATTR_COLD void netlist_mame_device_t::save_state() { for (pstate_entry_t::list_t::entry_t *p = netlist().save_list().first(); p != NULL; p = netlist().save_list().next(p)) @@ -279,8 +319,7 @@ netlist_mame_cpu_device_t::netlist_mame_cpu_device_t(const machine_config &mconf device_state_interface(mconfig, *this), device_disasm_interface(mconfig, *this), device_memory_interface(mconfig, *this), - m_program_config("program", ENDIANNESS_LITTLE, 8, 12, 0, ADDRESS_MAP_NAME(program_dummy)), - m_icount(0) + m_program_config("program", ENDIANNESS_LITTLE, 8, 12, 0, ADDRESS_MAP_NAME(program_dummy)) { } @@ -352,14 +391,16 @@ ATTR_HOT void netlist_mame_cpu_device_t::execute_run() { while (m_icount > 0) { - int m_temp = 1; m_genPC++; m_genPC &= 255; debugger_instruction_hook(this, m_genPC); - netlist().process_queue(m_temp); - m_icount -= (1 - m_temp); + netlist().process_queue(netlist_time::from_raw(m_div)); + update_time_x(); } } else - netlist().process_queue(m_icount); + { + netlist().process_queue(netlist_time::from_raw(m_div) * m_icount); + update_time_x(); + } } diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h index 54548a72bb1..bc73721e737 100644 --- a/src/emu/machine/netlist.h +++ b/src/emu/machine/netlist.h @@ -56,8 +56,8 @@ // MAME specific configuration -#define MCFG_NETLIST_ADD(_tag, _setup ) \ - MCFG_DEVICE_ADD(_tag, NETLIST_CPU, NETLIST_CLOCK) \ +#define MCFG_NETLIST_ADD(_tag, _setup, _clock ) \ + MCFG_DEVICE_ADD(_tag, NETLIST_CPU, _clock) \ MCFG_NETLIST_SETUP(_setup) #define MCFG_NETLIST_REPLACE(_tag, _setup) \ @@ -148,6 +148,12 @@ public: ATTR_HOT inline netlist_setup_t &setup() { return *m_setup; } ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; } + ATTR_HOT inline netlist_time last_time_update() { return m_old; } + ATTR_HOT void update_time_x(); + ATTR_HOT void check_mame_abort_slice(); + + int m_icount; + protected: // device_t overrides virtual void device_config_complete(); @@ -157,12 +163,20 @@ protected: virtual void device_post_load(); virtual void device_pre_save(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + //virtual void device_debug_setup(); + virtual void device_clock_changed(); + + UINT32 m_div; private: void save_state(); - netlist_mame_t *m_netlist; - netlist_setup_t *m_setup; + /* timing support here - so sound can hijack it ... */ + UINT32 m_rem; + netlist_time m_old; + + netlist_mame_t * m_netlist; + netlist_setup_t * m_setup; void (*m_setup_func)(netlist_setup_t &); }; @@ -241,7 +255,6 @@ protected: private: - int m_icount; int m_genPC; }; @@ -368,7 +381,9 @@ public: ATTR_HOT void update() { + m_cpu_device->update_time_x(); m_callback(INPANALOG(m_in), m_cpu_device->local_time()); + m_cpu_device->check_mame_abort_slice(); } private: diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index 0821390b841..9950c4fab47 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -27,6 +27,7 @@ void netlist_queue_t::register_state(pstate_manager_t &manager, const pstring &m manager.save_item(m_times, module + "." + "times"); manager.save_item(&(m_name[0][0]), module + "." + "names", sizeof(m_name)); } + void netlist_queue_t::on_pre_save() { NL_VERBOSE_OUT(("on_pre_save\n")); @@ -111,8 +112,6 @@ netlist_base_t::netlist_base_t() : netlist_object_t(NETLIST, GENERIC), m_time_ps(netlist_time::zero), m_queue(*this), - m_rem(0), - m_div(NETLIST_DIV), m_mainclock(NULL), m_solver(NULL) { @@ -168,7 +167,6 @@ ATTR_COLD void netlist_base_t::set_solver_dev(NETLIB_NAME(solver) *dev) ATTR_COLD void netlist_base_t::reset() { m_time_ps = netlist_time::zero; - m_rem = 0; m_queue.clear(); if (m_mainclock != NULL) m_mainclock->m_Q.net().set_time(netlist_time::zero); @@ -188,97 +186,56 @@ ATTR_COLD void netlist_base_t::reset() } } -void netlist_base_t::set_clock_freq(UINT64 clockfreq) + +ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(const netlist_time delta) { - m_div = netlist_time::from_hz(clockfreq).as_raw(); - m_rem = 0; - assert_always(m_div == NETLIST_DIV, "netlist: illegal clock!"); - NL_VERBOSE_OUT(("Setting clock %" I64FMT "d and divisor %d\n", clockfreq, m_div)); -} + m_stop = m_time_ps + delta; -ATTR_HOT ATTR_ALIGN inline void netlist_base_t::update_time(const netlist_time t, INT32 &atime) -{ - if (NETLIST_DIV_BITS == 0) - { - const netlist_time delta = t - m_time_ps; - m_time_ps = t; - atime -= delta.as_raw(); - } else { - const netlist_time delta = t - m_time_ps + netlist_time::from_raw(m_rem); - m_time_ps = t; - m_rem = delta.as_raw() & NETLIST_MASK; - atime -= (delta.as_raw() >> NETLIST_DIV_BITS); + if (m_mainclock == NULL) + { + while ( (m_time_ps < m_stop) && (m_queue.is_not_empty())) + { + const netlist_queue_t::entry_t &e = m_queue.pop(); + m_time_ps = e.time(); + e.object().update_devs(); - // The folling is suitable for non-power of 2 m_divs ... - // atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem); - } -} + add_to_stat(m_perf_out_processed, 1); + if (FATAL_ERROR_AFTER_NS) + if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) + xfatalerror("Stopped"); + } + if (m_queue.is_empty()) + m_time_ps = m_stop; -ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime) -{ - if (m_mainclock == NULL) - { - while ( (atime > 0) && (m_queue.is_not_empty())) - { - const netlist_queue_t::entry_t &e = m_queue.pop(); - update_time(e.time(), atime); + } else { + netlist_net_t &mcQ = m_mainclock->m_Q.net(); + const netlist_time inc = m_mainclock->m_inc; - //if (FATAL_ERROR_AFTER_NS) - // NL_VERBOSE_OUT(("%s\n", e.object().netdev()->name().cstr()); + while (m_time_ps < m_stop) + { + if (m_queue.is_not_empty()) + { + while (m_queue.peek().time() > mcQ.time()) + { + m_time_ps = mcQ.time(); + NETLIB_NAME(mainclock)::mc_update(mcQ, m_time_ps + inc); + } - e.object().update_devs(); + const netlist_queue_t::entry_t &e = m_queue.pop(); + m_time_ps = e.time(); + e.object().update_devs(); - add_to_stat(m_perf_out_processed, 1); + } else { + m_time_ps = mcQ.time(); + NETLIB_NAME(mainclock)::mc_update(mcQ, m_time_ps + inc); + } + if (FATAL_ERROR_AFTER_NS) + if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) + xfatalerror("Stopped"); - if (FATAL_ERROR_AFTER_NS) - if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) - xfatalerror("Stopped"); - } - - if (atime > 0) - { - m_time_ps += netlist_time::from_raw(atime * m_div); - atime = 0; - } - } else { - netlist_net_t &mcQ = m_mainclock->m_Q.net(); - const netlist_time inc = m_mainclock->m_inc; - - while (atime > 0) - { - if (m_queue.is_not_empty()) - { - while (m_queue.peek().time() > mcQ.time()) - { - update_time(mcQ.time(), atime); - - NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); - - } - const netlist_queue_t::entry_t &e = m_queue.pop(); - - update_time(e.time(), atime); - - e.object().update_devs(); - - } else { - update_time(mcQ.time(), atime); - - NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); - } - if (FATAL_ERROR_AFTER_NS) - if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) - xfatalerror("Stopped"); - - add_to_stat(m_perf_out_processed, 1); - } - - if (atime > 0) - { - m_time_ps += netlist_time::from_raw(atime * m_div); - atime = 0; - } - } + add_to_stat(m_perf_out_processed, 1); + } + } } ATTR_COLD void netlist_base_t::xfatalerror(const char *format, ...) const diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index df26a77fbf9..418652f75ea 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -1018,7 +1018,8 @@ public: ATTR_HOT NETLIB_NAME(solver) *solver() const { return m_solver; } - ATTR_HOT void process_queue(INT32 &atime); + ATTR_HOT void process_queue(const netlist_time delta); + ATTR_HOT inline void abort_current_queue_slice() { m_stop = netlist_time::zero; } ATTR_HOT inline const netlist_time &time() const { return m_time_ps; } @@ -1028,8 +1029,6 @@ public: ATTR_COLD netlist_net_t *find_net(const pstring &name); - ATTR_COLD void set_clock_freq(UINT64 clockfreq); - ATTR_COLD netlist_setup_t &setup() { return *m_setup; } ATTR_COLD void reset(); @@ -1048,8 +1047,6 @@ protected: { save(NAME(m_queue.callback())); save(NAME(m_time_ps)); - save(NAME(m_rem)); - save(NAME(m_div)); netlist_object_t::save_register(); } @@ -1061,12 +1058,10 @@ protected: #endif private: - ATTR_HOT void update_time(const netlist_time t, INT32 &atime); + netlist_time m_stop; // target time for current queue processing netlist_time m_time_ps; netlist_queue_t m_queue; - UINT32 m_rem; - UINT32 m_div; NETLIB_NAME(mainclock) * m_mainclock; NETLIB_NAME(solver) * m_solver; diff --git a/src/emu/netlist/nl_config.h b/src/emu/netlist/nl_config.h index 2465dedbef0..80586833365 100644 --- a/src/emu/netlist/nl_config.h +++ b/src/emu/netlist/nl_config.h @@ -29,15 +29,9 @@ // Use nano-second resolution - Sufficient for now #define NETLIST_INTERNAL_RES (U64(1000000000)) -#define NETLIST_DIV_BITS (0) //#define NETLIST_INTERNAL_RES (U64(1000000000000)) -//#define NETLIST_DIV_BITS (10) -#define NETLIST_DIV (U64(1) << NETLIST_DIV_BITS) -#define NETLIST_MASK (NETLIST_DIV-1) -#define NETLIST_CLOCK (NETLIST_INTERNAL_RES / NETLIST_DIV) -//FIXME: LEGACY -//#define NETLIST_HIGHIMP_V (1.23456e20) /* some voltage we should never see */ +#define NETLIST_CLOCK (NETLIST_INTERNAL_RES) #define NETLIST_GMIN (1e-9) diff --git a/src/emu/netlist/nl_time.h b/src/emu/netlist/nl_time.h index 33729fb38d9..738491e80e1 100644 --- a/src/emu/netlist/nl_time.h +++ b/src/emu/netlist/nl_time.h @@ -43,7 +43,9 @@ public: ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } ATTR_HOT inline const netlist_time &operator=(const double &right) { m_time = (INTERNALTYPE) ( right * (double) RESOLUTION); return *this; } - ATTR_HOT inline operator double() const { return as_double(); } + + // issues with ISO C++ standard + //ATTR_HOT inline operator double() const { return as_double(); } ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } diff --git a/src/mame/drivers/pong.c b/src/mame/drivers/pong.c index b4999093a80..117067fe390 100644 --- a/src/mame/drivers/pong.c +++ b/src/mame/drivers/pong.c @@ -901,7 +901,7 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( pong, pong_state ) /* basic machine hardware */ - MCFG_NETLIST_ADD("maincpu", pong) + MCFG_NETLIST_ADD("maincpu", pong, MASTER_CLOCK * 2) MCFG_NETLIST_ANALOG_INPUT("maincpu", "vr0", "ic_b9_R.R") MCFG_NETLIST_ANALOG_INPUT_MULT_OFFSET(1.0 / 100.0 * RES_K(50), RES_K(56) ) MCFG_NETLIST_ANALOG_INPUT("maincpu", "vr1", "ic_a9_R.R") diff --git a/src/tools/nltool.c b/src/tools/nltool.c index 5bdb965cb51..7c8a11e3485 100644 --- a/src/tools/nltool.c +++ b/src/tools/nltool.c @@ -116,8 +116,6 @@ public: this->init_object(*this, "netlist"); m_setup->init(); - this->set_clock_freq(NETLIST_CLOCK); - // read the netlist ... //m_setup_func(*m_setup); @@ -183,17 +181,12 @@ int main(int argc, char *argv[]) nt.read_netlist(filetobuf(opts.value("f"))); double ttr = opts.float_value("ttr"); - INT64 tt = ttr * NETLIST_CLOCK; - printf("startup time ==> %5.3f\n", (double) (osd_ticks() - t) / (double) osd_ticks_per_second() ); printf("runnning ...\n"); t = osd_ticks(); - while (tt>0) - { - INT32 tr = MIN(tt, NETLIST_CLOCK / 10); - tt -= tr; - nt.process_queue(tr); - } + + nt.process_queue(netlist_time::from_double(ttr)); + double emutime = (double) (osd_ticks() - t) / (double) osd_ticks_per_second(); printf("%f seconds emulation took %f real time ==> %5.2f%%\n", ttr, emutime, ttr/emutime*100.0);