Further untangled nl_base.[hc] and mame-specific netlist.c. No wn

This commit is contained in:
Couriersud 2013-12-29 01:27:49 +00:00
parent cbd26a0902
commit f6a91bbb13
8 changed files with 123 additions and 126 deletions

View File

@ -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<nld_analog_callback>( "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();
}
}

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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; }

View File

@ -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")

View File

@ -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);