mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
Further untangled nl_base.[hc] and mame-specific netlist.c. No wn
This commit is contained in:
parent
cbd26a0902
commit
f6a91bbb13
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user