trunk/src/emu/netlist/nl_base.c
| r26220 | r26221 | |
| 28 | 28 | m_mainclock = dev; |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | ATTR_COLD void netlist_base_t::set_solver_dev(NETLIB_NAME(solver) *dev) |
| 32 | { |
| 33 | m_solver = dev; |
| 34 | } |
| 35 | |
| 31 | 36 | ATTR_COLD void netlist_base_t::reset() |
| 32 | 37 | { |
| 33 | 38 | m_time_ps = netlist_time::zero; |
| r26220 | r26221 | |
| 173 | 178 | |
| 174 | 179 | ATTR_HOT ATTR_ALIGN const netlist_sig_t netlist_core_device_t::INPLOGIC_PASSIVE(netlist_logic_input_t &inp) |
| 175 | 180 | { |
| 176 | | if (inp.state() == netlist_input_t::INP_STATE_PASSIVE) |
| 181 | if (inp.state() == netlist_input_t::STATE_INP_PASSIVE) |
| 177 | 182 | { |
| 178 | 183 | inp.activate(); |
| 179 | 184 | const netlist_sig_t ret = inp.Q(); |
| r26220 | r26221 | |
| 211 | 216 | dev.init(*m_setup, name); |
| 212 | 217 | } |
| 213 | 218 | |
| 214 | | void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port) |
| 219 | ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port) |
| 215 | 220 | { |
| 216 | | m_setup->register_output(*this, dev, name, port); |
| 221 | m_setup->register_object(*this, dev, name, port, netlist_terminal_t::STATE_NONE); |
| 217 | 222 | } |
| 218 | 223 | |
| 219 | | void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port) |
| 224 | ATTR_COLD void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port) |
| 220 | 225 | { |
| 221 | | m_setup->register_terminal(*this,*this,name, port); |
| 226 | m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_NONE); |
| 222 | 227 | } |
| 223 | 228 | |
| 224 | | void netlist_device_t::register_output(const astring &name, netlist_output_t &port) |
| 229 | ATTR_COLD void netlist_device_t::register_output(const astring &name, netlist_output_t &port) |
| 225 | 230 | { |
| 226 | | m_setup->register_output(*this,*this,name, port); |
| 231 | m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_NONE); |
| 227 | 232 | } |
| 228 | 233 | |
| 229 | | void netlist_device_t::register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type) |
| 234 | ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &inp, netlist_input_t::state_e type) |
| 230 | 235 | { |
| 231 | | m_setup->register_input(*this, dev, name, inp, type); |
| 236 | m_setup->register_object(*this, dev, name, inp, type); |
| 232 | 237 | } |
| 233 | 238 | |
| 234 | | void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type) |
| 239 | ATTR_COLD void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::state_e type) |
| 235 | 240 | { |
| 236 | 241 | register_input(*this, name, inp, type); |
| 237 | 242 | } |
| 238 | 243 | |
| 239 | | void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState) |
| 244 | ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState) |
| 240 | 245 | { |
| 241 | | in.init_input(dev, aState); |
| 246 | in.init_terminal(dev); |
| 247 | in.set_state(aState); |
| 242 | 248 | // ensure we are not yet initialized ... |
| 243 | 249 | if (!out.net().isRailNet()) |
| 244 | 250 | out.init_terminal(dev); |
| r26220 | r26221 | |
| 246 | 252 | out.net().register_con(in); |
| 247 | 253 | } |
| 248 | 254 | |
| 249 | | void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState) |
| 255 | ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState) |
| 250 | 256 | { |
| 251 | 257 | register_link_internal(*this, in, out, aState); |
| 252 | 258 | } |
| 253 | 259 | |
| 254 | | void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t ¶m, double initialVal) |
| 260 | ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t ¶m, double initialVal) |
| 255 | 261 | { |
| 256 | 262 | param.set_netdev(dev); |
| 257 | 263 | param.initial(initialVal); |
| 258 | | m_setup->register_param(name, ¶m); |
| 264 | m_setup->register_object(*this, *this, name, param, netlist_terminal_t::STATE_NONE); |
| 259 | 265 | } |
| 260 | 266 | |
| 261 | | void netlist_device_t::register_param(const astring &name, netlist_param_t ¶m, double initialVal) |
| 267 | ATTR_COLD void netlist_device_t::register_param(const astring &name, netlist_param_t ¶m, double initialVal) |
| 262 | 268 | { |
| 263 | 269 | register_param(*this,name, param, initialVal); |
| 264 | 270 | } |
| r26220 | r26221 | |
| 326 | 332 | } |
| 327 | 333 | m_num_cons++; |
| 328 | 334 | |
| 329 | | if (terminal.state() != netlist_input_t::INP_STATE_PASSIVE) |
| 335 | if (terminal.state() != netlist_input_t::STATE_INP_PASSIVE) |
| 330 | 336 | m_active++; |
| 331 | 337 | } |
| 332 | 338 | |
| r26220 | r26221 | |
| 346 | 352 | { |
| 347 | 353 | assert(m_num_cons != 0); |
| 348 | 354 | |
| 349 | | //assert(this->isRailNet()); |
| 350 | | if (UNEXPECTED(!this->isRailNet())) |
| 355 | assert(this->isRailNet()); |
| 351 | 356 | { |
| 352 | | /* only inputs and terminals connected |
| 353 | | * approach: |
| 354 | | * |
| 355 | | * a) Update voltage on this net |
| 356 | | * b) Update devices |
| 357 | | * c) If difference old - new > trigger schedule immediate update |
| 358 | | * of number of updates < max_update_count |
| 359 | | * else clear number of updates |
| 360 | | */ |
| 361 | | m_in_queue = 2; /* mark as taken ... */ |
| 362 | | double gtot = 0; |
| 363 | | double iIdr = 0; |
| 364 | | netlist_terminal_t *p = m_head; |
| 365 | | do |
| 366 | | { |
| 367 | | p->netdev().update_dev(); |
| 368 | | gtot += p->m_g; |
| 369 | | iIdr += p->m_Idr; |
| 370 | 357 | |
| 371 | | p = p->m_update_list_next; |
| 372 | | } while (p != NULL); |
| 373 | | m_new.Analog = iIdr / gtot; |
| 374 | | printf("New: %f\n", m_new.Analog); |
| 375 | | } |
| 376 | | else |
| 377 | | { |
| 378 | | |
| 379 | 358 | const UINT32 masks[4] = { 1, 5, 3, 1 }; |
| 380 | 359 | m_cur = m_new; |
| 381 | 360 | m_in_queue = 2; /* mark as taken ... */ |
| r26220 | r26221 | |
| 417 | 396 | // net_input_t |
| 418 | 397 | // ---------------------------------------------------------------------------------------- |
| 419 | 398 | |
| 420 | | ATTR_COLD void netlist_input_t::init_input(netlist_core_device_t &dev, net_input_state astate) |
| 421 | | { |
| 422 | | init_terminal(dev); |
| 423 | | set_state(astate); |
| 424 | | } |
| 425 | | |
| 426 | 399 | // ---------------------------------------------------------------------------------------- |
| 427 | 400 | // net_output_t |
| 428 | 401 | // ---------------------------------------------------------------------------------------- |
trunk/src/emu/netlist/nl_base.h
| r26220 | r26221 | |
| 257 | 257 | m_netlist = &nl; |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | | ATTR_HOT inline const type_t object_type() const { return m_objtype; } |
| 260 | ATTR_HOT inline const type_t type() const { return m_objtype; } |
| 261 | 261 | ATTR_HOT inline const family_t family() const { return m_family; } |
| 262 | 262 | |
| 263 | 263 | ATTR_HOT inline const bool isType(const type_t atype) const { return (m_objtype == atype); } |
| r26220 | r26221 | |
| 282 | 282 | |
| 283 | 283 | /* needed here ... */ |
| 284 | 284 | |
| 285 | | enum net_input_state { |
| 286 | | INP_STATE_PASSIVE = 0, |
| 287 | | INP_STATE_ACTIVE = 1, |
| 288 | | INP_STATE_HL = 2, |
| 289 | | INP_STATE_LH = 4, |
| 285 | enum state_e { |
| 286 | STATE_INP_PASSIVE = 0, |
| 287 | STATE_INP_ACTIVE = 1, |
| 288 | STATE_INP_HL = 2, |
| 289 | STATE_INP_LH = 4, |
| 290 | STATE_NONE = 128 |
| 290 | 291 | }; |
| 291 | 292 | |
| 292 | 293 | ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily) |
| r26220 | r26221 | |
| 296 | 297 | , m_update_list_next(NULL) |
| 297 | 298 | , m_netdev(NULL) |
| 298 | 299 | , m_net(NULL) |
| 299 | | , m_state(INP_STATE_ACTIVE) |
| 300 | , m_state(STATE_NONE) |
| 300 | 301 | {} |
| 301 | 302 | |
| 302 | 303 | ATTR_COLD netlist_terminal_t() |
| r26220 | r26221 | |
| 305 | 306 | , m_update_list_next(NULL) |
| 306 | 307 | , m_netdev(NULL) |
| 307 | 308 | , m_net(NULL) |
| 308 | | , m_state(INP_STATE_ACTIVE) |
| 309 | , m_state(STATE_NONE) |
| 309 | 310 | {} |
| 310 | 311 | |
| 311 | 312 | ATTR_COLD virtual void init_terminal(netlist_core_device_t &dev); |
| r26220 | r26221 | |
| 316 | 317 | ATTR_HOT inline const netlist_net_t & RESTRICT net() const { return *m_net;} |
| 317 | 318 | ATTR_HOT inline netlist_net_t & RESTRICT net() { return *m_net;} |
| 318 | 319 | |
| 319 | | ATTR_HOT inline const bool is_state(const net_input_state astate) const { return (m_state == astate); } |
| 320 | | ATTR_HOT inline const net_input_state state() const { return m_state; } |
| 321 | | ATTR_HOT inline void set_state(const net_input_state astate) { m_state = astate; } |
| 320 | ATTR_HOT inline const bool is_state(const state_e astate) const { return (m_state == astate); } |
| 321 | ATTR_HOT inline const state_e state() const { return m_state; } |
| 322 | ATTR_HOT inline void set_state(const state_e astate) { m_state = astate; } |
| 322 | 323 | |
| 323 | 324 | ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; } |
| 324 | 325 | |
| r26220 | r26221 | |
| 330 | 331 | private: |
| 331 | 332 | netlist_core_device_t * RESTRICT m_netdev; |
| 332 | 333 | netlist_net_t * RESTRICT m_net; |
| 333 | | net_input_state m_state; |
| 334 | state_e m_state; |
| 334 | 335 | }; |
| 335 | 336 | |
| 336 | 337 | |
| r26220 | r26221 | |
| 347 | 348 | : netlist_terminal_t(atype, afamily) |
| 348 | 349 | , m_low_thresh_V(0) |
| 349 | 350 | , m_high_thresh_V(0) |
| 350 | | {} |
| 351 | { |
| 352 | set_state(STATE_INP_ACTIVE); |
| 353 | } |
| 351 | 354 | |
| 352 | | ATTR_COLD void init_input(netlist_core_device_t &dev, net_input_state astate = INP_STATE_ACTIVE); |
| 353 | | |
| 354 | 355 | ATTR_HOT inline void inactivate(); |
| 355 | 356 | ATTR_HOT inline void activate(); |
| 356 | 357 | ATTR_HOT inline void activate_hl(); |
| r26220 | r26221 | |
| 423 | 424 | public: |
| 424 | 425 | |
| 425 | 426 | friend class NETLIB_NAME(mainclock); |
| 427 | friend class NETLIB_NAME(solver); |
| 426 | 428 | friend class netlist_output_t; |
| 427 | 429 | friend class netlist_input_t; |
| 428 | 430 | friend class netlist_logic_output_t; |
| r26220 | r26221 | |
| 512 | 514 | // ---------------------------------------------------------------------------------------- |
| 513 | 515 | |
| 514 | 516 | class NETLIB_NAME(mainclock); |
| 517 | class NETLIB_NAME(solver); |
| 515 | 518 | |
| 516 | 519 | class netlist_output_t : public netlist_terminal_t |
| 517 | 520 | { |
| r26220 | r26221 | |
| 628 | 631 | |
| 629 | 632 | ATTR_HOT inline const netlist_sig_t INPLOGIC(const netlist_logic_input_t &inp) const |
| 630 | 633 | { |
| 631 | | assert(inp.state() != netlist_input_t::INP_STATE_PASSIVE); |
| 634 | assert(inp.state() != netlist_input_t::STATE_INP_PASSIVE); |
| 632 | 635 | return inp.Q(); |
| 633 | 636 | } |
| 634 | 637 | |
| r26220 | r26221 | |
| 658 | 661 | |
| 659 | 662 | ATTR_HOT virtual void dec_active() { /*printf("DeActivate %s\n", m_name);*/ } |
| 660 | 663 | |
| 664 | ATTR_HOT virtual void update_terminals() { } |
| 665 | |
| 661 | 666 | /* stats */ |
| 662 | 667 | osd_ticks_t total_time; |
| 663 | 668 | INT32 stat_count; |
| r26220 | r26221 | |
| 697 | 702 | ATTR_COLD void register_output(const astring &name, netlist_output_t &out); |
| 698 | 703 | ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out); |
| 699 | 704 | |
| 700 | | ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::net_input_state state = netlist_input_t::INP_STATE_ACTIVE); |
| 701 | | ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &in, netlist_input_t::net_input_state state = netlist_input_t::INP_STATE_ACTIVE); |
| 705 | ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); |
| 706 | ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); |
| 702 | 707 | |
| 703 | | ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState); |
| 704 | | ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState); |
| 708 | ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState); |
| 709 | ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState); |
| 705 | 710 | |
| 706 | | /* driving logic outputs don't count in here */ |
| 711 | ATTR_HOT virtual void update_terminals() { } |
| 712 | |
| 713 | /* driving logic outputs don't count in here */ |
| 707 | 714 | netlist_list_t<astring> m_terminals; |
| 708 | 715 | |
| 709 | 716 | protected: |
| r26220 | r26221 | |
| 767 | 774 | m_queue.push(queue_t::entry_t(attime, out)); |
| 768 | 775 | } |
| 769 | 776 | |
| 777 | ATTR_HOT NETLIB_NAME(solver) &solver() { return *m_solver; } |
| 778 | |
| 770 | 779 | ATTR_HOT void process_queue(INT32 &atime); |
| 771 | 780 | |
| 772 | 781 | ATTR_HOT inline const netlist_time &time() const { return m_time_ps; } |
| 773 | 782 | |
| 774 | 783 | ATTR_COLD void set_mainclock_dev(NETLIB_NAME(mainclock) *dev); |
| 784 | ATTR_COLD void set_solver_dev(NETLIB_NAME(solver) *dev); |
| 775 | 785 | |
| 776 | 786 | ATTR_COLD void reset(); |
| 777 | 787 | |
| r26220 | r26221 | |
| 785 | 795 | int m_perf_inp_active; |
| 786 | 796 | |
| 787 | 797 | private: |
| 788 | | NETLIB_NAME(mainclock) *m_mainclock; |
| 789 | | netlist_time m_time_ps; |
| 790 | | UINT32 m_rem; |
| 791 | | UINT32 m_div; |
| 798 | NETLIB_NAME(mainclock) * m_mainclock; |
| 799 | NETLIB_NAME(solver) * m_solver; |
| 800 | netlist_time m_time_ps; |
| 801 | UINT32 m_rem; |
| 802 | UINT32 m_div; |
| 792 | 803 | |
| 793 | | |
| 794 | 804 | ATTR_HOT void update_time(const netlist_time t, INT32 &atime); |
| 795 | 805 | |
| 796 | 806 | }; |
| r26220 | r26221 | |
| 819 | 829 | protected: |
| 820 | 830 | void start() |
| 821 | 831 | { |
| 822 | | m_I.init_input(*this); |
| 832 | m_I.init_terminal(*this); |
| 823 | 833 | |
| 824 | 834 | m_Q.init_terminal(*this); |
| 825 | 835 | m_Q.initial(1); |
| r26220 | r26221 | |
| 859 | 869 | protected: |
| 860 | 870 | void start() |
| 861 | 871 | { |
| 862 | | m_I.init_input(*this); |
| 872 | m_I.init_terminal(*this); |
| 863 | 873 | m_Q.init_terminal(*this); |
| 864 | 874 | m_Q.initial(0); |
| 865 | 875 | } |
| r26220 | r26221 | |
| 875 | 885 | }; |
| 876 | 886 | |
| 877 | 887 | // ---------------------------------------------------------------------------------------- |
| 878 | | // nld_twoterm |
| 879 | | // ---------------------------------------------------------------------------------------- |
| 880 | | |
| 881 | | class nld_twoterm : public netlist_device_t |
| 882 | | { |
| 883 | | public: |
| 884 | | nld_twoterm() |
| 885 | | : netlist_device_t(), m_g(0.0), m_V(0.0), m_I(0.0) |
| 886 | | { |
| 887 | | } |
| 888 | | |
| 889 | | netlist_terminal_t m_P; |
| 890 | | netlist_terminal_t m_N; |
| 891 | | |
| 892 | | protected: |
| 893 | | virtual void start() |
| 894 | | { |
| 895 | | } |
| 896 | | |
| 897 | | ATTR_HOT ATTR_ALIGN virtual void update() |
| 898 | | { |
| 899 | | m_N.m_Idr = (m_P.net().Q_Analog() - m_V) * m_g + m_I; |
| 900 | | m_P.m_Idr = (m_N.net().Q_Analog() + m_V) * m_g - m_I; |
| 901 | | printf("%f %f %f %f\n", m_N.m_Idr, m_P.m_Idr, m_N.net().Q_Analog(), m_P.net().Q_Analog()); |
| 902 | | if (!m_N.net().is_queued() && !m_N.net().isRailNet()) |
| 903 | | m_N.net().push_to_queue(NLTIME_FROM_NS(10)); |
| 904 | | if (!m_P.net().is_queued() && !m_P.net().isRailNet() ) |
| 905 | | m_P.net().push_to_queue(NLTIME_FROM_NS(10)); |
| 906 | | } |
| 907 | | |
| 908 | | double m_g; // conductance |
| 909 | | double m_V; // internal voltage source |
| 910 | | double m_I; // internal current source |
| 911 | | private: |
| 912 | | }; |
| 913 | | |
| 914 | | class nld_R : public nld_twoterm |
| 915 | | { |
| 916 | | public: |
| 917 | | nld_R() |
| 918 | | : nld_twoterm() |
| 919 | | { |
| 920 | | } |
| 921 | | |
| 922 | | netlist_param_t m_R; |
| 923 | | |
| 924 | | protected: |
| 925 | | void start() |
| 926 | | { |
| 927 | | register_terminal("1", m_P); |
| 928 | | register_terminal("2", m_N); |
| 929 | | |
| 930 | | register_param("R", m_R, NETLIST_GMIN); |
| 931 | | } |
| 932 | | |
| 933 | | virtual void update_param() |
| 934 | | { |
| 935 | | m_g = 1.0 / m_R.Value(); |
| 936 | | m_P.m_g = m_g; |
| 937 | | m_N.m_g = m_g; |
| 938 | | } |
| 939 | | |
| 940 | | private: |
| 941 | | }; |
| 942 | | |
| 943 | | // ---------------------------------------------------------------------------------------- |
| 944 | 888 | // Inline implementations |
| 945 | 889 | // ---------------------------------------------------------------------------------------- |
| 946 | 890 | |
| 947 | 891 | ATTR_HOT inline void netlist_input_t::inactivate() |
| 948 | 892 | { |
| 949 | | if (!is_state(INP_STATE_PASSIVE)) |
| 893 | if (!is_state(STATE_INP_PASSIVE)) |
| 950 | 894 | { |
| 951 | | set_state(INP_STATE_PASSIVE); |
| 895 | set_state(STATE_INP_PASSIVE); |
| 952 | 896 | net().dec_active(); |
| 953 | 897 | } |
| 954 | 898 | } |
| 955 | 899 | |
| 956 | 900 | ATTR_HOT inline void netlist_input_t::activate() |
| 957 | 901 | { |
| 958 | | if (is_state(INP_STATE_PASSIVE)) |
| 902 | if (is_state(STATE_INP_PASSIVE)) |
| 959 | 903 | { |
| 960 | 904 | net().inc_active(); |
| 961 | | set_state(INP_STATE_ACTIVE); |
| 905 | set_state(STATE_INP_ACTIVE); |
| 962 | 906 | } |
| 963 | 907 | } |
| 964 | 908 | |
| 965 | 909 | ATTR_HOT inline void netlist_input_t::activate_hl() |
| 966 | 910 | { |
| 967 | | if (is_state(INP_STATE_PASSIVE)) |
| 911 | if (is_state(STATE_INP_PASSIVE)) |
| 968 | 912 | { |
| 969 | 913 | net().inc_active(); |
| 970 | | set_state(INP_STATE_HL); |
| 914 | set_state(STATE_INP_HL); |
| 971 | 915 | } |
| 972 | 916 | } |
| 973 | 917 | |
| 974 | 918 | ATTR_HOT inline void netlist_input_t::activate_lh() |
| 975 | 919 | { |
| 976 | | if (is_state(INP_STATE_PASSIVE)) |
| 920 | if (is_state(STATE_INP_PASSIVE)) |
| 977 | 921 | { |
| 978 | 922 | net().inc_active(); |
| 979 | | set_state(INP_STATE_LH); |
| 923 | set_state(STATE_INP_LH); |
| 980 | 924 | } |
| 981 | 925 | } |
| 982 | 926 | |
trunk/src/emu/netlist/nl_setup.c
| r26220 | r26221 | |
| 100 | 100 | fatalerror("Error adding alias %s to alias list\n", alias.cstr()); |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | | void netlist_setup_t::register_output(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_output_t &out) |
| 103 | astring netlist_setup_t::objtype_as_astr(netlist_object_t &in) |
| 104 | 104 | { |
| 105 | | NL_VERBOSE_OUT(("output %s\n", name.cstr())); |
| 106 | | astring temp = dev.name(); |
| 107 | | temp.cat("."); |
| 108 | | temp.cat(name); |
| 109 | | out.init_terminal(upd_dev); |
| 110 | | if (!(m_terminals.add(temp, &out, false)==TMERR_NONE)) |
| 111 | | fatalerror("Error adding output %s to terminal list\n", name.cstr()); |
| 105 | switch (in.type()) |
| 106 | { |
| 107 | case netlist_terminal_t::TERMINAL: |
| 108 | return "TERMINAL"; |
| 109 | break; |
| 110 | case netlist_terminal_t::INPUT: |
| 111 | return "INPUT"; |
| 112 | break; |
| 113 | case netlist_terminal_t::OUTPUT: |
| 114 | return "OUTPUT"; |
| 115 | break; |
| 116 | case netlist_terminal_t::NET: |
| 117 | return "NET"; |
| 118 | break; |
| 119 | case netlist_terminal_t::PARAM: |
| 120 | return "PARAM"; |
| 121 | break; |
| 122 | case netlist_terminal_t::DEVICE: |
| 123 | return "DEVICE"; |
| 124 | break; |
| 125 | } |
| 126 | fatalerror("Unknown object type %d\n", in.type()); |
| 112 | 127 | } |
| 113 | 128 | |
| 114 | | void netlist_setup_t::register_terminal(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_terminal_t &out) |
| 129 | void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state) |
| 115 | 130 | { |
| 116 | | NL_VERBOSE_OUT(("output %s\n", name.cstr())); |
| 117 | | assert(out.isType(netlist_terminal_t::TERMINAL)); |
| 118 | | astring temp = dev.name(); |
| 119 | | temp.cat("."); |
| 120 | | temp.cat(name); |
| 121 | | out.init_terminal(upd_dev); |
| 122 | | if (!(m_terminals.add(temp, &out, false)==TMERR_NONE)) |
| 123 | | fatalerror("Error adding output %s to terminal list\n", name.cstr()); |
| 131 | switch (obj.type()) |
| 132 | { |
| 133 | case netlist_terminal_t::TERMINAL: |
| 134 | case netlist_terminal_t::INPUT: |
| 135 | case netlist_terminal_t::OUTPUT: |
| 136 | { |
| 137 | netlist_terminal_t &term = dynamic_cast<netlist_terminal_t &>(obj); |
| 138 | astring temp = dev.name(); |
| 139 | temp.cat("."); |
| 140 | temp.cat(name); |
| 141 | term.init_terminal(upd_dev); |
| 142 | term.set_state(state); |
| 143 | if (!(m_terminals.add(temp, &term, false)==TMERR_NONE)) |
| 144 | fatalerror("Error adding %s %s to terminal list\n", objtype_as_astr(term).cstr(), name.cstr()); |
| 145 | NL_VERBOSE_OUT(("%s %s\n", objtype_as_astr(term).cstr(), name.cstr())); |
| 146 | } |
| 147 | break; |
| 148 | case netlist_terminal_t::NET: |
| 149 | break; |
| 150 | case netlist_terminal_t::PARAM: |
| 151 | { |
| 152 | netlist_param_t ¶m = dynamic_cast<netlist_param_t &>(obj); |
| 153 | astring temp = param.netdev().name(); |
| 154 | temp.cat("."); |
| 155 | temp.cat(name); |
| 156 | if (!(m_params.add(temp, ¶m, false)==TMERR_NONE)) |
| 157 | fatalerror("Error adding parameter %s to parameter list\n", name.cstr()); |
| 158 | } |
| 159 | break; |
| 160 | case netlist_terminal_t::DEVICE: |
| 161 | break; |
| 162 | } |
| 124 | 163 | } |
| 125 | 164 | |
| 126 | | void netlist_setup_t::register_input(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type) |
| 127 | | { |
| 128 | | NL_VERBOSE_OUT(("input %s\n", name.cstr())); |
| 129 | | astring temp = dev.name(); |
| 130 | | temp.cat("."); |
| 131 | | temp.cat(name); |
| 132 | | inp.init_input(upd_dev, type); |
| 133 | | /* add to list of terminals so logic devices are supported in parser */ |
| 134 | | dev.m_terminals.add(temp); |
| 135 | | if (!(m_terminals.add(temp, &inp, false) == TMERR_NONE)) |
| 136 | | fatalerror("Error adding input %s to terminal list\n", name.cstr()); |
| 137 | | } |
| 138 | | |
| 139 | 165 | void netlist_setup_t::register_link(const astring &sin, const astring &sout) |
| 140 | 166 | { |
| 141 | 167 | const astring *temp = new astring(sout); |
| r26220 | r26221 | |
| 144 | 170 | fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr()); |
| 145 | 171 | } |
| 146 | 172 | |
| 147 | | |
| 148 | | void netlist_setup_t::register_param(const astring &name, netlist_param_t *param) |
| 149 | | { |
| 150 | | astring temp = param->netdev().name(); |
| 151 | | temp.cat("."); |
| 152 | | temp.cat(name); |
| 153 | | if (!(m_params.add(temp, param, false)==TMERR_NONE)) |
| 154 | | fatalerror("Error adding parameter %s to parameter list\n", name.cstr()); |
| 155 | | } |
| 156 | | |
| 157 | | |
| 158 | 173 | const astring &netlist_setup_t::resolve_alias(const astring &name) const |
| 159 | 174 | { |
| 160 | 175 | const astring *ret = m_alias.find(name); |
| r26220 | r26221 | |
| 163 | 178 | return name; |
| 164 | 179 | } |
| 165 | 180 | |
| 166 | | netlist_output_t *netlist_setup_t::find_output_exact(const astring &outname_in) |
| 181 | netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in) |
| 167 | 182 | { |
| 168 | | netlist_terminal_t *term = m_terminals.find(outname_in); |
| 169 | | return dynamic_cast<netlist_output_t *>(term); |
| 170 | | } |
| 183 | const astring &tname = resolve_alias(terminal_in); |
| 184 | netlist_terminal_t *ret; |
| 171 | 185 | |
| 172 | | netlist_output_t &netlist_setup_t::find_output(const astring &outname_in) |
| 173 | | { |
| 174 | | const astring &outname = resolve_alias(outname_in); |
| 175 | | netlist_output_t *ret; |
| 176 | | |
| 177 | | ret = find_output_exact(outname); |
| 178 | | /* look for default */ |
| 179 | | if (ret == NULL) |
| 180 | | { |
| 181 | | /* look for ".Q" std output */ |
| 182 | | astring s = outname; |
| 183 | | s.cat(".Q"); |
| 184 | | ret = find_output_exact(s); |
| 185 | | } |
| 186 | | if (ret == NULL) |
| 187 | | fatalerror("output %s(%s) not found!\n", outname_in.cstr(), outname.cstr()); |
| 188 | | NL_VERBOSE_OUT(("Found input %s\n", outname.cstr())); |
| 189 | | return *ret; |
| 186 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname)); |
| 187 | /* look for default */ |
| 188 | if (ret == NULL) |
| 189 | { |
| 190 | /* look for ".Q" std output */ |
| 191 | astring s = tname; |
| 192 | s.cat(".Q"); |
| 193 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s)); |
| 194 | } |
| 195 | if (ret == NULL) |
| 196 | fatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr()); |
| 197 | NL_VERBOSE_OUT(("Found input %s\n", tname.cstr())); |
| 198 | return *ret; |
| 190 | 199 | } |
| 191 | 200 | |
| 192 | | netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in) |
| 201 | netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, netlist_object_t::type_t atype) |
| 193 | 202 | { |
| 194 | 203 | const astring &tname = resolve_alias(terminal_in); |
| 195 | 204 | netlist_terminal_t *ret; |
| 196 | 205 | |
| 197 | 206 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname)); |
| 198 | 207 | /* look for default */ |
| 199 | | if (ret == NULL) |
| 208 | if (ret == NULL && atype == netlist_object_t::OUTPUT) |
| 200 | 209 | { |
| 201 | 210 | /* look for ".Q" std output */ |
| 202 | 211 | astring s = tname; |
| r26220 | r26221 | |
| 205 | 214 | } |
| 206 | 215 | if (ret == NULL) |
| 207 | 216 | fatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr()); |
| 217 | if (ret->type() != atype) |
| 218 | fatalerror("object %s(%s) found but wrong type\n", terminal_in.cstr(), tname.cstr()); |
| 208 | 219 | NL_VERBOSE_OUT(("Found input %s\n", tname.cstr())); |
| 209 | 220 | return *ret; |
| 210 | 221 | } |
| r26220 | r26221 | |
| 297 | 308 | if (in.has_net() && out.has_net()) |
| 298 | 309 | { |
| 299 | 310 | in.net().merge_net(&out.net()); |
| 300 | | //in.net().register_con(out); |
| 301 | | //in.net().register_con(in); |
| 302 | 311 | } |
| 303 | 312 | else if (out.has_net()) |
| 304 | 313 | { |
| 305 | 314 | out.net().register_con(in); |
| 306 | | //out.net().register_con(out); |
| 307 | 315 | } |
| 308 | 316 | else if (in.has_net()) |
| 309 | 317 | { |
| 310 | 318 | in.net().register_con(out); |
| 311 | | //in.net().register_con(in); |
| 312 | 319 | } |
| 313 | 320 | else |
| 314 | 321 | { |
| 315 | 322 | NL_VERBOSE_OUT(("adding net ...\n")); |
| 316 | | in.set_net(*(new netlist_net_t(netlist_object_t::NET, netlist_object_t::ANALOG))); |
| 323 | netlist_net_t *anet = new netlist_net_t(netlist_object_t::NET, netlist_object_t::ANALOG); |
| 324 | in.set_net(*anet); |
| 325 | m_netlist.solver().m_nets.add(anet); |
| 317 | 326 | in.net().init_object(netlist()); |
| 318 | 327 | in.net().register_con(out); |
| 319 | 328 | in.net().register_con(in); |
| r26220 | r26221 | |
| 322 | 331 | |
| 323 | 332 | void netlist_setup_t::resolve_inputs(void) |
| 324 | 333 | { |
| 325 | | NL_VERBOSE_OUT(("Searching for clocks ...\n")); |
| 334 | NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n")); |
| 326 | 335 | /* find the main clock ... */ |
| 327 | 336 | for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) |
| 328 | 337 | { |
| r26220 | r26221 | |
| 331 | 340 | { |
| 332 | 341 | m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev)); |
| 333 | 342 | } |
| 343 | if (dynamic_cast<NETLIB_NAME(solver)*>(dev) != NULL) |
| 344 | { |
| 345 | m_netlist.set_solver_dev(dynamic_cast<NETLIB_NAME(solver)*>(dev)); |
| 346 | } |
| 334 | 347 | } |
| 335 | 348 | |
| 336 | 349 | NL_VERBOSE_OUT(("Resolving ...\n")); |
trunk/src/emu/netlist/nl_setup.h
| r26220 | r26221 | |
| 76 | 76 | netlist_device_t *register_dev(netlist_device_t *dev); |
| 77 | 77 | void remove_dev(const astring &name); |
| 78 | 78 | |
| 79 | | void register_terminal(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_terminal_t &out); |
| 80 | | void register_output(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_output_t &out); |
| 81 | | void register_input(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type); |
| 82 | | void register_alias(const astring &alias, const astring &out); |
| 83 | | void register_param(const astring &sname, netlist_param_t *param); |
| 79 | void register_alias(const astring &alias, const astring &out); |
| 84 | 80 | |
| 85 | | void register_link(const astring &sin, const astring &sout); |
| 81 | void register_link(const astring &sin, const astring &sout); |
| 86 | 82 | |
| 87 | | netlist_output_t &find_output(const astring &outname_in); |
| 83 | void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state); |
| 84 | |
| 88 | 85 | netlist_terminal_t &find_terminal(const astring &outname_in); |
| 89 | | netlist_param_t &find_param(const astring ¶m_in); |
| 86 | netlist_terminal_t &find_terminal(const astring &outname_in, netlist_object_t::type_t atype); |
| 90 | 87 | |
| 88 | netlist_param_t &find_param(const astring ¶m_in); |
| 89 | |
| 91 | 90 | void register_callback(const astring &devname, netlist_output_delegate delegate); |
| 92 | 91 | |
| 93 | 92 | void parse(char *buf); |
| r26220 | r26221 | |
| 108 | 107 | |
| 109 | 108 | tagmap_devices_t m_devices; |
| 110 | 109 | tagmap_astring_t m_alias; |
| 111 | | //tagmap_input_t m_inputs; |
| 112 | 110 | tagmap_param_t m_params; |
| 113 | 111 | tagmap_astring_t m_links; |
| 114 | 112 | |
| r26220 | r26221 | |
| 118 | 116 | void connect_input_output(netlist_input_t &in, netlist_output_t &out); |
| 119 | 117 | void connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out); |
| 120 | 118 | |
| 121 | | netlist_output_t *find_output_exact(const astring &outname_in); |
| 119 | // helpers |
| 120 | astring objtype_as_astr(netlist_object_t &in); |
| 121 | |
| 122 | 122 | const astring &resolve_alias(const astring &name) const; |
| 123 | 123 | }; |
| 124 | 124 | |
trunk/src/emu/netlist/devices/nld_system.h
| r26220 | r26221 | |
| 11 | 11 | |
| 12 | 12 | #include "../nl_setup.h" |
| 13 | 13 | #include "../nl_base.h" |
| 14 | #include "../nl_lists.h" |
| 14 | 15 | |
| 15 | 16 | // ---------------------------------------------------------------------------------------- |
| 16 | 17 | // Macros |
| r26220 | r26221 | |
| 24 | 25 | NET_REGISTER_DEV(analog_const, _name) \ |
| 25 | 26 | NETDEV_PARAM(_name.CONST, _v) |
| 26 | 27 | |
| 28 | #define NETDEV_MAINCLOCK(_name) \ |
| 29 | NET_REGISTER_DEV(mainclock, _name) |
| 30 | |
| 31 | #define NETDEV_CLOCK(_name) \ |
| 32 | NET_REGISTER_DEV(clock, _name) |
| 33 | |
| 34 | #define NETDEV_SOLVER(_name) \ |
| 35 | NET_REGISTER_DEV(solver, _name) |
| 36 | |
| 27 | 37 | // ---------------------------------------------------------------------------------------- |
| 28 | 38 | // netdev_*_const |
| 29 | 39 | // ---------------------------------------------------------------------------------------- |
| r26220 | r26221 | |
| 65 | 75 | ); |
| 66 | 76 | |
| 67 | 77 | // ---------------------------------------------------------------------------------------- |
| 68 | | // solver_clock |
| 78 | // solver |
| 69 | 79 | // ---------------------------------------------------------------------------------------- |
| 70 | 80 | |
| 71 | | NETLIB_DEVICE_WITH_PARAMS_DERIVED(solver_clock, clock, |
| 81 | NETLIB_DEVICE_WITH_PARAMS(solver, |
| 82 | netlist_ttl_input_t m_feedback; |
| 83 | netlist_ttl_output_t m_Q; |
| 84 | |
| 85 | netlist_time m_inc; |
| 72 | 86 | public: |
| 87 | netlist_list_t<netlist_net_t *> m_nets; |
| 88 | |
| 89 | ATTR_HOT inline void schedule(); |
| 73 | 90 | ); |
| 74 | 91 | |
| 92 | inline void NETLIB_NAME(solver)::schedule() |
| 93 | { |
| 94 | // FIXME: time should be parameter; |
| 95 | if (!m_Q.net().is_queued()) |
| 96 | m_Q.net().push_to_queue(NLTIME_FROM_NS(10)); |
| 97 | } |
| 98 | |
| 75 | 99 | // ---------------------------------------------------------------------------------------- |
| 76 | 100 | // netdev_callback |
| 77 | 101 | // ---------------------------------------------------------------------------------------- |
| r26220 | r26221 | |
| 100 | 124 | netlist_output_delegate m_callback; |
| 101 | 125 | }; |
| 102 | 126 | |
| 127 | |
| 128 | // ---------------------------------------------------------------------------------------- |
| 129 | // nld_twoterm |
| 130 | // ---------------------------------------------------------------------------------------- |
| 131 | |
| 132 | class nld_twoterm : public netlist_device_t |
| 133 | { |
| 134 | public: |
| 135 | nld_twoterm() |
| 136 | : netlist_device_t(), m_g(0.0), m_V(0.0), m_I(0.0) |
| 137 | { |
| 138 | } |
| 139 | |
| 140 | netlist_terminal_t m_P; |
| 141 | netlist_terminal_t m_N; |
| 142 | |
| 143 | protected: |
| 144 | virtual void start() |
| 145 | { |
| 146 | } |
| 147 | |
| 148 | ATTR_HOT ATTR_ALIGN virtual void update_terminals() |
| 149 | { |
| 150 | m_N.m_Idr = (m_P.net().Q_Analog() - m_V) * m_g + m_I; |
| 151 | m_P.m_Idr = (m_N.net().Q_Analog() + m_V) * m_g - m_I; |
| 152 | //printf("%f %f %f %f\n", m_N.m_Idr, m_P.m_Idr, m_N.net().Q_Analog(), m_P.net().Q_Analog()); |
| 153 | } |
| 154 | |
| 155 | ATTR_HOT ATTR_ALIGN virtual void update() |
| 156 | { |
| 157 | netlist().solver().schedule(); |
| 158 | #if 0 |
| 159 | if (!m_N.net().is_queued() && !m_N.net().isRailNet()) |
| 160 | m_N.net().push_to_queue(NLTIME_FROM_NS(10)); |
| 161 | if (!m_P.net().is_queued() && !m_P.net().isRailNet() ) |
| 162 | m_P.net().push_to_queue(NLTIME_FROM_NS(10)); |
| 163 | #endif |
| 164 | } |
| 165 | |
| 166 | double m_g; // conductance |
| 167 | double m_V; // internal voltage source |
| 168 | double m_I; // internal current source |
| 169 | private: |
| 170 | }; |
| 171 | |
| 172 | class nld_R : public nld_twoterm |
| 173 | { |
| 174 | public: |
| 175 | nld_R() |
| 176 | : nld_twoterm() |
| 177 | { |
| 178 | } |
| 179 | |
| 180 | netlist_param_t m_R; |
| 181 | |
| 182 | protected: |
| 183 | void start() |
| 184 | { |
| 185 | register_terminal("1", m_P); |
| 186 | register_terminal("2", m_N); |
| 187 | |
| 188 | register_param("R", m_R, NETLIST_GMIN); |
| 189 | } |
| 190 | |
| 191 | virtual void update_param() |
| 192 | { |
| 193 | m_g = 1.0 / m_R.Value(); |
| 194 | m_P.m_g = m_g; |
| 195 | m_N.m_g = m_g; |
| 196 | } |
| 197 | |
| 198 | private: |
| 199 | }; |
| 200 | |
| 103 | 201 | #endif /* NLD_SYSTEM_H_ */ |
trunk/src/emu/netlist/devices/net_lib.c
| r26220 | r26221 | |
| 195 | 195 | register_param("VL", m_VL, 0.0 *5.0); |
| 196 | 196 | |
| 197 | 197 | m_THRESHOLD_OUT.init_terminal(*this); |
| 198 | | register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, netlist_input_t::INP_STATE_ACTIVE); |
| 198 | register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, netlist_input_t::STATE_INP_ACTIVE); |
| 199 | 199 | |
| 200 | 200 | m_Q.initial(5.0 * 0.4); |
| 201 | 201 | m_last = false; |
| r26220 | r26221 | |
| 481 | 481 | NETLIB_START(nic7474) |
| 482 | 482 | { |
| 483 | 483 | register_sub(sub, "sub"); |
| 484 | | register_input(sub, "CLK", sub.m_clk, netlist_input_t::INP_STATE_LH); |
| 484 | register_input(sub, "CLK", sub.m_clk, netlist_input_t::STATE_INP_LH); |
| 485 | 485 | register_input("D", m_D); |
| 486 | 486 | register_input("CLRQ", m_clrQ); |
| 487 | 487 | register_input("PREQ", m_preQ); |
| r26220 | r26221 | |
| 592 | 592 | register_sub(C, "C"); |
| 593 | 593 | register_sub(D, "D"); |
| 594 | 594 | |
| 595 | | register_input(A, "CLKA", A.m_I, netlist_input_t::INP_STATE_HL); |
| 596 | | register_input(B, "CLKB", B.m_I, netlist_input_t::INP_STATE_HL); |
| 595 | register_input(A, "CLKA", A.m_I, netlist_input_t::STATE_INP_HL); |
| 596 | register_input(B, "CLKB", B.m_I, netlist_input_t::STATE_INP_HL); |
| 597 | 597 | register_input("R1", m_R1); |
| 598 | 598 | register_input("R2", m_R2); |
| 599 | 599 | |
| r26220 | r26221 | |
| 602 | 602 | register_output(C, "QC", C.m_Q); |
| 603 | 603 | register_output(D, "QD", D.m_Q); |
| 604 | 604 | |
| 605 | | register_link_internal(C, C.m_I, B.m_Q, netlist_input_t::INP_STATE_HL); |
| 606 | | register_link_internal(D, D.m_I, C.m_Q, netlist_input_t::INP_STATE_HL); |
| 605 | register_link_internal(C, C.m_I, B.m_Q, netlist_input_t::STATE_INP_HL); |
| 606 | register_link_internal(D, D.m_I, C.m_Q, netlist_input_t::STATE_INP_HL); |
| 607 | 607 | |
| 608 | 608 | } |
| 609 | 609 | |
| r26220 | r26221 | |
| 642 | 642 | { |
| 643 | 643 | m_cnt = 0; |
| 644 | 644 | |
| 645 | | register_input("CLKA", m_CLK, netlist_input_t::INP_STATE_HL); |
| 646 | | register_input("CLKB", m_CLKB, netlist_input_t::INP_STATE_HL); |
| 645 | register_input("CLKA", m_CLK, netlist_input_t::STATE_INP_HL); |
| 646 | register_input("CLKB", m_CLKB, netlist_input_t::STATE_INP_HL); |
| 647 | 647 | register_input("R1", m_R1); |
| 648 | 648 | register_input("R2", m_R2); |
| 649 | 649 | |
| r26220 | r26221 | |
| 722 | 722 | { |
| 723 | 723 | register_sub(sub, "sub"); |
| 724 | 724 | |
| 725 | | register_input(sub, "CLK", sub.m_clk, netlist_input_t::INP_STATE_HL); |
| 725 | register_input(sub, "CLK", sub.m_clk, netlist_input_t::STATE_INP_HL); |
| 726 | 726 | register_input("J", m_J); |
| 727 | 727 | register_input("K", m_K); |
| 728 | 728 | register_input("CLRQ", m_clrQ); |
| r26220 | r26221 | |
| 832 | 832 | sub.m_loadq = 1; |
| 833 | 833 | sub.m_ent = 1; |
| 834 | 834 | |
| 835 | | register_input(sub, "CLK", sub.m_clk, netlist_input_t::INP_STATE_LH); |
| 835 | register_input(sub, "CLK", sub.m_clk, netlist_input_t::STATE_INP_LH); |
| 836 | 836 | |
| 837 | 837 | register_input("ENP", m_ENP); |
| 838 | 838 | register_input("ENT", m_ENT); |
| 839 | 839 | register_input("CLRQ", m_CLRQ); |
| 840 | 840 | register_input("LOADQ", m_LOADQ); |
| 841 | 841 | |
| 842 | | register_input(sub, "A", sub.m_A, netlist_input_t::INP_STATE_PASSIVE); |
| 843 | | register_input(sub, "B", sub.m_B, netlist_input_t::INP_STATE_PASSIVE); |
| 844 | | register_input(sub, "C", sub.m_C, netlist_input_t::INP_STATE_PASSIVE); |
| 845 | | register_input(sub, "D", sub.m_D, netlist_input_t::INP_STATE_PASSIVE); |
| 842 | register_input(sub, "A", sub.m_A, netlist_input_t::STATE_INP_PASSIVE); |
| 843 | register_input(sub, "B", sub.m_B, netlist_input_t::STATE_INP_PASSIVE); |
| 844 | register_input(sub, "C", sub.m_C, netlist_input_t::STATE_INP_PASSIVE); |
| 845 | register_input(sub, "D", sub.m_D, netlist_input_t::STATE_INP_PASSIVE); |
| 846 | 846 | |
| 847 | 847 | register_output(sub, "QA", sub.m_QA); |
| 848 | 848 | register_output(sub, "QB", sub.m_QB); |
| r26220 | r26221 | |
| 957 | 957 | ENTRY(log, NETDEV_LOG) |
| 958 | 958 | ENTRY(clock, NETDEV_CLOCK) |
| 959 | 959 | ENTRY(mainclock, NETDEV_MAINCLOCK) |
| 960 | ENTRY(solver, NETDEV_SOLVER) |
| 960 | 961 | ENTRY(analog_callback, NETDEV_CALLBACK) |
| 961 | 962 | ENTRY(nicMultiSwitch, NETDEV_SWITCH2) |
| 962 | 963 | ENTRY(nicRSFF, NETDEV_RSFF) |
trunk/src/emu/netlist/devices/nld_system.c
| r26220 | r26221 | |
| 62 | 62 | register_param("FREQ", m_freq, 7159000.0 * 5); |
| 63 | 63 | m_inc = netlist_time::from_hz(m_freq.Value()*2); |
| 64 | 64 | |
| 65 | | register_link_internal(m_feedback, m_Q, netlist_input_t::INP_STATE_ACTIVE); |
| 65 | register_link_internal(m_feedback, m_Q, netlist_input_t::STATE_INP_ACTIVE); |
| 66 | 66 | |
| 67 | 67 | } |
| 68 | 68 | |
| r26220 | r26221 | |
| 73 | 73 | |
| 74 | 74 | NETLIB_UPDATE(clock) |
| 75 | 75 | { |
| 76 | | //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc ); |
| 77 | 76 | OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); |
| 78 | 77 | } |
| 78 | |
| 79 | // ---------------------------------------------------------------------------------------- |
| 80 | // solver |
| 81 | // ---------------------------------------------------------------------------------------- |
| 82 | |
| 83 | NETLIB_START(solver) |
| 84 | { |
| 85 | register_output("Q", m_Q); |
| 86 | //register_input("FB", m_feedback); |
| 87 | |
| 88 | m_inc = netlist_time::from_hz(48000); |
| 89 | |
| 90 | register_link_internal(m_feedback, m_Q, netlist_input_t::STATE_INP_ACTIVE); |
| 91 | |
| 92 | } |
| 93 | |
| 94 | NETLIB_UPDATE_PARAM(solver) |
| 95 | { |
| 96 | //m_inc = netlist_time::from_hz(m_freq.Value()*2); |
| 97 | } |
| 98 | |
| 99 | NETLIB_UPDATE(solver) |
| 100 | { |
| 101 | //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc ); |
| 102 | //OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); |
| 103 | |
| 104 | netlist_net_t **pn = m_nets.first(); |
| 105 | bool resched = false; |
| 106 | |
| 107 | while (pn <= m_nets.last()) |
| 108 | { |
| 109 | double gtot = 0; |
| 110 | double iIdr = 0; |
| 111 | |
| 112 | netlist_terminal_t *p = (*pn)->m_head; |
| 113 | do |
| 114 | { |
| 115 | p->netdev().update_terminals(); |
| 116 | gtot += p->m_g; |
| 117 | iIdr += p->m_Idr; |
| 118 | |
| 119 | p = p->m_update_list_next; |
| 120 | } while (p != NULL); |
| 121 | (*pn)->m_new.Analog = iIdr / gtot; |
| 122 | if (fabs((*pn)->m_new.Analog - (*pn)->m_cur.Analog) > 1e-4) |
| 123 | resched = true; |
| 124 | (*pn)->m_cur.Analog = (*pn)->m_new.Analog; |
| 125 | |
| 126 | //printf("New: %f\n", (*pn)->m_new.Analog); |
| 127 | pn++; |
| 128 | } |
| 129 | if (resched) |
| 130 | schedule(); |
| 131 | else |
| 132 | m_Q.net().push_to_queue(m_inc); // step circuit |
| 133 | |
| 134 | /* only inputs and terminals connected |
| 135 | * approach: |
| 136 | * |
| 137 | * a) Update voltage on this net |
| 138 | * b) Update devices |
| 139 | * c) If difference old - new > trigger schedule immediate update |
| 140 | * of number of updates < max_update_count |
| 141 | * else clear number of updates |
| 142 | */ |
| 143 | |
| 144 | } |