trunk/src/emu/machine/netlist.c
| r26667 | r26668 | |
| 50 | 50 | #include "netlist/nl_setup.h" |
| 51 | 51 | #include "netlist/devices/net_lib.h" |
| 52 | 52 | |
| 53 | | #define LOG_DEV_CALLS(x) do { } while (0); |
| 53 | //#define LOG_DEV_CALLS(x) printf x |
| 54 | #define LOG_DEV_CALLS(x) do { } while (0) |
| 54 | 55 | |
| 55 | 56 | // ---------------------------------------------------------------------------------------- |
| 56 | 57 | // netlist_mame_device |
| r26667 | r26668 | |
| 61 | 62 | netlist_mame_device::netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 62 | 63 | : device_t(mconfig, NETLIST, "netlist", tag, owner, clock, "netlist_mame", __FILE__), |
| 63 | 64 | device_execute_interface(mconfig, *this), |
| 65 | //device_state_interface(mconfig, *this), |
| 64 | 66 | m_device_start_list(100), |
| 65 | 67 | m_netlist(NULL), |
| 66 | 68 | m_setup(NULL), |
| r26667 | r26668 | |
| 86 | 88 | LOG_DEV_CALLS(("device_start\n")); |
| 87 | 89 | |
| 88 | 90 | m_netlist = global_alloc_clear(netlist_mame_t(*this)); |
| 89 | | m_netlist->set_clock_freq(this->clock()); |
| 90 | | |
| 91 | 91 | m_setup = global_alloc_clear(netlist_setup_t(*m_netlist)); |
| 92 | m_netlist->init_object(*m_netlist, "netlist"); |
| 93 | m_setup->init(); |
| 92 | 94 | |
| 93 | | // register additional devices |
| 95 | m_netlist->set_clock_freq(this->clock()); |
| 94 | 96 | |
| 97 | // register additional devices |
| 98 | |
| 95 | 99 | m_setup->factory().register_device<nld_analog_callback>( "NETDEV_CALLBACK", "nld_analog_callback"); |
| 96 | 100 | |
| 97 | 101 | m_setup_func(*m_setup); |
| r26667 | r26668 | |
| 107 | 111 | m_netlist->xfatalerror("required elements not found\n"); |
| 108 | 112 | |
| 109 | 113 | save_state(); |
| 110 | | /* TODO: we have to save the round robin queue as well */ |
| 111 | 114 | |
| 112 | 115 | // set our instruction counter |
| 113 | 116 | m_icountptr = &m_icount; |
| r26667 | r26668 | |
| 130 | 133 | m_netlist = NULL; |
| 131 | 134 | } |
| 132 | 135 | |
| 133 | | void netlist_mame_device::device_post_load() |
| 136 | ATTR_COLD void netlist_mame_device::device_post_load() |
| 134 | 137 | { |
| 138 | LOG_DEV_CALLS(("device_post_load\n")); |
| 139 | m_netlist->queue().clear(); |
| 140 | NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); |
| 141 | for (int i = 0; i < qsize; i++ ) |
| 142 | { |
| 143 | netlist_net_t *n = m_netlist->find_net(qtemp[i].m_name); |
| 144 | NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n)); |
| 145 | NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double())); |
| 146 | m_netlist->queue().push(netlist_base_t::queue_t::entry_t(qtemp[i].m_time, *n)); |
| 147 | } |
| 135 | 148 | } |
| 136 | 149 | |
| 150 | ATTR_COLD void netlist_mame_device::device_pre_save() |
| 151 | { |
| 152 | LOG_DEV_CALLS(("device_pre_save\n")); |
| 153 | |
| 154 | qsize = m_netlist->queue().count(); |
| 155 | NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); |
| 156 | for (int i = 0; i < qsize; i++ ) |
| 157 | { |
| 158 | qtemp[i].m_time = m_netlist->queue().listptr()[i].time(); |
| 159 | const char *p = m_netlist->queue().listptr()[i].object().name().cstr(); |
| 160 | int n = MIN(63, strlen(p)); |
| 161 | strncpy(qtemp[i].m_name, p, n); |
| 162 | qtemp[i].m_name[n] = 0; |
| 163 | } |
| 164 | #if 0 |
| 165 | |
| 166 | netlist_time *nlt = (netlist_time *) ; |
| 167 | netlist_base_t::queue_t::entry_t *p = m_netlist->queue().listptr()[i]; |
| 168 | netlist_time *nlt = (netlist_time *) p->time_ptr(); |
| 169 | save_pointer(nlt->get_internaltype_ptr(), "queue", 1, i); |
| 170 | #endif |
| 171 | } |
| 172 | |
| 137 | 173 | void netlist_mame_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 138 | 174 | { |
| 139 | 175 | } |
| 140 | 176 | |
| 141 | | void netlist_mame_device::save_state() |
| 177 | |
| 178 | |
| 179 | ATTR_COLD void netlist_mame_device::save_state() |
| 142 | 180 | { |
| 181 | for (netlist_setup_t::save_entry_list_t::entry_t *p = setup().m_save.first(); p != NULL; p = setup().m_save.next(p)) |
| 182 | { |
| 183 | netlist_setup_t::save_entry_t *s = p->object(); |
| 184 | NL_VERBOSE_OUT(("saving state for %s\n", s->m_name.cstr())); |
| 185 | switch (s->m_dt) |
| 186 | { |
| 187 | case DT_DOUBLE: |
| 188 | save_pointer((double *) s->m_ptr, s->m_name, 1); |
| 189 | break; |
| 190 | case DT_INT64: |
| 191 | save_pointer((INT64 *) s->m_ptr, s->m_name, 1); |
| 192 | break; |
| 193 | case DT_INT8: |
| 194 | save_pointer((INT8 *) s->m_ptr, s->m_name, 1); |
| 195 | break; |
| 196 | case DT_INT: |
| 197 | save_pointer((int *) s->m_ptr, s->m_name, 1); |
| 198 | break; |
| 199 | case DT_BOOLEAN: |
| 200 | save_pointer((bool *) s->m_ptr, s->m_name, 1); |
| 201 | break; |
| 143 | 202 | #if 0 |
| 144 | | for (netlist_setup_t::tagmap_output_t::entry_t *entry = m_setup->m_outputs.first(); entry != NULL; entry = m_setup->m_outputs.next(entry)) |
| 145 | | { |
| 146 | | save_item(*entry->object()->Q_ptr(), entry->tag().cstr(), 0); |
| 147 | | save_item(*entry->object()->new_Q_ptr(), entry->tag().cstr(), 1); |
| 148 | | } |
| 203 | case DT_NLTIME: |
| 204 | { |
| 205 | netlist_time *nlt = (netlist_time *) s->m_ptr; |
| 206 | //save_pointer((netlist_time::INTERNALTYPE *) s->m_ptr, s->m_name, 1); |
| 207 | //save_pointer(nlt->get_internaltype_ptr(), s->m_name, 1); |
| 208 | save_item(*nlt->get_internaltype_ptr(), s->m_name.cstr()); |
| 209 | } |
| 210 | break; |
| 149 | 211 | #endif |
| 212 | case NOT_SUPPORTED: |
| 213 | default: |
| 214 | m_netlist->xfatalerror("found unsupported save element %s\n", s->m_name.cstr()); |
| 215 | break; |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | // handle the queue |
| 220 | |
| 221 | save_item(NAME(qsize)); |
| 222 | for (int i = 0; i < m_netlist->queue().capacity(); i++ ) |
| 223 | { |
| 224 | save_pointer(qtemp[i].m_time.get_internaltype_ptr(), "queue_time", 1, i); |
| 225 | save_pointer(qtemp[i].m_name, "queue_name", sizeof(qtemp[i].m_name), i); |
| 226 | |
| 227 | } |
| 228 | #if 0 |
| 229 | |
| 230 | netlist_time *nlt = (netlist_time *) ; |
| 231 | netlist_base_t::queue_t::entry_t *p = m_netlist->queue().listptr()[i]; |
| 232 | netlist_time *nlt = (netlist_time *) p->time_ptr(); |
| 233 | save_pointer(nlt->get_internaltype_ptr(), "queue", 1, i); |
| 234 | #endif |
| 150 | 235 | } |
| 151 | 236 | |
| 152 | | UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const |
| 237 | ATTR_COLD UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const |
| 153 | 238 | { |
| 154 | 239 | return clocks; |
| 155 | 240 | } |
| 156 | 241 | |
| 157 | | UINT64 netlist_mame_device::execute_cycles_to_clocks(UINT64 cycles) const |
| 242 | ATTR_COLD UINT64 netlist_mame_device::execute_cycles_to_clocks(UINT64 cycles) const |
| 158 | 243 | { |
| 159 | 244 | return cycles; |
| 160 | 245 | } |
| r26667 | r26668 | |
| 169 | 254 | // debugger_instruction_hook(this, 0); //m_pc); |
| 170 | 255 | |
| 171 | 256 | m_netlist->process_queue(m_icount); |
| 172 | | |
| 173 | 257 | } |
trunk/src/emu/netlist/nl_base.h
| r26667 | r26668 | |
| 247 | 247 | class NETLIB_NAME(mainclock); |
| 248 | 248 | |
| 249 | 249 | // ---------------------------------------------------------------------------------------- |
| 250 | // state saving ... |
| 251 | // ---------------------------------------------------------------------------------------- |
| 252 | |
| 253 | enum netlist_data_type_e { |
| 254 | NOT_SUPPORTED, |
| 255 | DT_DOUBLE, |
| 256 | DT_INT64, |
| 257 | DT_INT8, |
| 258 | DT_INT, |
| 259 | DT_BOOLEAN |
| 260 | }; |
| 261 | |
| 262 | template<typename _ItemType> struct nl_datatype { static const netlist_data_type_e type = netlist_data_type_e(NOT_SUPPORTED); }; |
| 263 | //template<typename _ItemType> struct type_checker<_ItemType*> { static const bool is_atom = false; static const bool is_pointer = true; }; |
| 264 | |
| 265 | #define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) template<> struct nl_datatype<TYPE>{ static const netlist_data_type_e type = netlist_data_type_e(TYPEDESC); } |
| 266 | |
| 267 | NETLIST_SAVE_TYPE(double, DT_DOUBLE); |
| 268 | NETLIST_SAVE_TYPE(INT8, DT_INT8); |
| 269 | NETLIST_SAVE_TYPE(UINT8, DT_INT8); |
| 270 | NETLIST_SAVE_TYPE(INT64, DT_INT64); |
| 271 | NETLIST_SAVE_TYPE(UINT64, DT_INT64); |
| 272 | NETLIST_SAVE_TYPE(bool, DT_BOOLEAN); |
| 273 | NETLIST_SAVE_TYPE(UINT32, DT_INT); |
| 274 | NETLIST_SAVE_TYPE(INT32, DT_INT); |
| 275 | |
| 276 | // ---------------------------------------------------------------------------------------- |
| 250 | 277 | // netlist_object_t |
| 251 | 278 | // ---------------------------------------------------------------------------------------- |
| 252 | 279 | |
| r26667 | r26668 | |
| 261 | 288 | PARAM = 3, |
| 262 | 289 | NET = 4, |
| 263 | 290 | DEVICE = 5, |
| 291 | NETLIST = 6, |
| 264 | 292 | }; |
| 265 | 293 | enum family_t { |
| 266 | 294 | // Terminal families |
| r26667 | r26668 | |
| 285 | 313 | |
| 286 | 314 | ATTR_COLD const pstring &name() const; |
| 287 | 315 | |
| 316 | ATTR_COLD void save_state_ptr(const pstring &stname, const netlist_data_type_e, const int size, void *ptr); |
| 317 | template<class C> ATTR_COLD void save(C &state, const pstring &stname) |
| 318 | { |
| 319 | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), &state); |
| 320 | } |
| 321 | |
| 288 | 322 | ATTR_HOT inline const type_t type() const { return m_objtype; } |
| 289 | 323 | ATTR_HOT inline const family_t family() const { return m_family; } |
| 290 | 324 | |
| r26667 | r26668 | |
| 294 | 328 | ATTR_HOT inline netlist_base_t & RESTRICT netlist() { return *m_netlist; } |
| 295 | 329 | ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; } |
| 296 | 330 | |
| 331 | protected: |
| 332 | |
| 333 | // must call parent save_register ! |
| 334 | ATTR_COLD virtual void save_register() { }; |
| 335 | |
| 297 | 336 | private: |
| 298 | 337 | pstring m_name; |
| 299 | 338 | const type_t m_objtype; |
| r26667 | r26668 | |
| 301 | 340 | netlist_base_t * RESTRICT m_netlist; |
| 302 | 341 | }; |
| 303 | 342 | |
| 343 | template<> ATTR_COLD inline void netlist_object_t::save(netlist_time &state, const pstring &stname) |
| 344 | { |
| 345 | save_state_ptr(stname, DT_INT64, sizeof(netlist_time::INTERNALTYPE), state.get_internaltype_ptr()); |
| 346 | } |
| 347 | |
| 304 | 348 | // ---------------------------------------------------------------------------------------- |
| 305 | 349 | // netlist_owned_object_t |
| 306 | 350 | // ---------------------------------------------------------------------------------------- |
| r26667 | r26668 | |
| 338 | 382 | STATE_NONEX = 256 |
| 339 | 383 | }; |
| 340 | 384 | |
| 385 | |
| 341 | 386 | ATTR_COLD netlist_core_terminal_t(const type_t atype, const family_t afamily); |
| 342 | 387 | |
| 343 | 388 | ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate); |
| r26667 | r26668 | |
| 357 | 402 | |
| 358 | 403 | netlist_core_terminal_t *m_update_list_next; |
| 359 | 404 | |
| 405 | protected: |
| 406 | ATTR_COLD virtual void save_register() { save(NAME(m_state)); netlist_owned_object_t::save_register(); } |
| 407 | |
| 360 | 408 | private: |
| 361 | 409 | netlist_net_t * RESTRICT m_net; |
| 362 | 410 | state_e m_state; |
| 363 | 411 | }; |
| 364 | 412 | |
| 413 | NETLIST_SAVE_TYPE(netlist_core_terminal_t::state_e, DT_INT); |
| 414 | |
| 415 | |
| 365 | 416 | class netlist_terminal_t : public netlist_core_terminal_t |
| 366 | 417 | { |
| 367 | 418 | NETLIST_PREVENT_COPYING(netlist_terminal_t) |
| r26667 | r26668 | |
| 394 | 445 | |
| 395 | 446 | |
| 396 | 447 | netlist_terminal_t *m_otherterm; |
| 448 | |
| 449 | protected: |
| 450 | ATTR_COLD virtual void save_register() |
| 451 | { |
| 452 | save(NAME(m_Idr)); |
| 453 | save(NAME(m_go)); |
| 454 | save(NAME(m_gt)); |
| 455 | netlist_core_terminal_t::save_register(); |
| 456 | } |
| 457 | |
| 397 | 458 | }; |
| 398 | 459 | |
| 399 | 460 | |
| r26667 | r26668 | |
| 502 | 563 | }; |
| 503 | 564 | |
| 504 | 565 | ATTR_COLD netlist_net_t(const type_t atype, const family_t afamily); |
| 566 | ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname); |
| 505 | 567 | |
| 506 | 568 | ATTR_COLD void register_con(netlist_core_terminal_t &terminal); |
| 507 | 569 | ATTR_COLD void merge_net(netlist_net_t *othernet); |
| r26667 | r26668 | |
| 568 | 630 | |
| 569 | 631 | UINT32 m_num_cons; |
| 570 | 632 | |
| 633 | protected: |
| 634 | ATTR_COLD virtual void save_register() |
| 635 | { |
| 636 | save(NAME(m_last.Analog)); |
| 637 | save(NAME(m_cur.Analog)); |
| 638 | save(NAME(m_new.Analog)); |
| 639 | save(NAME(m_last.Q)); |
| 640 | save(NAME(m_cur.Q)); |
| 641 | save(NAME(m_new.Q)); |
| 642 | save(NAME(m_time)); |
| 643 | save(NAME(m_active)); |
| 644 | save(NAME(m_in_queue)); |
| 645 | netlist_object_t::save_register(); |
| 646 | } |
| 647 | |
| 571 | 648 | private: |
| 572 | 649 | ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask) const; |
| 573 | 650 | |
| r26667 | r26668 | |
| 688 | 765 | ATTR_COLD inline void initial(const double val) { m_param = val; } |
| 689 | 766 | ATTR_HOT inline const double Value() const { return m_param; } |
| 690 | 767 | |
| 768 | protected: |
| 769 | ATTR_COLD virtual void save_register() |
| 770 | { |
| 771 | save(NAME(m_param)); |
| 772 | netlist_param_t::save_register(); |
| 773 | } |
| 774 | |
| 691 | 775 | private: |
| 692 | 776 | double m_param; |
| 693 | 777 | }; |
| r26667 | r26668 | |
| 703 | 787 | |
| 704 | 788 | ATTR_HOT inline const int Value() const { return m_param; } |
| 705 | 789 | |
| 790 | protected: |
| 791 | ATTR_COLD virtual void save_register() |
| 792 | { |
| 793 | save(NAME(m_param)); |
| 794 | netlist_param_t::save_register(); |
| 795 | } |
| 796 | |
| 706 | 797 | private: |
| 707 | 798 | int m_param; |
| 708 | 799 | }; |
| r26667 | r26668 | |
| 832 | 923 | protected: |
| 833 | 924 | |
| 834 | 925 | ATTR_HOT virtual void update() { } |
| 835 | | ATTR_HOT virtual void start() { } |
| 926 | ATTR_COLD virtual void start() { } |
| 836 | 927 | |
| 837 | 928 | private: |
| 838 | 929 | }; |
| r26667 | r26668 | |
| 892 | 983 | |
| 893 | 984 | typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t; |
| 894 | 985 | |
| 895 | | class netlist_base_t |
| 986 | class netlist_base_t : public netlist_object_t |
| 896 | 987 | { |
| 897 | 988 | NETLIST_PREVENT_COPYING(netlist_base_t) |
| 898 | 989 | public: |
| r26667 | r26668 | |
| 920 | 1011 | ATTR_COLD void set_solver_dev(NETLIB_NAME(solver) *dev); |
| 921 | 1012 | ATTR_COLD void set_setup(netlist_setup_t *asetup) { m_setup = asetup; } |
| 922 | 1013 | |
| 1014 | ATTR_COLD netlist_net_t *find_net(const pstring &name); |
| 1015 | |
| 923 | 1016 | ATTR_COLD void set_clock_freq(UINT64 clockfreq); |
| 924 | 1017 | |
| 925 | 1018 | ATTR_COLD netlist_setup_t &setup() { return *m_setup; } |
| r26667 | r26668 | |
| 928 | 1021 | ATTR_COLD void xfatalerror(const char *format, ...) const; |
| 929 | 1022 | |
| 930 | 1023 | tagmap_devices_t m_devices; |
| 1024 | netlist_net_t::list_t m_nets; |
| 931 | 1025 | |
| 932 | 1026 | protected: |
| 933 | 1027 | |
| 934 | 1028 | // any derived netlist must override this ... |
| 935 | 1029 | virtual void vfatalerror(const char *format, va_list ap) const = 0; |
| 1030 | |
| 1031 | protected: |
| 1032 | ATTR_COLD virtual void save_register() |
| 1033 | { |
| 1034 | //queue_t m_queue; |
| 1035 | save(NAME(m_time_ps)); |
| 1036 | save(NAME(m_rem)); |
| 1037 | save(NAME(m_div)); |
| 1038 | netlist_object_t::save_register(); |
| 1039 | } |
| 1040 | |
| 936 | 1041 | #if (NL_KEEP_STATISTICS) |
| 937 | 1042 | // performance |
| 938 | 1043 | int m_perf_out_processed; |
| r26667 | r26668 | |
| 978 | 1083 | protected: |
| 979 | 1084 | ATTR_COLD void start() |
| 980 | 1085 | { |
| 981 | | m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE); |
| 982 | | |
| 983 | | m_Q.init_object(*this, "Q"); |
| 1086 | register_input("I", m_I, netlist_terminal_t::STATE_INP_ACTIVE); |
| 1087 | register_output("Q", m_Q); |
| 984 | 1088 | m_Q.initial(1); |
| 985 | 1089 | } |
| 986 | 1090 | |
| r26667 | r26668 | |
| 1020 | 1124 | protected: |
| 1021 | 1125 | ATTR_COLD void start() |
| 1022 | 1126 | { |
| 1023 | | m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE); |
| 1024 | | m_Q.init_object(*this, "Q"); |
| 1127 | register_input("I", m_I, netlist_terminal_t::STATE_INP_ACTIVE); |
| 1128 | register_output("Q", m_Q); |
| 1025 | 1129 | m_Q.initial(0); |
| 1026 | 1130 | } |
| 1027 | 1131 | |
trunk/src/emu/netlist/nl_setup.c
| r26667 | r26668 | |
| 33 | 33 | , m_proxy_cnt(0) |
| 34 | 34 | { |
| 35 | 35 | netlist.set_setup(this); |
| 36 | } |
| 37 | |
| 38 | void netlist_setup_t::init() |
| 39 | { |
| 36 | 40 | m_factory.initialize(); |
| 37 | 41 | NETLIST_NAME(base)(*this); |
| 38 | 42 | } |
| r26667 | r26668 | |
| 45 | 49 | m_params.reset(); |
| 46 | 50 | m_terminals.reset(); |
| 47 | 51 | m_params_temp.reset(); |
| 52 | m_save.reset_and_free(); |
| 48 | 53 | |
| 49 | 54 | netlist().set_setup(NULL); |
| 50 | 55 | |
| r26667 | r26668 | |
| 132 | 137 | case netlist_terminal_t::DEVICE: |
| 133 | 138 | return "DEVICE"; |
| 134 | 139 | break; |
| 140 | case netlist_terminal_t::NETLIST: |
| 141 | return "NETLIST"; |
| 142 | break; |
| 135 | 143 | } |
| 136 | 144 | // FIXME: noreturn |
| 137 | 145 | netlist().xfatalerror("Unknown object type %d\n", in.type()); |
| r26667 | r26668 | |
| 161 | 169 | break; |
| 162 | 170 | case netlist_terminal_t::PARAM: |
| 163 | 171 | { |
| 164 | | |
| 165 | 172 | netlist_param_t ¶m = dynamic_cast<netlist_param_t &>(obj); |
| 166 | | pstring temp = param.netdev().name() + "." + name; |
| 167 | | const pstring val = m_params_temp.find(temp); |
| 173 | const pstring val = m_params_temp.find(name); |
| 168 | 174 | if (val != "") |
| 169 | 175 | { |
| 170 | 176 | switch (param.param_type()) |
| r26667 | r26668 | |
| 174 | 180 | NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", temp.cstr(), val->cstr())); |
| 175 | 181 | double vald = 0; |
| 176 | 182 | if (sscanf(val.cstr(), "%lf", &vald) != 1) |
| 177 | | netlist().xfatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr()); |
| 183 | netlist().xfatalerror("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); |
| 178 | 184 | dynamic_cast<netlist_param_double_t &>(param).initial(vald); |
| 179 | 185 | } |
| 180 | 186 | break; |
| 181 | 187 | case netlist_param_t::INTEGER: |
| 182 | 188 | case netlist_param_t::LOGIC: |
| 183 | 189 | { |
| 184 | | NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", temp.cstr(), val->cstr())); |
| 190 | NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", name.cstr(), val->cstr())); |
| 185 | 191 | int vald = 0; |
| 186 | 192 | if (sscanf(val.cstr(), "%d", &vald) != 1) |
| 187 | | netlist().xfatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr()); |
| 193 | netlist().xfatalerror("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); |
| 188 | 194 | dynamic_cast<netlist_param_int_t &>(param).initial(vald); |
| 189 | 195 | } |
| 190 | 196 | break; |
| r26667 | r26668 | |
| 213 | 219 | } |
| 214 | 220 | break; |
| 215 | 221 | default: |
| 216 | | netlist().xfatalerror("Parameter is not supported %s : %s\n", temp.cstr(), val.cstr()); |
| 222 | netlist().xfatalerror("Parameter is not supported %s : %s\n", name.cstr(), val.cstr()); |
| 217 | 223 | } |
| 218 | 224 | } |
| 219 | | if (!(m_params.add(temp, ¶m, false)==TMERR_NONE)) |
| 225 | if (!(m_params.add(name, ¶m, false)==TMERR_NONE)) |
| 220 | 226 | netlist().xfatalerror("Error adding parameter %s to parameter list\n", name.cstr()); |
| 221 | 227 | } |
| 222 | 228 | break; |
| 223 | 229 | case netlist_terminal_t::DEVICE: |
| 230 | netlist().xfatalerror("Device registration not yet supported - \n", name.cstr()); |
| 224 | 231 | break; |
| 232 | case netlist_terminal_t::NETLIST: |
| 233 | netlist().xfatalerror("Netlist registration not yet supported - \n", name.cstr()); |
| 234 | break; |
| 225 | 235 | } |
| 226 | 236 | } |
| 227 | 237 | |
| r26667 | r26668 | |
| 462 | 472 | NL_VERBOSE_OUT(("adding net ...\n")); |
| 463 | 473 | netlist_net_t *anet = new netlist_net_t(netlist_object_t::NET, netlist_object_t::ANALOG); |
| 464 | 474 | t1.set_net(*anet); |
| 465 | | m_netlist.solver()->m_nets.add(anet); |
| 475 | //m_netlist.solver()->m_nets.add(anet); |
| 466 | 476 | // FIXME: Nets should have a unique name |
| 467 | | t1.net().init_object(netlist(),"some net"); |
| 477 | t1.net().init_object(netlist(),"net." + t1.name() ); |
| 468 | 478 | t1.net().register_con(t2); |
| 469 | 479 | t1.net().register_con(t1); |
| 470 | 480 | } |
| r26667 | r26668 | |
| 533 | 543 | //VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr())); |
| 534 | 544 | } |
| 535 | 545 | |
| 546 | #if 0 |
| 547 | NL_VERBOSE_OUT(("deleting empty nets ...\n")); |
| 548 | |
| 549 | // delete empty nets ... |
| 550 | for (netlist_net_t::list_t::entry_t *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn)) |
| 551 | { |
| 552 | if (pn->object()->m_head == NULL) |
| 553 | { |
| 554 | NL_VERBOSE_OUT(("Deleting net ...\n")); |
| 555 | netlist_net_t *to_delete = pn->object(); |
| 556 | netlist().m_nets.remove(to_delete); |
| 557 | if (!to_delete->isRailNet()) |
| 558 | delete to_delete; |
| 559 | pn--; |
| 560 | } |
| 561 | } |
| 562 | #endif |
| 536 | 563 | if (m_netlist.solver() != NULL) |
| 537 | 564 | m_netlist.solver()->post_start(); |
| 538 | 565 | |
| r26667 | r26668 | |
| 578 | 605 | netlist_device_t *dev = entry->object(); |
| 579 | 606 | dev->init(netlist(), entry->tag().cstr()); |
| 580 | 607 | } |
| 608 | |
| 581 | 609 | } |
| 582 | 610 | |
| 583 | 611 | void netlist_setup_t::parse(const char *buf) |
trunk/src/emu/netlist/devices/nld_solver.c
| r26667 | r26668 | |
| 187 | 187 | static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net) |
| 188 | 188 | { |
| 189 | 189 | /* add the net */ |
| 190 | if (net->m_head == NULL) |
| 191 | return; |
| 190 | 192 | groups[cur_group].add(net); |
| 191 | 193 | for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next) |
| 192 | 194 | { |
| r26667 | r26668 | |
| 216 | 218 | register_param("ACCURACY", m_accuracy, 1e-3); |
| 217 | 219 | register_param("CONVERG", m_convergence, 0.3); |
| 218 | 220 | |
| 219 | | register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE); |
| 220 | | register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE); |
| 221 | // internal staff |
| 222 | |
| 223 | register_input("FB_sync", m_fb_sync, netlist_input_t::STATE_INP_ACTIVE); |
| 224 | register_input("FB_step", m_fb_step, netlist_input_t::STATE_INP_ACTIVE); |
| 225 | |
| 226 | setup().connect(m_fb_sync, m_Q_sync); |
| 227 | setup().connect(m_fb_step, m_Q_step); |
| 228 | |
| 221 | 229 | m_last_step = netlist_time::zero; |
| 222 | 230 | |
| 231 | save(NAME(m_last_step)); |
| 232 | |
| 223 | 233 | } |
| 224 | 234 | |
| 225 | 235 | NETLIB_UPDATE_PARAM(solver) |
| r26667 | r26668 | |
| 237 | 247 | e = en; |
| 238 | 248 | } |
| 239 | 249 | |
| 240 | | netlist_net_t::list_t::entry_t *p = m_nets.first(); |
| 241 | | while (p != NULL) |
| 242 | | { |
| 243 | | netlist_net_t::list_t::entry_t *pn = m_nets.next(p); |
| 244 | | delete p->object(); |
| 245 | | p = pn; |
| 246 | | } |
| 247 | 250 | } |
| 248 | 251 | |
| 249 | 252 | NETLIB_FUNC_VOID(solver, post_start, ()) |
| r26667 | r26668 | |
| 251 | 254 | netlist_net_t::list_t groups[100]; |
| 252 | 255 | int cur_group = -1; |
| 253 | 256 | |
| 254 | | NL_VERBOSE_OUT(("post start solver ...\n")); |
| 255 | | |
| 256 | | // delete empty nets ... |
| 257 | | for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) |
| 258 | | { |
| 259 | | if (pn->object()->m_head == NULL) |
| 260 | | { |
| 261 | | NL_VERBOSE_OUT(("Deleting net ...\n")); |
| 262 | | netlist_net_t *to_delete = pn->object(); |
| 263 | | m_nets.remove(to_delete); |
| 264 | | delete to_delete; |
| 265 | | pn--; |
| 266 | | } |
| 267 | | } |
| 268 | | |
| 269 | 257 | SOLVER_VERBOSE_OUT(("Scanning net groups ...\n")); |
| 270 | 258 | // determine net groups |
| 271 | | for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) |
| 259 | for (netlist_net_t::list_t::entry_t *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn)) |
| 272 | 260 | { |
| 273 | 261 | if (!already_processed(groups, cur_group, pn->object())) |
| 274 | 262 | { |
trunk/src/emu/netlist/nl_base.c
| r26667 | r26668 | |
| 29 | 29 | { |
| 30 | 30 | m_netlist = &nl; |
| 31 | 31 | m_name = aname; |
| 32 | save_register(); |
| 32 | 33 | } |
| 33 | 34 | |
| 34 | 35 | ATTR_COLD const pstring &netlist_object_t::name() const |
| r26667 | r26668 | |
| 38 | 39 | return m_name; |
| 39 | 40 | } |
| 40 | 41 | |
| 42 | ATTR_COLD void netlist_object_t::save_state_ptr(const pstring &stname, const netlist_data_type_e dt, const int size, void *ptr) |
| 43 | { |
| 44 | pstring fullname = name() + "." + stname; |
| 45 | // do nothing for now; |
| 46 | ATTR_UNUSED pstring ts[] = { |
| 47 | "NOT_SUPPORTED", |
| 48 | "DT_DOUBLE", |
| 49 | "DT_INT64", |
| 50 | "DT_INT8", |
| 51 | "DT_INT", |
| 52 | "DT_BOOLEAN" |
| 53 | }; |
| 54 | |
| 55 | NL_VERBOSE_OUT(("SAVE: <%s> %s(%d) %p\n", fullname.cstr(), ts[dt].cstr(), size, ptr)); |
| 56 | netlist().setup().save_state_ptr(fullname, dt, size, ptr); |
| 57 | } |
| 58 | |
| 41 | 59 | // ---------------------------------------------------------------------------------------- |
| 42 | 60 | // netlist_owned_object_t |
| 43 | 61 | // ---------------------------------------------------------------------------------------- |
| r26667 | r26668 | |
| 61 | 79 | // ---------------------------------------------------------------------------------------- |
| 62 | 80 | |
| 63 | 81 | netlist_base_t::netlist_base_t() |
| 64 | | : m_time_ps(netlist_time::zero), |
| 82 | : netlist_object_t(NETLIST, GENERIC), |
| 83 | m_time_ps(netlist_time::zero), |
| 65 | 84 | m_rem(0), |
| 66 | 85 | m_div(NETLIST_DIV), |
| 67 | 86 | m_mainclock(NULL), |
| r26667 | r26668 | |
| 82 | 101 | netlist_base_t::~netlist_base_t() |
| 83 | 102 | { |
| 84 | 103 | tagmap_free_entries<tagmap_devices_t>(m_devices); |
| 104 | |
| 105 | netlist_net_t::list_t::entry_t *p = m_nets.first(); |
| 106 | while (p != NULL) |
| 107 | { |
| 108 | netlist_net_t::list_t::entry_t *pn = m_nets.next(p); |
| 109 | if (!p->object()->isRailNet()) |
| 110 | delete p->object(); |
| 111 | p = pn; |
| 112 | } |
| 113 | |
| 114 | m_nets.reset(); |
| 85 | 115 | pstring::resetmem(); |
| 86 | 116 | } |
| 87 | 117 | |
| 118 | ATTR_COLD netlist_net_t *netlist_base_t::find_net(const pstring &name) |
| 119 | { |
| 120 | for (netlist_net_t::list_t::entry_t *p = m_nets.first(); p != NULL; p = m_nets.next(p)) |
| 121 | { |
| 122 | if (p->object()->name() == name) |
| 123 | return p->object(); |
| 124 | } |
| 125 | return NULL; |
| 126 | } |
| 127 | |
| 88 | 128 | ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev) |
| 89 | 129 | { |
| 90 | 130 | m_mainclock = dev; |
| r26667 | r26668 | |
| 339 | 379 | setup().register_object(*this, *this, name, inp, type); |
| 340 | 380 | } |
| 341 | 381 | |
| 382 | //FIXME: Get rid of this |
| 342 | 383 | static void init_term(netlist_core_device_t &dev, netlist_core_terminal_t &term, netlist_input_t::state_e aState) |
| 343 | 384 | { |
| 344 | 385 | if (!term.isInitalized()) |
| r26667 | r26668 | |
| 346 | 387 | switch (term.type()) |
| 347 | 388 | { |
| 348 | 389 | case netlist_terminal_t::OUTPUT: |
| 349 | | dynamic_cast<netlist_output_t &>(term).init_object(dev, "internal output"); |
| 390 | dynamic_cast<netlist_output_t &>(term).init_object(dev, dev.name() + ".INTOUT"); |
| 350 | 391 | break; |
| 351 | 392 | case netlist_terminal_t::INPUT: |
| 352 | | dynamic_cast<netlist_input_t &>(term).init_object(dev, "internal input", aState); |
| 393 | dynamic_cast<netlist_input_t &>(term).init_object(dev, dev.name() + ".INTINP", aState); |
| 353 | 394 | break; |
| 354 | 395 | case netlist_terminal_t::TERMINAL: |
| 355 | | dynamic_cast<netlist_terminal_t &>(term).init_object(dev, "internal terminal", aState); |
| 396 | dynamic_cast<netlist_terminal_t &>(term).init_object(dev, dev.name() + ".INTTERM", aState); |
| 356 | 397 | break; |
| 357 | 398 | default: |
| 358 | 399 | dev.netlist().xfatalerror("Unknown terminal type"); |
| r26667 | r26668 | |
| 362 | 403 | } |
| 363 | 404 | |
| 364 | 405 | // FIXME: Revise internal links ... |
| 406 | //FIXME: Get rid of this |
| 365 | 407 | ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState) |
| 366 | 408 | { |
| 367 | 409 | init_term(dev, in, aState); |
| r26667 | r26668 | |
| 377 | 419 | template <class C, class T> |
| 378 | 420 | ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &sname, C ¶m, const T initialVal) |
| 379 | 421 | { |
| 380 | | param.init_object(dev, sname); |
| 422 | pstring fullname = dev.name() + "." + sname; |
| 423 | param.init_object(dev, fullname); |
| 381 | 424 | param.initial(initialVal); |
| 382 | | setup().register_object(*this, *this, sname, param, netlist_terminal_t::STATE_NONEX); |
| 425 | //FIXME: pass fullname from above |
| 426 | setup().register_object(*this, *this, fullname, param, netlist_terminal_t::STATE_NONEX); |
| 383 | 427 | } |
| 384 | 428 | |
| 385 | 429 | template ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &sname, netlist_param_double_t ¶m, const double initialVal); |
| r26667 | r26668 | |
| 405 | 449 | { |
| 406 | 450 | }; |
| 407 | 451 | |
| 452 | ATTR_COLD void netlist_net_t::init_object(netlist_base_t &nl, const pstring &aname) |
| 453 | { |
| 454 | netlist_object_t::init_object(nl, aname); |
| 455 | nl.m_nets.add(this); |
| 456 | } |
| 457 | |
| 408 | 458 | ATTR_COLD void netlist_net_t::register_railterminal(netlist_output_t &mr) |
| 409 | 459 | { |
| 410 | 460 | assert(m_railterminal == NULL); |
| r26667 | r26668 | |
| 551 | 601 | ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) |
| 552 | 602 | { |
| 553 | 603 | netlist_core_terminal_t::init_object(dev, aname, STATE_OUT); |
| 554 | | net().init_object(dev.netlist(), aname); |
| 604 | net().init_object(dev.netlist(), aname + ".net"); |
| 555 | 605 | net().register_railterminal(*this); |
| 556 | 606 | } |
| 557 | 607 | |
trunk/src/mame/drivers/pong.c
| r26667 | r26668 | |
| 982 | 982 | ROM_END |
| 983 | 983 | |
| 984 | 984 | |
| 985 | | GAME( 1972, pong, 0, pong, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E)", 0 ) |
| 986 | | GAME( 1972, pongf, 0, pongf, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E), no subcycles", 0 ) |
| 985 | GAME( 1972, pong, 0, pong, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E)", GAME_SUPPORTS_SAVE ) |
| 986 | GAME( 1972, pongf, 0, pongf, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E), no subcycles", GAME_SUPPORTS_SAVE ) |