trunk/src/emu/netlist/nl_base.h
r26398 | r26399 | |
138 | 138 | #include "nl_config.h" |
139 | 139 | #include "nl_lists.h" |
140 | 140 | #include "nl_time.h" |
| 141 | #include "pstring.h" |
141 | 142 | |
142 | 143 | // ---------------------------------------------------------------------------------------- |
143 | 144 | // Type definitions |
r26398 | r26399 | |
248 | 249 | |
249 | 250 | virtual ~netlist_object_t(); |
250 | 251 | |
251 | | ATTR_COLD void init_object(netlist_base_t &nl, const astring &aname); |
| 252 | ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname); |
252 | 253 | |
253 | | ATTR_COLD const astring &name() const; |
| 254 | ATTR_COLD const pstring &name() const; |
254 | 255 | |
255 | 256 | ATTR_HOT inline const type_t type() const { return m_objtype; } |
256 | 257 | ATTR_HOT inline const family_t family() const { return m_family; } |
r26398 | r26399 | |
262 | 263 | ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; } |
263 | 264 | |
264 | 265 | private: |
| 266 | pstring m_name; |
265 | 267 | const type_t m_objtype; |
266 | 268 | const family_t m_family; |
267 | 269 | netlist_base_t * RESTRICT m_netlist; |
268 | | astring *m_name; |
269 | 270 | }; |
270 | 271 | |
271 | 272 | // ---------------------------------------------------------------------------------------- |
r26398 | r26399 | |
277 | 278 | public: |
278 | 279 | ATTR_COLD netlist_owned_object_t(const type_t atype, const family_t afamily); |
279 | 280 | |
280 | | ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname); |
| 281 | ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname); |
281 | 282 | |
282 | 283 | ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; } |
283 | 284 | private: |
r26398 | r26399 | |
306 | 307 | ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily); |
307 | 308 | ATTR_COLD netlist_terminal_t(); |
308 | 309 | |
309 | | ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate); |
| 310 | ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate); |
310 | 311 | |
311 | 312 | ATTR_COLD void set_net(netlist_net_t &anet); |
312 | 313 | ATTR_COLD inline bool has_net() { return (m_net != NULL); } |
r26398 | r26399 | |
515 | 516 | |
516 | 517 | ATTR_COLD netlist_output_t(const type_t atype, const family_t afamily); |
517 | 518 | |
518 | | ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname); |
| 519 | ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname); |
519 | 520 | |
520 | 521 | double m_low_V; |
521 | 522 | double m_high_V; |
r26398 | r26399 | |
601 | 602 | |
602 | 603 | ATTR_COLD virtual ~netlist_core_device_t(); |
603 | 604 | |
604 | | ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name); |
| 605 | ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name); |
605 | 606 | |
606 | 607 | |
607 | 608 | ATTR_HOT virtual void update_param() {} |
r26398 | r26399 | |
656 | 657 | ATTR_HOT virtual void step_time(const double st) { } |
657 | 658 | ATTR_HOT virtual void update_terminals() { } |
658 | 659 | |
659 | | /* stats */ |
| 660 | #if (NL_KEEP_STATISTICS) |
| 661 | /* stats */ |
660 | 662 | osd_ticks_t total_time; |
661 | 663 | INT32 stat_count; |
| 664 | #endif |
662 | 665 | |
663 | 666 | #if USE_DELEGATES |
664 | 667 | net_update_delegate static_update; |
r26398 | r26399 | |
681 | 684 | |
682 | 685 | ATTR_COLD virtual ~netlist_device_t(); |
683 | 686 | |
684 | | ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name); |
| 687 | ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name); |
685 | 688 | |
686 | 689 | ATTR_COLD const netlist_setup_t *setup() const { return m_setup; } |
687 | 690 | |
688 | 691 | ATTR_COLD bool variable_input_count() { return m_variable_input_count; } |
689 | 692 | |
690 | | ATTR_COLD void register_sub(netlist_core_device_t &dev, const astring &name); |
| 693 | ATTR_COLD void register_sub(netlist_core_device_t &dev, const pstring &name); |
691 | 694 | |
692 | | ATTR_COLD void register_terminal(const astring &name, netlist_terminal_t &port); |
| 695 | ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port); |
693 | 696 | |
694 | | ATTR_COLD void register_output(const astring &name, netlist_output_t &out); |
695 | | ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out); |
| 697 | ATTR_COLD void register_output(const pstring &name, netlist_output_t &out); |
| 698 | ATTR_COLD void register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &out); |
696 | 699 | |
697 | | ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); |
698 | | 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); |
| 700 | ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); |
| 701 | ATTR_COLD void register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); |
699 | 702 | |
700 | 703 | ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState); |
701 | 704 | 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); |
r26398 | r26399 | |
703 | 706 | ATTR_HOT virtual void update_terminals() { } |
704 | 707 | |
705 | 708 | /* driving logic outputs don't count in here */ |
706 | | netlist_list_t<astring> m_terminals; |
| 709 | netlist_list_t<pstring, 20> m_terminals; |
707 | 710 | |
708 | 711 | protected: |
709 | 712 | |
710 | 713 | virtual void update() { } |
711 | 714 | virtual void start() { } |
712 | 715 | |
713 | | ATTR_COLD void register_param(const astring &sname, netlist_param_t ¶m, const double initialVal = 0.0); |
714 | | ATTR_COLD void register_param(netlist_core_device_t &dev, const astring &sname, netlist_param_t ¶m, const double initialVal = 0.0); |
| 716 | ATTR_COLD void register_param(const pstring &sname, netlist_param_t ¶m, const double initialVal = 0.0); |
| 717 | ATTR_COLD void register_param(netlist_core_device_t &dev, const pstring &sname, netlist_param_t ¶m, const double initialVal = 0.0); |
715 | 718 | |
716 | 719 | netlist_setup_t *m_setup; |
717 | 720 | bool m_variable_input_count; |
r26398 | r26399 | |
780 | 783 | ATTR_COLD void reset(); |
781 | 784 | |
782 | 785 | protected: |
| 786 | #if (NL_KEEP_STATISTICS) |
783 | 787 | // performance |
784 | 788 | int m_perf_out_processed; |
785 | 789 | int m_perf_inp_processed; |
786 | 790 | int m_perf_inp_active; |
| 791 | #endif |
787 | 792 | |
788 | 793 | private: |
| 794 | netlist_time m_time_ps; |
789 | 795 | queue_t m_queue; |
790 | | NETLIB_NAME(mainclock) * m_mainclock; |
791 | | NETLIB_NAME(solver) * m_solver; |
792 | | netlist_time m_time_ps; |
793 | 796 | UINT32 m_rem; |
794 | 797 | UINT32 m_div; |
795 | 798 | |
| 799 | NETLIB_NAME(mainclock) * m_mainclock; |
| 800 | NETLIB_NAME(solver) * m_solver; |
| 801 | |
796 | 802 | ATTR_HOT void update_time(const netlist_time t, INT32 &atime); |
797 | 803 | |
798 | 804 | }; |
r26398 | r26399 | |
994 | 1000 | class net_device_t_base_factory |
995 | 1001 | { |
996 | 1002 | public: |
997 | | net_device_t_base_factory(const astring &name, const astring &classname) |
| 1003 | net_device_t_base_factory(const pstring &name, const pstring &classname) |
998 | 1004 | : m_name(name), m_classname(classname) |
999 | 1005 | {} |
1000 | 1006 | |
r26398 | r26399 | |
1002 | 1008 | |
1003 | 1009 | virtual netlist_device_t *Create() const = 0; |
1004 | 1010 | |
1005 | | const astring &name() const { return m_name; } |
1006 | | const astring &classname() const { return m_classname; } |
| 1011 | const pstring &name() const { return m_name; } |
| 1012 | const pstring &classname() const { return m_classname; } |
1007 | 1013 | protected: |
1008 | | astring m_name; /* device name */ |
1009 | | astring m_classname; /* device class name */ |
| 1014 | pstring m_name; /* device name */ |
| 1015 | pstring m_classname; /* device class name */ |
1010 | 1016 | }; |
1011 | 1017 | |
1012 | 1018 | template <class C> |
1013 | 1019 | class net_device_t_factory : public net_device_t_base_factory |
1014 | 1020 | { |
1015 | 1021 | public: |
1016 | | net_device_t_factory(const astring &name, const astring &classname) |
| 1022 | net_device_t_factory(const pstring &name, const pstring &classname) |
1017 | 1023 | : net_device_t_base_factory(name, classname) { } |
1018 | 1024 | |
1019 | 1025 | netlist_device_t *Create() const |
r26398 | r26399 | |
1024 | 1030 | } |
1025 | 1031 | }; |
1026 | 1032 | |
1027 | | netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup); |
1028 | | netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup); |
| 1033 | netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup); |
| 1034 | netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup); |
1029 | 1035 | |
1030 | 1036 | |
1031 | 1037 | #endif /* NLBASE_H_ */ |
trunk/src/emu/netlist/nl_setup.c
r26398 | r26399 | |
41 | 41 | netlist_setup_t::~netlist_setup_t() |
42 | 42 | { |
43 | 43 | tagmap_free_entries<tagmap_devices_t>(m_devices); |
44 | | tagmap_free_entries<tagmap_link_t>(m_links); |
45 | | tagmap_free_entries<tagmap_astring_t>(m_alias); |
| 44 | //tagmap_free_entries<tagmap_link_t>(m_links); |
| 45 | //tagmap_free_entries<tagmap_nstring_t>(m_alias); |
| 46 | m_links.reset(); |
| 47 | m_alias.reset(); |
46 | 48 | m_params.reset(); |
47 | 49 | m_terminals.reset(); |
| 50 | m_params_temp.reset(); |
| 51 | pstring::resetmem(); |
48 | 52 | } |
49 | 53 | |
50 | | netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const astring &name) |
| 54 | netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const pstring &name) |
51 | 55 | { |
52 | 56 | if (!(m_devices.add(name, dev, false)==TMERR_NONE)) |
53 | 57 | fatalerror("Error adding %s to device list\n", name.cstr()); |
r26398 | r26399 | |
55 | 59 | } |
56 | 60 | |
57 | 61 | template <class T> |
58 | | static void remove_start_with(T &hm, astring &sw) |
| 62 | static void remove_start_with(T &hm, pstring &sw) |
59 | 63 | { |
60 | 64 | typename T::entry_t *entry = hm.first(); |
61 | 65 | while (entry != NULL) |
62 | 66 | { |
63 | 67 | typename T::entry_t *next = hm.next(entry); |
64 | | if (sw.cmpsubstr(entry->tag(), 0, sw.len()) == 0) |
| 68 | pstring x = entry->tag().cstr(); |
| 69 | if (sw.equals(x.substr(0, sw.len()))) |
65 | 70 | { |
66 | 71 | NL_VERBOSE_OUT(("removing %s\n", entry->tag().cstr())); |
67 | 72 | hm.remove(entry->object()); |
r26398 | r26399 | |
70 | 75 | } |
71 | 76 | } |
72 | 77 | |
73 | | void netlist_setup_t::remove_dev(const astring &name) |
| 78 | void netlist_setup_t::remove_dev(const pstring &name) |
74 | 79 | { |
75 | 80 | netlist_device_t *dev = m_devices.find(name); |
76 | | astring temp = name; |
| 81 | pstring temp = name + "."; |
77 | 82 | if (dev == NULL) |
78 | 83 | fatalerror("Device %s does not exist\n", name.cstr()); |
79 | 84 | |
80 | | temp.cat("."); |
81 | | |
82 | 85 | //remove_start_with<tagmap_input_t>(m_inputs, temp); |
83 | 86 | remove_start_with<tagmap_terminal_t>(m_terminals, temp); |
84 | 87 | remove_start_with<tagmap_param_t>(m_params, temp); |
r26398 | r26399 | |
87 | 90 | while (p != NULL) |
88 | 91 | { |
89 | 92 | tagmap_link_t::entry_t *n = m_links.next(p); |
90 | | if (temp.cmpsubstr(p->object()->e1,0,temp.len()) == 0 || temp.cmpsubstr(p->object()->e2,0,temp.len()) == 0) |
| 93 | if (temp.equals(p->object().e1.substr(0,temp.len())) || temp.equals(p->object().e2.substr(0,temp.len()))) |
91 | 94 | m_links.remove(p->object()); |
92 | 95 | p = n; |
93 | 96 | } |
94 | 97 | m_devices.remove(name); |
95 | 98 | } |
96 | 99 | |
97 | | void netlist_setup_t::register_callback(const astring &devname, netlist_output_delegate delegate) |
| 100 | void netlist_setup_t::register_callback(const pstring &devname, netlist_output_delegate delegate) |
98 | 101 | { |
99 | 102 | NETLIB_NAME(analog_callback) *dev = (NETLIB_NAME(analog_callback) *) m_devices.find(devname); |
100 | 103 | if (dev == NULL) |
r26398 | r26399 | |
102 | 105 | dev->register_callback(delegate); |
103 | 106 | } |
104 | 107 | |
105 | | void netlist_setup_t::register_alias(const astring &alias, const astring &out) |
| 108 | void netlist_setup_t::register_alias(const pstring &alias, const pstring &out) |
106 | 109 | { |
107 | | if (!(m_alias.add(alias, new astring(out), false)==TMERR_NONE)) |
| 110 | //if (!(m_alias.add(alias, new nstring(out), false)==TMERR_NONE)) |
| 111 | if (!(m_alias.add(alias, out, false)==TMERR_NONE)) |
108 | 112 | fatalerror("Error adding alias %s to alias list\n", alias.cstr()); |
109 | 113 | } |
110 | 114 | |
111 | | astring netlist_setup_t::objtype_as_astr(netlist_object_t &in) |
| 115 | pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in) |
112 | 116 | { |
113 | 117 | switch (in.type()) |
114 | 118 | { |
r26398 | r26399 | |
134 | 138 | fatalerror("Unknown object type %d\n", in.type()); |
135 | 139 | } |
136 | 140 | |
137 | | 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) |
| 141 | void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state) |
138 | 142 | { |
139 | 143 | switch (obj.type()) |
140 | 144 | { |
r26398 | r26399 | |
157 | 161 | break; |
158 | 162 | case netlist_terminal_t::PARAM: |
159 | 163 | { |
| 164 | |
160 | 165 | netlist_param_t ¶m = dynamic_cast<netlist_param_t &>(obj); |
161 | | astring temp = param.netdev().name(); |
162 | | temp.cat("."); |
163 | | temp.cat(name); |
164 | | const astring *val = m_params_temp.find(temp); |
165 | | if (val != NULL) |
| 166 | pstring temp = param.netdev().name() + "." + name; |
| 167 | const pstring val = m_params_temp.find(temp); |
| 168 | if (val != "") |
166 | 169 | { |
167 | 170 | //printf("Found parameter ... %s : %s\n", temp.cstr(), val->cstr()); |
168 | 171 | double vald = 0; |
169 | | if (sscanf(val->cstr(), "%lf", &vald) != 1) |
170 | | fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val->cstr()); |
| 172 | if (sscanf(val.cstr(), "%lf", &vald) != 1) |
| 173 | fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr()); |
171 | 174 | param.initial(vald); |
172 | 175 | } |
173 | 176 | if (!(m_params.add(temp, ¶m, false)==TMERR_NONE)) |
r26398 | r26399 | |
179 | 182 | } |
180 | 183 | } |
181 | 184 | |
182 | | void netlist_setup_t::register_link(const astring &sin, const astring &sout) |
| 185 | void netlist_setup_t::register_link(const pstring &sin, const pstring &sout) |
183 | 186 | { |
184 | | link_t *temp = new link_t(sin, sout); |
| 187 | link_t temp = link_t(sin, sout); |
185 | 188 | NL_VERBOSE_OUT(("link %s <== %s\n", sin.cstr(), sout.cstr())); |
186 | | if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE)) |
187 | | fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr()); |
| 189 | m_links.add(temp); |
| 190 | //if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE)) |
| 191 | // fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr()); |
188 | 192 | } |
189 | 193 | |
190 | | void netlist_setup_t::register_param(const astring ¶m, const double value) |
| 194 | void netlist_setup_t::register_param(const pstring ¶m, const double value) |
191 | 195 | { |
192 | 196 | // FIXME: there should be a better way |
193 | | astring temp; |
194 | | temp.printf("%.9e", value); |
195 | | register_param(param, temp); |
| 197 | register_param(param, pstring::sprintf("%.9e", value)); |
196 | 198 | } |
197 | 199 | |
198 | | void netlist_setup_t::register_param(const astring ¶m, const astring &value) |
| 200 | void netlist_setup_t::register_param(const pstring ¶m, const pstring &value) |
199 | 201 | { |
200 | | if (!(m_params_temp.add(param, new astring(value), false)==TMERR_NONE)) |
| 202 | //if (!(m_params_temp.add(param, new nstring(value), false)==TMERR_NONE)) |
| 203 | if (!(m_params_temp.add(param, value, false)==TMERR_NONE)) |
201 | 204 | fatalerror("Error adding parameter %s to parameter list\n", param.cstr()); |
202 | 205 | } |
203 | 206 | |
204 | | const astring netlist_setup_t::resolve_alias(const astring &name) const |
| 207 | const pstring netlist_setup_t::resolve_alias(const pstring &name) const |
205 | 208 | { |
206 | | const astring *temp = m_alias.find(name); |
207 | | astring ret = name; |
208 | | if (temp != NULL) |
209 | | ret = *temp; |
| 209 | const pstring temp = m_alias.find(name); |
| 210 | pstring ret = name; |
| 211 | if (temp != "") |
| 212 | ret = temp; |
210 | 213 | int p = ret.find(".["); |
211 | 214 | if (p > 0) |
212 | 215 | { |
213 | | astring dname = ret; |
| 216 | pstring dname = ret; |
214 | 217 | netlist_device_t *dev = m_devices.find(dname.substr(0,p)); |
215 | 218 | if (dev == NULL) |
216 | 219 | fatalerror("Device for %s not found\n", name.cstr()); |
217 | | ret.substr(p+2,ret.len()-p-3); |
218 | | int c = atoi(ret); |
219 | | ret = dev->name() + "." + *(dev->m_terminals.item(c)); |
| 220 | int c = atoi(ret.substr(p+2,ret.len()-p-3)); |
| 221 | ret = dev->name() + "." + dev->m_terminals.item(c)->object(); |
220 | 222 | } |
221 | 223 | |
| 224 | //printf("%s==>%s\n", name.cstr(), ret.cstr()); |
222 | 225 | return ret; |
223 | 226 | } |
224 | 227 | |
225 | | netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in) |
| 228 | netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in) |
226 | 229 | { |
227 | | const astring &tname = resolve_alias(terminal_in); |
| 230 | const pstring &tname = resolve_alias(terminal_in); |
228 | 231 | netlist_terminal_t *ret; |
229 | 232 | |
230 | 233 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname)); |
r26398 | r26399 | |
232 | 235 | if (ret == NULL) |
233 | 236 | { |
234 | 237 | /* look for ".Q" std output */ |
235 | | astring s = tname; |
236 | | s.cat(".Q"); |
| 238 | pstring s = tname + ".Q"; |
237 | 239 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s)); |
238 | 240 | } |
239 | 241 | if (ret == NULL) |
r26398 | r26399 | |
242 | 244 | return *ret; |
243 | 245 | } |
244 | 246 | |
245 | | netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, netlist_object_t::type_t atype) |
| 247 | netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in, netlist_object_t::type_t atype) |
246 | 248 | { |
247 | | const astring &tname = resolve_alias(terminal_in); |
| 249 | const pstring &tname = resolve_alias(terminal_in); |
248 | 250 | netlist_terminal_t *ret; |
249 | 251 | |
250 | 252 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname)); |
r26398 | r26399 | |
252 | 254 | if (ret == NULL && atype == netlist_object_t::OUTPUT) |
253 | 255 | { |
254 | 256 | /* look for ".Q" std output */ |
255 | | astring s = tname; |
256 | | s.cat(".Q"); |
| 257 | pstring s = tname + ".Q"; |
257 | 258 | ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s)); |
258 | 259 | } |
259 | 260 | if (ret == NULL) |
r26398 | r26399 | |
264 | 265 | return *ret; |
265 | 266 | } |
266 | 267 | |
267 | | netlist_param_t &netlist_setup_t::find_param(const astring ¶m_in) |
| 268 | netlist_param_t &netlist_setup_t::find_param(const pstring ¶m_in) |
268 | 269 | { |
269 | | const astring &outname = resolve_alias(param_in); |
| 270 | const pstring &outname = resolve_alias(param_in); |
270 | 271 | netlist_param_t *ret; |
271 | 272 | |
272 | 273 | ret = m_params.find(outname); |
r26398 | r26399 | |
282 | 283 | if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC)) |
283 | 284 | { |
284 | 285 | nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(in); |
285 | | astring x = ""; |
286 | | x.printf("proxy_ad_%d", m_proxy_cnt++); |
| 286 | pstring x = pstring::sprintf("proxy_ad_%d", m_proxy_cnt); |
| 287 | m_proxy_cnt++; |
287 | 288 | |
288 | | proxy->init(*this, x.cstr()); |
| 289 | proxy->init(*this, x); |
289 | 290 | register_dev(proxy, x); |
290 | 291 | |
291 | 292 | proxy->m_Q.net().register_con(in); |
r26398 | r26399 | |
296 | 297 | { |
297 | 298 | //printf("here 1\n"); |
298 | 299 | nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out); |
299 | | astring x = ""; |
300 | | x.printf("proxy_da_%d", m_proxy_cnt++); |
301 | | proxy->init(*this, x.cstr()); |
| 300 | pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt); |
| 301 | m_proxy_cnt++; |
| 302 | |
| 303 | proxy->init(*this, x); |
302 | 304 | register_dev(proxy, x); |
303 | 305 | |
304 | 306 | proxy->m_Q.net().register_con(in); |
r26398 | r26399 | |
320 | 322 | { |
321 | 323 | NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n")); |
322 | 324 | nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(inp); |
323 | | astring x = ""; |
324 | | x.printf("proxy_da_%d", m_proxy_cnt++); |
325 | | proxy->init(*this, x.cstr()); |
| 325 | pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt); |
| 326 | m_proxy_cnt++; |
| 327 | |
| 328 | proxy->init(*this, x); |
326 | 329 | register_dev(proxy, x); |
327 | 330 | |
328 | 331 | connect_terminals(term, proxy->m_I); |
r26398 | r26399 | |
355 | 358 | { |
356 | 359 | NL_VERBOSE_OUT(("connect_terminal_output: connecting proxy\n")); |
357 | 360 | nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out); |
358 | | astring x = ""; |
359 | | x.printf("proxy_da_%d", m_proxy_cnt++); |
360 | | proxy->init(*this, x.cstr()); |
| 361 | pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt); |
| 362 | m_proxy_cnt++; |
| 363 | |
| 364 | proxy->init(*this, x); |
361 | 365 | register_dev(proxy, x); |
362 | 366 | |
363 | 367 | out.net().register_con(proxy->m_I); |
r26398 | r26399 | |
426 | 430 | NL_VERBOSE_OUT(("Resolving ...\n")); |
427 | 431 | for (tagmap_link_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry)) |
428 | 432 | { |
429 | | const astring t1s = entry->object()->e1; |
430 | | const astring t2s = entry->object()->e2; |
| 433 | const pstring t1s = entry->object().e1; |
| 434 | const pstring t2s = entry->object().e2; |
431 | 435 | netlist_terminal_t &t1 = find_terminal(t1s); |
432 | 436 | netlist_terminal_t &t2 = find_terminal(t2s); |
433 | 437 | |
r26398 | r26399 | |
490 | 494 | for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) |
491 | 495 | { |
492 | 496 | netlist_device_t *dev = entry->object(); |
493 | | dev->init(*this, entry->tag()); |
| 497 | dev->init(*this, entry->tag().cstr()); |
494 | 498 | } |
495 | 499 | } |
496 | 500 | |
r26398 | r26399 | |
518 | 522 | |
519 | 523 | void netlist_setup_t::print_stats() |
520 | 524 | { |
521 | | if (NL_KEEP_STATISTICS) |
| 525 | #if (NL_KEEP_STATISTICS) |
522 | 526 | { |
523 | 527 | for (netlist_setup_t::tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) |
524 | 528 | { |
r26398 | r26399 | |
530 | 534 | printf("Queue Sort %15d\n", m_netlist.queue().m_prof_sort); |
531 | 535 | printf("Queue Move %15d\n", m_netlist.queue().m_prof_sortmove); |
532 | 536 | } |
| 537 | #endif |
533 | 538 | } |
trunk/src/emu/netlist/pstring.h
r0 | r26399 | |
| 1 | // license:GPL-2.0+ |
| 2 | // copyright-holders:Couriersud |
| 3 | /* |
| 4 | * pstring.h |
| 5 | */ |
| 6 | |
| 7 | #ifndef _PSTRING_H_ |
| 8 | #define _PSTRING_H_ |
| 9 | |
| 10 | #include "nl_config.h" |
| 11 | |
| 12 | // ---------------------------------------------------------------------------------------- |
| 13 | // nstring: immutable strings ... |
| 14 | // |
| 15 | // nstrings are just a pointer to a "pascal-style" string representation. |
| 16 | // It uses reference counts and only uses new memory when a string changes. |
| 17 | // ---------------------------------------------------------------------------------------- |
| 18 | |
| 19 | struct pstring |
| 20 | { |
| 21 | public: |
| 22 | // simple construction/destruction |
| 23 | pstring() |
| 24 | { |
| 25 | init(); |
| 26 | } |
| 27 | ~pstring(); |
| 28 | |
| 29 | // construction with copy |
| 30 | pstring(const char *string) {init(); if (string != NULL) pcopy(string); } |
| 31 | pstring(const pstring &string) {init(); pcopy(string); } |
| 32 | |
| 33 | // assignment operators |
| 34 | pstring &operator=(const char *string) { pcopy(string); return *this; } |
| 35 | pstring &operator=(const pstring &string) { pcopy(string); return *this; } |
| 36 | |
| 37 | // C string conversion operators and helpers |
| 38 | operator const char *() const { return m_ptr->str(); } |
| 39 | inline const char *cstr() const { return m_ptr->str(); } |
| 40 | |
| 41 | // concatenation operators |
| 42 | pstring& operator+=(const pstring &string) { pcat(string.cstr()); return *this; } |
| 43 | friend pstring operator+(const pstring &lhs, const pstring &rhs) { return pstring(lhs) += rhs; } |
| 44 | friend pstring operator+(const pstring &lhs, const char *rhs) { return pstring(lhs) += rhs; } |
| 45 | friend pstring operator+(const char *lhs, const pstring &rhs) { return pstring(lhs) += rhs; } |
| 46 | |
| 47 | // comparison operators |
| 48 | bool operator==(const char *string) const { return (pcmp(string) == 0); } |
| 49 | bool operator==(const pstring &string) const { return (pcmp(string.cstr()) == 0); } |
| 50 | bool operator!=(const char *string) const { return (pcmp(string) != 0); } |
| 51 | bool operator!=(const pstring &string) const { return (pcmp(string.cstr()) != 0); } |
| 52 | bool operator<(const char *string) const { return (pcmp(string) < 0); } |
| 53 | bool operator<(const pstring &string) const { return (pcmp(string.cstr()) < 0); } |
| 54 | bool operator<=(const char *string) const { return (pcmp(string) <= 0); } |
| 55 | bool operator<=(const pstring &string) const { return (pcmp(string.cstr()) <= 0); } |
| 56 | bool operator>(const char *string) const { return (pcmp(string) > 0); } |
| 57 | bool operator>(const pstring &string) const { return (pcmp(string.cstr()) > 0); } |
| 58 | bool operator>=(const char *string) const { return (pcmp(string) >= 0); } |
| 59 | bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); } |
| 60 | |
| 61 | // |
| 62 | inline const int len() const { return m_ptr->len(); } |
| 63 | |
| 64 | inline bool equals(const pstring &string) { return (pcmp(string.cstr(), m_ptr->str()) == 0); } |
| 65 | int cmp(pstring &string) { return pcmp(string.cstr()); } |
| 66 | |
| 67 | int find(const char *search, int start = 0) const |
| 68 | { |
| 69 | int alen = len(); |
| 70 | const char *result = strstr(cstr() + MIN(start, alen), search); |
| 71 | return (result != NULL) ? (result - cstr()) : -1; |
| 72 | } |
| 73 | |
| 74 | // various |
| 75 | |
| 76 | bool startsWith(pstring &arg) { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); } |
| 77 | bool startsWith(const char *arg) { return (pcmp(cstr(), arg, strlen(arg)) == 0); } |
| 78 | |
| 79 | // these return nstring ... |
| 80 | pstring cat(const pstring &s) const { return *this + s; } |
| 81 | pstring cat(const char *s) const { return *this + s; } |
| 82 | |
| 83 | pstring substr(unsigned int start, int count = -1) const ; |
| 84 | |
| 85 | pstring left(unsigned int count) const { return substr(0, count); } |
| 86 | pstring right(unsigned int count) const { return substr(len() - count, count); } |
| 87 | |
| 88 | // printf using string as format ... |
| 89 | |
| 90 | pstring vprintf(va_list args) const; |
| 91 | |
| 92 | // static |
| 93 | static pstring sprintf(const char *format, ...); |
| 94 | static void resetmem(); |
| 95 | |
| 96 | protected: |
| 97 | |
| 98 | struct str_t |
| 99 | { |
| 100 | int reference_count; |
| 101 | char *str() { return &m_str[0]; } |
| 102 | int len() { return m_len; } |
| 103 | //private: |
| 104 | int m_len; |
| 105 | char m_str[]; |
| 106 | }; |
| 107 | |
| 108 | str_t *m_ptr; |
| 109 | |
| 110 | private: |
| 111 | void init(); |
| 112 | |
| 113 | inline int pcmp(const char *right) const |
| 114 | { |
| 115 | return pcmp(m_ptr->str(), right); |
| 116 | } |
| 117 | |
| 118 | inline int pcmp(const char *left, const char *right, int count = -1) const |
| 119 | { |
| 120 | if (count < 0) |
| 121 | return strcmp(left, right); |
| 122 | else |
| 123 | return strncmp(left, right, count); |
| 124 | } |
| 125 | |
| 126 | void pcopy(const char *from, int size); |
| 127 | |
| 128 | inline void pcopy(const char *from) |
| 129 | { |
| 130 | pcopy(from, strlen(from)); |
| 131 | } |
| 132 | |
| 133 | inline void pcopy(const pstring &from) |
| 134 | { |
| 135 | sfree(m_ptr); |
| 136 | m_ptr = from.m_ptr; |
| 137 | m_ptr->reference_count++; |
| 138 | } |
| 139 | |
| 140 | void pcat(const char *s); |
| 141 | |
| 142 | static str_t *m_zero; |
| 143 | |
| 144 | static str_t *salloc(int n); |
| 145 | static void sfree(str_t *s); |
| 146 | |
| 147 | struct memblock |
| 148 | { |
| 149 | memblock *next; |
| 150 | int size; |
| 151 | int allocated; |
| 152 | int remaining; |
| 153 | char *cur; |
| 154 | char data[]; |
| 155 | }; |
| 156 | |
| 157 | static memblock *m_first; |
| 158 | static char *alloc_str(int n); |
| 159 | static void dealloc_str(void *ptr); |
| 160 | }; |
| 161 | |
| 162 | |
| 163 | #endif /* _PSTRING_H_ */ |
| 164 | |
trunk/src/emu/netlist/nl_lists.h
r26398 | r26399 | |
15 | 15 | // ---------------------------------------------------------------------------------------- |
16 | 16 | |
17 | 17 | |
18 | | template <class _ListClass> |
| 18 | template <class _ListClass, int _NumElem = 128> |
19 | 19 | struct netlist_list_t |
20 | 20 | { |
21 | 21 | public: |
22 | | ATTR_COLD netlist_list_t(int numElements = 100) |
| 22 | |
| 23 | struct entry_t { |
| 24 | |
| 25 | // keep compatibility with tagmap |
| 26 | _ListClass object() { return m_obj; } |
| 27 | |
| 28 | _ListClass m_obj; |
| 29 | }; |
| 30 | |
| 31 | ATTR_COLD netlist_list_t(int numElements = _NumElem) |
23 | 32 | { |
24 | 33 | m_num_elements = numElements; |
25 | | m_list = new _ListClass[m_num_elements]; |
| 34 | m_list = new entry_t[m_num_elements]; |
26 | 35 | m_ptr = m_list; |
27 | 36 | m_ptr--; |
28 | 37 | } |
r26398 | r26399 | |
32 | 41 | } |
33 | 42 | ATTR_HOT inline void add(const _ListClass elem) |
34 | 43 | { |
35 | | assert(m_ptr-m_list <= m_num_elements - 1); |
| 44 | if (m_ptr-m_list >= m_num_elements - 1) |
| 45 | resize(m_num_elements * 2); |
36 | 46 | |
37 | | *(++m_ptr) = elem; |
| 47 | (++m_ptr)->m_obj = elem; |
38 | 48 | } |
39 | 49 | ATTR_HOT inline void resize(const int new_size) |
40 | 50 | { |
41 | 51 | int cnt = count(); |
42 | | _ListClass *m_new = new _ListClass[new_size]; |
43 | | memcpy(m_new, m_list, new_size * sizeof(_ListClass)); |
| 52 | entry_t *m_new = new entry_t[new_size]; |
| 53 | entry_t *pd = m_new; |
| 54 | |
| 55 | for (entry_t *ps = m_list; ps <= m_ptr; ps++, pd++) |
| 56 | *pd = *ps; |
44 | 57 | delete[] m_list; |
45 | 58 | m_list = m_new; |
46 | 59 | m_ptr = m_list + cnt - 1; |
| 60 | m_num_elements = new_size; |
47 | 61 | } |
48 | | ATTR_HOT inline void del(const _ListClass elem) |
| 62 | ATTR_HOT inline void remove(const _ListClass elem) |
49 | 63 | { |
50 | | for (_ListClass * i=m_list; i<=m_ptr; i++) |
| 64 | for (entry_t *i = m_list; i <= m_ptr; i++) |
51 | 65 | { |
52 | | if (*i == elem) |
| 66 | if (i->object() == elem) |
53 | 67 | { |
54 | 68 | while (i <= m_ptr) |
55 | 69 | { |
r26398 | r26399 | |
61 | 75 | } |
62 | 76 | } |
63 | 77 | } |
64 | | ATTR_HOT inline _ListClass *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); } |
65 | | ATTR_HOT inline _ListClass *next(_ListClass *lc) { return (lc < last() ? lc + 1 : NULL ); } |
66 | | ATTR_HOT inline _ListClass *last() { return m_ptr; } |
67 | | ATTR_HOT inline _ListClass *item(int i) { return &m_list[i]; } |
| 78 | ATTR_HOT inline entry_t *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); } |
| 79 | ATTR_HOT inline entry_t *next(entry_t *lc) { return (lc < last() ? lc + 1 : NULL ); } |
| 80 | ATTR_HOT inline entry_t *last() { return m_ptr; } |
| 81 | ATTR_HOT inline entry_t *item(int i) { return &m_list[i]; } |
68 | 82 | ATTR_HOT inline int count() const { return m_ptr - m_list + 1; } |
69 | 83 | ATTR_HOT inline bool empty() { return (m_ptr < m_list); } |
70 | | ATTR_HOT inline void clear() { m_ptr = m_list - 1; } |
| 84 | ATTR_HOT inline void reset() { m_ptr = m_list - 1; } |
71 | 85 | private: |
72 | | _ListClass * m_ptr; |
73 | | _ListClass * m_list; |
| 86 | entry_t * m_ptr; |
| 87 | entry_t * m_list; |
74 | 88 | int m_num_elements; |
75 | 89 | //_ListClass m_list[_NumElements]; |
76 | 90 | }; |
r26398 | r26399 | |
111 | 125 | if (is_empty() || (e.time() <= (m_end - 1)->time())) |
112 | 126 | { |
113 | 127 | *m_end++ = e; |
114 | | //inc_stat(m_prof_end); |
| 128 | inc_stat(m_prof_end); |
115 | 129 | } |
116 | 130 | else |
117 | 131 | { |
r26398 | r26399 | |
120 | 134 | { |
121 | 135 | i--; |
122 | 136 | *(i+1) = *i; |
123 | | //inc_stat(m_prof_sortmove); |
| 137 | inc_stat(m_prof_sortmove); |
124 | 138 | } |
125 | 139 | *i = e; |
126 | | //inc_stat(m_prof_sort); |
| 140 | inc_stat(m_prof_sort); |
127 | 141 | } |
128 | 142 | assert(m_end - m_list < _Size); |
129 | 143 | } |
130 | 144 | |
131 | | ATTR_HOT inline const entry_t pop() |
| 145 | ATTR_HOT inline const entry_t &pop() |
132 | 146 | { |
133 | 147 | return *--m_end; |
134 | 148 | } |
135 | 149 | |
136 | | ATTR_HOT inline const entry_t peek() const |
| 150 | ATTR_HOT inline const entry_t &peek() const |
137 | 151 | { |
138 | 152 | return *(m_end-1); |
139 | 153 | } |
r26398 | r26399 | |
142 | 156 | { |
143 | 157 | m_end = &m_list[0]; |
144 | 158 | } |
| 159 | |
| 160 | #if (NL_KEEP_STATISTICS) |
145 | 161 | // profiling |
146 | | |
147 | 162 | INT32 m_prof_start; |
148 | 163 | INT32 m_prof_end; |
149 | 164 | INT32 m_prof_sortmove; |
150 | 165 | INT32 m_prof_sort; |
| 166 | #endif |
| 167 | |
151 | 168 | private: |
152 | 169 | |
153 | 170 | entry_t * RESTRICT m_end; |
trunk/src/emu/netlist/nl_time.h
r26398 | r26399 | |
26 | 26 | { |
27 | 27 | public: |
28 | 28 | |
29 | | typedef UINT64 INTERNALTYPE; |
| 29 | typedef UINT64 INTERNALTYPE; |
30 | 30 | |
31 | | static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES; |
| 31 | static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES; |
32 | 32 | |
33 | | ATTR_HOT inline netlist_time() : m_time(0) {} |
| 33 | ATTR_HOT inline netlist_time() : m_time(0) {} |
34 | 34 | |
35 | | ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right); |
36 | | ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right); |
37 | | ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor); |
| 35 | ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right); |
| 36 | ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right); |
| 37 | ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor); |
38 | 38 | ATTR_HOT friend inline const UINT32 operator/(const netlist_time &left, const netlist_time &right); |
39 | | ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right); |
40 | | ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right); |
41 | | ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right); |
42 | | ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right); |
| 39 | ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right); |
| 40 | ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right); |
| 41 | ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right); |
| 42 | ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right); |
43 | 43 | |
44 | | ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } |
45 | | ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } |
| 44 | ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } |
| 45 | ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } |
46 | 46 | |
47 | | ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; } |
| 47 | ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; } |
48 | 48 | ATTR_HOT inline const double as_double() const { return (double) m_time / (double) RESOLUTION; } |
49 | 49 | |
50 | | ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } |
51 | | ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } |
52 | | ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } |
53 | | ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); } |
54 | | ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); } |
| 50 | ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } |
| 51 | ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } |
| 52 | ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } |
| 53 | ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); } |
| 54 | ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); } |
55 | 55 | |
56 | | static const netlist_time zero; |
| 56 | static const netlist_time zero; |
57 | 57 | |
58 | 58 | protected: |
59 | 59 | |
60 | | ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {} |
| 60 | ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {} |
61 | 61 | |
62 | | INTERNALTYPE m_time; |
| 62 | INTERNALTYPE m_time; |
63 | 63 | }; |
64 | 64 | |
65 | 65 | ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right) |
66 | 66 | { |
67 | | return netlist_time::from_raw(left.m_time - right.m_time); |
| 67 | return netlist_time::from_raw(left.m_time - right.m_time); |
68 | 68 | } |
69 | 69 | |
70 | 70 | ATTR_HOT inline const netlist_time operator*(const netlist_time &left, const UINT32 factor) |
71 | 71 | { |
72 | | return netlist_time::from_raw(left.m_time * factor); |
| 72 | return netlist_time::from_raw(left.m_time * factor); |
73 | 73 | } |
74 | 74 | |
75 | 75 | ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_time &right) |
r26398 | r26399 | |
79 | 79 | |
80 | 80 | ATTR_HOT inline const netlist_time operator+(const netlist_time &left, const netlist_time &right) |
81 | 81 | { |
82 | | return netlist_time::from_raw(left.m_time + right.m_time); |
| 82 | return netlist_time::from_raw(left.m_time + right.m_time); |
83 | 83 | } |
84 | 84 | |
85 | 85 | ATTR_HOT inline bool operator<(const netlist_time &left, const netlist_time &right) |
86 | 86 | { |
87 | | return (left.m_time < right.m_time); |
| 87 | return (left.m_time < right.m_time); |
88 | 88 | } |
89 | 89 | |
90 | 90 | ATTR_HOT inline bool operator>(const netlist_time &left, const netlist_time &right) |
91 | 91 | { |
92 | | return (left.m_time > right.m_time); |
| 92 | return (left.m_time > right.m_time); |
93 | 93 | } |
94 | 94 | |
95 | 95 | ATTR_HOT inline bool operator<=(const netlist_time &left, const netlist_time &right) |
96 | 96 | { |
97 | | return (left.m_time <= right.m_time); |
| 97 | return (left.m_time <= right.m_time); |
98 | 98 | } |
99 | 99 | |
100 | 100 | ATTR_HOT inline bool operator>=(const netlist_time &left, const netlist_time &right) |
101 | 101 | { |
102 | | return (left.m_time >= right.m_time); |
| 102 | return (left.m_time >= right.m_time); |
103 | 103 | } |
104 | 104 | |
105 | 105 | |
trunk/src/emu/netlist/nl_setup.h
r26398 | r26399 | |
68 | 68 | |
69 | 69 | struct link_t |
70 | 70 | { |
71 | | link_t(const astring &ae1, const astring &ae2) |
| 71 | link_t() { } |
| 72 | // Copy constructor |
| 73 | link_t(const link_t &from) |
72 | 74 | { |
| 75 | e1 = from.e1; |
| 76 | e2 = from.e2; |
| 77 | } |
| 78 | |
| 79 | link_t(const pstring &ae1, const pstring &ae2) |
| 80 | { |
73 | 81 | e1 = ae1; |
74 | 82 | e2 = ae2; |
75 | 83 | } |
76 | | astring e1; |
77 | | astring e2; |
| 84 | pstring e1; |
| 85 | pstring e2; |
| 86 | |
| 87 | bool operator==(const link_t &rhs) const { return (e1 == rhs.e1) && (e2 == rhs.e2); } |
| 88 | link_t &operator=(const link_t &rhs) { e1 = rhs.e1; e2 = rhs.e2; return *this; } |
78 | 89 | }; |
79 | 90 | |
80 | 91 | typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t; |
81 | | typedef tagmap_t<link_t *, 393> tagmap_link_t; |
82 | | typedef tagmap_t<const astring *, 393> tagmap_astring_t; |
| 92 | typedef tagmap_t<pstring, 393> tagmap_nstring_t; |
83 | 93 | typedef tagmap_t<netlist_param_t *, 393> tagmap_param_t; |
84 | 94 | typedef tagmap_t<netlist_terminal_t *, 393> tagmap_terminal_t; |
| 95 | typedef netlist_list_t<link_t> tagmap_link_t; |
85 | 96 | |
86 | 97 | netlist_setup_t(netlist_base_t &netlist); |
87 | 98 | ~netlist_setup_t(); |
88 | 99 | |
89 | 100 | netlist_base_t &netlist() { return m_netlist; } |
90 | 101 | |
91 | | netlist_device_t *register_dev(netlist_device_t *dev, const astring &name); |
92 | | void remove_dev(const astring &name); |
| 102 | netlist_device_t *register_dev(netlist_device_t *dev, const pstring &name); |
| 103 | void remove_dev(const pstring &name); |
93 | 104 | |
94 | | void register_alias(const astring &alias, const astring &out); |
95 | | void register_link(const astring &sin, const astring &sout); |
96 | | void register_param(const astring ¶m, const astring &value); |
97 | | void register_param(const astring ¶m, const double value); |
| 105 | void register_alias(const pstring &alias, const pstring &out); |
| 106 | void register_link(const pstring &sin, const pstring &sout); |
| 107 | void register_param(const pstring ¶m, const pstring &value); |
| 108 | void register_param(const pstring ¶m, const double value); |
98 | 109 | |
99 | | 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); |
| 110 | void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state); |
100 | 111 | |
101 | | netlist_terminal_t &find_terminal(const astring &outname_in); |
102 | | netlist_terminal_t &find_terminal(const astring &outname_in, netlist_object_t::type_t atype); |
| 112 | netlist_terminal_t &find_terminal(const pstring &outname_in); |
| 113 | netlist_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype); |
103 | 114 | |
104 | | netlist_param_t &find_param(const astring ¶m_in); |
| 115 | netlist_param_t &find_param(const pstring ¶m_in); |
105 | 116 | |
106 | | void register_callback(const astring &devname, netlist_output_delegate delegate); |
| 117 | void register_callback(const pstring &devname, netlist_output_delegate delegate); |
107 | 118 | |
108 | 119 | void parse(char *buf); |
109 | 120 | |
r26398 | r26399 | |
123 | 134 | netlist_base_t &m_netlist; |
124 | 135 | |
125 | 136 | tagmap_devices_t m_devices; |
126 | | tagmap_astring_t m_alias; |
| 137 | tagmap_nstring_t m_alias; |
127 | 138 | tagmap_param_t m_params; |
128 | | tagmap_link_t m_links; |
129 | | tagmap_astring_t m_params_temp; |
| 139 | tagmap_link_t m_links; |
| 140 | tagmap_nstring_t m_params_temp; |
130 | 141 | |
131 | 142 | int m_proxy_cnt; |
132 | 143 | |
r26398 | r26399 | |
136 | 147 | void connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp); |
137 | 148 | |
138 | 149 | // helpers |
139 | | astring objtype_as_astr(netlist_object_t &in); |
| 150 | pstring objtype_as_astr(netlist_object_t &in); |
140 | 151 | |
141 | | const astring resolve_alias(const astring &name) const; |
| 152 | const pstring resolve_alias(const pstring &name) const; |
142 | 153 | }; |
143 | 154 | |
144 | 155 | #endif /* NLSETUP_H_ */ |
trunk/src/emu/netlist/devices/nld_system.c
r26398 | r26399 | |
98 | 98 | m_inc = netlist_time::from_hz(m_freq.Value()); |
99 | 99 | } |
100 | 100 | |
| 101 | NETLIB_NAME(solver)::~NETLIB_NAME(solver)() |
| 102 | { |
| 103 | net_list_t::entry_t *p = m_nets.first(); |
| 104 | while (p != NULL) |
| 105 | { |
| 106 | net_list_t::entry_t *pn = m_nets.next(pn); |
| 107 | delete pn->object(); |
| 108 | p = pn; |
| 109 | } |
| 110 | } |
| 111 | |
101 | 112 | NETLIB_FUNC_VOID(solver, post_start, ()) |
102 | 113 | { |
103 | 114 | NL_VERBOSE_OUT(("post start solver ...\n")); |
104 | | for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) |
| 115 | for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) |
105 | 116 | { |
106 | 117 | NL_VERBOSE_OUT(("setting up net\n")); |
107 | | for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next) |
| 118 | for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next) |
108 | 119 | { |
109 | 120 | switch (p->type()) |
110 | 121 | { |
r26398 | r26399 | |
121 | 132 | break; |
122 | 133 | } |
123 | 134 | } |
124 | | if ((*pn)->m_head == NULL) |
| 135 | if (pn->object()->m_head == NULL) |
125 | 136 | { |
126 | 137 | NL_VERBOSE_OUT(("Deleting net ...\n")); |
127 | | netlist_net_t *to_delete = *pn; |
128 | | m_nets.del(to_delete); |
| 138 | netlist_net_t *to_delete = pn->object(); |
| 139 | m_nets.remove(to_delete); |
129 | 140 | delete to_delete; |
130 | 141 | pn--; |
131 | 142 | } |
r26398 | r26399 | |
146 | 157 | NL_VERBOSE_OUT(("Step!\n")); |
147 | 158 | /* update all terminals for new time step */ |
148 | 159 | m_last_step = now; |
149 | | for (netlist_terminal_t **p = m_terms.first(); p != NULL; p = m_terms.next(p)) |
150 | | (*p)->netdev().step_time(delta.as_double()); |
| 160 | for (terminal_list_t::entry_t *p = m_terms.first(); p != NULL; p = m_terms.next(p)) |
| 161 | p->object()->netdev().step_time(delta.as_double()); |
151 | 162 | } |
152 | | for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) |
| 163 | for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) |
153 | 164 | { |
154 | 165 | double gtot = 0; |
155 | 166 | double iIdr = 0; |
156 | 167 | |
157 | | for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next) |
| 168 | for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next) |
158 | 169 | { |
159 | 170 | if (p->isType(netlist_terminal_t::TERMINAL)) |
160 | 171 | { |
r26398 | r26399 | |
165 | 176 | } |
166 | 177 | |
167 | 178 | double new_val = iIdr / gtot; |
168 | | if (fabs(new_val - (*pn)->m_cur.Analog) > 1e-4) |
| 179 | if (fabs(new_val - pn->object()->m_cur.Analog) > 1e-4) |
169 | 180 | resched = true; |
170 | | (*pn)->m_cur.Analog = (*pn)->m_new.Analog = new_val; |
| 181 | pn->object()->m_cur.Analog = pn->object()->m_new.Analog = new_val; |
171 | 182 | |
172 | 183 | NL_VERBOSE_OUT(("Info: %d\n", (*pn)->m_num_cons)); |
173 | 184 | NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val)); |
r26398 | r26399 | |
179 | 190 | else |
180 | 191 | { |
181 | 192 | /* update all inputs connected */ |
182 | | for (netlist_terminal_t **p = m_inps.first(); p != NULL; p = m_inps.next(p)) |
183 | | (*p)->netdev().update_dev(); |
| 193 | for (terminal_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p)) |
| 194 | p->object()->netdev().update_dev(); |
184 | 195 | /* step circuit */ |
185 | 196 | if (!m_Q.net().is_queued()) |
186 | 197 | { |
trunk/src/emu/netlist/nl_base.c
r26398 | r26399 | |
5 | 5 | |
6 | 6 | #include "nl_base.h" |
7 | 7 | #include "devices/nld_system.h" |
| 8 | #include "pstring.h" |
8 | 9 | |
| 10 | const netlist_time netlist_time::zero = netlist_time::from_raw(0); |
| 11 | |
9 | 12 | // ---------------------------------------------------------------------------------------- |
10 | 13 | // netlist_object_t |
11 | 14 | // ---------------------------------------------------------------------------------------- |
r26398 | r26399 | |
14 | 17 | : m_objtype(atype) |
15 | 18 | , m_family(afamily) |
16 | 19 | , m_netlist(NULL) |
17 | | , m_name(NULL) |
18 | 20 | {} |
19 | 21 | |
20 | 22 | ATTR_COLD netlist_object_t::~netlist_object_t() |
21 | 23 | { |
22 | | delete m_name; |
| 24 | //delete m_name; |
23 | 25 | } |
24 | 26 | |
25 | | ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const astring &aname) |
| 27 | ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const pstring &aname) |
26 | 28 | { |
27 | 29 | m_netlist = &nl; |
28 | | m_name = new astring(aname); |
| 30 | m_name = aname; |
29 | 31 | } |
30 | 32 | |
31 | | ATTR_COLD const astring &netlist_object_t::name() const |
| 33 | ATTR_COLD const pstring &netlist_object_t::name() const |
32 | 34 | { |
33 | | if (m_name == NULL) |
| 35 | if (m_name == "") |
34 | 36 | fatalerror("object not initialized"); |
35 | | return *m_name; |
| 37 | return m_name; |
36 | 38 | } |
37 | 39 | |
38 | 40 | // ---------------------------------------------------------------------------------------- |
r26398 | r26399 | |
47 | 49 | } |
48 | 50 | |
49 | 51 | ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev, |
50 | | const astring &aname) |
| 52 | const pstring &aname) |
51 | 53 | { |
52 | 54 | netlist_object_t::init_object(dev.netlist(), aname); |
53 | 55 | m_netdev = &dev; |
r26398 | r26399 | |
58 | 60 | // ---------------------------------------------------------------------------------------- |
59 | 61 | |
60 | 62 | netlist_base_t::netlist_base_t() |
61 | | : m_mainclock(NULL), |
62 | | m_time_ps(netlist_time::zero), |
| 63 | : m_time_ps(netlist_time::zero), |
63 | 64 | m_rem(0), |
64 | | m_div(NETLIST_DIV) |
| 65 | m_div(NETLIST_DIV), |
| 66 | m_mainclock(NULL), |
| 67 | m_solver(NULL) |
65 | 68 | { |
66 | 69 | } |
67 | 70 | |
68 | 71 | netlist_base_t::~netlist_base_t() |
69 | 72 | { |
| 73 | pstring::resetmem(); |
70 | 74 | } |
71 | 75 | |
72 | 76 | ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev) |
r26398 | r26399 | |
81 | 85 | |
82 | 86 | ATTR_COLD void netlist_base_t::reset() |
83 | 87 | { |
84 | | m_time_ps = netlist_time::zero; |
85 | | m_rem = 0; |
86 | | m_queue.clear(); |
87 | | if (m_mainclock != NULL) |
88 | | m_mainclock->m_Q.net().set_time(netlist_time::zero); |
| 88 | m_time_ps = netlist_time::zero; |
| 89 | m_rem = 0; |
| 90 | m_queue.clear(); |
| 91 | if (m_mainclock != NULL) |
| 92 | m_mainclock->m_Q.net().set_time(netlist_time::zero); |
| 93 | |
89 | 94 | } |
90 | 95 | |
91 | 96 | |
r26398 | r26399 | |
121 | 126 | { |
122 | 127 | while ( (atime > 0) && (m_queue.is_not_empty())) |
123 | 128 | { |
124 | | const queue_t::entry_t e = m_queue.pop(); |
| 129 | const queue_t::entry_t &e = m_queue.pop(); |
125 | 130 | update_time(e.time(), atime); |
126 | 131 | |
127 | 132 | //if (FATAL_ERROR_AFTER_NS) |
r26398 | r26399 | |
156 | 161 | NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); |
157 | 162 | |
158 | 163 | } |
159 | | const queue_t::entry_t e = m_queue.pop(); |
| 164 | const queue_t::entry_t &e = m_queue.pop(); |
160 | 165 | |
161 | 166 | update_time(e.time(), atime); |
162 | 167 | |
r26398 | r26399 | |
197 | 202 | { |
198 | 203 | } |
199 | 204 | |
200 | | ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const astring &name) |
| 205 | ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const pstring &name) |
201 | 206 | { |
202 | 207 | init_object(setup.netlist(), name); |
203 | 208 | |
r26398 | r26399 | |
248 | 253 | //NL_VERBOSE_OUT(("~net_device_t\n"); |
249 | 254 | } |
250 | 255 | |
251 | | ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &name) |
| 256 | ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const pstring &name) |
252 | 257 | { |
253 | 258 | netlist_core_device_t::init(setup, name); |
254 | 259 | m_setup = &setup; |
r26398 | r26399 | |
256 | 261 | } |
257 | 262 | |
258 | 263 | |
259 | | ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const astring &name) |
| 264 | ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const pstring &name) |
260 | 265 | { |
261 | 266 | dev.init(*m_setup, this->name() + "." + name); |
262 | 267 | } |
263 | 268 | |
264 | | ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port) |
| 269 | ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &port) |
265 | 270 | { |
266 | 271 | m_setup->register_object(*this, dev, name, port, netlist_terminal_t::STATE_OUT); |
267 | 272 | } |
268 | 273 | |
269 | | ATTR_COLD void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port) |
| 274 | ATTR_COLD void netlist_device_t::register_terminal(const pstring &name, netlist_terminal_t &port) |
270 | 275 | { |
271 | 276 | m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_INP_ACTIVE); |
272 | 277 | } |
273 | 278 | |
274 | | ATTR_COLD void netlist_device_t::register_output(const astring &name, netlist_output_t &port) |
| 279 | ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_output_t &port) |
275 | 280 | { |
276 | 281 | m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_OUT); |
277 | 282 | } |
278 | 283 | |
279 | | 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) |
| 284 | ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type) |
280 | 285 | { |
281 | 286 | m_terminals.add(name); |
282 | 287 | m_setup->register_object(*this, dev, name, inp, type); |
283 | 288 | } |
284 | 289 | |
285 | | ATTR_COLD void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::state_e type) |
| 290 | ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type) |
286 | 291 | { |
287 | 292 | register_input(*this, name, inp, type); |
288 | 293 | } |
r26398 | r26399 | |
303 | 308 | register_link_internal(*this, in, out, aState); |
304 | 309 | } |
305 | 310 | |
306 | | ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t ¶m, double initialVal) |
| 311 | ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &name, netlist_param_t ¶m, double initialVal) |
307 | 312 | { |
308 | 313 | param.set_netdev(dev); |
309 | 314 | param.initial(initialVal); |
310 | 315 | m_setup->register_object(*this, *this, name, param, netlist_terminal_t::STATE_NONEX); |
311 | 316 | } |
312 | 317 | |
313 | | ATTR_COLD void netlist_device_t::register_param(const astring &name, netlist_param_t ¶m, double initialVal) |
| 318 | ATTR_COLD void netlist_device_t::register_param(const pstring &name, netlist_param_t ¶m, double initialVal) |
314 | 319 | { |
315 | 320 | register_param(*this,name, param, initialVal); |
316 | 321 | } |
r26398 | r26399 | |
451 | 456 | |
452 | 457 | } |
453 | 458 | |
454 | | ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate) |
| 459 | ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate) |
455 | 460 | { |
456 | 461 | set_state(astate); |
457 | 462 | netlist_owned_object_t::init_object(dev, aname); |
r26398 | r26399 | |
480 | 485 | this->set_net(m_my_net); |
481 | 486 | } |
482 | 487 | |
483 | | ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const astring &aname) |
| 488 | ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) |
484 | 489 | { |
485 | 490 | netlist_terminal_t::init_object(dev, aname, STATE_OUT); |
486 | 491 | net().init_object(dev.netlist(), aname); |
trunk/src/emu/netlist/pstring.c
r0 | r26399 | |
| 1 | /* |
| 2 | * nl_string.c |
| 3 | * |
| 4 | */ |
| 5 | |
| 6 | #include "pstring.h" |
| 7 | #include <cstdio> |
| 8 | |
| 9 | //nstring::str_t *nstring::m_zero = NULL; |
| 10 | pstring::str_t *pstring::m_zero = pstring::salloc(0); |
| 11 | pstring::memblock *pstring::m_first = NULL; |
| 12 | |
| 13 | #define IMMEDIATE_MODE (1) |
| 14 | #define DEBUG_MODE (0) |
| 15 | |
| 16 | pstring::~pstring() |
| 17 | { |
| 18 | sfree(m_ptr); |
| 19 | } |
| 20 | |
| 21 | void pstring::init() |
| 22 | { |
| 23 | if (m_zero == NULL) |
| 24 | { |
| 25 | m_zero = (str_t *) alloc_str(sizeof(str_t) + 1); |
| 26 | m_zero->reference_count = 1; |
| 27 | m_zero->m_len = 0; |
| 28 | m_zero->m_str[0] = 0; |
| 29 | } |
| 30 | m_ptr = m_zero; |
| 31 | m_ptr->reference_count++; |
| 32 | } |
| 33 | |
| 34 | void pstring::pcat(const char *s) |
| 35 | { |
| 36 | int slen = strlen(s); |
| 37 | str_t *n = salloc(m_ptr->len() + slen); |
| 38 | if (m_ptr->len() > 0) |
| 39 | memcpy(n->str(), m_ptr->str(), m_ptr->len()); |
| 40 | if (slen > 0) |
| 41 | memcpy(n->str() + m_ptr->len(), s, slen); |
| 42 | *(n->str() + n->len()) = 0; |
| 43 | sfree(m_ptr); |
| 44 | m_ptr = n; |
| 45 | } |
| 46 | |
| 47 | void pstring::pcopy(const char *from, int size) |
| 48 | { |
| 49 | str_t *n = salloc(size); |
| 50 | if (size > 0) |
| 51 | memcpy(n->str(), from, size); |
| 52 | *(n->str() + size) = 0; |
| 53 | sfree(m_ptr); |
| 54 | m_ptr = n; |
| 55 | } |
| 56 | |
| 57 | pstring pstring::substr(unsigned int start, int count) const |
| 58 | { |
| 59 | int alen = len(); |
| 60 | if (start >= alen) |
| 61 | return pstring(); |
| 62 | if (count <0 || start + count > alen) |
| 63 | count = alen - start; |
| 64 | pstring ret; |
| 65 | ret.pcopy(cstr() + start, count); |
| 66 | return ret; |
| 67 | } |
| 68 | |
| 69 | pstring pstring::vprintf(va_list args) const |
| 70 | { |
| 71 | // sprintf into the temporary buffer |
| 72 | char tempbuf[4096]; |
| 73 | vsprintf(tempbuf, cstr(), args); |
| 74 | |
| 75 | return pstring(tempbuf); |
| 76 | } |
| 77 | |
| 78 | // ---------------------------------------------------------------------------------------- |
| 79 | // static stuff ... |
| 80 | // ---------------------------------------------------------------------------------------- |
| 81 | |
| 82 | void pstring::sfree(str_t *s) |
| 83 | { |
| 84 | s->reference_count--; |
| 85 | if (s->reference_count == 0) |
| 86 | dealloc_str(s); |
| 87 | } |
| 88 | |
| 89 | pstring::str_t *pstring::salloc(int n) |
| 90 | { |
| 91 | str_t *ret = (str_t *) alloc_str(sizeof(str_t) + n + 1); |
| 92 | ret->reference_count = 1; |
| 93 | ret->m_len = n; |
| 94 | ret->m_str[0] = 0; |
| 95 | return ret; |
| 96 | //std::printf("old string %d <%s> %p %p\n", n, old, old, m_ptr); |
| 97 | } |
| 98 | |
| 99 | pstring pstring::sprintf(const char *format, ...) |
| 100 | { |
| 101 | va_list ap; |
| 102 | va_start(ap, format); |
| 103 | pstring ret = pstring(format).vprintf(ap); |
| 104 | va_end(ap); |
| 105 | return ret; |
| 106 | } |
| 107 | |
| 108 | char *pstring::alloc_str(int n) |
| 109 | { |
| 110 | #if (IMMEDIATE_MODE) |
| 111 | return (char *) malloc(n); |
| 112 | #else |
| 113 | #if (DEBUG_MODE) |
| 114 | int min_alloc = MAX(0, n+sizeof(memblock)); |
| 115 | #else |
| 116 | int min_alloc = MAX(8192, n+sizeof(memblock)); |
| 117 | #endif |
| 118 | char *ret = NULL; |
| 119 | |
| 120 | //std::printf("m_first %p\n", m_first); |
| 121 | for (memblock *p = m_first; p != NULL && ret == NULL; p = p->next) |
| 122 | { |
| 123 | if (p->remaining > n) |
| 124 | { |
| 125 | ret = p->cur; |
| 126 | p->cur += n; |
| 127 | p->allocated += 1; |
| 128 | p->remaining -= n; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | if (ret == NULL) |
| 133 | { |
| 134 | // need to allocate a new block |
| 135 | memblock *p = (memblock *) malloc(min_alloc); //new char[min_alloc]; |
| 136 | p->allocated = 0; |
| 137 | p->cur = &p->data[0]; |
| 138 | p->size = p->remaining = min_alloc - sizeof(memblock); |
| 139 | p->next = m_first; |
| 140 | //std::printf("allocated block size %d\n", p->size); |
| 141 | |
| 142 | ret = p->cur; |
| 143 | p->cur += n; |
| 144 | p->allocated += 1; |
| 145 | p->remaining -= n; |
| 146 | |
| 147 | m_first = p; |
| 148 | } |
| 149 | |
| 150 | return ret; |
| 151 | #endif |
| 152 | } |
| 153 | |
| 154 | void pstring::dealloc_str(void *ptr) |
| 155 | { |
| 156 | #if (IMMEDIATE_MODE) |
| 157 | free(ptr); |
| 158 | #else |
| 159 | for (memblock *p = m_first; p != NULL; p = p->next) |
| 160 | { |
| 161 | if (ptr >= &p->data[0] && ptr < &p->data[p->size]) |
| 162 | { |
| 163 | p->allocated -= 1; |
| 164 | if (p->allocated < 0) |
| 165 | fatalerror("nstring: memory corruption\n"); |
| 166 | if (p->allocated == 0) |
| 167 | { |
| 168 | //std::printf("Block entirely freed\n"); |
| 169 | p->remaining = p->size; |
| 170 | p->cur = &p->data[0]; |
| 171 | } |
| 172 | // shutting down ? |
| 173 | if (m_zero == NULL) |
| 174 | resetmem(); // try to free blocks |
| 175 | return; |
| 176 | } |
| 177 | } |
| 178 | fatalerror("nstring: string <%p> not found\n", ptr); |
| 179 | #endif |
| 180 | } |
| 181 | |
| 182 | void pstring::resetmem() |
| 183 | { |
| 184 | #if (IMMEDIATE_MODE) |
| 185 | #else |
| 186 | memblock **p = &m_first; |
| 187 | int totalblocks = 0; |
| 188 | int freedblocks = 0; |
| 189 | |
| 190 | // Release the 0 string |
| 191 | if (m_zero != NULL) sfree(m_zero); |
| 192 | m_zero = NULL; |
| 193 | |
| 194 | while (*p != NULL) |
| 195 | { |
| 196 | totalblocks++; |
| 197 | memblock **next = &((*p)->next); |
| 198 | if ((*p)->allocated == 0) |
| 199 | { |
| 200 | //std::printf("freeing block %p\n", *p); |
| 201 | memblock *freeme = *p; |
| 202 | *p = *next; |
| 203 | free(freeme); //delete[] *p; |
| 204 | freedblocks++; |
| 205 | } |
| 206 | else |
| 207 | { |
| 208 | #if (DEBUG_MODE) |
| 209 | std::printf("Allocated: <%s>\n", ((str_t *)(&(*p)->data[0]))->str()); |
| 210 | #endif |
| 211 | p = next; |
| 212 | } |
| 213 | } |
| 214 | #if (DEBUG_MODE) |
| 215 | std::printf("Freed %d out of total %d blocks\n", freedblocks, totalblocks); |
| 216 | #endif |
| 217 | #endif |
| 218 | } |