mirror of
https://github.com/holub/mame
synced 2025-07-08 03:12:37 +03:00
netlist: Proxy and power terminal hack removal. [Couriersud]
- Devices ttlhigh and ttlhow are no longer automatically created. - All logic input devices (e.g. TTL_INPUT, LOGIC_INPUT) now need to have their power terminals (VCC, GND) connected. This opens the route for more appropriate proxy devices but comes at a cost. If the connections are omitted your circuit will not work as expected. Example: LOGIC_INPUT(I_SD0, 1, "AY8910PORT") NET_C(VCC, I_SD0.VCC) NET_C(GND, I_SD0.GND) - Updated all netlists. - Removed proxy information from terminal objects. This was replaced by a lookup hash whose life-span does not exceed netlest setup. These changes enable the removal of a number of hacks from the source going forward.
This commit is contained in:
parent
ce3c38914d
commit
dc4fa04201
@ -16,6 +16,7 @@
|
||||
#include "netlist/nl_factory.h"
|
||||
#include "netlist/nl_parser.h"
|
||||
#include "netlist/devices/net_lib.h"
|
||||
#include "netlist/devices/nlid_system.h"
|
||||
|
||||
#include "netlist/plib/palloc.h"
|
||||
|
||||
@ -225,6 +226,7 @@ public:
|
||||
, m_in(*this, "IN")
|
||||
, m_cpu_device(nullptr)
|
||||
, m_last(*this, "m_last", 0)
|
||||
, m_supply(*this)
|
||||
{
|
||||
auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&state());
|
||||
if (nl != nullptr)
|
||||
@ -261,6 +263,7 @@ private:
|
||||
std::unique_ptr<netlist_mame_logic_output_device::output_delegate> m_callback; // TODO: change to std::optional for C++17
|
||||
netlist_mame_cpu_device *m_cpu_device;
|
||||
netlist::state_var<netlist::netlist_sig_t> m_last;
|
||||
netlist::devices::NETLIB_NAME(power_pins) m_supply;
|
||||
};
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "netlist/nl_setup.h"
|
||||
#include "netlist/solver/nld_solver.h"
|
||||
#include "nld_generic_models.h"
|
||||
#include "plib/pfunction.h"
|
||||
#include "netlist/plib/pfunction.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Implementation
|
||||
@ -102,6 +102,16 @@ namespace analog
|
||||
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
|
||||
}
|
||||
|
||||
nl_fptype V1P() const noexcept
|
||||
{
|
||||
return m_P.net().Q_Analog();
|
||||
}
|
||||
|
||||
nl_fptype V2N() const noexcept
|
||||
{
|
||||
return m_N.net().Q_Analog();
|
||||
}
|
||||
|
||||
void set_mat(nl_fptype a11, nl_fptype a12, nl_fptype rhs1,
|
||||
nl_fptype a21, nl_fptype a22, nl_fptype rhs2) const noexcept
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "nld_tms4800.h"
|
||||
#include "netlist/nl_base.h"
|
||||
#include "netlist/devices/nlid_system.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
@ -22,6 +23,7 @@ namespace netlist
|
||||
, m_D(*this, {{ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7" }})
|
||||
, m_last_data(*this, "m_last_data", 1)
|
||||
, m_ROM(*this, "ROM")
|
||||
, m_supply(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -37,6 +39,7 @@ namespace netlist
|
||||
state_var<unsigned> m_last_data;
|
||||
|
||||
param_rom_t<uint8_t, 11, 8> m_ROM; // 16 Kbits, used as 2 Kbit x 8
|
||||
NETLIB_NAME(power_pins) m_supply;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT_DERIVED(TMS4800_dip, TMS4800)
|
||||
@ -97,7 +100,7 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_DEVICE_IMPL(TMS4800, "ROM_TMS4800", "+AR,+OE1,+OE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10")
|
||||
NETLIB_DEVICE_IMPL(TMS4800, "ROM_TMS4800", "+AR,+OE1,+OE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10,@VCC,@GND")
|
||||
NETLIB_DEVICE_IMPL(TMS4800_dip, "ROM_TMS4800_DIP", "")
|
||||
|
||||
} //namespace devices
|
||||
|
@ -45,7 +45,9 @@
|
||||
NET_CONNECT(name, A7, cA7) \
|
||||
NET_CONNECT(name, A8, cA8) \
|
||||
NET_CONNECT(name, A9, cA9) \
|
||||
NET_CONNECT(name, A10, cA10)
|
||||
NET_CONNECT(name, A10, cA10) \
|
||||
NET_CONNECT(name, VCC, VCC) \
|
||||
NET_CONNECT(name, GND, GND)
|
||||
|
||||
#define ROM_TMS4800_DIP(name) \
|
||||
NET_REGISTER_DEV(ROM_TMS4800_DIP, name)
|
||||
|
@ -33,20 +33,31 @@ namespace netlist
|
||||
for (auto & pwr_sym : power_syms)
|
||||
{
|
||||
pstring devname = inout_proxied->device().name();
|
||||
auto tp_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
auto tn_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
if (f && (tp_t != nullptr && tn_t != nullptr))
|
||||
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(),
|
||||
m_tp->name(), m_tn->name(),
|
||||
tp_t ? tp_t->name() : "",
|
||||
tn_t ? tn_t->name() : ""));
|
||||
else if (tp_t != nullptr && tn_t != nullptr)
|
||||
|
||||
auto tp_ct(anetlist.setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
/*detail::terminal_type::INPUT,*/ false));
|
||||
auto tp_cn(anetlist.setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
/*detail::terminal_type::INPUT,*/ false));
|
||||
if (tp_ct && tp_cn)
|
||||
{
|
||||
m_tp = tp_t;
|
||||
m_tn = tn_t;
|
||||
f = true;
|
||||
if (tp_ct && !tp_ct->is_analog())
|
||||
plib::pthrow<nl_exception>(plib::pfmt("Not an analog terminal: {1}")(tp_ct->name()));
|
||||
if (tp_cn && !tp_cn->is_analog())
|
||||
plib::pthrow<nl_exception>(plib::pfmt("Not an analog terminal: {1}")(tp_cn->name()));
|
||||
|
||||
auto tp_t = static_cast<analog_t* >(tp_ct);
|
||||
auto tn_t = static_cast<analog_t *>(tp_cn);
|
||||
if (f && (tp_t != nullptr && tn_t != nullptr))
|
||||
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(),
|
||||
m_tp->name(), m_tn->name(),
|
||||
tp_t ? tp_t->name() : "",
|
||||
tn_t ? tn_t->name() : ""));
|
||||
else if (tp_t != nullptr && tn_t != nullptr)
|
||||
{
|
||||
m_tp = tp_t;
|
||||
m_tn = tn_t;
|
||||
f = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//FIXME: Use power terminals and change info to warning or error
|
||||
@ -56,7 +67,7 @@ namespace netlist
|
||||
if (logic_family()->fixed_V() == nlconst::zero())
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name())));
|
||||
else
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name())));
|
||||
log().warning(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name())));
|
||||
#endif
|
||||
m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
|
||||
m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
|
||||
@ -93,10 +104,24 @@ namespace netlist
|
||||
|
||||
NETLIB_RESET(a_to_d_proxy)
|
||||
{
|
||||
// FIXME: Variable voltage
|
||||
nl_fptype supply_V = logic_family()->fixed_V();
|
||||
// FIXME: comparison to zero
|
||||
if (supply_V == nlconst::zero())
|
||||
supply_V = nlconst::magic(5.0);
|
||||
|
||||
if (need_hack())
|
||||
{
|
||||
if (m_tn)
|
||||
m_GNDHack->initial(0);
|
||||
if (m_tp)
|
||||
m_VCCHack->initial(supply_V);
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(a_to_d_proxy)
|
||||
{
|
||||
#if 0
|
||||
nl_assert(m_logic_family != nullptr);
|
||||
// FIXME: Variable supply voltage!
|
||||
nl_fptype supply_V = logic_family()->fixed_V();
|
||||
@ -111,6 +136,20 @@ namespace netlist
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
#else
|
||||
const auto v(m_I.Q_Analog());
|
||||
const auto vn(m_tn->net().Q_Analog());
|
||||
const auto vp(m_tp->net().Q_Analog());
|
||||
|
||||
if (logic_family()->is_above_high_thresh_V(v, vn, vp))
|
||||
out().push(1, netlist_time::quantum());
|
||||
else if (logic_family()->is_below_low_thresh_V(v, vn, vp))
|
||||
out().push(0, netlist_time::quantum());
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -133,18 +172,20 @@ namespace netlist
|
||||
{
|
||||
register_subalias("Q", m_RN.m_P);
|
||||
|
||||
//FIXME: Use power terminals and change info to warning or error
|
||||
if (need_hack())
|
||||
{
|
||||
#if 1
|
||||
// FIXME: move to base proxy class
|
||||
if (logic_family()->fixed_V() == nlconst::zero())
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name())));
|
||||
if (anetlist.setup().is_extended_validation())
|
||||
{
|
||||
// During validation, don't connect to terminals found
|
||||
// This will cause terminals not connected to a rail net to
|
||||
// fail connection stage.
|
||||
connect(m_RN.m_N, m_RP.m_P);
|
||||
}
|
||||
else
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name())));
|
||||
#endif
|
||||
connect(m_RN.m_N, *m_tn);
|
||||
connect(m_RP.m_P, *m_tp);
|
||||
{
|
||||
connect(m_RN.m_N, *m_tn);
|
||||
connect(m_RP.m_P, *m_tp);
|
||||
}
|
||||
connect(m_RN.m_P, m_RP.m_N);
|
||||
}
|
||||
else
|
||||
|
@ -33,8 +33,10 @@ namespace devices
|
||||
detail::core_terminal_t &proxy_term() const { return *m_proxy_term; }
|
||||
|
||||
protected:
|
||||
detail::core_terminal_t *m_tp;
|
||||
detail::core_terminal_t *m_tn;
|
||||
// FIXME: these should be core_terminal_t and only used for connecting
|
||||
// inputs. Fix, once the ugly hacks have been removed
|
||||
analog_t *m_tp;
|
||||
analog_t *m_tn;
|
||||
|
||||
plib::unique_ptr<analog_output_t> m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
plib::unique_ptr<analog_output_t> m_VCCHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "netlist/analog/nlid_twoterm.h"
|
||||
#include "netlist/nl_base.h"
|
||||
#include "netlist/nl_setup.h"
|
||||
#include "plib/putil.h"
|
||||
#include "netlist/plib/putil.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
@ -40,6 +40,50 @@ namespace devices
|
||||
param_num_t<unsigned> m_max_link_loops;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// power pins - not a device, but a helper
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// \brief Power pins class.
|
||||
///
|
||||
/// Power Pins are passive inputs. Delegate noop will silently ignore any
|
||||
/// updates.
|
||||
class nld_power_pins
|
||||
{
|
||||
public:
|
||||
explicit nld_power_pins(device_t &owner, const pstring &sVCC = sPowerVCC,
|
||||
const pstring &sGND = sPowerGND, bool force_analog_input = true)
|
||||
{
|
||||
if (owner.state().setup().is_extended_validation() || force_analog_input)
|
||||
{
|
||||
m_GND = owner.state().make_object<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop));
|
||||
m_VCC = owner.state().make_object<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop));
|
||||
}
|
||||
else
|
||||
{
|
||||
owner.create_and_register_subdevice(sPowerDevRes, m_RVG);
|
||||
owner.register_subalias(sVCC, pstring(sPowerDevRes) + ".1");
|
||||
owner.register_subalias(sGND, pstring(sPowerDevRes) + ".2");
|
||||
}
|
||||
}
|
||||
|
||||
nl_fptype VCC() const noexcept
|
||||
{
|
||||
return (m_VCC ? m_VCC->Q_Analog() : m_RVG->V1P());
|
||||
}
|
||||
nl_fptype GND() const noexcept
|
||||
{
|
||||
return (m_GND ? m_GND->Q_Analog() : m_RVG->V2N());
|
||||
}
|
||||
|
||||
private:
|
||||
void noop() { }
|
||||
unique_pool_ptr<analog_input_t> m_VCC; // only used during validation or force_analog_input
|
||||
unique_pool_ptr<analog_input_t> m_GND; // only used during validation or force_analog_input
|
||||
|
||||
NETLIB_SUB_UPTR(analog, R) m_RVG; // dummy resistor between VCC and GND
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// clock
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -188,6 +232,7 @@ namespace devices
|
||||
, m_IN(*this, "IN", false)
|
||||
// make sure we get the family first
|
||||
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
|
||||
, m_supply(*this)
|
||||
{
|
||||
set_logic_family(state().setup().family_from_model(m_FAMILY()));
|
||||
m_Q.set_logic_family(this->logic_family());
|
||||
@ -202,6 +247,7 @@ namespace devices
|
||||
|
||||
param_logic_t m_IN;
|
||||
param_model_t m_FAMILY;
|
||||
NETLIB_NAME(power_pins) m_supply;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(analog_input)
|
||||
@ -410,45 +456,6 @@ namespace devices
|
||||
state_var<netlist_sig_t> m_last_state;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// power pins - not a device, but a helper
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// \brief Power pins class.
|
||||
///
|
||||
/// Power Pins are passive inputs. Delegate noop will silently ignore any
|
||||
/// updates.
|
||||
class nld_power_pins
|
||||
{
|
||||
public:
|
||||
explicit nld_power_pins(device_t &owner, const pstring &sVCC = sPowerVCC,
|
||||
const pstring &sGND = sPowerGND, bool force_analog_input = false)
|
||||
{
|
||||
if (owner.state().setup().is_extended_validation() || force_analog_input)
|
||||
{
|
||||
m_GND = owner.state().make_object<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop));
|
||||
m_VCC = owner.state().make_object<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop));
|
||||
}
|
||||
else
|
||||
{
|
||||
owner.create_and_register_subdevice(sPowerDevRes, m_RVG);
|
||||
owner.register_subalias(sVCC, pstring(sPowerDevRes) + ".1");
|
||||
owner.register_subalias(sGND, pstring(sPowerDevRes) + ".2");
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this will seg-fault if force_analog_input = false
|
||||
nl_fptype VCC() const noexcept { return m_VCC->Q_Analog(); }
|
||||
nl_fptype GND() const noexcept { return m_GND->Q_Analog(); }
|
||||
|
||||
private:
|
||||
void noop() { }
|
||||
unique_pool_ptr<analog_input_t> m_VCC; // only used during validation or force_analog_input
|
||||
unique_pool_ptr<analog_input_t> m_GND; // only used during validation or force_analog_input
|
||||
|
||||
NETLIB_SUB_UPTR(analog, R) m_RVG; // dummy resistor between VCC and GND
|
||||
};
|
||||
|
||||
} // namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
|
@ -89,8 +89,6 @@ NETLIST_END()
|
||||
* ---------------------------------------------------------------------------*/
|
||||
|
||||
NETLIST_START(base)
|
||||
TTL_INPUT(ttlhigh, 1)
|
||||
TTL_INPUT(ttllow, 0)
|
||||
NET_REGISTER_DEV(GNDA, GND)
|
||||
NET_REGISTER_DEV(PARAMETER, NETLIST)
|
||||
|
||||
|
@ -762,7 +762,6 @@ namespace netlist
|
||||
nldelegate delegate)
|
||||
: core_terminal_t(dev, aname, state, delegate)
|
||||
, logic_family_t()
|
||||
, m_proxy(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -267,6 +267,12 @@ namespace netlist
|
||||
nl_fptype R_low() const noexcept{ return m_R_low; }
|
||||
nl_fptype R_high() const noexcept{ return m_R_high; }
|
||||
|
||||
bool is_above_high_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
|
||||
{ return (V - VN) > high_thresh_V(VN, VP); }
|
||||
|
||||
bool is_below_low_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
|
||||
{ return (V - VN) < low_thresh_V(VN, VP); }
|
||||
|
||||
nl_fptype m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5.
|
||||
nl_fptype m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled
|
||||
nl_fptype m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled
|
||||
@ -839,17 +845,12 @@ namespace netlist
|
||||
logic_t(core_device_t &dev, const pstring &aname,
|
||||
const state_e state, nldelegate delegate = nldelegate());
|
||||
|
||||
bool has_proxy() const noexcept { return (m_proxy != nullptr); }
|
||||
devices::nld_base_proxy *get_proxy() const noexcept { return m_proxy; }
|
||||
void set_proxy(devices::nld_base_proxy *proxy) noexcept { m_proxy = proxy; }
|
||||
|
||||
logic_net_t & net() noexcept;
|
||||
const logic_net_t & net() const noexcept;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
devices::nld_base_proxy *m_proxy; // FIXME: only used during setup
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -914,7 +915,6 @@ namespace netlist
|
||||
using detail::net_t::set_Q_and_push;
|
||||
using detail::net_t::set_Q_time;
|
||||
using detail::net_t::Q_state_ptr;
|
||||
|
||||
};
|
||||
|
||||
class analog_net_t : public detail::net_t
|
||||
|
@ -81,6 +81,7 @@ namespace netlist
|
||||
PERRMSGV(MF_OBJECT_1_2_WRONG_TYPE, 2, "object {1}({2}) found but wrong type")
|
||||
PERRMSGV(MF_PARAMETER_1_2_NOT_FOUND, 2, "parameter {1}({2}) not found!")
|
||||
PERRMSGV(MF_CONNECTING_1_TO_2, 2, "Error connecting {1} to {2}")
|
||||
PERRMSGV(MF_DUPLICATE_PROXY_1, 1, "Terminal {1} already has proxy")
|
||||
PERRMSGV(MF_MERGE_RAIL_NETS_1_AND_2, 2, "Trying to merge two rail nets: {1} and {2}")
|
||||
PERRMSGV(MF_OBJECT_INPUT_TYPE_1, 1, "Unable to determine input type of {1}")
|
||||
PERRMSGV(MF_OBJECT_OUTPUT_TYPE_1, 1, "Unable to determine output type of {1}")
|
||||
|
@ -506,7 +506,11 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool
|
||||
plib::pthrow<nl_exception>(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
|
||||
}
|
||||
if (term != nullptr)
|
||||
{
|
||||
log().debug("Found input {1}\n", tname);
|
||||
}
|
||||
|
||||
// FIXME: this should resolve any proxy
|
||||
return term;
|
||||
}
|
||||
|
||||
@ -565,9 +569,9 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
|
||||
nl_assert(out.is_logic());
|
||||
|
||||
auto &out_cast = static_cast<logic_output_t &>(out);
|
||||
devices::nld_base_proxy *proxy = out_cast.get_proxy();
|
||||
auto iter_proxy(m_proxies.find(&out));
|
||||
|
||||
if (proxy == nullptr)
|
||||
if (iter_proxy == m_proxies.end())
|
||||
{
|
||||
// create a new one ...
|
||||
pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt);
|
||||
@ -587,17 +591,19 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
|
||||
new_proxy->proxy_term().name(), (*p).name()));
|
||||
}
|
||||
}
|
||||
out.net().core_terms().clear(); // clear the list
|
||||
out.net().core_terms().clear();
|
||||
|
||||
out.net().add_terminal(new_proxy->in());
|
||||
//out_cast.set_proxy(proxy); - Wrong!
|
||||
|
||||
proxy = new_proxy.get();
|
||||
out_cast.set_proxy(proxy);
|
||||
auto proxy(new_proxy.get());
|
||||
if (!m_proxies.insert({&out, proxy}).second)
|
||||
plib::pthrow<nl_exception>(MF_DUPLICATE_PROXY_1(out.name()));
|
||||
|
||||
m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
|
||||
return proxy;
|
||||
}
|
||||
return proxy;
|
||||
else
|
||||
return iter_proxy->second;
|
||||
}
|
||||
|
||||
devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
|
||||
@ -605,20 +611,24 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
|
||||
nl_assert(inp.is_logic());
|
||||
|
||||
auto &incast = dynamic_cast<logic_input_t &>(inp);
|
||||
devices::nld_base_proxy *proxy = incast.get_proxy();
|
||||
|
||||
if (proxy != nullptr)
|
||||
return proxy;
|
||||
auto iter_proxy(m_proxies.find(&inp));
|
||||
|
||||
if (iter_proxy != m_proxies.end())
|
||||
return iter_proxy->second;
|
||||
else
|
||||
{
|
||||
log().debug("connect_terminal_input: connecting proxy\n");
|
||||
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt);
|
||||
auto new_proxy = incast.logic_family()->create_a_d_proxy(m_nlstate, x, &incast);
|
||||
//auto new_proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
|
||||
incast.set_proxy(new_proxy.get());
|
||||
m_proxy_cnt++;
|
||||
|
||||
auto ret = new_proxy.get();
|
||||
auto ret(new_proxy.get());
|
||||
|
||||
if (!m_proxies.insert({&inp, ret}).second)
|
||||
plib::pthrow<nl_exception>(MF_DUPLICATE_PROXY_1(inp.name()));
|
||||
|
||||
m_proxy_cnt++;
|
||||
|
||||
// connect all existing terminals to new net
|
||||
|
||||
@ -644,6 +654,18 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
|
||||
}
|
||||
}
|
||||
|
||||
detail::core_terminal_t &setup_t::resolve_proxy(detail::core_terminal_t &term)
|
||||
{
|
||||
if (term.is_logic())
|
||||
{
|
||||
auto &out = dynamic_cast<logic_t &>(term);
|
||||
auto iter_proxy(m_proxies.find(&out));
|
||||
if (iter_proxy != m_proxies.end())
|
||||
return iter_proxy->second->proxy_term();
|
||||
}
|
||||
return term;
|
||||
}
|
||||
|
||||
void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet)
|
||||
{
|
||||
log().debug("merging nets ...\n");
|
||||
@ -775,17 +797,6 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin
|
||||
}
|
||||
}
|
||||
|
||||
static detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term)
|
||||
{
|
||||
if (term.is_logic())
|
||||
{
|
||||
auto &out = dynamic_cast<logic_t &>(term);
|
||||
if (out.has_proxy())
|
||||
return out.get_proxy()->proxy_term();
|
||||
}
|
||||
return term;
|
||||
}
|
||||
|
||||
bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
|
||||
{
|
||||
bool ret = false;
|
||||
@ -840,7 +851,7 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t
|
||||
}
|
||||
else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT))
|
||||
{
|
||||
if (t1.has_net() && t1.net().isRailNet())
|
||||
if (t1.has_net() && t1.net().isRailNet())
|
||||
{
|
||||
log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
|
||||
plib::pthrow<nl_exception>(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
|
||||
|
@ -453,12 +453,15 @@ namespace netlist
|
||||
|
||||
devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
|
||||
devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);
|
||||
detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term);
|
||||
|
||||
std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
|
||||
|
||||
netlist_state_t &m_nlstate;
|
||||
devices::nld_netlistparams *m_netlist_params;
|
||||
std::unordered_map<pstring, param_ref_t> m_params;
|
||||
std::unordered_map<detail::core_terminal_t *,
|
||||
devices::nld_base_proxy *> m_proxies;
|
||||
|
||||
unsigned m_proxy_cnt;
|
||||
bool m_validation;
|
||||
|
@ -10,11 +10,11 @@
|
||||
|
||||
#include "netlist/nl_base.h"
|
||||
#include "netlist/nl_errstr.h"
|
||||
#include "plib/mat_cr.h"
|
||||
#include "plib/palloc.h"
|
||||
#include "plib/pmatrix2d.h"
|
||||
#include "plib/putil.h"
|
||||
#include "plib/vector_ops.h"
|
||||
#include "netlist/plib/mat_cr.h"
|
||||
#include "netlist/plib/palloc.h"
|
||||
#include "netlist/plib/pmatrix2d.h"
|
||||
#include "netlist/plib/putil.h"
|
||||
#include "netlist/plib/vector_ops.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -286,6 +286,11 @@ NETLIST_START(cheekyms)
|
||||
NET_C(I_PEST_DIES.Q, IC2_1.RESET)
|
||||
NET_C(I_COIN_EXTRA.Q, IC4_2.RESET)
|
||||
|
||||
NET_C(I_V5, I_MUTE.VCC, I_CHEESE.VCC, I_MUSIC.VCC, I_MOUSE.VCC, I_HAMMER.VCC,
|
||||
I_PEST.VCC, I_MOUSE_DIES.VCC, I_PEST_DIES.VCC, I_COIN_EXTRA.VCC)
|
||||
NET_C(I_V5, I_MUTE.GND, I_CHEESE.GND, I_MUSIC.GND, I_MOUSE.GND, I_HAMMER.GND,
|
||||
I_PEST.GND, I_MOUSE_DIES.GND, I_PEST_DIES.GND, I_COIN_EXTRA.GND)
|
||||
|
||||
NETLIST_END()
|
||||
|
||||
|
||||
|
@ -40,6 +40,9 @@ NETLIST_START(gamemachine)
|
||||
LOGIC_INPUT(P14, 1, "OPENDRAIN")
|
||||
LOGIC_INPUT(P15, 1, "OPENDRAIN")
|
||||
|
||||
NET_C(V5, P08.VCC, P09.VCC, P10.VCC, P11.VCC, P12.VCC, P13.VCC, P14.VCC, P15.VCC)
|
||||
NET_C(GND, P08.GND, P09.GND, P10.GND, P11.GND, P12.GND, P13.GND, P14.GND, P15.GND)
|
||||
|
||||
RES(R1, RES_K(2.4))
|
||||
RES(R2, RES_K(10))
|
||||
RES(R3, RES_K(4.3))
|
||||
|
@ -368,7 +368,9 @@ NETLIST_START(kidniki)
|
||||
PARAM(Solver.GS_LOOPS, 10)
|
||||
//PARAM(Solver.METHOD, "SOR")
|
||||
PARAM(Solver.METHOD, "MAT_CR")
|
||||
PARAM(Solver.FPTYPE, "DOUBLE")
|
||||
//PARAM(Solver.METHOD, "MAT")
|
||||
//PARAM(Solver.PIVOT, 1)
|
||||
//PARAM(Solver.METHOD, "GMRES")
|
||||
PARAM(Solver.SOR_FACTOR, 1.313)
|
||||
PARAM(Solver.DYNAMIC_TS, 0)
|
||||
@ -421,6 +423,7 @@ NETLIST_START(kidniki)
|
||||
ALIAS(I_SOUND0, R_AY45L_A.2)
|
||||
|
||||
TTL_INPUT(SINH, 1)
|
||||
|
||||
#if (D6_EXISTS)
|
||||
DIODE(D6, "1N914")
|
||||
NET_C(D6.K, SINH)
|
||||
@ -438,6 +441,9 @@ NETLIST_START(kidniki)
|
||||
LOGIC_INPUT(I_CH0, 1, "AY8910PORT")
|
||||
LOGIC_INPUT(I_OH0, 1, "AY8910PORT")
|
||||
|
||||
NET_C(I_V5, I_SD0.VCC, I_BD0.VCC, I_CH0.VCC, I_OH0.VCC, SINH.VCC)
|
||||
NET_C(GND, I_SD0.GND, I_BD0.GND, I_CH0.GND, I_OH0.GND, SINH.GND)
|
||||
|
||||
ANALOG_INPUT(I_MSM2K0, 0)
|
||||
ANALOG_INPUT(I_MSM3K0, 0)
|
||||
|
||||
|
@ -227,6 +227,10 @@ NETLIST_START(mario)
|
||||
|
||||
ANALOG_INPUT(V5, 5)
|
||||
ALIAS(VCC, V5) // no-ttl-dip devices need VCC!
|
||||
TTL_INPUT(ttlhigh, 1)
|
||||
TTL_INPUT(ttllow, 0)
|
||||
NET_C(VCC, ttlhigh.VCC, ttllow.VCC, SOUND0.VCC, SOUND1.VCC, SOUND7.VCC)
|
||||
NET_C(GND, ttlhigh.GND, ttllow.GND, SOUND0.GND, SOUND1.GND, SOUND7.GND)
|
||||
|
||||
TTL_INPUT(SOUND0, 1)
|
||||
INCLUDE(nl_mario_snd0)
|
||||
|
@ -369,6 +369,7 @@ NETLIST_START(zac1b11142)
|
||||
LOGIC_INPUT(I_LEVEL, 1, "AY8910PORT")
|
||||
LOGIC_INPUT(I_LEVELT, 1, "AY8910PORT")
|
||||
LOGIC_INPUT(I_SW1, 1, "AY8910PORT")
|
||||
|
||||
ALIAS(IOA0, I_IOA0.Q)
|
||||
ALIAS(IOA1, I_IOA1.Q)
|
||||
ALIAS(IOA2, I_IOA2.Q)
|
||||
@ -378,6 +379,11 @@ NETLIST_START(zac1b11142)
|
||||
ALIAS(LEVELT, I_LEVELT.Q)
|
||||
ALIAS(SW1, I_SW1.Q)
|
||||
|
||||
NET_C(VCC, I_IOA0.VCC, I_IOA1.VCC, I_IOA2.VCC, I_IOA3.VCC, I_IOA4.VCC,
|
||||
I_LEVEL.VCC, I_LEVELT.VCC, I_SW1.VCC)
|
||||
NET_C(GND, I_IOA0.GND, I_IOA1.GND, I_IOA2.GND, I_IOA3.GND, I_IOA4.GND,
|
||||
I_LEVEL.GND, I_LEVELT.GND, I_SW1.GND)
|
||||
|
||||
// AY-3-8910 4G/4H analog outputs
|
||||
RES(R_AY4G_A, 1000)
|
||||
RES(R_AY4G_B, 1000)
|
||||
|
@ -117,6 +117,13 @@ NETLIST_START(breakout)
|
||||
ALIAS(GNDD ,GND.Q)
|
||||
ALIAS(P ,V5.Q)
|
||||
|
||||
TTL_INPUT(ttlhigh, 1)
|
||||
TTL_INPUT(ttllow, 0)
|
||||
TTL_INPUT(antenna, 0)
|
||||
|
||||
NET_C(VCC, ttlhigh.VCC, ttllow.VCC, antenna.VCC)
|
||||
NET_C(GND, ttlhigh.GND, ttllow.GND, antenna.GND)
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Clock circuit
|
||||
//----------------------------------------------------------------
|
||||
@ -168,8 +175,6 @@ NETLIST_START(breakout)
|
||||
// Startup / Antenna latch
|
||||
//----------------------------------------------------------------
|
||||
|
||||
TTL_INPUT(antenna, 0)
|
||||
|
||||
DIODE(CR3, "1N914")
|
||||
DIODE(CR4, "1N914")
|
||||
DIODE(CR5, "1N914")
|
||||
|
@ -31,6 +31,9 @@ NETLIST_START(gtrak10)
|
||||
TTL_INPUT(high, 1)
|
||||
TTL_INPUT(low, 0)
|
||||
|
||||
NET_C(VCC, high.VCC, low.VCC)
|
||||
NET_C(GND, high.GND, low.GND)
|
||||
|
||||
MAINCLOCK(CLOCK, 14318181)
|
||||
|
||||
ALIAS(P, high)
|
||||
|
@ -244,4 +244,9 @@ NETLIST_START(hazelvid)
|
||||
NET_C(R21_POT.3, GND)
|
||||
NET_C(R21_POT.2, GND)
|
||||
|
||||
NET_C(VCC, high.VCC, low.VCC, cpu_ba4.VCC, cpu_iowq.VCC, ba13.VCC, memwq.VCC, rwq.VCC, mrq.VCC,
|
||||
cpu_db0.VCC, cpu_db1.VCC, cpu_db2.VCC, cpu_db3.VCC, cpu_db4.VCC, cpu_db5.VCC, cpu_db6.VCC, cpu_db7.VCC)
|
||||
NET_C(GND, high.GND, low.GND, cpu_ba4.GND, cpu_iowq.GND, ba13.GND, memwq.GND, rwq.GND, mrq.GND,
|
||||
cpu_db0.GND, cpu_db1.GND, cpu_db2.GND, cpu_db3.GND, cpu_db4.GND, cpu_db5.GND, cpu_db6.GND, cpu_db7.GND)
|
||||
|
||||
NETLIST_END()
|
||||
|
@ -42,6 +42,8 @@ NETLIST_START(palestra)
|
||||
|
||||
TTL_INPUT(high, 1)
|
||||
TTL_INPUT(low, 0)
|
||||
NET_C(VCC, high.VCC, low.VCC)
|
||||
NET_C(GND, high.GND, low.GND)
|
||||
|
||||
/*
|
||||
* board A2 -- score display
|
||||
|
@ -575,4 +575,11 @@ NETLIST_START(pongf)
|
||||
|
||||
ALIAS(videomix, RV3.2)
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// power terminals
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NET_C(VCC, high.VCC, low.VCC, antenna.VCC)
|
||||
NET_C(GND, high.GND, low.GND, antenna.GND)
|
||||
|
||||
NETLIST_END()
|
||||
|
@ -81,6 +81,8 @@ static NETLIST_START(rebound_schematics)
|
||||
SWITCH2(START_SW)
|
||||
|
||||
TTL_INPUT(antenna, 0)
|
||||
NET_C(V5, antenna.VCC)
|
||||
NET_C(GND, antenna.GND)
|
||||
|
||||
// DSW1a/b are actually only a 1 contact switches.
|
||||
// The logic is needed to force high level on
|
||||
@ -116,6 +118,12 @@ static NETLIST_START(rebound_schematics)
|
||||
|
||||
NET_C(CON15, antenna)
|
||||
|
||||
// Coin Counter is connected to CON10 as well. Simulate using resistor
|
||||
|
||||
RES(RCOINCOUNTER, 10)
|
||||
NET_C(RCOINCOUNTER.1, CON10)
|
||||
NET_C(RCOINCOUNTER.2, V5)
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* Real netlist start
|
||||
* -----------------------------------------------------------------------*/
|
||||
@ -1289,8 +1297,6 @@ NETLIST_START(rebound)
|
||||
|
||||
LOCAL_SOURCE(rebound_schematics)
|
||||
SOLVER(Solver, 480)
|
||||
PARAM(Solver.VNTOL, 1e-9)
|
||||
PARAM(Solver.RELTOL, 1e-9)
|
||||
PARAM(Solver.DYNAMIC_TS, 1)
|
||||
PARAM(Solver.DYNAMIC_LTE, 1e-6)
|
||||
PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 5e-7)
|
||||
|
@ -657,5 +657,18 @@ NETLIST_START(stuntcyc)
|
||||
|
||||
TTL_7404_INVERT(K8_2, CYCLE_RESET)
|
||||
ALIAS(CYCLE_RESET_A_Q, K8_2.Q)
|
||||
|
||||
// Power terminals
|
||||
|
||||
NET_C(VCC, high.VCC, low.VCC, ANTENNA.VCC, FREESCORE_SW_B0.VCC, FREESCORE_SW_B1.VCC, FREESCORE_SW_B2.VCC, FREESCORE_SW_B3.VCC,
|
||||
MISS_SW_B0.VCC, MISS_SW_B1.VCC, MISS_SW_B2.VCC, R38_2.VCC, R39_2.VCC)
|
||||
NET_C(GND, high.GND, low.GND, ANTENNA.GND, FREESCORE_SW_B0.GND, FREESCORE_SW_B1.GND, FREESCORE_SW_B2.GND, FREESCORE_SW_B3.GND,
|
||||
MISS_SW_B0.GND, MISS_SW_B1.GND, MISS_SW_B2.GND, R38_2.GND, R39_2.GND)
|
||||
|
||||
NET_C(VCC, OUT_probe_bit0.VCC, OUT_probe_bit1.VCC, OUT_probe_bit2.VCC, OUT_probe_bit3.VCC,
|
||||
OUT_probe_bit4.VCC, OUT_probe_bit5.VCC, OUT_probe_bit6.VCC, OUT_probe_clock.VCC)
|
||||
NET_C(GND, OUT_probe_bit0.GND, OUT_probe_bit1.GND, OUT_probe_bit2.GND, OUT_probe_bit3.GND,
|
||||
OUT_probe_bit4.GND, OUT_probe_bit5.GND, OUT_probe_bit6.GND, OUT_probe_clock.GND)
|
||||
|
||||
#endif
|
||||
NETLIST_END()
|
||||
|
@ -40,6 +40,8 @@ NETLIST_START(tp1983)
|
||||
|
||||
TTL_INPUT(high, 1)
|
||||
TTL_INPUT(low, 0)
|
||||
NET_C(VCC, high.VCC, low.VCC)
|
||||
NET_C(GND, high.GND, low.GND)
|
||||
|
||||
// skipping D7.1 D7.2 D8.2 clock generator circuit
|
||||
MAINCLOCK(clk, 250000.0)
|
||||
|
@ -47,6 +47,8 @@ NETLIST_START(tp1985)
|
||||
|
||||
TTL_INPUT(high, 1)
|
||||
TTL_INPUT(low, 0)
|
||||
NET_C(VCC, high.VCC, low.VCC)
|
||||
NET_C(GND, high.GND, low.GND)
|
||||
|
||||
MAINCLOCK(clk, 4000000.0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user