trunk/src/mame/drivers/pong.c
r26874 | r26875 | |
461 | 461 | TTL_7402_NOR(ic_d2c, ic_e3c.Q, ic_e3b.Q) |
462 | 462 | TTL_7404_INVERT(ic_g1a, 32V) |
463 | 463 | TTL_7425_NOR(ic_f2a, ic_g1a.Q, 64V, 128V, ic_d2c.Q) |
464 | | NET_ALIAS(c5-en, ic_f2a.Q) |
| 464 | NET_ALIAS(c5_en, ic_f2a.Q) |
465 | 465 | |
466 | 466 | // ---------------------------------------------------------------------------------------- |
467 | 467 | // Score logic ... |
r26874 | r26875 | |
507 | 507 | TTL_74153(ic_c6a, high, score1_1, high, score2_1, 32H, 64H, low) |
508 | 508 | TTL_74153(ic_c6b, score1_10Q, score1_2, score2_10Q, score2_2, 32H, 64H, low) |
509 | 509 | |
510 | | TTL_7448(ic_c5, ic_c6a.AY, ic_c6b.AY, ic_d6a.AY, ic_d6b.AY, high, c5-en, high) |
| 510 | TTL_7448(ic_c5, ic_c6a.AY, ic_c6b.AY, ic_d6a.AY, ic_d6b.AY, high, c5_en, high) |
511 | 511 | |
512 | 512 | TTL_7404_INVERT(ic_e4b, 16H) |
513 | 513 | TTL_7427_NOR(ic_e5c, ic_e4b.Q, 8H, 4H) |
r26874 | r26875 | |
592 | 592 | required_device<netlist_mame_logic_input_t> m_sw1a; |
593 | 593 | required_device<netlist_mame_logic_input_t> m_sw1b; |
594 | 594 | |
595 | | UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 595 | //UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
596 | 596 | |
597 | 597 | DECLARE_INPUT_CHANGED_MEMBER(input_changed); |
598 | 598 | |
r26874 | r26875 | |
677 | 677 | PORT_ADJUSTER( 50, "VR1 - 50k, Paddle 1 adjustment" ) NETLIST_ANALOG_PORT_CHANGED("maincpu", "vr0") |
678 | 678 | PORT_START("VR2") |
679 | 679 | PORT_ADJUSTER( 50, "VR2 - 50k, Paddle 2 adjustment" ) NETLIST_ANALOG_PORT_CHANGED("maincpu", "vr1") |
680 | | //PORT_START("GATESPEED") |
681 | | //PORT_ADJUSTER( 100, "Logic Gate Delay" ) PORT_MINMAX(10, 200) PORT_CHANGED_MEMBER(DEVICE_SELF, pong_state, input_changed, IC_GATEDELAY) |
682 | 680 | |
683 | 681 | INPUT_PORTS_END |
684 | 682 | |
trunk/src/emu/netlist/nl_setup.c
r26874 | r26875 | |
60 | 60 | netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const pstring &name) |
61 | 61 | { |
62 | 62 | if (!(netlist().m_devices.add(name, dev, false)==TMERR_NONE)) |
63 | | netlist().xfatalerror("Error adding %s to device list\n", name.cstr()); |
| 63 | netlist().error("Error adding %s to device list\n", name.cstr()); |
64 | 64 | return dev; |
65 | 65 | } |
66 | 66 | |
r26874 | r26875 | |
86 | 86 | netlist_device_t *dev = netlist().m_devices.find(name); |
87 | 87 | pstring temp = name + "."; |
88 | 88 | if (dev == NULL) |
89 | | netlist().xfatalerror("Device %s does not exist\n", name.cstr()); |
| 89 | netlist().error("Device %s does not exist\n", name.cstr()); |
90 | 90 | |
91 | 91 | //remove_start_with<tagmap_input_t>(m_inputs, temp); |
92 | 92 | remove_start_with<tagmap_terminal_t>(m_terminals, temp); |
r26874 | r26875 | |
112 | 112 | { |
113 | 113 | //if (!(m_alias.add(alias, new nstring(out), false)==TMERR_NONE)) |
114 | 114 | if (!(m_alias.add(alias, out, false)==TMERR_NONE)) |
115 | | netlist().xfatalerror("Error adding alias %s to alias list\n", alias.cstr()); |
| 115 | netlist().error("Error adding alias %s to alias list\n", alias.cstr()); |
116 | 116 | } |
117 | 117 | |
118 | 118 | pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in) |
r26874 | r26875 | |
142 | 142 | break; |
143 | 143 | } |
144 | 144 | // FIXME: noreturn |
145 | | netlist().xfatalerror("Unknown object type %d\n", in.type()); |
| 145 | netlist().error("Unknown object type %d\n", in.type()); |
146 | 146 | return "Error"; |
147 | 147 | } |
148 | 148 | |
r26874 | r26875 | |
161 | 161 | term.init_object(upd_dev, dev.name() + "." + name, state); |
162 | 162 | |
163 | 163 | if (!(m_terminals.add(term.name(), &term, false)==TMERR_NONE)) |
164 | | netlist().xfatalerror("Error adding %s %s to terminal list\n", objtype_as_astr(term).cstr(), term.name().cstr()); |
| 164 | netlist().error("Error adding %s %s to terminal list\n", objtype_as_astr(term).cstr(), term.name().cstr()); |
165 | 165 | NL_VERBOSE_OUT(("%s %s\n", objtype_as_astr(term).cstr(), name.cstr())); |
166 | 166 | } |
167 | 167 | break; |
r26874 | r26875 | |
180 | 180 | NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", temp.cstr(), val->cstr())); |
181 | 181 | double vald = 0; |
182 | 182 | if (sscanf(val.cstr(), "%lf", &vald) != 1) |
183 | | netlist().xfatalerror("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); |
| 183 | netlist().error("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); |
184 | 184 | dynamic_cast<netlist_param_double_t &>(param).initial(vald); |
185 | 185 | } |
186 | 186 | break; |
r26874 | r26875 | |
190 | 190 | NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", name.cstr(), val->cstr())); |
191 | 191 | int vald = 0; |
192 | 192 | if (sscanf(val.cstr(), "%d", &vald) != 1) |
193 | | netlist().xfatalerror("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); |
| 193 | netlist().error("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); |
194 | 194 | dynamic_cast<netlist_param_int_t &>(param).initial(vald); |
195 | 195 | } |
196 | 196 | break; |
r26874 | r26875 | |
215 | 215 | } |
216 | 216 | } |
217 | 217 | if (!found) |
218 | | netlist().xfatalerror("Model %s not found\n", val.cstr()); |
| 218 | netlist().error("Model %s not found\n", val.cstr()); |
219 | 219 | } |
220 | 220 | break; |
221 | 221 | default: |
222 | | netlist().xfatalerror("Parameter is not supported %s : %s\n", name.cstr(), val.cstr()); |
| 222 | netlist().error("Parameter is not supported %s : %s\n", name.cstr(), val.cstr()); |
223 | 223 | } |
224 | 224 | } |
225 | 225 | if (!(m_params.add(name, ¶m, false)==TMERR_NONE)) |
226 | | netlist().xfatalerror("Error adding parameter %s to parameter list\n", name.cstr()); |
| 226 | netlist().error("Error adding parameter %s to parameter list\n", name.cstr()); |
227 | 227 | } |
228 | 228 | break; |
229 | 229 | case netlist_terminal_t::DEVICE: |
230 | | netlist().xfatalerror("Device registration not yet supported - \n", name.cstr()); |
| 230 | netlist().error("Device registration not yet supported - \n", name.cstr()); |
231 | 231 | break; |
232 | 232 | case netlist_terminal_t::NETLIST: |
233 | | netlist().xfatalerror("Netlist registration not yet supported - \n", name.cstr()); |
| 233 | netlist().error("Netlist registration not yet supported - \n", name.cstr()); |
234 | 234 | break; |
235 | 235 | } |
236 | 236 | } |
r26874 | r26875 | |
254 | 254 | { |
255 | 255 | //if (!(m_params_temp.add(param, new nstring(value), false)==TMERR_NONE)) |
256 | 256 | if (!(m_params_temp.add(param, value, false)==TMERR_NONE)) |
257 | | netlist().xfatalerror("Error adding parameter %s to parameter list\n", param.cstr()); |
| 257 | netlist().error("Error adding parameter %s to parameter list\n", param.cstr()); |
258 | 258 | } |
259 | 259 | |
260 | 260 | const pstring netlist_setup_t::resolve_alias(const pstring &name) const |
r26874 | r26875 | |
274 | 274 | pstring dname = ret; |
275 | 275 | netlist_device_t *dev = netlist().m_devices.find(dname.substr(0,p)); |
276 | 276 | if (dev == NULL) |
277 | | netlist().xfatalerror("Device for %s not found\n", name.cstr()); |
| 277 | netlist().error("Device for %s not found\n", name.cstr()); |
278 | 278 | int c = atoi(ret.substr(p+2,ret.len()-p-3)); |
279 | 279 | temp = dev->name() + "." + dev->m_terminals[c]; |
280 | 280 | // reresolve .... |
r26874 | r26875 | |
302 | 302 | ret = m_terminals.find(s); |
303 | 303 | } |
304 | 304 | if (ret == NULL && required) |
305 | | netlist().xfatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr()); |
| 305 | netlist().error("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr()); |
306 | 306 | if (ret != NULL) |
307 | 307 | NL_VERBOSE_OUT(("Found input %s\n", tname.cstr())); |
308 | 308 | return ret; |
r26874 | r26875 | |
322 | 322 | ret = m_terminals.find(s); |
323 | 323 | } |
324 | 324 | if (ret == NULL && required) |
325 | | netlist().xfatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr()); |
| 325 | netlist().error("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr()); |
326 | 326 | if (ret != NULL && ret->type() != atype) |
327 | 327 | { |
328 | 328 | if (required) |
329 | | netlist().xfatalerror("object %s(%s) found but wrong type\n", terminal_in.cstr(), tname.cstr()); |
| 329 | netlist().error("object %s(%s) found but wrong type\n", terminal_in.cstr(), tname.cstr()); |
330 | 330 | else |
331 | 331 | ret = NULL; |
332 | 332 | } |
r26874 | r26875 | |
342 | 342 | |
343 | 343 | ret = m_params.find(outname); |
344 | 344 | if (ret == NULL && required) |
345 | | netlist().xfatalerror("parameter %s(%s) not found!\n", param_in.cstr(), outname.cstr()); |
| 345 | netlist().error("parameter %s(%s) not found!\n", param_in.cstr(), outname.cstr()); |
346 | 346 | if (ret != NULL) |
347 | 347 | NL_VERBOSE_OUT(("Found parameter %s\n", outname.cstr())); |
348 | 348 | return ret; |
r26874 | r26875 | |
408 | 408 | } |
409 | 409 | else |
410 | 410 | { |
411 | | netlist().xfatalerror("Netlist: Severe Error"); |
| 411 | netlist().error("Netlist: Severe Error"); |
412 | 412 | } |
413 | 413 | } |
414 | 414 | |
r26874 | r26875 | |
443 | 443 | } |
444 | 444 | else |
445 | 445 | { |
446 | | netlist().xfatalerror("Netlist: Severe Error"); |
| 446 | netlist().error("Netlist: Severe Error"); |
447 | 447 | } |
448 | 448 | } |
449 | 449 | |
r26874 | r26875 | |
518 | 518 | connect_terminals(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_terminal_t &>(t2)); |
519 | 519 | } |
520 | 520 | else |
521 | | netlist().xfatalerror("Connecting %s to %s not supported!\n", t1.name().cstr(), t2.name().cstr()); |
| 521 | netlist().error("Connecting %s to %s not supported!\n", t1.name().cstr(), t2.name().cstr()); |
522 | 522 | } |
523 | 523 | |
524 | 524 | void netlist_setup_t::resolve_inputs() |
r26874 | r26875 | |
570 | 570 | for (tagmap_terminal_t::entry_t *entry = m_terminals.first(); entry != NULL; entry = m_terminals.next(entry)) |
571 | 571 | { |
572 | 572 | if (!entry->object()->has_net()) |
573 | | netlist().xfatalerror("Found terminal %s without a net\n", |
| 573 | netlist().error("Found terminal %s without a net\n", |
574 | 574 | entry->object()->name().cstr()); |
575 | 575 | } |
576 | 576 | |
r26874 | r26875 | |
583 | 583 | { |
584 | 584 | has_twoterms = true; |
585 | 585 | if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet()) |
586 | | netlist().xfatalerror("Found device %s connected only to railterminals %s/%s\n", |
| 586 | netlist().error("Found device %s connected only to railterminals %s/%s\n", |
587 | 587 | t->name().cstr(), t->m_N.net().name().cstr(), t->m_P.net().name().cstr()); |
588 | 588 | } |
589 | 589 | } |
r26874 | r26875 | |
593 | 593 | if (m_netlist.solver() == NULL) |
594 | 594 | { |
595 | 595 | if (!has_twoterms) |
596 | | netlist().xfatalerror("No solver found for this net although analog elements are present\n"); |
| 596 | netlist().error("No solver found for this net although analog elements are present\n"); |
597 | 597 | } |
598 | 598 | else |
599 | 599 | m_netlist.solver()->post_start(); |
r26874 | r26875 | |
629 | 629 | if (dynamic_cast<NETLIB_NAME(mainclock)*>(dev) != NULL) |
630 | 630 | { |
631 | 631 | if (has_mainclock) |
632 | | m_netlist.xfatalerror("Found more than one mainclock"); |
| 632 | m_netlist.error("Found more than one mainclock"); |
633 | 633 | m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev)); |
634 | 634 | has_mainclock = true; |
635 | 635 | } |
636 | 636 | if (dynamic_cast<NETLIB_NAME(solver)*>(dev) != NULL) |
637 | 637 | { |
638 | 638 | if (has_solver) |
639 | | m_netlist.xfatalerror("Found more than one solver"); |
| 639 | m_netlist.error("Found more than one solver"); |
640 | 640 | m_netlist.set_solver_dev(dynamic_cast<NETLIB_NAME(solver)*>(dev)); |
641 | 641 | has_solver = true; |
642 | 642 | } |
trunk/src/emu/netlist/nl_lists.h
r26874 | r26875 | |
37 | 37 | |
38 | 38 | ATTR_COLD netlist_list_t(const netlist_list_t &rhs) |
39 | 39 | { |
| 40 | m_num_elements = rhs.capacity(); |
40 | 41 | m_list = new entry_t[m_num_elements]; |
41 | 42 | m_ptr = m_list; |
42 | 43 | m_ptr--; |
r26874 | r26875 | |
60 | 61 | { |
61 | 62 | delete[] m_list; |
62 | 63 | } |
| 64 | |
63 | 65 | ATTR_HOT inline void add(const _ListClass elem) |
64 | 66 | { |
65 | 67 | if (m_ptr-m_list >= m_num_elements - 1) |
r26874 | r26875 | |
67 | 69 | |
68 | 70 | (++m_ptr)->m_obj = elem; |
69 | 71 | } |
| 72 | |
70 | 73 | ATTR_HOT inline void resize(const int new_size) |
71 | 74 | { |
72 | 75 | int cnt = count(); |
r26874 | r26875 | |
80 | 83 | m_ptr = m_list + cnt - 1; |
81 | 84 | m_num_elements = new_size; |
82 | 85 | } |
| 86 | |
83 | 87 | ATTR_HOT inline void remove(const _ListClass elem) |
84 | 88 | { |
85 | 89 | for (entry_t *i = m_list; i <= m_ptr; i++) |
r26874 | r26875 | |
96 | 100 | } |
97 | 101 | } |
98 | 102 | } |
| 103 | |
99 | 104 | ATTR_HOT inline bool contains(const _ListClass elem) const |
100 | 105 | { |
101 | 106 | for (entry_t *i = m_list; i <= m_ptr; i++) |
r26874 | r26875 | |
105 | 110 | } |
106 | 111 | return false; |
107 | 112 | } |
| 113 | |
108 | 114 | ATTR_HOT inline entry_t *first() const { return (m_ptr >= m_list ? &m_list[0] : NULL ); } |
109 | 115 | ATTR_HOT inline entry_t *next(entry_t *lc) const { return (lc < last() ? lc + 1 : NULL ); } |
110 | 116 | ATTR_HOT inline entry_t *last() const { return m_ptr; } |
111 | 117 | ATTR_HOT inline int count() const { return m_ptr - m_list + 1; } |
112 | 118 | ATTR_HOT inline bool empty() const { return (m_ptr < m_list); } |
113 | 119 | ATTR_HOT inline void reset() { m_ptr = m_list - 1; } |
| 120 | ATTR_HOT inline int capacity() const { return m_num_elements; } |
114 | 121 | |
115 | 122 | ATTR_COLD void reset_and_free() |
116 | 123 | { |
r26874 | r26875 | |
121 | 128 | reset(); |
122 | 129 | } |
123 | 130 | |
124 | | //ATTR_HOT inline entry_t *item(int i) const { return &m_list[i]; } |
125 | 131 | ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index].m_obj; } |
126 | 132 | ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index].m_obj; } |
127 | 133 | |
r26874 | r26875 | |
145 | 151 | struct entry_t |
146 | 152 | { |
147 | 153 | public: |
148 | | inline entry_t() |
149 | | : m_time(), m_object(NULL) {} |
150 | | inline entry_t(const _Time atime, _Element &elem) : m_time(atime), m_object(&elem) {} |
151 | | ATTR_HOT inline const _Time &time() const { return m_time; } |
152 | | ATTR_HOT inline _Element & object() const { return *m_object; } |
| 154 | ATTR_HOT inline entry_t() |
| 155 | : m_time(), m_object() {} |
| 156 | ATTR_HOT inline entry_t(const _Time atime, _Element elem) : m_time(atime), m_object(elem) {} |
| 157 | ATTR_HOT inline _Time time() const { return m_time; } |
| 158 | ATTR_HOT inline _Element object() const { return m_object; } |
153 | 159 | |
154 | | ATTR_HOT inline const _Time *time_ptr() const { return &m_time; } |
155 | | ATTR_HOT inline _Element *object_ptr() const { return m_object; } |
156 | 160 | private: |
157 | 161 | _Time m_time; |
158 | | _Element *m_object; |
| 162 | _Element m_object; |
159 | 163 | }; |
160 | 164 | |
161 | 165 | netlist_timed_queue() |
r26874 | r26875 | |
168 | 172 | ATTR_HOT inline bool is_empty() const { return (m_end == &m_list[0]); } |
169 | 173 | ATTR_HOT inline bool is_not_empty() const { return (m_end > &m_list[0]); } |
170 | 174 | |
171 | | ATTR_HOT ATTR_ALIGN inline void push(const entry_t &e) |
| 175 | ATTR_HOT ATTR_ALIGN void push(const entry_t &e) |
172 | 176 | { |
173 | | if (is_empty() || (e.time() <= (m_end - 1)->time())) |
| 177 | #if 0 |
| 178 | // less is more |
| 179 | if (is_empty() || (e.time() <= (m_end - 1)->time())) |
174 | 180 | { |
175 | 181 | *m_end++ = e; |
176 | 182 | inc_stat(m_prof_end); |
177 | 183 | } |
178 | 184 | else |
| 185 | #endif |
179 | 186 | { |
180 | 187 | entry_t * RESTRICT i = m_end++; |
181 | | while ((i>&m_list[0]) && (e.time() > (i-1)->time()) ) |
| 188 | while ((i > &m_list[0]) && (e.time() > (i - 1)->time()) ) |
182 | 189 | { |
183 | | i--; |
| 190 | i--; |
184 | 191 | *(i+1) = *i; |
185 | 192 | inc_stat(m_prof_sortmove); |
186 | 193 | } |
r26874 | r26875 | |
190 | 197 | assert(m_end - m_list < _Size); |
191 | 198 | } |
192 | 199 | |
193 | | ATTR_HOT inline const entry_t &pop() |
| 200 | ATTR_HOT inline entry_t pop() |
194 | 201 | { |
195 | 202 | return *--m_end; |
196 | 203 | } |
r26874 | r26875 | |
207 | 214 | |
208 | 215 | // save state support & mame disasm |
209 | 216 | |
210 | | ATTR_COLD entry_t *listptr() { return &m_list[0]; } |
211 | | ATTR_COLD int count() const { return m_end - m_list; } |
212 | | ATTR_HOT inline entry_t & operator[](const int & index) { return m_list[index]; } |
| 217 | ATTR_COLD inline const entry_t *listptr() const { return &m_list[0]; } |
| 218 | ATTR_HOT inline int count() const { return m_end - m_list; } |
| 219 | ATTR_HOT inline const entry_t & operator[](const int & index) const { return m_list[index]; } |
213 | 220 | |
214 | 221 | #if (NL_KEEP_STATISTICS) |
215 | 222 | // profiling |
trunk/src/emu/netlist/nl_base.c
r26874 | r26875 | |
15 | 15 | // ---------------------------------------------------------------------------------------- |
16 | 16 | |
17 | 17 | netlist_queue_t::netlist_queue_t(netlist_base_t &nl) |
18 | | : netlist_timed_queue<netlist_net_t, netlist_time, 512>(), pstate_callback_t(), |
| 18 | : netlist_timed_queue<netlist_net_t *, netlist_time, 512>(), pstate_callback_t(), |
19 | 19 | m_netlist(nl), |
20 | 20 | m_qsize(0) |
21 | 21 | { } |
r26874 | r26875 | |
36 | 36 | for (int i = 0; i < m_qsize; i++ ) |
37 | 37 | { |
38 | 38 | m_times[i] = this->listptr()[i].time().as_raw(); |
39 | | const char *p = this->listptr()[i].object().name().cstr(); |
| 39 | const char *p = this->listptr()[i].object()->name().cstr(); |
40 | 40 | int n = MIN(63, strlen(p)); |
41 | 41 | strncpy(&(m_name[i][0]), p, n); |
42 | 42 | m_name[i][n] = 0; |
r26874 | r26875 | |
53 | 53 | netlist_net_t *n = m_netlist.find_net(&(m_name[i][0])); |
54 | 54 | NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n)); |
55 | 55 | NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double())); |
56 | | this->push(netlist_queue_t::entry_t(netlist_time::from_raw(m_times[i]), *n)); |
| 56 | this->push(netlist_queue_t::entry_t(netlist_time::from_raw(m_times[i]), n)); |
57 | 57 | } |
58 | 58 | } |
59 | 59 | |
r26874 | r26875 | |
82 | 82 | ATTR_COLD const pstring &netlist_object_t::name() const |
83 | 83 | { |
84 | 84 | if (m_name == "") |
85 | | netlist().xfatalerror("object not initialized"); |
| 85 | netlist().error("object not initialized"); |
86 | 86 | return m_name; |
87 | 87 | } |
88 | 88 | |
r26874 | r26875 | |
197 | 197 | { |
198 | 198 | const netlist_queue_t::entry_t &e = m_queue.pop(); |
199 | 199 | m_time_ps = e.time(); |
200 | | e.object().update_devs(); |
| 200 | e.object()->update_devs(); |
201 | 201 | |
202 | 202 | add_to_stat(m_perf_out_processed, 1); |
203 | 203 | if (FATAL_ERROR_AFTER_NS) |
204 | 204 | if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) |
205 | | xfatalerror("Stopped"); |
| 205 | error("Stopped"); |
206 | 206 | } |
207 | 207 | if (m_queue.is_empty()) |
208 | 208 | m_time_ps = m_stop; |
r26874 | r26875 | |
223 | 223 | |
224 | 224 | const netlist_queue_t::entry_t &e = m_queue.pop(); |
225 | 225 | m_time_ps = e.time(); |
226 | | e.object().update_devs(); |
| 226 | e.object()->update_devs(); |
227 | 227 | |
228 | 228 | } else { |
229 | 229 | m_time_ps = mcQ.time(); |
r26874 | r26875 | |
231 | 231 | } |
232 | 232 | if (FATAL_ERROR_AFTER_NS) |
233 | 233 | if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS)) |
234 | | xfatalerror("Stopped"); |
| 234 | error("Stopped"); |
235 | 235 | |
236 | 236 | add_to_stat(m_perf_out_processed, 1); |
237 | 237 | } |
238 | 238 | } |
239 | 239 | } |
240 | 240 | |
241 | | ATTR_COLD void netlist_base_t::xfatalerror(const char *format, ...) const |
| 241 | ATTR_COLD void netlist_base_t::error(const char *format, ...) const |
242 | 242 | { |
243 | 243 | va_list ap; |
244 | 244 | va_start(ap, format); |
r26874 | r26875 | |
273 | 273 | { |
274 | 274 | init_object(anetlist, name); |
275 | 275 | |
276 | | #if USE_DELEGATES |
277 | 276 | #if USE_PMFDELEGATES |
278 | 277 | void (netlist_core_device_t::* pFunc)() = &netlist_core_device_t::update; |
279 | 278 | static_update = reinterpret_cast<net_update_delegate>((this->*pFunc)); |
280 | | #else |
281 | | static_update = net_update_delegate(&netlist_core_device_t::update, "update", this); |
282 | | // get the pointer to the member function |
283 | 279 | #endif |
284 | | #endif |
285 | 280 | |
286 | 281 | } |
287 | 282 | |
r26874 | r26875 | |
383 | 378 | dynamic_cast<netlist_terminal_t &>(term).init_object(dev, dev.name() + ".INTTERM", aState); |
384 | 379 | break; |
385 | 380 | default: |
386 | | dev.netlist().xfatalerror("Unknown terminal type"); |
| 381 | dev.netlist().error("Unknown terminal type"); |
387 | 382 | break; |
388 | 383 | } |
389 | 384 | } |
r26874 | r26875 | |
455 | 450 | return; // Nothing to do |
456 | 451 | |
457 | 452 | if (this->isRailNet() && othernet->isRailNet()) |
458 | | netlist().xfatalerror("Trying to merge to rail nets\n"); |
| 453 | netlist().error("Trying to merge to rail nets\n"); |
459 | 454 | |
460 | 455 | if (othernet->isRailNet()) |
461 | 456 | { |
r26874 | r26875 | |
505 | 500 | assert(m_num_cons != 0); |
506 | 501 | |
507 | 502 | assert(this->isRailNet()); |
508 | | { |
509 | | const UINT32 masks[4] = { 1, 5, 3, 1 }; |
510 | | m_cur = m_new; |
511 | | m_in_queue = 2; /* mark as taken ... */ |
512 | 503 | |
513 | | const UINT32 mask = masks[ (m_last.Q << 1) | m_cur.Q ]; |
| 504 | const UINT32 masks[4] = { 1, 5, 3, 1 }; |
| 505 | m_cur = m_new; |
| 506 | m_in_queue = 2; /* mark as taken ... */ |
514 | 507 | |
515 | | netlist_core_terminal_t *p = m_head; |
516 | | switch (m_num_cons) |
517 | | { |
518 | | case 2: |
519 | | update_dev(p, mask); |
520 | | p = p->m_update_list_next; |
521 | | case 1: |
522 | | update_dev(p, mask); |
523 | | break; |
524 | | default: |
525 | | do |
526 | | { |
527 | | update_dev(p, mask); |
528 | | p = p->m_update_list_next; |
529 | | } while (p != NULL); |
530 | | break; |
531 | | } |
532 | | m_last = m_cur; |
533 | | } |
| 508 | const UINT32 mask = masks[ (m_last.Q << 1) | m_cur.Q ]; |
| 509 | |
| 510 | netlist_core_terminal_t *p = m_head; |
| 511 | switch (m_num_cons) |
| 512 | { |
| 513 | case 2: |
| 514 | update_dev(p, mask); |
| 515 | p = p->m_update_list_next; |
| 516 | case 1: |
| 517 | update_dev(p, mask); |
| 518 | break; |
| 519 | default: |
| 520 | do |
| 521 | { |
| 522 | update_dev(p, mask); |
| 523 | p = p->m_update_list_next; |
| 524 | } while (p != NULL); |
| 525 | break; |
| 526 | } |
| 527 | m_last = m_cur; |
534 | 528 | } |
535 | 529 | |
536 | 530 | // ---------------------------------------------------------------------------------------- |
r26874 | r26875 | |
688 | 682 | tmp = tmp.substr(p, pblank - p); |
689 | 683 | int pequal = tmp.find("=", 0); |
690 | 684 | if (pequal < 0) |
691 | | netlist().xfatalerror("parameter %s misformat in model %s temp %s\n", entity.cstr(), Value().cstr(), tmp.cstr()); |
| 685 | netlist().error("parameter %s misformat in model %s temp %s\n", entity.cstr(), Value().cstr(), tmp.cstr()); |
692 | 686 | tmp = tmp.substr(pequal+1); |
693 | 687 | double factor = 1.0; |
694 | 688 | switch (*(tmp.right(1).cstr())) |
r26874 | r26875 | |
716 | 710 | |
717 | 711 | ATTR_HOT inline void NETLIB_NAME(mainclock)::mc_update(netlist_net_t &net, const netlist_time curtime) |
718 | 712 | { |
719 | | net.m_new.Q = !net.m_new.Q; |
| 713 | net.m_new.Q ^= 1; |
720 | 714 | net.set_time(curtime); |
721 | 715 | net.update_devs(); |
722 | 716 | } |
trunk/src/emu/netlist/nl_base.h
r26874 | r26875 | |
163 | 163 | |
164 | 164 | class netlist_core_device_t; |
165 | 165 | |
166 | | #if USE_DELEGATES |
167 | 166 | #if USE_PMFDELEGATES |
168 | 167 | typedef void (*net_update_delegate)(netlist_core_device_t *); |
169 | | #else |
170 | | typedef delegate<void ()> net_update_delegate; |
171 | 168 | #endif |
172 | | #endif |
173 | 169 | |
174 | 170 | //============================================================ |
175 | 171 | // MACROS / netlist devices |
r26874 | r26875 | |
578 | 574 | return m_cur.Analog; |
579 | 575 | } |
580 | 576 | |
581 | | ATTR_HOT inline void push_to_queue(const netlist_time &delay); |
| 577 | ATTR_HOT inline void push_to_queue(const netlist_time delay); |
582 | 578 | ATTR_HOT bool is_queued() { return m_in_queue == 1; } |
583 | 579 | |
584 | 580 | /* internal state support |
r26874 | r26875 | |
681 | 677 | ATTR_COLD void initial(const netlist_sig_t val); |
682 | 678 | ATTR_COLD void set_levels(const double low, const double high); |
683 | 679 | |
684 | | ATTR_HOT inline void set_Q(const netlist_sig_t newQ, const netlist_time &delay) |
| 680 | ATTR_HOT inline void set_Q(const netlist_sig_t newQ, const netlist_time delay) |
685 | 681 | { |
686 | | netlist_net_t &anet = net(); |
| 682 | assert(net().m_num_cons != 1); |
687 | 683 | |
688 | | if (EXPECTED(newQ != anet.m_new.Q)) |
| 684 | if (EXPECTED(newQ != net().m_new.Q)) |
689 | 685 | { |
690 | | anet.m_new.Q = newQ; |
691 | | if (anet.m_num_cons) |
692 | | anet.push_to_queue(delay); |
| 686 | net().m_new.Q = newQ; |
| 687 | net().push_to_queue(delay); |
693 | 688 | } |
694 | 689 | } |
695 | 690 | }; |
r26874 | r26875 | |
711 | 706 | |
712 | 707 | ATTR_COLD void initial(const double val); |
713 | 708 | |
714 | | ATTR_HOT inline void set_Q(const double newQ, const netlist_time &delay) |
| 709 | ATTR_HOT inline void set_Q(const double newQ, const netlist_time delay) |
715 | 710 | { |
716 | 711 | if (newQ != net().m_new.Analog) |
717 | 712 | { |
r26874 | r26875 | |
852 | 847 | |
853 | 848 | ATTR_HOT inline void update_dev() |
854 | 849 | { |
855 | | #if USE_DELEGATES |
856 | 850 | #if USE_PMFDELEGATES |
857 | 851 | static_update(this); |
858 | 852 | #else |
859 | | static_update(); |
860 | | #endif |
861 | | #else |
862 | 853 | update(); |
863 | 854 | #endif |
864 | 855 | } |
r26874 | r26875 | |
871 | 862 | return inp.Q(); |
872 | 863 | } |
873 | 864 | |
874 | | ATTR_HOT inline void OUTLOGIC(netlist_logic_output_t &out, const netlist_sig_t val, const netlist_time &delay) |
| 865 | ATTR_HOT inline void OUTLOGIC(netlist_logic_output_t &out, const netlist_sig_t val, const netlist_time delay) |
875 | 866 | { |
876 | 867 | out.set_Q(val, delay); |
877 | 868 | } |
r26874 | r26875 | |
890 | 881 | |
891 | 882 | ATTR_HOT inline const double TERMANALOG(const netlist_terminal_t &term) const { return term.net().Q_Analog(); } |
892 | 883 | |
893 | | ATTR_HOT inline void OUTANALOG(netlist_analog_output_t &out, const double val, const netlist_time &delay) |
| 884 | ATTR_HOT inline void OUTANALOG(netlist_analog_output_t &out, const double val, const netlist_time delay) |
894 | 885 | { |
895 | 886 | out.set_Q(val, delay); |
896 | 887 | } |
r26874 | r26875 | |
908 | 899 | INT32 stat_count; |
909 | 900 | #endif |
910 | 901 | |
911 | | #if USE_DELEGATES |
| 902 | #if USE_PMFDELEGATES |
912 | 903 | net_update_delegate static_update; |
913 | 904 | #endif |
914 | 905 | |
r26874 | r26875 | |
973 | 964 | // netlist_queue_t |
974 | 965 | // ---------------------------------------------------------------------------------------- |
975 | 966 | |
976 | | class netlist_queue_t : public netlist_timed_queue<netlist_net_t, netlist_time, 512>, |
| 967 | class netlist_queue_t : public netlist_timed_queue<netlist_net_t *, netlist_time, 512>, |
977 | 968 | public pstate_callback_t |
978 | 969 | { |
979 | 970 | public: |
r26874 | r26875 | |
1011 | 1002 | ATTR_HOT inline const netlist_queue_t &queue() const { return m_queue; } |
1012 | 1003 | ATTR_HOT inline netlist_queue_t &queue() { return m_queue; } |
1013 | 1004 | |
1014 | | ATTR_HOT inline void push_to_queue(netlist_net_t &out, const netlist_time &attime) |
| 1005 | ATTR_HOT inline void push_to_queue(netlist_net_t *out, const netlist_time attime) |
1015 | 1006 | { |
1016 | 1007 | m_queue.push(netlist_queue_t::entry_t(attime, out)); |
1017 | 1008 | } |
r26874 | r26875 | |
1021 | 1012 | ATTR_HOT void process_queue(const netlist_time delta); |
1022 | 1013 | ATTR_HOT inline void abort_current_queue_slice() { m_stop = netlist_time::zero; } |
1023 | 1014 | |
1024 | | ATTR_HOT inline const netlist_time &time() const { return m_time_ps; } |
| 1015 | ATTR_HOT inline const netlist_time time() const { return m_time_ps; } |
1025 | 1016 | |
1026 | 1017 | ATTR_COLD void set_mainclock_dev(NETLIB_NAME(mainclock) *dev); |
1027 | 1018 | ATTR_COLD void set_solver_dev(NETLIB_NAME(solver) *dev); |
r26874 | r26875 | |
1032 | 1023 | ATTR_COLD netlist_setup_t &setup() { return *m_setup; } |
1033 | 1024 | ATTR_COLD void reset(); |
1034 | 1025 | |
1035 | | ATTR_COLD void xfatalerror(const char *format, ...) const; |
| 1026 | ATTR_COLD void error(const char *format, ...) const; |
1036 | 1027 | |
1037 | 1028 | tagmap_devices_t m_devices; |
1038 | 1029 | netlist_net_t::list_t m_nets; |
r26874 | r26875 | |
1042 | 1033 | // any derived netlist must override this ... |
1043 | 1034 | virtual void vfatalerror(const char *format, va_list ap) const = 0; |
1044 | 1035 | |
1045 | | protected: |
1046 | 1036 | ATTR_COLD virtual void save_register() |
1047 | 1037 | { |
1048 | 1038 | save(NAME(m_queue.callback())); |
r26874 | r26875 | |
1079 | 1069 | ATTR_COLD nld_a_to_d_proxy(netlist_input_t &in_proxied) |
1080 | 1070 | : netlist_device_t() |
1081 | 1071 | { |
1082 | | //assert(in_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL); |
1083 | 1072 | assert(in_proxied.family() == LOGIC); |
1084 | 1073 | m_I.m_high_thresh_V = in_proxied.m_high_thresh_V; |
1085 | 1074 | m_I.m_low_thresh_V = in_proxied.m_low_thresh_V; |
r26874 | r26875 | |
1120 | 1109 | ATTR_COLD nld_d_to_a_proxy(netlist_output_t &out_proxied) |
1121 | 1110 | : netlist_device_t() |
1122 | 1111 | { |
1123 | | //assert(out_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL); |
1124 | 1112 | assert(out_proxied.family() == LOGIC); |
1125 | 1113 | m_low_V = out_proxied.m_low_V; |
1126 | 1114 | m_high_V = out_proxied.m_high_V; |
r26874 | r26875 | |
1211 | 1199 | } |
1212 | 1200 | |
1213 | 1201 | |
1214 | | ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time &delay) |
| 1202 | ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time delay) |
1215 | 1203 | { |
1216 | 1204 | // if (m_in_queue == 1) return; FIXME: check this at some time |
1217 | 1205 | m_time = netlist().time() + delay; |
r26874 | r26875 | |
1219 | 1207 | if (m_in_queue) |
1220 | 1208 | { |
1221 | 1209 | //m_in_queue = 1; /* pending */ |
1222 | | netlist().push_to_queue(*this, m_time); |
| 1210 | netlist().push_to_queue(this, m_time); |
1223 | 1211 | } |
1224 | 1212 | } |
1225 | 1213 | |
r26874 | r26875 | |
1227 | 1215 | { |
1228 | 1216 | m_active++; |
1229 | 1217 | |
1230 | | if (USE_DEACTIVE_DEVICE) |
1231 | | if (m_active == 1 && m_in_queue > 0) |
1232 | | { |
1233 | | m_last = m_cur; |
1234 | | railterminal().netdev().inc_active(); |
1235 | | m_cur = m_new; |
1236 | | } |
| 1218 | if (USE_DEACTIVE_DEVICE && m_active == 1 && m_in_queue > 0) |
| 1219 | { |
| 1220 | m_last = m_cur; |
| 1221 | railterminal().netdev().inc_active(); |
| 1222 | m_cur = m_new; |
| 1223 | } |
1237 | 1224 | |
1238 | | if (EXPECTED(m_active == 1 && m_in_queue == 0)) |
| 1225 | if (m_active == 1 && m_in_queue == 0) |
1239 | 1226 | { |
1240 | | if (EXPECTED(m_time > netlist().time())) |
| 1227 | if (m_time > netlist().time()) |
1241 | 1228 | { |
1242 | 1229 | m_in_queue = 1; /* pending */ |
1243 | | netlist().push_to_queue(*this, m_time); |
| 1230 | netlist().push_to_queue(this, m_time); |
1244 | 1231 | } |
1245 | 1232 | else |
1246 | 1233 | { |
r26874 | r26875 | |
1253 | 1240 | ATTR_HOT inline void netlist_net_t::dec_active() |
1254 | 1241 | { |
1255 | 1242 | m_active--; |
1256 | | if (USE_DEACTIVE_DEVICE) |
1257 | | if (m_active == 0) |
1258 | | railterminal().netdev().dec_active(); |
| 1243 | if (USE_DEACTIVE_DEVICE && (m_active == 0)) |
| 1244 | railterminal().netdev().dec_active(); |
1259 | 1245 | |
1260 | 1246 | } |
1261 | 1247 | |