trunk/src/emu/netlist/nl_base.c
| r26741 | r26742 | |
| 11 | 11 | const netlist_time netlist_time::zero = netlist_time::from_raw(0); |
| 12 | 12 | |
| 13 | 13 | // ---------------------------------------------------------------------------------------- |
| 14 | // netlist_queue_t |
| 15 | // ---------------------------------------------------------------------------------------- |
| 16 | |
| 17 | netlist_queue_t::netlist_queue_t(netlist_base_t &nl) |
| 18 | : netlist_timed_queue<netlist_net_t, netlist_time, 512>(), pstate_callback_t(), |
| 19 | m_netlist(nl), |
| 20 | m_qsize(0) |
| 21 | { } |
| 22 | |
| 23 | void netlist_queue_t::register_state(pstate_manager_t &manager, const pstring &module) |
| 24 | { |
| 25 | NL_VERBOSE_OUT(("register_state\n")); |
| 26 | manager.save_manager(m_qsize, module + "." + "qsize"); |
| 27 | manager.save_manager(m_times, module + "." + "times"); |
| 28 | manager.save_manager(&(m_name[0][0]), module + "." + "names", sizeof(m_name)); |
| 29 | } |
| 30 | void netlist_queue_t::on_pre_save() |
| 31 | { |
| 32 | NL_VERBOSE_OUT(("on_pre_save\n")); |
| 33 | m_qsize = this->count(); |
| 34 | NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); |
| 35 | for (int i = 0; i < m_qsize; i++ ) |
| 36 | { |
| 37 | m_times[i] = this->listptr()[i].time().as_raw(); |
| 38 | const char *p = this->listptr()[i].object().name().cstr(); |
| 39 | int n = MIN(63, strlen(p)); |
| 40 | strncpy(&(m_name[i][0]), p, n); |
| 41 | m_name[i][n] = 0; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | |
| 46 | void netlist_queue_t::on_post_load() |
| 47 | { |
| 48 | printf("on_post_load\n"); |
| 49 | this->clear(); |
| 50 | printf("qsize %d\n", m_qsize); |
| 51 | NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); |
| 52 | for (int i = 0; i < m_qsize; i++ ) |
| 53 | { |
| 54 | netlist_net_t *n = m_netlist.find_net(&(m_name[i][0])); |
| 55 | NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n)); |
| 56 | printf("Got %s ==> %p\n", m_name[i], n); |
| 57 | NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double())); |
| 58 | printf("schedule time %f (%f)\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double()); |
| 59 | this->push(netlist_queue_t::entry_t(netlist_time::from_raw(m_times[i]), *n)); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | // ---------------------------------------------------------------------------------------- |
| 14 | 64 | // netlist_object_t |
| 15 | 65 | // ---------------------------------------------------------------------------------------- |
| 16 | 66 | |
| r26741 | r26742 | |
| 62 | 112 | // ---------------------------------------------------------------------------------------- |
| 63 | 113 | |
| 64 | 114 | netlist_base_t::netlist_base_t() |
| 65 | | : netlist_object_t(NETLIST, GENERIC), |
| 66 | | m_time_ps(netlist_time::zero), |
| 67 | | m_rem(0), |
| 68 | | m_div(NETLIST_DIV), |
| 69 | | m_mainclock(NULL), |
| 70 | | m_solver(NULL) |
| 115 | : netlist_object_t(NETLIST, GENERIC), |
| 116 | m_time_ps(netlist_time::zero), |
| 117 | m_queue(*this), |
| 118 | m_rem(0), |
| 119 | m_div(NETLIST_DIV), |
| 120 | m_mainclock(NULL), |
| 121 | m_solver(NULL) |
| 71 | 122 | { |
| 72 | 123 | } |
| 73 | 124 | |
| r26741 | r26742 | |
| 169 | 220 | |
| 170 | 221 | ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime) |
| 171 | 222 | { |
| 172 | | if (m_mainclock == NULL) |
| 173 | | { |
| 174 | | while ( (atime > 0) && (m_queue.is_not_empty())) |
| 175 | | { |
| 176 | | const queue_t::entry_t &e = m_queue.pop(); |
| 177 | | update_time(e.time(), atime); |
| 223 | if (m_mainclock == NULL) |
| 224 | { |
| 225 | while ( (atime > 0) && (m_queue.is_not_empty())) |
| 226 | { |
| 227 | const netlist_queue_t::entry_t &e = m_queue.pop(); |
| 228 | update_time(e.time(), atime); |
| 178 | 229 | |
| 179 | 230 | //if (FATAL_ERROR_AFTER_NS) |
| 180 | 231 | // NL_VERBOSE_OUT(("%s\n", e.object().netdev()->name().cstr()); |
| r26741 | r26742 | |
| 207 | 258 | |
| 208 | 259 | NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); |
| 209 | 260 | |
| 210 | | } |
| 211 | | const queue_t::entry_t &e = m_queue.pop(); |
| 261 | } |
| 262 | const netlist_queue_t::entry_t &e = m_queue.pop(); |
| 212 | 263 | |
| 213 | 264 | update_time(e.time(), atime); |
| 214 | 265 | |
trunk/src/emu/netlist/pstate.h
| r26741 | r26742 | |
| 16 | 16 | // ---------------------------------------------------------------------------------------- |
| 17 | 17 | |
| 18 | 18 | #define PSTATE_INTERFACE(manager, module) \ |
| 19 | | template<class C> ATTR_COLD void save(C &state, const pstring &stname) \ |
| 20 | | { \ |
| 21 | | dynamic_cast<pstate_manager_t &>(manager).save_manager(state, module + "." + stname); \ |
| 22 | | } |
| 19 | template<typename C> ATTR_COLD void save(C &state, const pstring &stname) \ |
| 20 | { \ |
| 21 | dynamic_cast<pstate_manager_t &>(manager).save_manager(state, module + "." + stname); \ |
| 22 | } |
| 23 | 23 | |
| 24 | | enum netlist_data_type_e { |
| 25 | | NOT_SUPPORTED, |
| 26 | | DT_DOUBLE, |
| 27 | | DT_INT64, |
| 28 | | DT_INT8, |
| 29 | | DT_INT, |
| 30 | | DT_BOOLEAN |
| 24 | enum pstate_data_type_e { |
| 25 | NOT_SUPPORTED, |
| 26 | DT_CUSTOM, |
| 27 | DT_DOUBLE, |
| 28 | DT_INT64, |
| 29 | DT_INT8, |
| 30 | DT_INT, |
| 31 | DT_BOOLEAN |
| 31 | 32 | }; |
| 32 | 33 | |
| 33 | | template<typename _ItemType> struct nl_datatype { static const netlist_data_type_e type = netlist_data_type_e(NOT_SUPPORTED); }; |
| 34 | template<typename _ItemType> struct nl_datatype { static const pstate_data_type_e type = pstate_data_type_e(NOT_SUPPORTED); }; |
| 34 | 35 | //template<typename _ItemType> struct type_checker<_ItemType*> { static const bool is_atom = false; static const bool is_pointer = true; }; |
| 35 | 36 | |
| 36 | | #define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) template<> struct nl_datatype<TYPE>{ static const netlist_data_type_e type = netlist_data_type_e(TYPEDESC); } |
| 37 | #define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) template<> struct nl_datatype<TYPE>{ static const pstate_data_type_e type = pstate_data_type_e(TYPEDESC); } |
| 37 | 38 | |
| 39 | NETLIST_SAVE_TYPE(char, DT_INT8); |
| 38 | 40 | NETLIST_SAVE_TYPE(double, DT_DOUBLE); |
| 39 | 41 | NETLIST_SAVE_TYPE(INT8, DT_INT8); |
| 40 | 42 | NETLIST_SAVE_TYPE(UINT8, DT_INT8); |
| r26741 | r26742 | |
| 43 | 45 | NETLIST_SAVE_TYPE(bool, DT_BOOLEAN); |
| 44 | 46 | NETLIST_SAVE_TYPE(UINT32, DT_INT); |
| 45 | 47 | NETLIST_SAVE_TYPE(INT32, DT_INT); |
| 48 | //NETLIST_SAVE_TYPE(netlist_time::INTERNALTYPE, DT_INT64); |
| 46 | 49 | |
| 47 | 50 | struct pstate_entry_t |
| 48 | 51 | { |
| 49 | 52 | typedef netlist_list_t<pstate_entry_t *> list_t; |
| 50 | 53 | |
| 51 | | pstate_entry_t(const pstring &stname, const netlist_data_type_e dt, const int size, const int count, void *ptr) : |
| 52 | | m_name(stname), m_dt(dt), m_size(size), m_count(count), m_ptr(ptr) { } |
| 53 | | pstring m_name; |
| 54 | | netlist_data_type_e m_dt; |
| 55 | | int m_size; |
| 56 | | int m_count; |
| 57 | | void *m_ptr; |
| 54 | pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const int size, const int count, void *ptr) : |
| 55 | m_name(stname), m_dt(dt), m_size(size), m_count(count), m_ptr(ptr) { } |
| 56 | pstring m_name; |
| 57 | pstate_data_type_e m_dt; |
| 58 | int m_size; |
| 59 | int m_count; |
| 60 | void *m_ptr; |
| 58 | 61 | }; |
| 59 | 62 | |
| 63 | class pstate_manager_t; |
| 64 | |
| 65 | class pstate_callback_t |
| 66 | { |
| 67 | public: |
| 68 | typedef netlist_list_t<pstate_callback_t *> list_t; |
| 69 | |
| 70 | virtual ~pstate_callback_t() { }; |
| 71 | |
| 72 | virtual void register_state(pstate_manager_t &manager, const pstring &module) = 0; |
| 73 | virtual void on_pre_save() = 0; |
| 74 | virtual void on_post_load() = 0; |
| 75 | protected: |
| 76 | }; |
| 77 | |
| 60 | 78 | class pstate_manager_t |
| 61 | 79 | { |
| 62 | 80 | public: |
| 63 | 81 | |
| 64 | 82 | ATTR_COLD ~pstate_manager_t(); |
| 65 | 83 | |
| 66 | | template<class C> ATTR_COLD void save_manager(C &state, const pstring &stname) |
| 67 | | { |
| 68 | | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), 1, &state); |
| 69 | | } |
| 84 | template<typename C> ATTR_COLD void save_manager(C &state, const pstring &stname) |
| 85 | { |
| 86 | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), 1, &state); |
| 87 | } |
| 70 | 88 | |
| 71 | | template<class C> ATTR_COLD void save_manager(C *state, const pstring &stname, const int count) |
| 72 | | { |
| 73 | | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), count, state); |
| 74 | | } |
| 89 | template<typename C, std::size_t N> ATTR_COLD void save_manager(C (&state)[N], const pstring &stname) |
| 90 | { |
| 91 | save_state_ptr(stname, nl_datatype<C>::type, sizeof(state[0]), N, &(state[0])); |
| 92 | } |
| 75 | 93 | |
| 76 | | template<class C, std::size_t N> ATTR_COLD void save_manager(C (&state)[N], const pstring &stname) |
| 77 | | { |
| 78 | | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), N, &(state[0])); |
| 79 | | } |
| 94 | template<typename C> ATTR_COLD void save_manager(C *state, const pstring &stname, const int count) |
| 95 | { |
| 96 | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), count, state); |
| 97 | } |
| 80 | 98 | |
| 99 | ATTR_COLD void pre_save(); |
| 100 | ATTR_COLD void post_load(); |
| 101 | |
| 81 | 102 | inline const pstate_entry_t::list_t &save_list() const { return m_save; } |
| 82 | 103 | |
| 83 | 104 | protected: |
| 84 | | ATTR_COLD void save_state_ptr(const pstring &stname, const netlist_data_type_e, const int size, const int count, void *ptr); |
| 105 | ATTR_COLD void save_state_ptr(const pstring &stname, const pstate_data_type_e, const int size, const int count, void *ptr); |
| 85 | 106 | |
| 86 | 107 | private: |
| 87 | 108 | pstate_entry_t::list_t m_save; |
| 109 | pstate_callback_t::list_t m_callback; |
| 88 | 110 | }; |
| 89 | 111 | |
| 112 | template<> ATTR_COLD inline void pstate_manager_t::save_manager(pstate_callback_t &state, const pstring &stname) |
| 113 | { |
| 114 | //save_state_ptr(stname, DT_CUSTOM, 0, 1, &state); |
| 115 | m_callback.add(&state); |
| 116 | state.register_state(*this, stname); |
| 117 | } |
| 118 | |
| 90 | 119 | template<> ATTR_COLD inline void pstate_manager_t::save_manager(netlist_time &nlt, const pstring &stname) |
| 91 | 120 | { |
| 92 | 121 | save_state_ptr(stname, DT_INT64, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr()); |
trunk/src/emu/netlist/nl_base.h
| r26741 | r26742 | |
| 289 | 289 | |
| 290 | 290 | PSTATE_INTERFACE(*m_netlist, name()) |
| 291 | 291 | |
| 292 | | #if 0 |
| 293 | | template<class C> ATTR_COLD void save(C &state, const pstring &stname) |
| 294 | | { |
| 295 | | save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), &state); |
| 296 | | } |
| 297 | | #endif |
| 298 | | |
| 299 | 292 | ATTR_HOT inline const type_t type() const { return m_objtype; } |
| 300 | 293 | ATTR_HOT inline const family_t family() const { return m_family; } |
| 301 | 294 | |
| r26741 | r26742 | |
| 307 | 300 | |
| 308 | 301 | protected: |
| 309 | 302 | |
| 310 | | #if 0 |
| 311 | | // pstate_interface virtual |
| 312 | | ATTR_COLD virtual void save_state_ptr(const pstring &stname, const netlist_data_type_e, const int size, const int count, void *ptr); |
| 313 | | #endif |
| 314 | | |
| 315 | 303 | // must call parent save_register ! |
| 316 | 304 | ATTR_COLD virtual void save_register() { }; |
| 317 | 305 | |
| r26741 | r26742 | |
| 470 | 458 | class netlist_logic_input_t : public netlist_input_t |
| 471 | 459 | { |
| 472 | 460 | public: |
| 473 | | netlist_logic_input_t() |
| 461 | ATTR_COLD netlist_logic_input_t() |
| 474 | 462 | : netlist_input_t(INPUT, LOGIC) |
| 475 | 463 | { |
| 476 | 464 | // default to TTL |
| r26741 | r26742 | |
| 495 | 483 | class netlist_ttl_input_t : public netlist_logic_input_t |
| 496 | 484 | { |
| 497 | 485 | public: |
| 498 | | netlist_ttl_input_t() |
| 486 | ATTR_COLD netlist_ttl_input_t() |
| 499 | 487 | : netlist_logic_input_t() { set_thresholds(0.8 , 2.0); } |
| 500 | 488 | }; |
| 501 | 489 | |
| r26741 | r26742 | |
| 506 | 494 | class netlist_analog_input_t : public netlist_input_t |
| 507 | 495 | { |
| 508 | 496 | public: |
| 509 | | netlist_analog_input_t() |
| 497 | ATTR_COLD netlist_analog_input_t() |
| 510 | 498 | : netlist_input_t(INPUT, ANALOG) { } |
| 511 | 499 | |
| 512 | 500 | ATTR_HOT inline const bool is_highz() const; |
| r26741 | r26742 | |
| 598 | 586 | |
| 599 | 587 | netlist_core_terminal_t *m_head; |
| 600 | 588 | |
| 601 | | protected: |
| 589 | // the following three must be public for mame support |
| 590 | //protected: |
| 602 | 591 | |
| 603 | | |
| 604 | 592 | hybrid_t m_last; |
| 605 | 593 | hybrid_t m_cur; |
| 606 | 594 | hybrid_t m_new; |
| 607 | 595 | |
| 596 | protected: |
| 608 | 597 | UINT32 m_num_cons; |
| 609 | 598 | |
| 610 | | protected: |
| 611 | 599 | ATTR_COLD virtual void save_register() |
| 612 | 600 | { |
| 613 | 601 | save(NAME(m_last.Analog)); |
| r26741 | r26742 | |
| 955 | 943 | |
| 956 | 944 | |
| 957 | 945 | // ---------------------------------------------------------------------------------------- |
| 946 | // netlist_queue_t |
| 947 | // ---------------------------------------------------------------------------------------- |
| 948 | |
| 949 | class netlist_queue_t : public netlist_timed_queue<netlist_net_t, netlist_time, 512>, |
| 950 | public pstate_callback_t |
| 951 | { |
| 952 | public: |
| 953 | |
| 954 | netlist_queue_t(netlist_base_t &nl); |
| 955 | |
| 956 | void register_state(pstate_manager_t &manager, const pstring &module); |
| 957 | void on_pre_save(); |
| 958 | void on_post_load(); |
| 959 | |
| 960 | pstate_callback_t &callback() { return *this; } |
| 961 | |
| 962 | private: |
| 963 | netlist_base_t &m_netlist; |
| 964 | int m_qsize; |
| 965 | netlist_time::INTERNALTYPE m_times[512]; |
| 966 | char m_name[512][64]; |
| 967 | }; |
| 968 | |
| 969 | // ---------------------------------------------------------------------------------------- |
| 958 | 970 | // netlist_base_t |
| 959 | 971 | // ---------------------------------------------------------------------------------------- |
| 960 | 972 | |
| 973 | |
| 961 | 974 | typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t; |
| 962 | 975 | |
| 963 | 976 | class netlist_base_t : public netlist_object_t, public pstate_manager_t |
| r26741 | r26742 | |
| 965 | 978 | NETLIST_PREVENT_COPYING(netlist_base_t) |
| 966 | 979 | public: |
| 967 | 980 | |
| 968 | | typedef netlist_timed_queue<netlist_net_t, netlist_time, 512> queue_t; |
| 969 | | |
| 970 | 981 | netlist_base_t(); |
| 971 | 982 | virtual ~netlist_base_t(); |
| 972 | 983 | |
| 973 | | ATTR_HOT inline const queue_t &queue() const { return m_queue; } |
| 974 | | ATTR_HOT inline queue_t &queue() { return m_queue; } |
| 984 | ATTR_HOT inline const netlist_queue_t &queue() const { return m_queue; } |
| 985 | ATTR_HOT inline netlist_queue_t &queue() { return m_queue; } |
| 975 | 986 | |
| 976 | 987 | ATTR_HOT inline void push_to_queue(netlist_net_t &out, const netlist_time &attime) |
| 977 | 988 | { |
| 978 | | m_queue.push(queue_t::entry_t(attime, out)); |
| 989 | m_queue.push(netlist_queue_t::entry_t(attime, out)); |
| 979 | 990 | } |
| 980 | 991 | |
| 981 | 992 | ATTR_HOT NETLIB_NAME(solver) *solver() const { return m_solver; } |
| r26741 | r26742 | |
| 1006 | 1017 | virtual void vfatalerror(const char *format, va_list ap) const = 0; |
| 1007 | 1018 | |
| 1008 | 1019 | protected: |
| 1009 | | ATTR_COLD virtual void save_register() |
| 1010 | | { |
| 1011 | | //queue_t m_queue; |
| 1012 | | save(NAME(m_time_ps)); |
| 1013 | | save(NAME(m_rem)); |
| 1014 | | save(NAME(m_div)); |
| 1015 | | netlist_object_t::save_register(); |
| 1016 | | } |
| 1020 | ATTR_COLD virtual void save_register() |
| 1021 | { |
| 1022 | //netlist_queue_t m_queue; |
| 1023 | //netlist().save_manager(m_queue.callback(), "m_queue"); |
| 1024 | save(NAME(m_queue.callback())); |
| 1025 | save(NAME(m_time_ps)); |
| 1026 | save(NAME(m_rem)); |
| 1027 | save(NAME(m_div)); |
| 1028 | netlist_object_t::save_register(); |
| 1029 | } |
| 1017 | 1030 | |
| 1018 | 1031 | #if (NL_KEEP_STATISTICS) |
| 1019 | 1032 | // performance |
| r26741 | r26742 | |
| 1025 | 1038 | private: |
| 1026 | 1039 | ATTR_HOT void update_time(const netlist_time t, INT32 &atime); |
| 1027 | 1040 | |
| 1028 | | netlist_time m_time_ps; |
| 1029 | | queue_t m_queue; |
| 1041 | netlist_time m_time_ps; |
| 1042 | netlist_queue_t m_queue; |
| 1030 | 1043 | UINT32 m_rem; |
| 1031 | 1044 | UINT32 m_div; |
| 1032 | 1045 | |
| r26741 | r26742 | |
| 1253 | 1266 | { |
| 1254 | 1267 | NETLIST_PREVENT_COPYING(net_device_t_base_factory) |
| 1255 | 1268 | public: |
| 1256 | | net_device_t_base_factory(const pstring &name, const pstring &classname) |
| 1269 | ATTR_COLD net_device_t_base_factory(const pstring &name, const pstring &classname) |
| 1257 | 1270 | : m_name(name), m_classname(classname) |
| 1258 | 1271 | {} |
| 1259 | 1272 | |
| 1260 | | virtual ~net_device_t_base_factory() {} |
| 1273 | ATTR_COLD virtual ~net_device_t_base_factory() {} |
| 1261 | 1274 | |
| 1262 | | virtual netlist_device_t *Create() const = 0; |
| 1275 | ATTR_COLD virtual netlist_device_t *Create() const = 0; |
| 1263 | 1276 | |
| 1264 | | const pstring &name() const { return m_name; } |
| 1265 | | const pstring &classname() const { return m_classname; } |
| 1277 | ATTR_COLD const pstring &name() const { return m_name; } |
| 1278 | ATTR_COLD const pstring &classname() const { return m_classname; } |
| 1266 | 1279 | protected: |
| 1267 | 1280 | pstring m_name; /* device name */ |
| 1268 | 1281 | pstring m_classname; /* device class name */ |
| r26741 | r26742 | |
| 1273 | 1286 | { |
| 1274 | 1287 | NETLIST_PREVENT_COPYING(net_device_t_factory) |
| 1275 | 1288 | public: |
| 1276 | | net_device_t_factory(const pstring &name, const pstring &classname) |
| 1289 | ATTR_COLD net_device_t_factory(const pstring &name, const pstring &classname) |
| 1277 | 1290 | : net_device_t_base_factory(name, classname) { } |
| 1278 | 1291 | |
| 1279 | | netlist_device_t *Create() const |
| 1292 | ATTR_COLD netlist_device_t *Create() const |
| 1280 | 1293 | { |
| 1281 | 1294 | netlist_device_t *r = new C(); |
| 1282 | 1295 | //r->init(setup, name); |
| r26741 | r26742 | |
| 1288 | 1301 | { |
| 1289 | 1302 | public: |
| 1290 | 1303 | |
| 1291 | | netlist_factory(); |
| 1292 | | ~netlist_factory(); |
| 1304 | ATTR_COLD netlist_factory(); |
| 1305 | ATTR_COLD ~netlist_factory(); |
| 1293 | 1306 | |
| 1294 | | void initialize(); |
| 1307 | ATTR_COLD void initialize(); |
| 1295 | 1308 | |
| 1296 | | template<class _C> |
| 1297 | | void register_device(const pstring &name, const pstring &classname) |
| 1309 | template<class _C> |
| 1310 | ATTR_COLD void register_device(const pstring &name, const pstring &classname) |
| 1298 | 1311 | { |
| 1299 | 1312 | m_list.add(new net_device_t_factory< _C >(name, classname) ); |
| 1300 | 1313 | } |
| 1301 | 1314 | |
| 1302 | | netlist_device_t *new_device_by_classname(const pstring &classname, netlist_setup_t &setup) const; |
| 1303 | | netlist_device_t *new_device_by_name(const pstring &name, netlist_setup_t &setup) const; |
| 1315 | ATTR_COLD netlist_device_t *new_device_by_classname(const pstring &classname, netlist_setup_t &setup) const; |
| 1316 | ATTR_COLD netlist_device_t *new_device_by_name(const pstring &name, netlist_setup_t &setup) const; |
| 1304 | 1317 | |
| 1305 | 1318 | private: |
| 1306 | 1319 | typedef netlist_list_t<net_device_t_base_factory *> list_t; |
trunk/src/emu/machine/netlist.c
| r26741 | r26742 | |
| 60 | 60 | |
| 61 | 61 | const device_type NETLIST = &device_creator<netlist_mame_device>; |
| 62 | 62 | |
| 63 | static ADDRESS_MAP_START(program_dummy, AS_PROGRAM, 8, netlist_mame_device) |
| 64 | AM_RANGE(0x000, 0x3ff) AM_ROM |
| 65 | ADDRESS_MAP_END |
| 66 | |
| 63 | 67 | netlist_mame_device::netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 64 | 68 | : device_t(mconfig, NETLIST, "netlist", tag, owner, clock, "netlist_mame", __FILE__), |
| 65 | 69 | device_execute_interface(mconfig, *this), |
| 66 | | //device_state_interface(mconfig, *this), |
| 70 | device_state_interface(mconfig, *this), |
| 71 | device_disasm_interface(mconfig, *this), |
| 72 | device_memory_interface(mconfig, *this), |
| 67 | 73 | m_device_start_list(100), |
| 74 | m_program_config("program", ENDIANNESS_LITTLE, 8, 12, 0, ADDRESS_MAP_NAME(program_dummy)), |
| 68 | 75 | m_netlist(NULL), |
| 69 | 76 | m_setup(NULL), |
| 70 | 77 | m_setup_func(NULL), |
| 71 | | m_icount(0) |
| 78 | m_icount(0), |
| 79 | m_genPC(0) |
| 72 | 80 | { |
| 73 | 81 | } |
| 74 | 82 | |
| r26741 | r26742 | |
| 113 | 121 | |
| 114 | 122 | save_state(); |
| 115 | 123 | |
| 124 | // State support |
| 125 | |
| 126 | state_add(STATE_GENPC, "curpc", m_genPC).noshow(); |
| 127 | |
| 128 | for (int i=0; i < m_netlist->m_nets.count(); i++) |
| 129 | { |
| 130 | netlist_net_t *n = m_netlist->m_nets[i]; |
| 131 | if (n->isRailNet()) |
| 132 | { |
| 133 | state_add(i*2, n->name(), n->m_cur.Q); |
| 134 | } |
| 135 | else |
| 136 | { |
| 137 | state_add(i*2+1, n->name(), n->m_cur.Analog).formatstr("%20s"); |
| 138 | } |
| 139 | } |
| 140 | |
| 116 | 141 | // set our instruction counter |
| 117 | 142 | m_icountptr = &m_icount; |
| 118 | 143 | } |
| r26741 | r26742 | |
| 136 | 161 | |
| 137 | 162 | ATTR_COLD void netlist_mame_device::device_post_load() |
| 138 | 163 | { |
| 139 | | LOG_DEV_CALLS(("device_post_load\n")); |
| 140 | | m_netlist->queue().clear(); |
| 141 | | NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); |
| 142 | | for (int i = 0; i < qsize; i++ ) |
| 143 | | { |
| 144 | | netlist_net_t *n = m_netlist->find_net(qtemp[i].m_name); |
| 145 | | NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n)); |
| 146 | | NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double())); |
| 147 | | m_netlist->queue().push(netlist_base_t::queue_t::entry_t(qtemp[i].m_time, *n)); |
| 148 | | } |
| 164 | LOG_DEV_CALLS(("device_post_load\n")); |
| 165 | |
| 166 | m_netlist->post_load(); |
| 149 | 167 | } |
| 150 | 168 | |
| 151 | 169 | ATTR_COLD void netlist_mame_device::device_pre_save() |
| 152 | 170 | { |
| 153 | 171 | LOG_DEV_CALLS(("device_pre_save\n")); |
| 154 | 172 | |
| 155 | | qsize = m_netlist->queue().count(); |
| 156 | | NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); |
| 157 | | for (int i = 0; i < qsize; i++ ) |
| 158 | | { |
| 159 | | qtemp[i].m_time = m_netlist->queue().listptr()[i].time(); |
| 160 | | const char *p = m_netlist->queue().listptr()[i].object().name().cstr(); |
| 161 | | int n = MIN(63, strlen(p)); |
| 162 | | strncpy(qtemp[i].m_name, p, n); |
| 163 | | qtemp[i].m_name[n] = 0; |
| 164 | | } |
| 165 | | #if 0 |
| 166 | | |
| 167 | | netlist_time *nlt = (netlist_time *) ; |
| 168 | | netlist_base_t::queue_t::entry_t *p = m_netlist->queue().listptr()[i]; |
| 169 | | netlist_time *nlt = (netlist_time *) p->time_ptr(); |
| 170 | | save_pointer(nlt->get_internaltype_ptr(), "queue", 1, i); |
| 171 | | #endif |
| 173 | m_netlist->pre_save(); |
| 172 | 174 | } |
| 173 | 175 | |
| 174 | 176 | void netlist_mame_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| r26741 | r26742 | |
| 179 | 181 | |
| 180 | 182 | ATTR_COLD void netlist_mame_device::save_state() |
| 181 | 183 | { |
| 182 | | for (pstate_entry_t::list_t::entry_t *p = m_netlist->save_list().first(); p != NULL; p = m_netlist->save_list().next(p)) |
| 183 | | { |
| 184 | | pstate_entry_t *s = p->object(); |
| 185 | | NL_VERBOSE_OUT(("saving state for %s\n", s->m_name.cstr())); |
| 186 | | switch (s->m_dt) |
| 187 | | { |
| 188 | | case DT_DOUBLE: |
| 189 | | save_pointer((double *) s->m_ptr, s->m_name, s->m_count); |
| 190 | | break; |
| 191 | | case DT_INT64: |
| 192 | | save_pointer((INT64 *) s->m_ptr, s->m_name, s->m_count); |
| 193 | | break; |
| 194 | | case DT_INT8: |
| 195 | | save_pointer((INT8 *) s->m_ptr, s->m_name, s->m_count); |
| 196 | | break; |
| 197 | | case DT_INT: |
| 198 | | save_pointer((int *) s->m_ptr, s->m_name, s->m_count); |
| 199 | | break; |
| 200 | | case DT_BOOLEAN: |
| 201 | | save_pointer((bool *) s->m_ptr, s->m_name, s->m_count); |
| 202 | | break; |
| 203 | | case NOT_SUPPORTED: |
| 204 | | default: |
| 205 | | m_netlist->xfatalerror("found unsupported save element %s\n", s->m_name.cstr()); |
| 206 | | break; |
| 207 | | } |
| 208 | | } |
| 184 | for (pstate_entry_t::list_t::entry_t *p = m_netlist->save_list().first(); p != NULL; p = m_netlist->save_list().next(p)) |
| 185 | { |
| 186 | pstate_entry_t *s = p->object(); |
| 187 | NL_VERBOSE_OUT(("saving state for %s\n", s->m_name.cstr())); |
| 188 | switch (s->m_dt) |
| 189 | { |
| 190 | case DT_DOUBLE: |
| 191 | save_pointer((double *) s->m_ptr, s->m_name, s->m_count); |
| 192 | break; |
| 193 | case DT_INT64: |
| 194 | save_pointer((INT64 *) s->m_ptr, s->m_name, s->m_count); |
| 195 | break; |
| 196 | case DT_INT8: |
| 197 | save_pointer((INT8 *) s->m_ptr, s->m_name, s->m_count); |
| 198 | break; |
| 199 | case DT_INT: |
| 200 | save_pointer((int *) s->m_ptr, s->m_name, s->m_count); |
| 201 | break; |
| 202 | case DT_BOOLEAN: |
| 203 | save_pointer((bool *) s->m_ptr, s->m_name, s->m_count); |
| 204 | break; |
| 205 | case DT_CUSTOM: |
| 206 | case NOT_SUPPORTED: |
| 207 | default: |
| 208 | m_netlist->xfatalerror("found unsupported save element %s\n", s->m_name.cstr()); |
| 209 | break; |
| 210 | } |
| 211 | } |
| 209 | 212 | |
| 210 | | // handle the queue |
| 211 | | |
| 212 | | save_item(NAME(qsize)); |
| 213 | | for (int i = 0; i < m_netlist->queue().capacity(); i++ ) |
| 214 | | { |
| 215 | | save_pointer(qtemp[i].m_time.get_internaltype_ptr(), "queue_time", 1, i); |
| 216 | | save_pointer(qtemp[i].m_name, "queue_name", sizeof(qtemp[i].m_name), i); |
| 217 | | |
| 218 | | } |
| 219 | 213 | } |
| 220 | 214 | |
| 221 | 215 | ATTR_COLD UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const |
| r26741 | r26742 | |
| 228 | 222 | return cycles; |
| 229 | 223 | } |
| 230 | 224 | |
| 225 | ATTR_COLD offs_t netlist_mame_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 226 | { |
| 227 | //char tmp[16]; |
| 228 | unsigned startpc = pc; |
| 229 | int relpc = pc - m_genPC; |
| 230 | //UINT16 opcode = (oprom[pc - startpc] << 8) | oprom[pc+1 - startpc]; |
| 231 | //UINT8 inst = opcode >> 13; |
| 232 | |
| 233 | if (relpc >= 0 && relpc < m_netlist->queue().count()) |
| 234 | { |
| 235 | // sprintf(buffer, "%04x %02d %s", pc, relpc, m_netlist->queue()[m_netlist->queue().count() - relpc - 1].object().name().cstr()); |
| 236 | int dpc = m_netlist->queue().count() - relpc - 1; |
| 237 | sprintf(buffer, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', m_netlist->queue()[dpc].object().name().cstr(), |
| 238 | m_netlist->queue()[dpc].time().as_double()); |
| 239 | } |
| 240 | else |
| 241 | sprintf(buffer, "%s", ""); |
| 242 | pc+=1; |
| 243 | return (pc - startpc); |
| 244 | } |
| 245 | |
| 231 | 246 | ATTR_HOT void netlist_mame_device::execute_run() |
| 232 | 247 | { |
| 233 | 248 | bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0); |
| 234 | | |
| 235 | 249 | // debugging |
| 236 | 250 | //m_ppc = m_pc; // copy PC to previous PC |
| 237 | 251 | if (check_debugger) |
| 238 | | debugger_instruction_hook(this, 0); //m_pc); |
| 252 | { |
| 253 | while (m_icount > 0) |
| 254 | { |
| 255 | int m_temp = 1; |
| 256 | m_genPC++; |
| 257 | m_genPC &= 255; |
| 258 | debugger_instruction_hook(this, m_genPC); |
| 259 | m_netlist->process_queue(m_temp); |
| 260 | m_icount -= (1 - m_temp); |
| 261 | } |
| 262 | } |
| 263 | else |
| 264 | m_netlist->process_queue(m_icount); |
| 265 | } |
| 239 | 266 | |
| 240 | | m_netlist->process_queue(m_icount); |
| 241 | | } |
trunk/src/emu/machine/netlist.h
| r26741 | r26742 | |
| 121 | 121 | // ======================> netlist_mame_device |
| 122 | 122 | |
| 123 | 123 | class netlist_mame_device : public device_t, |
| 124 | | public device_execute_interface |
| 125 | | //public device_state_interface |
| 126 | | //, public device_memory_interface |
| 124 | public device_execute_interface, |
| 125 | public device_state_interface, |
| 126 | public device_disasm_interface, |
| 127 | public device_memory_interface |
| 127 | 128 | { |
| 128 | 129 | public: |
| 129 | 130 | |
| r26741 | r26742 | |
| 166 | 167 | |
| 167 | 168 | ATTR_HOT virtual void execute_run(); |
| 168 | 169 | |
| 170 | // device_disasm_interface overrides |
| 171 | ATTR_COLD virtual UINT32 disasm_min_opcode_bytes() const { return 1; } |
| 172 | ATTR_COLD virtual UINT32 disasm_max_opcode_bytes() const { return 1; } |
| 173 | ATTR_COLD virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 174 | |
| 175 | // device_memory_interface overrides |
| 176 | |
| 177 | address_space_config m_program_config; |
| 178 | |
| 179 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const |
| 180 | { |
| 181 | switch (spacenum) |
| 182 | { |
| 183 | case AS_PROGRAM: return &m_program_config; |
| 184 | case AS_IO: return NULL; |
| 185 | default: return NULL; |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | virtual void state_string_export(const device_state_entry &entry, astring &string) |
| 190 | { |
| 191 | if (entry.index() >= 0) |
| 192 | { |
| 193 | if (entry.index() & 1) |
| 194 | string.format("%10.6f", *((double *) entry.dataptr())); |
| 195 | else |
| 196 | string.format("%d", *((netlist_sig_t *) entry.dataptr())); |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | |
| 169 | 201 | netlist_mame_t *m_netlist; |
| 170 | 202 | |
| 171 | 203 | netlist_setup_t *m_setup; |
| r26741 | r26742 | |
| 187 | 219 | void (*m_setup_func)(netlist_setup_t &); |
| 188 | 220 | |
| 189 | 221 | int m_icount; |
| 222 | int m_genPC; |
| 190 | 223 | |
| 191 | 224 | |
| 225 | |
| 192 | 226 | }; |
| 193 | 227 | |
| 194 | 228 | inline running_machine &netlist_mame_t::machine() |