trunk/src/emu/netlist/pstring.h
| r26459 | r26460 | |
| 10 | 10 | #include "nl_config.h" |
| 11 | 11 | |
| 12 | 12 | // ---------------------------------------------------------------------------------------- |
| 13 | // pblockbool: allocate small memory more efficiently at the expense of some overhead |
| 14 | // ---------------------------------------------------------------------------------------- |
| 15 | |
| 16 | struct pblockpool { |
| 17 | |
| 18 | struct memblock |
| 19 | { |
| 20 | memblock *next; |
| 21 | int size; |
| 22 | int allocated; |
| 23 | int remaining; |
| 24 | char *cur; |
| 25 | char data[]; |
| 26 | }; |
| 27 | |
| 28 | pblockpool(); |
| 29 | |
| 30 | void resetmem(); |
| 31 | |
| 32 | void *alloc(std::size_t n); |
| 33 | void dealloc(void *ptr); |
| 34 | |
| 35 | template<class T> |
| 36 | void destroy(T* object) |
| 37 | { |
| 38 | object->~T(); |
| 39 | dealloc(object); |
| 40 | } |
| 41 | |
| 42 | bool m_shutdown; |
| 43 | memblock *m_first; |
| 44 | int m_blocksize; |
| 45 | int m_align; |
| 46 | }; |
| 47 | |
| 48 | // ---------------------------------------------------------------------------------------- |
| 13 | 49 | // nstring: immutable strings ... |
| 14 | 50 | // |
| 15 | 51 | // nstrings are just a pointer to a "pascal-style" string representation. |
| r26459 | r26460 | |
| 59 | 95 | bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); } |
| 60 | 96 | |
| 61 | 97 | // |
| 62 | | inline const int len() const { return m_ptr->len(); } |
| 98 | inline int len() const { return m_ptr->len(); } |
| 63 | 99 | |
| 64 | 100 | inline bool equals(const pstring &string) { return (pcmp(string.cstr(), m_ptr->str()) == 0); } |
| 65 | 101 | inline bool iequals(const pstring &string) { return (pcmpi(string.cstr(), m_ptr->str()) == 0); } |
| 66 | 102 | |
| 67 | | int cmp(pstring &string) { return pcmp(string.cstr()); } |
| 68 | | int cmpi(pstring &string) { return pcmpi(cstr(), string.cstr()); } |
| 103 | int cmp(const pstring &string) const { return pcmp(string.cstr()); } |
| 104 | int cmpi(const pstring &string) const { return pcmpi(cstr(), string.cstr()); } |
| 69 | 105 | |
| 70 | 106 | int find(const char *search, int start = 0) const |
| 71 | 107 | { |
| r26459 | r26460 | |
| 76 | 112 | |
| 77 | 113 | // various |
| 78 | 114 | |
| 79 | | bool startsWith(pstring &arg) { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); } |
| 80 | | bool startsWith(const char *arg) { return (pcmp(cstr(), arg, strlen(arg)) == 0); } |
| 115 | bool startsWith(const pstring &arg) const { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); } |
| 116 | bool startsWith(const char *arg) const { return (pcmp(cstr(), arg, strlen(arg)) == 0); } |
| 81 | 117 | |
| 82 | 118 | // these return nstring ... |
| 83 | 119 | pstring cat(const pstring &s) const { return *this + s; } |
| r26459 | r26460 | |
| 100 | 136 | |
| 101 | 137 | struct str_t |
| 102 | 138 | { |
| 103 | | int reference_count; |
| 139 | str_t(int alen) : m_ref_count(1), m_len(alen) { m_str[0] = 0; } |
| 140 | |
| 104 | 141 | char *str() { return &m_str[0]; } |
| 105 | 142 | int len() { return m_len; } |
| 106 | 143 | //private: |
| 144 | int m_ref_count; |
| 107 | 145 | int m_len; |
| 108 | | char m_str[]; |
| 146 | char m_str[1]; |
| 109 | 147 | }; |
| 110 | 148 | |
| 111 | 149 | str_t *m_ptr; |
| 112 | 150 | |
| 151 | static pblockpool *m_pool; |
| 152 | |
| 113 | 153 | private: |
| 114 | | void init(); |
| 154 | inline void init() |
| 155 | { |
| 156 | m_ptr = m_zero; |
| 157 | m_ptr->m_ref_count++; |
| 158 | } |
| 115 | 159 | |
| 116 | 160 | inline int pcmp(const char *right) const |
| 117 | 161 | { |
| r26459 | r26460 | |
| 139 | 183 | { |
| 140 | 184 | sfree(m_ptr); |
| 141 | 185 | m_ptr = from.m_ptr; |
| 142 | | m_ptr->reference_count++; |
| 186 | m_ptr->m_ref_count++; |
| 143 | 187 | } |
| 144 | 188 | |
| 145 | 189 | void pcat(const char *s); |
| 146 | 190 | |
| 147 | | static str_t *m_zero; |
| 148 | | |
| 149 | 191 | static str_t *salloc(int n); |
| 150 | 192 | static void sfree(str_t *s); |
| 151 | 193 | |
| 152 | | struct memblock |
| 153 | | { |
| 154 | | memblock *next; |
| 155 | | int size; |
| 156 | | int allocated; |
| 157 | | int remaining; |
| 158 | | char *cur; |
| 159 | | char data[]; |
| 160 | | }; |
| 161 | | |
| 162 | | static memblock *m_first; |
| 163 | | static char *alloc_str(int n); |
| 164 | | static void dealloc_str(void *ptr); |
| 194 | static str_t *m_zero; |
| 165 | 195 | }; |
| 166 | 196 | |
| 197 | /* objects must be destroyed using destroy above */ |
| 167 | 198 | |
| 199 | inline void *operator new(std::size_t size, pblockpool &pool, int extra = 0) throw (std::bad_alloc) |
| 200 | { |
| 201 | void *result = pool.alloc(size + extra); |
| 202 | if (result == NULL) |
| 203 | throw std::bad_alloc(); |
| 204 | return result; |
| 205 | } |
| 206 | |
| 207 | |
| 168 | 208 | #endif /* _PSTRING_H_ */ |
| 169 | 209 | |
trunk/src/emu/netlist/devices/nld_twoterm.c
| r0 | r26460 | |
| 1 | /* |
| 2 | * nld_twoterm.c |
| 3 | * |
| 4 | */ |
| 5 | |
| 6 | #include "nld_twoterm.h" |
| 7 | #include "nld_system.h" |
| 8 | |
| 9 | // ---------------------------------------------------------------------------------------- |
| 10 | // nld_twoterm |
| 11 | // ---------------------------------------------------------------------------------------- |
| 12 | |
| 13 | NETLIB_START(twoterm) |
| 14 | { |
| 15 | } |
| 16 | |
| 17 | NETLIB_UPDATE(twoterm) |
| 18 | { |
| 19 | /* only called if connected to a rail net ==> notify the solver to recalculate */ |
| 20 | netlist().solver()->schedule(); |
| 21 | } |
| 22 | |
| 23 | // ---------------------------------------------------------------------------------------- |
| 24 | // nld_R |
| 25 | // ---------------------------------------------------------------------------------------- |
| 26 | |
| 27 | NETLIB_START(R) |
| 28 | { |
| 29 | register_terminal("1", m_P); |
| 30 | register_terminal("2", m_N); |
| 31 | |
| 32 | register_param("R", m_R, NETLIST_GMIN); |
| 33 | } |
| 34 | |
| 35 | NETLIB_UPDATE_PARAM(R) |
| 36 | { |
| 37 | m_g = 1.0 / m_R.Value(); |
| 38 | } |
| 39 | |
| 40 | NETLIB_UPDATE(R) |
| 41 | { |
| 42 | NETLIB_NAME(twoterm)::update(); |
| 43 | } |
| 44 | |
| 45 | // ---------------------------------------------------------------------------------------- |
| 46 | // nld_C |
| 47 | // ---------------------------------------------------------------------------------------- |
| 48 | |
| 49 | NETLIB_START(C) |
| 50 | { |
| 51 | register_terminal("1", m_P); |
| 52 | register_terminal("2", m_N); |
| 53 | |
| 54 | register_param("C", m_C, NETLIST_GMIN); |
| 55 | } |
| 56 | |
| 57 | NETLIB_UPDATE_PARAM(C) |
| 58 | { |
| 59 | // set to some very small step time for now |
| 60 | step_time(1e-9); |
| 61 | } |
| 62 | |
| 63 | NETLIB_UPDATE(C) |
| 64 | { |
| 65 | NETLIB_NAME(twoterm)::update(); |
| 66 | } |
| 67 | |
| 68 | // ---------------------------------------------------------------------------------------- |
| 69 | // nld_D |
| 70 | // ---------------------------------------------------------------------------------------- |
| 71 | |
| 72 | NETLIB_START(D) |
| 73 | { |
| 74 | register_terminal("A", m_P); |
| 75 | register_terminal("K", m_N); |
| 76 | register_param("model", m_model, ""); |
| 77 | |
| 78 | m_Vd = 0.7; |
| 79 | } |
| 80 | |
| 81 | NETLIB_UPDATE_PARAM(D) |
| 82 | { |
| 83 | m_Is = m_model.dValue("Is", 1e-15); |
| 84 | m_n = m_model.dValue("N", 1); |
| 85 | |
| 86 | m_Vt = 0.0258 * m_n; |
| 87 | |
| 88 | m_Vcrit = m_Vt * log(m_Vt / m_Is / sqrt(2.0)); |
| 89 | m_VtInv = 1.0 / m_Vt; |
| 90 | NL_VERBOSE_OUT(("VCutoff: %f\n", m_Vcrit)); |
| 91 | } |
| 92 | |
| 93 | NETLIB_UPDATE(D) |
| 94 | { |
| 95 | NETLIB_NAME(twoterm)::update(); |
| 96 | } |
trunk/src/emu/netlist/devices/nld_twoterm.h
| r0 | r26460 | |
| 1 | // license:GPL-2.0+ |
| 2 | // copyright-holders:Couriersud |
| 3 | /* |
| 4 | * nld_twoterm.h |
| 5 | * |
| 6 | * Devices with two terminals ... |
| 7 | * |
| 8 | * |
| 9 | * (k) |
| 10 | * +-----T-----+ |
| 11 | * | | | |
| 12 | * | +--+--+ | |
| 13 | * | | | | |
| 14 | * | R | | |
| 15 | * | R | | |
| 16 | * | R I | |
| 17 | * | | I | Device n |
| 18 | * | V+ I | |
| 19 | * | V | | |
| 20 | * | V- | | |
| 21 | * | | | | |
| 22 | * | +--+--+ | |
| 23 | * | | | |
| 24 | * +-----T-----+ |
| 25 | * (l) |
| 26 | * |
| 27 | * This is a resistance in series to a voltage source and paralleled by a current source. |
| 28 | * This is suitable to model voltage sources, current sources, resistors, capacitors, |
| 29 | * inductances and diodes. |
| 30 | * |
| 31 | */ |
| 32 | |
| 33 | #ifndef NLD_TWOTERM_H_ |
| 34 | #define NLD_TWOTERM_H_ |
| 35 | |
| 36 | #include "../nl_base.h" |
| 37 | |
| 38 | // ---------------------------------------------------------------------------------------- |
| 39 | // Macros |
| 40 | // ---------------------------------------------------------------------------------------- |
| 41 | |
| 42 | #define NETDEV_R(_name, _R) \ |
| 43 | NET_REGISTER_DEV(R, _name) \ |
| 44 | NETDEV_PARAMI(_name, R, _R) |
| 45 | |
| 46 | #define NETDEV_C(_name, _C) \ |
| 47 | NET_REGISTER_DEV(C, _name) \ |
| 48 | NETDEV_PARAMI(_name, C, _C) |
| 49 | |
| 50 | /* Generic Diode */ |
| 51 | #define NETDEV_D(_name, _model) \ |
| 52 | NET_REGISTER_DEV(D, _name) \ |
| 53 | NETDEV_PARAMI(_name, model, _model) |
| 54 | |
| 55 | #define NETDEV_1N914(_name) NETDEV_D(_name, "Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon") |
| 56 | |
| 57 | // ---------------------------------------------------------------------------------------- |
| 58 | // Implementation |
| 59 | // ---------------------------------------------------------------------------------------- |
| 60 | |
| 61 | // ---------------------------------------------------------------------------------------- |
| 62 | // nld_twoterm |
| 63 | // ---------------------------------------------------------------------------------------- |
| 64 | |
| 65 | class nld_twoterm : public netlist_device_t |
| 66 | { |
| 67 | public: |
| 68 | nld_twoterm() |
| 69 | : netlist_device_t(), m_g(0.0), m_V(0.0), m_I(0.0) { } |
| 70 | |
| 71 | netlist_terminal_t m_P; |
| 72 | netlist_terminal_t m_N; |
| 73 | |
| 74 | protected: |
| 75 | virtual void start(); |
| 76 | |
| 77 | virtual NETLIB_UPDATE_TERMINALS() |
| 78 | { |
| 79 | m_P.m_g = m_N.m_g = m_g; |
| 80 | m_N.m_Idr = (m_P.net().Q_Analog() - m_V) * m_g + m_I; |
| 81 | m_P.m_Idr = (m_N.net().Q_Analog() + m_V) * m_g - m_I; |
| 82 | //printf("%f %f %f %f\n", m_N.m_Idr, m_P.m_Idr, m_N.net().Q_Analog(), m_P.net().Q_Analog()); |
| 83 | } |
| 84 | |
| 85 | ATTR_HOT ATTR_ALIGN void update(); |
| 86 | |
| 87 | double m_g; // conductance |
| 88 | double m_V; // internal voltage source |
| 89 | double m_I; // internal current source |
| 90 | private: |
| 91 | }; |
| 92 | |
| 93 | // ---------------------------------------------------------------------------------------- |
| 94 | // nld_R |
| 95 | // ---------------------------------------------------------------------------------------- |
| 96 | |
| 97 | NETLIB_DEVICE_WITH_PARAMS_DERIVED(R, twoterm, |
| 98 | netlist_param_double_t m_R; |
| 99 | |
| 100 | NETLIB_UPDATE_TERMINALS() { NETLIB_NAME(twoterm)::update_terminals(); } |
| 101 | |
| 102 | ); |
| 103 | |
| 104 | // ---------------------------------------------------------------------------------------- |
| 105 | // nld_C |
| 106 | // ---------------------------------------------------------------------------------------- |
| 107 | |
| 108 | NETLIB_DEVICE_WITH_PARAMS_DERIVED(C, twoterm, |
| 109 | |
| 110 | netlist_param_double_t m_C; |
| 111 | |
| 112 | ATTR_HOT void step_time(const double st) |
| 113 | { |
| 114 | m_g = m_P.m_g = m_N.m_g = m_C.Value() / st; |
| 115 | m_I = -m_g * (m_P.net().Q_Analog()- m_N.net().Q_Analog()); |
| 116 | } |
| 117 | |
| 118 | ); |
| 119 | |
| 120 | // ---------------------------------------------------------------------------------------- |
| 121 | // nld_D |
| 122 | // ---------------------------------------------------------------------------------------- |
| 123 | |
| 124 | NETLIB_DEVICE_WITH_PARAMS_DERIVED(D, twoterm, |
| 125 | |
| 126 | netlist_param_multi_t m_model; |
| 127 | |
| 128 | double m_Vt; |
| 129 | double m_Is; |
| 130 | double m_n; |
| 131 | |
| 132 | double m_VtInv; |
| 133 | double m_Vcrit; |
| 134 | double m_Vd; |
| 135 | |
| 136 | NETLIB_UPDATE_TERMINALS() |
| 137 | { |
| 138 | const double nVd = m_P.net().Q_Analog()- m_N.net().Q_Analog(); |
| 139 | |
| 140 | //FIXME: Optimize cutoff case |
| 141 | m_Vd = (nVd > m_Vcrit) ? m_Vd + log((nVd - m_Vd) * m_VtInv + 1.0) * m_Vt : nVd; |
| 142 | |
| 143 | const double eVDVt = exp(m_Vd * m_VtInv); |
| 144 | const double Id = m_Is * (eVDVt - 1.0); |
| 145 | |
| 146 | m_g = m_Is * m_VtInv * eVDVt; |
| 147 | |
| 148 | m_I = (Id - m_Vd * m_g); |
| 149 | //printf("Vd: %f %f %f %f\n", m_Vd, m_g, Id, m_I); |
| 150 | |
| 151 | nld_twoterm::update_terminals(); |
| 152 | } |
| 153 | |
| 154 | private: |
| 155 | ); |
| 156 | |
| 157 | |
| 158 | #endif /* NLD_TWOTERM_H_ */ |
trunk/src/emu/netlist/devices/nld_system.h
| r26459 | r26460 | |
| 33 | 33 | #define NETDEV_SOLVER(_name) \ |
| 34 | 34 | NET_REGISTER_DEV(solver, _name) |
| 35 | 35 | |
| 36 | | // ---------------------------------------------------------------------------------------- |
| 37 | | // 2 terminal devices |
| 38 | | // ---------------------------------------------------------------------------------------- |
| 39 | | |
| 40 | | #define NETDEV_R(_name, _R) \ |
| 41 | | NET_REGISTER_DEV(R, _name) \ |
| 42 | | NETDEV_PARAMI(_name, R, _R) |
| 43 | | |
| 44 | | #define NETDEV_C(_name, _C) \ |
| 45 | | NET_REGISTER_DEV(C, _name) \ |
| 46 | | NETDEV_PARAMI(_name, C, _C) |
| 47 | | |
| 48 | | /* Generic Diode */ |
| 49 | | #define NETDEV_D(_name, _model) \ |
| 50 | | NET_REGISTER_DEV(D, _name) \ |
| 51 | | NETDEV_PARAMI(_name, model, _model) |
| 52 | | |
| 53 | | #define NETDEV_1N914(_name) NETDEV_D(_name, "Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon") |
| 54 | | |
| 55 | 36 | // .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon) |
| 56 | 37 | |
| 57 | 38 | // ---------------------------------------------------------------------------------------- |
| r26459 | r26460 | |
| 165 | 146 | }; |
| 166 | 147 | |
| 167 | 148 | |
| 168 | | // ---------------------------------------------------------------------------------------- |
| 169 | | // nld_twoterm |
| 170 | | // ---------------------------------------------------------------------------------------- |
| 171 | 149 | |
| 172 | | class nld_twoterm : public netlist_device_t |
| 173 | | { |
| 174 | | public: |
| 175 | | nld_twoterm() |
| 176 | | : netlist_device_t(), m_g(0.0), m_V(0.0), m_I(0.0) |
| 177 | | { |
| 178 | | } |
| 179 | | |
| 180 | | netlist_terminal_t m_P; |
| 181 | | netlist_terminal_t m_N; |
| 182 | | |
| 183 | | protected: |
| 184 | | virtual void start() |
| 185 | | { |
| 186 | | } |
| 187 | | |
| 188 | | ATTR_HOT ATTR_ALIGN virtual void update_terminals() |
| 189 | | { |
| 190 | | m_P.m_g = m_N.m_g = m_g; |
| 191 | | m_N.m_Idr = (m_P.net().Q_Analog() - m_V) * m_g + m_I; |
| 192 | | m_P.m_Idr = (m_N.net().Q_Analog() + m_V) * m_g - m_I; |
| 193 | | //printf("%f %f %f %f\n", m_N.m_Idr, m_P.m_Idr, m_N.net().Q_Analog(), m_P.net().Q_Analog()); |
| 194 | | } |
| 195 | | |
| 196 | | ATTR_HOT ATTR_ALIGN virtual void update() |
| 197 | | { |
| 198 | | /* only called if connected to a rail net ==> notify the solver to recalculate */ |
| 199 | | netlist().solver()->schedule(); |
| 200 | | } |
| 201 | | |
| 202 | | double m_g; // conductance |
| 203 | | double m_V; // internal voltage source |
| 204 | | double m_I; // internal current source |
| 205 | | private: |
| 206 | | }; |
| 207 | | |
| 208 | | class nld_R : public nld_twoterm |
| 209 | | { |
| 210 | | public: |
| 211 | | nld_R() |
| 212 | | : nld_twoterm() |
| 213 | | { |
| 214 | | } |
| 215 | | |
| 216 | | netlist_param_double_t m_R; |
| 217 | | |
| 218 | | protected: |
| 219 | | void start() |
| 220 | | { |
| 221 | | register_terminal("1", m_P); |
| 222 | | register_terminal("2", m_N); |
| 223 | | |
| 224 | | register_param("R", m_R, NETLIST_GMIN); |
| 225 | | } |
| 226 | | |
| 227 | | virtual void update_param() |
| 228 | | { |
| 229 | | m_g = 1.0 / m_R.Value(); |
| 230 | | } |
| 231 | | |
| 232 | | private: |
| 233 | | }; |
| 234 | | |
| 235 | | class nld_C : public nld_twoterm |
| 236 | | { |
| 237 | | public: |
| 238 | | nld_C() |
| 239 | | : nld_twoterm() |
| 240 | | { |
| 241 | | } |
| 242 | | |
| 243 | | netlist_param_double_t m_C; |
| 244 | | |
| 245 | | protected: |
| 246 | | void start() |
| 247 | | { |
| 248 | | register_terminal("1", m_P); |
| 249 | | register_terminal("2", m_N); |
| 250 | | |
| 251 | | register_param("C", m_C, NETLIST_GMIN); |
| 252 | | } |
| 253 | | |
| 254 | | virtual void update_param() |
| 255 | | { |
| 256 | | // set to some very small step time for now |
| 257 | | step_time(1e-9); |
| 258 | | } |
| 259 | | |
| 260 | | ATTR_HOT virtual void step_time(const double st) |
| 261 | | { |
| 262 | | m_g = m_P.m_g = m_N.m_g = m_C.Value() / st; |
| 263 | | m_I = -m_g * (m_P.net().Q_Analog()- m_N.net().Q_Analog()); |
| 264 | | } |
| 265 | | private: |
| 266 | | }; |
| 267 | | |
| 268 | | class nld_D : public nld_twoterm |
| 269 | | { |
| 270 | | public: |
| 271 | | nld_D() |
| 272 | | : nld_twoterm() |
| 273 | | { |
| 274 | | } |
| 275 | | |
| 276 | | netlist_param_multi_t m_model; |
| 277 | | |
| 278 | | double m_Vt; |
| 279 | | double m_Is; |
| 280 | | double m_n; |
| 281 | | |
| 282 | | double m_VtInv; |
| 283 | | double m_Vcrit; |
| 284 | | double m_Vd; |
| 285 | | |
| 286 | | protected: |
| 287 | | void start() |
| 288 | | { |
| 289 | | register_terminal("A", m_P); |
| 290 | | register_terminal("K", m_N); |
| 291 | | register_param("model", m_model, ""); |
| 292 | | |
| 293 | | m_Vd = 0.7; |
| 294 | | } |
| 295 | | |
| 296 | | virtual void update_param() |
| 297 | | { |
| 298 | | m_Is = m_model.dValue("Is", 1e-15); |
| 299 | | m_n = m_model.dValue("N", 1); |
| 300 | | |
| 301 | | m_Vt = 0.0258 * m_n; |
| 302 | | |
| 303 | | m_Vcrit = m_Vt * log(m_Vt / m_Is / sqrt(2.0)); |
| 304 | | m_VtInv = 1.0 / m_Vt; |
| 305 | | NL_VERBOSE_OUT(("VCutoff: %f\n", m_Vcrit)); |
| 306 | | } |
| 307 | | |
| 308 | | ATTR_HOT ATTR_ALIGN virtual void update_terminals() |
| 309 | | { |
| 310 | | const double nVd = m_P.net().Q_Analog()- m_N.net().Q_Analog(); |
| 311 | | |
| 312 | | //FIXME: Optimize cutoff case |
| 313 | | m_Vd = (nVd > m_Vcrit) ? m_Vd + log((nVd - m_Vd) * m_VtInv + 1.0) * m_Vt : nVd; |
| 314 | | |
| 315 | | const double eVDVt = exp(m_Vd * m_VtInv); |
| 316 | | const double Id = m_Is * (eVDVt - 1.0); |
| 317 | | |
| 318 | | m_g = m_Is * m_VtInv * eVDVt; |
| 319 | | |
| 320 | | m_I = (Id - m_Vd * m_g); |
| 321 | | //printf("Vd: %f %f %f %f\n", m_Vd, m_g, Id, m_I); |
| 322 | | |
| 323 | | nld_twoterm::update_terminals(); |
| 324 | | } |
| 325 | | |
| 326 | | private: |
| 327 | | }; |
| 328 | | |
| 329 | 150 | #endif /* NLD_SYSTEM_H_ */ |
trunk/src/emu/netlist/pstring.c
| r26459 | r26460 | |
| 6 | 6 | #include "pstring.h" |
| 7 | 7 | #include <cstdio> |
| 8 | 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 | 9 | |
| 13 | | #define IMMEDIATE_MODE (1) |
| 10 | pblockpool *pstring::m_pool = new pblockpool; |
| 11 | pstring::str_t *pstring::m_zero = new(*pstring::m_pool, 0) pstring::str_t(0); |
| 12 | |
| 13 | #define IMMEDIATE_MODE (0) |
| 14 | 14 | #define DEBUG_MODE (0) |
| 15 | 15 | |
| 16 | 16 | pstring::~pstring() |
| r26459 | r26460 | |
| 18 | 18 | sfree(m_ptr); |
| 19 | 19 | } |
| 20 | 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 | 21 | void pstring::pcat(const char *s) |
| 35 | 22 | { |
| 36 | 23 | int slen = strlen(s); |
| r26459 | r26460 | |
| 101 | 88 | |
| 102 | 89 | void pstring::sfree(str_t *s) |
| 103 | 90 | { |
| 104 | | s->reference_count--; |
| 105 | | if (s->reference_count == 0) |
| 106 | | dealloc_str(s); |
| 91 | s->m_ref_count--; |
| 92 | if (s->m_ref_count == 0) |
| 93 | m_pool->dealloc(s); |
| 107 | 94 | } |
| 108 | 95 | |
| 109 | 96 | pstring::str_t *pstring::salloc(int n) |
| 110 | 97 | { |
| 111 | | str_t *ret = (str_t *) alloc_str(sizeof(str_t) + n + 1); |
| 112 | | ret->reference_count = 1; |
| 113 | | ret->m_len = n; |
| 114 | | ret->m_str[0] = 0; |
| 98 | str_t *ret = new(*m_pool, n) str_t(n); |
| 115 | 99 | return ret; |
| 116 | | //std::printf("old string %d <%s> %p %p\n", n, old, old, m_ptr); |
| 117 | 100 | } |
| 118 | 101 | |
| 119 | 102 | pstring pstring::sprintf(const char *format, ...) |
| r26459 | r26460 | |
| 125 | 108 | return ret; |
| 126 | 109 | } |
| 127 | 110 | |
| 128 | | char *pstring::alloc_str(int n) |
| 111 | |
| 112 | void pstring::resetmem() |
| 129 | 113 | { |
| 114 | // Release the 0 string |
| 115 | if (m_zero != NULL) |
| 116 | sfree(m_zero); |
| 117 | m_zero = NULL; |
| 118 | m_pool->m_shutdown = true; |
| 119 | m_pool->resetmem(); |
| 120 | } |
| 121 | |
| 122 | // ---------------------------------------------------------------------------------------- |
| 123 | // block allocation pool |
| 124 | // ---------------------------------------------------------------------------------------- |
| 125 | |
| 126 | |
| 127 | pblockpool::pblockpool() |
| 128 | : m_shutdown(false) |
| 129 | , m_first(NULL) |
| 130 | , m_blocksize((DEBUG_MODE) ? 0 : 16384) |
| 131 | , m_align(8) |
| 132 | { |
| 133 | } |
| 134 | |
| 135 | |
| 136 | void *pblockpool::alloc(const std::size_t n) |
| 137 | { |
| 130 | 138 | if (IMMEDIATE_MODE) |
| 131 | 139 | return (char *) malloc(n); |
| 132 | 140 | else |
| 133 | 141 | { |
| 134 | | int min_alloc = MAX((DEBUG_MODE) ? 0 : 8192, n+sizeof(memblock)); |
| 142 | int min_alloc = MAX(m_blocksize, n+sizeof(memblock)); |
| 135 | 143 | char *ret = NULL; |
| 136 | | |
| 144 | int memsize = ((n + m_align - 1) / m_align) * m_align; |
| 137 | 145 | //std::printf("m_first %p\n", m_first); |
| 138 | 146 | for (memblock *p = m_first; p != NULL && ret == NULL; p = p->next) |
| 139 | 147 | { |
| 140 | | if (p->remaining > n) |
| 148 | if (p->remaining > memsize) |
| 141 | 149 | { |
| 142 | 150 | ret = p->cur; |
| 143 | | p->cur += n; |
| 151 | p->cur += memsize; |
| 144 | 152 | p->allocated += 1; |
| 145 | | p->remaining -= n; |
| 153 | p->remaining -= memsize; |
| 146 | 154 | } |
| 147 | 155 | } |
| 148 | 156 | |
| r26459 | r26460 | |
| 157 | 165 | //std::printf("allocated block size %d\n", p->size); |
| 158 | 166 | |
| 159 | 167 | ret = p->cur; |
| 160 | | p->cur += n; |
| 168 | p->cur += memsize; |
| 161 | 169 | p->allocated += 1; |
| 162 | | p->remaining -= n; |
| 170 | p->remaining -= memsize; |
| 163 | 171 | |
| 164 | 172 | m_first = p; |
| 165 | 173 | } |
| r26459 | r26460 | |
| 168 | 176 | } |
| 169 | 177 | } |
| 170 | 178 | |
| 171 | | void pstring::dealloc_str(void *ptr) |
| 179 | void pblockpool::dealloc(void *ptr) |
| 172 | 180 | { |
| 173 | 181 | if (IMMEDIATE_MODE) |
| 174 | 182 | free(ptr); |
| r26459 | r26460 | |
| 188 | 196 | p->cur = &p->data[0]; |
| 189 | 197 | } |
| 190 | 198 | // shutting down ? |
| 191 | | if (m_zero == NULL) |
| 199 | if (m_shutdown) |
| 192 | 200 | resetmem(); // try to free blocks |
| 193 | 201 | return; |
| 194 | 202 | } |
| r26459 | r26460 | |
| 197 | 205 | } |
| 198 | 206 | } |
| 199 | 207 | |
| 200 | | void pstring::resetmem() |
| 208 | void pblockpool::resetmem() |
| 201 | 209 | { |
| 202 | 210 | if (!IMMEDIATE_MODE) |
| 203 | 211 | { |
| r26459 | r26460 | |
| 205 | 213 | int totalblocks = 0; |
| 206 | 214 | int freedblocks = 0; |
| 207 | 215 | |
| 208 | | // Release the 0 string |
| 209 | | if (m_zero != NULL) sfree(m_zero); |
| 210 | | m_zero = NULL; |
| 211 | | |
| 212 | 216 | while (*p != NULL) |
| 213 | 217 | { |
| 214 | 218 | totalblocks++; |
| r26459 | r26460 | |
| 223 | 227 | } |
| 224 | 228 | else |
| 225 | 229 | { |
| 226 | | if (DEBUG_MODE) |
| 227 | | std::printf("Allocated: <%s>\n", ((str_t *)(&(*p)->data[0]))->str()); |
| 230 | //if (DEBUG_MODE) |
| 231 | // std::printf("Allocated: <%s>\n", ((str_t *)(&(*p)->data[0]))->str()); |
| 228 | 232 | |
| 229 | 233 | p = next; |
| 230 | 234 | } |