summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/p2000t_cas.cpp321
-rw-r--r--src/lib/formats/p2000t_cas.h19
-rw-r--r--src/lib/netlist/analog/nld_generic_models.h1
-rw-r--r--src/lib/netlist/core/setup.h19
-rw-r--r--src/lib/netlist/devices/net_lib.h2
-rwxr-xr-xsrc/lib/netlist/generated/nlm_modules_lib.cpp4
-rw-r--r--src/lib/netlist/generated/static_solvers.cpp8
-rw-r--r--src/lib/netlist/macro/modules/nlmod_ICL8038_DIP.cpp61
-rw-r--r--src/lib/netlist/macro/modules/nlmod_NE556_DIP.cpp24
-rw-r--r--src/lib/netlist/macro/nlm_base_lib.cpp21
-rw-r--r--src/lib/netlist/nl_base.cpp4
-rw-r--r--src/lib/netlist/nl_parser.cpp22
-rw-r--r--src/lib/netlist/nl_parser.h23
-rw-r--r--src/lib/netlist/nl_setup.cpp24
-rw-r--r--src/lib/netlist/nl_setup.h3
-rw-r--r--src/lib/netlist/nltypes.h16
-rw-r--r--src/lib/netlist/plib/pexception.h4
-rw-r--r--src/lib/netlist/plib/ptokenizer.h46
-rw-r--r--src/lib/netlist/plib/ptypes.h24
-rw-r--r--src/lib/netlist/prg/nltool.cpp4
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp2
21 files changed, 570 insertions, 82 deletions
diff --git a/src/lib/formats/p2000t_cas.cpp b/src/lib/formats/p2000t_cas.cpp
new file mode 100644
index 00000000000..e3351dc99dc
--- /dev/null
+++ b/src/lib/formats/p2000t_cas.cpp
@@ -0,0 +1,321 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+
+#include <cassert>
+
+#include "cassimg.h"
+#include "p2000t_cas.h"
+#include <ostream>
+
+// This code will reproduce the timing of a P2000 mini cassette tape.
+constexpr double P2000_CLOCK_PERIOD = 0.000084;
+constexpr double P2000_BOT_GAP = 1;
+constexpr double P2000_BOB_GAP = 0.515;
+constexpr double P2000_MARK_GAP = 0.085;
+constexpr double P2000_END_GAP = 0.155;
+constexpr double P2000_EOT_GAP = 1.8;
+constexpr int P2000_HIGH = 0x7FFFFFFF;
+constexpr int P2000_LOW = -1 * 0x7FFFFFFF;
+
+
+#define CHR(x) \
+ err = (x); \
+ if (err != cassette_image::error::SUCCESS) \
+ return err;
+
+/*
+Here's a description on how the P2000t stores data on tape.
+
+## Tape Format
+
+Each track (or side) of a cassette is divided into 40 block of information. A
+file may comprise between 1 and 40 blocks, depending on its length.
+
+## Blocks, Gaps, Marks and Records
+
+At the start of the tape is an area of clear (erased) tape, the BOT (beginning
+of tape) gap; to read pas this gap takes approximately 1 second. After this, the
+first block starts, followed directly by the second, third and so on. After the
+last block on the track comes the EOT (end of tape) gap; if all 40 blocks on the
+tracks are used, this area of erased tape has a length equivalent to 1.8 seconds
+of reading time.
+
+ | BOT | BLOCK 1 | BLOCK 2 | BLOCK ... | EOT |
+
+### BLOCK
+
+Each tape block is made up of five sections of tape:
+
+| START GAP | MARK | MARK GAP | DATA RECORD | END GAP |
+
+- Start gap: A section of erased tape separating the start of one block from the
+ end of the previous block. This takes approx. 515ms to read over.
+- Mark: Four bytes of recorded information (described below)
+- Mark Gap: A section of erased tape separating the mark from the data record;
+ length about 85ms.
+- Data Record: 1056 bytes of recorded data (described below)
+- End Gap: A section of erased tape of around 155 ms.
+
+### MARK
+
+The mark is made up of four bytes with the following bit patterns:
+
+ - preamble syncronization pattern (0xAA)
+ - 0000 0000 (0x00)
+ - 0000 0000 (0x00)
+ - postamble syncronization pattern (0xAA)
+
+The function of the synchronisation byte is to make sure the RDC clock is set
+properly.
+
+### DATA RECORD
+
+The data record contains the information which has been written onto the tape.
+It compromises five sections:
+
+| sync byte | header | data | check sum | post sync |
+
+- sync byte: Preamble synchronisation pattern 0xAA
+- header: 32 bytes which specify the contents and type of the data section. (See below)
+- data section: 1024 bytes of information.
+- checksum: 2 bytes that contain checksum
+- post sync: 0xAA
+
+### HEADER
+
+See the struct declaration below for details on what is contained.
+
+### DATA
+
+The data section consists of 1024 bytes written in serial form, least
+significant byte first.
+
+### Checksum
+
+The checksum is only calculated for the header and data section. The algorithm
+is not documented, an implementation can be found below.
+*/
+
+// Specifies the type of data stored in the tape block
+enum P2000_File_Type : uint8_t
+{
+ Basic = 'B',
+ Program = 'P',
+ Viewdata = 'V',
+ WordProcessing = 'W',
+ Other = 'O',
+};
+
+// Represents the internal code for data, differrent codes are used in different countries
+// only relevant when P2000_File_Type is Program.
+enum P2000_Data_Type : uint8_t
+{
+ German = 'D',
+ Swedish = 'S',
+ Dutch_English = 'U',
+};
+
+
+// This is the 32 byte header definition used by the P2000, it is mainly
+// here for documentation.
+struct P2000T_Header
+{
+ // Starting address in ram where data should go. This address is supplied by
+ // the application program when calling the monitor cassette routine to write
+ // the data on cassette in the first place.
+ uint16_t data_transfer_address;
+ // Total # of bytes which make up the file (can be spread over many blocks).
+ // The monitor uses this to determine how many blocks to read.
+ uint16_t file_length;
+ // # bytes in this record that are actually used. For example if this is 256
+ // only 256 bytes will be loaded in ram
+ uint16_t data_section_length;
+ // The eight character file name identifies the file to which the record
+ // belongs; it will be the same in all records making up the file. Each record
+ // except the first is considered an extension.
+ char file_name[8];
+ // Addition file extension.
+ char ext[3];
+ // This file type specifies the type of data stored.
+ P2000_File_Type file_type;
+ // Code and region information.
+ P2000_Data_Type data_code;
+ // Start address where program should start. (if type = Program)
+ uint16_t start_addr;
+ // Address in ram where the program should load (if type = Program)
+ uint16_t load_addr;
+ // Unused.
+ char reserved[8];
+ // Record number (i.e. which block)
+ uint8_t rec_nr;
+};
+
+std::ostream &operator<<(std::ostream &os, P2000T_Header const &hdr)
+{
+ return os << "File: " << std::string(hdr.file_name, 8) << '.'
+ << std::string(hdr.ext, 3) << " " << hdr.file_length;
+}
+
+static cassette_image::error p2000t_cas_identify(cassette_image *cass, struct CassetteOptions *opts)
+{
+ opts->bits_per_sample = 32;
+ opts->channels = 1;
+ opts->sample_frequency = 44100;
+ return cassette_image::error::SUCCESS;
+}
+
+uint16_t rotr16a(uint16_t x, uint16_t n)
+{
+ return (x >> n) | (x << (16 - n));
+}
+
+void update_chksum(uint16_t *de, bool bit)
+{
+ // Reverse engineered from monitor.rom
+ // code is at: [0x07ac, 0x07c5]
+ uint8_t e = *de & 0xff;
+ uint8_t d = (*de >> 8) & 0xff;
+ e = e ^ (bit ? 1 : 0);
+ if (e & 0x01)
+ {
+ e = e ^ 2;
+ d = d ^ 0x40;
+ }
+ else
+ {
+ d = d ^ 0x00;
+ }
+ *de = rotr16a((d << 8) | e, 1);
+}
+
+/*
+ A transition on a clock boundary from low to high is a 1.
+ A transition on a clock boundary from high to low is a 0
+ An intermediate transition halfway between the clock boundary
+ can occur when there are consecutive 0s or 1s. See the example
+ below where the clock is marked by a |
+
+
+ 1 0 1 1 0 0
+ RDA: _|----|____|--__|----|__--|__--
+ RDC: _|-___|-___|-___|-___|-___|-___
+ ^ ^
+ |-- clock signal |-- intermediate transition.
+
+ This signal can be written by a simple algorithm where the first bit
+ is always false (transition to low, half clock). Now only one bit is needed
+ to determine what the next partial clock should look like.
+
+ This works because we are always guaranteed that a block starts with 0xAA,
+ and hence will ALWAYS find a signal like this on tape: _-- (low, high, high)
+ after a gap. This is guaranteed when the tape is moving forward as well as
+ backwards.
+*/
+cassette_image::error p2000t_put_bit(cassette_image *cass, double *time_index, bool bit)
+{
+ const int channel = 0;
+ cassette_image::error err = cassette_image::error::SUCCESS;
+ CHR(cassette_put_sample(cass, channel, *time_index, P2000_CLOCK_PERIOD, bit ? P2000_HIGH : P2000_LOW));
+ *time_index += P2000_CLOCK_PERIOD;
+
+ CHR(cassette_put_sample(cass, channel, *time_index, P2000_CLOCK_PERIOD, bit ? P2000_LOW : P2000_HIGH));
+ *time_index += P2000_CLOCK_PERIOD;
+ return err;
+}
+
+// Store byte of data, updating the checksum
+cassette_image::error p2000t_put_byte(cassette_image *cass, double *time_index, uint16_t *chksum, uint8_t byte)
+{
+ cassette_image::error err = cassette_image::error::SUCCESS;
+ for (int i = 0; i < 8 && err == cassette_image::error::SUCCESS; i++)
+ {
+ update_chksum(chksum, util::BIT(byte, i));
+ CHR(p2000t_put_bit(cass, time_index, util::BIT(byte, i)));
+ }
+ return err;
+}
+
+// Store a sequence of bytes, updating the checksum
+cassette_image::error p2000t_put_bytes(cassette_image *cass, double *time_index, uint16_t *chksum, const uint8_t *bytes, const uint16_t cByte)
+{
+ cassette_image::error err = cassette_image::error::SUCCESS;
+ for (int i = 0; i < cByte && err == cassette_image::error::SUCCESS; i++)
+ {
+ CHR(p2000t_put_byte(cass, time_index, chksum, bytes[i]));
+ }
+ return err;
+}
+
+// Insert time seconds of silence.
+cassette_image::error p2000t_silence(cassette_image *cassette,
+double *time_index,
+double time)
+{
+ auto err = cassette_put_sample(cassette, 0, *time_index, time, 0);
+ *time_index += time;
+ return err;
+}
+
+static cassette_image::error p2000t_cas_load(cassette_image *cassette)
+{
+ cassette_image::error err = cassette_image::error::SUCCESS;
+ uint64_t image_size = cassette_image_size(cassette);
+ constexpr int CAS_BLOCK = 1280;
+
+ /*
+ The cas format is pretty simple. it consists of a sequence of blocks,
+ where a block consists of the following:
+
+ [0-256] P2000 memory address 0x6000 - 0x6100
+ .... Nonsense (keyboard status etc.)
+ 0x30 P200T_Header
+ 0x50
+ ... Nonsense..
+ [0-1024] Data block
+
+ This means that one block gets stored in 1280 bytes.
+ */
+ if (image_size % CAS_BLOCK != 0)
+ {
+ return cassette_image::error::INVALID_IMAGE;
+ }
+
+ uint8_t block[CAS_BLOCK];
+ constexpr uint8_t BLOCK_MARK[4] = { 0xAA, 0x00, 0x00, 0xAA };
+ auto blocks = image_size / CAS_BLOCK;
+ double time_idx = 0;
+
+ // Beginning of tape marker
+ CHR(p2000t_silence(cassette, &time_idx, P2000_BOT_GAP));
+ for (int i = 0; i < blocks; i++)
+ {
+ uint16_t crc = 0, unused = 0;
+ cassette_image_read(cassette, &block, CAS_BLOCK * i, CAS_BLOCK);
+
+ // Insert sync header.. 0xAA, 0x00, 0x00, 0xAA
+ CHR(p2000t_silence(cassette, &time_idx, P2000_BOB_GAP));
+ CHR(p2000t_put_bytes(cassette, &time_idx, &unused, BLOCK_MARK, ARRAY_LENGTH(BLOCK_MARK)));
+ CHR(p2000t_silence(cassette, &time_idx, P2000_MARK_GAP));
+
+ // Insert data block
+ CHR(p2000t_put_byte(cassette, &time_idx, &unused, 0xAA));
+ CHR(p2000t_put_bytes(cassette, &time_idx, &crc, block + 0x30, 32));
+ CHR(p2000t_put_bytes(cassette, &time_idx, &crc, block + 256, 1024));
+ CHR(p2000t_put_bytes(cassette, &time_idx, &unused, ( uint8_t * )&crc, 2));
+ CHR(p2000t_put_byte(cassette, &time_idx, &unused, 0xAA));
+
+ // Block finished.
+ CHR(p2000t_silence(cassette, &time_idx, P2000_END_GAP));
+ }
+
+ // End of tape marker
+ return p2000t_silence(cassette, &time_idx, P2000_EOT_GAP);
+}
+
+static const struct CassetteFormat p2000t_cas = {
+ "cas", p2000t_cas_identify, p2000t_cas_load, nullptr /* no save */
+};
+
+CASSETTE_FORMATLIST_START(p2000t_cassette_formats)
+CASSETTE_FORMAT(p2000t_cas)
+CASSETTE_FORMATLIST_END
diff --git a/src/lib/formats/p2000t_cas.h b/src/lib/formats/p2000t_cas.h
new file mode 100644
index 00000000000..6d63e314a33
--- /dev/null
+++ b/src/lib/formats/p2000t_cas.h
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Erwin Jansen
+/*********************************************************************
+
+ p2000t_cas.h
+
+ Format code for P2000t .cas cassette files.
+
+*********************************************************************/
+#ifndef MAME_FORMATS_P2000T_CAS_H
+#define MAME_FORMATS_P2000T_CAS_H
+
+#pragma once
+
+#include "cassimg.h"
+
+CASSETTE_FORMATLIST_EXTERN(p2000t_cassette_formats);
+
+#endif // MAME_FORMATS_P2000T_CAS_H
diff --git a/src/lib/netlist/analog/nld_generic_models.h b/src/lib/netlist/analog/nld_generic_models.h
index 781dc2a16bb..bb8adc466eb 100644
--- a/src/lib/netlist/analog/nld_generic_models.h
+++ b/src/lib/netlist/analog/nld_generic_models.h
@@ -9,7 +9,6 @@
///
#include "nl_base.h"
-//#include "../nl_setup.h"
//
// Set to 0 to use a linearized diode model in the range exceeding
diff --git a/src/lib/netlist/core/setup.h b/src/lib/netlist/core/setup.h
index 61ab79de545..8b8a49dbc34 100644
--- a/src/lib/netlist/core/setup.h
+++ b/src/lib/netlist/core/setup.h
@@ -340,25 +340,6 @@ namespace netlist
pstring m_setup_func_name;
};
- class source_token_t : public source_netlist_t
- {
- public:
- source_token_t(const pstring &name, const parser_t::token_store &store)
- : m_store(store)
- , m_name(name)
- {
- }
-
- bool parse(nlparse_t &setup, const pstring &name) override;
-
- protected:
- plib::istream_uptr stream(const pstring &name) override;
-
- private:
- parser_t::token_store m_store;
- pstring m_name;
- };
-
} // namespace netlist
diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h
index db3f9c1519d..1a8b72fcd5a 100644
--- a/src/lib/netlist/devices/net_lib.h
+++ b/src/lib/netlist/devices/net_lib.h
@@ -28,8 +28,6 @@
#define IND_P(ind) ((ind) * 1e-12)
#endif
-NETLIST_EXTERNAL(base_lib)
-
#include "../generated/nld_devinc.h"
diff --git a/src/lib/netlist/generated/nlm_modules_lib.cpp b/src/lib/netlist/generated/nlm_modules_lib.cpp
index d9fe63979d9..7f91075ac40 100755
--- a/src/lib/netlist/generated/nlm_modules_lib.cpp
+++ b/src/lib/netlist/generated/nlm_modules_lib.cpp
@@ -1,12 +1,14 @@
// license:CC0
// copyright-holders:Couriersud
-// File programmatically created Sat Sep 12 14:42:49 2020
+// File programmatically created Sun Sep 13 20:49:39 2020
#include "devices/net_lib.h"
NETLIST_START(modules_lib)
+ EXTERNAL_LIB_ENTRY(ICL8038_DIP)
+ EXTERNAL_LIB_ENTRY(NE556_DIP)
EXTERNAL_LIB_ENTRY(RTEST)
NETLIST_END()
diff --git a/src/lib/netlist/generated/static_solvers.cpp b/src/lib/netlist/generated/static_solvers.cpp
index 8c3173b98d2..367af35bbb9 100644
--- a/src/lib/netlist/generated/static_solvers.cpp
+++ b/src/lib/netlist/generated/static_solvers.cpp
@@ -1,5 +1,7 @@
#include "plib/pdynlib.h"
+#if !defined(__EMSCRIPTEN__)
+
// elim
static void nl_gcr_11c2ae166b240b6e_10_double_double(double * __restrict V, const double * __restrict go, const double * __restrict gt, const double * __restrict Idr, const double * const * __restrict cnV)
@@ -72411,8 +72413,12 @@ static void nl_gcr_feae15b80dd73620_7_double_double(double * __restrict V, const
V[0] = (RHS0 - tmp0) / m_A0;
}
+#endif
+
extern const plib::dynlib_static_sym nl_static_solver_syms[];
const plib::dynlib_static_sym nl_static_solver_syms[] = {
+#if !defined(__EMSCRIPTEN__)
+
// elim
{"nl_gcr_11c2ae166b240b6e_10_double_double", reinterpret_cast<void *>(&nl_gcr_11c2ae166b240b6e_10_double_double)},
// tankbatt
@@ -72809,5 +72815,7 @@ const plib::dynlib_static_sym nl_static_solver_syms[] = {
{"nl_gcr_fd2796828f1ebd00_36_double_double", reinterpret_cast<void *>(&nl_gcr_fd2796828f1ebd00_36_double_double)},
// starfire
{"nl_gcr_feae15b80dd73620_7_double_double", reinterpret_cast<void *>(&nl_gcr_feae15b80dd73620_7_double_double)},
+#endif
+
{"", nullptr}
};
diff --git a/src/lib/netlist/macro/modules/nlmod_ICL8038_DIP.cpp b/src/lib/netlist/macro/modules/nlmod_ICL8038_DIP.cpp
new file mode 100644
index 00000000000..05a4d300099
--- /dev/null
+++ b/src/lib/netlist/macro/modules/nlmod_ICL8038_DIP.cpp
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+
+#include "devices/net_lib.h"
+
+//
+// ICL8038 is broadly similar to a 566 VCO, and can be simulated partially as such.
+//
+
+NETLIST_START(ICL8038_DIP)
+ VCVS(VI, 1)
+ CCCS(CI1, -1)
+ CCCS(CI2, 2)
+ SYS_COMPD(COMP)
+ SYS_DSW2(SW)
+ VCVS(VO, 1)
+ RES(R_SHUNT, RES_R(50))
+
+ PARAM(VO.RO, 50)
+ PARAM(COMP.MODEL, "FAMILY(TYPE=CUSTOM IVL=0.16 IVH=0.4 OVL=0.01 OVH=0.01 ORL=50 ORH=50)")
+ PARAM(SW.GOFF, 0) // This has to be zero to block current sources
+
+ NET_C(VI.OP, CI1.IN, CI2.IN)
+ NET_C(CI1.OP, VO.IP)
+ NET_C(COMP.Q, SW.I)
+ NET_C(CI2.OP, SW.2)
+ NET_C(COMP.VCC, R_SHUNT.1)
+ NET_C(SW.1, R_SHUNT.2)
+ NET_C(SW.3, VO.IP)
+ NET_C(VO.OP, COMP.IN)
+
+ // Avoid singular Matrix due to G=0 switch
+ RES(RX1, 1e10)
+ RES(RX2, 1e10)
+ NET_C(RX1.1, SW.1)
+ NET_C(RX2.1, SW.3)
+
+ NET_C(COMP.GND, RX1.2, RX2.2)
+
+ RES(R1, 5000)
+ RES(R2, 5000)
+ RES(R3, 5000)
+
+ // Square output wave
+ VCVS(V_SQR, 1)
+ NET_C(COMP.Q, V_SQR.IP)
+
+ NET_C(COMP.GND, SW.GND, VI.ON, VI.IN, CI1.ON, CI2.ON, VO.IN, VO.ON, R2.2, V_SQR.IN, V_SQR.ON)
+ NET_C(COMP.VCC, SW.VCC, R1.2)
+ NET_C(COMP.IP, R1.1, R2.1, R3.1)
+ NET_C(COMP.Q, R3.2)
+
+ ALIAS(11, VI.ON) // GND
+ ALIAS(9, V_SQR.OP) // Square out
+ ALIAS(3, VO.OP) // Triag out
+ ALIAS(8, VI.IP) // VC
+ ALIAS(4, CI1.IP) // R1
+ ALIAS(5, CI2.IP) // R2
+ ALIAS(10, VO.IP) // C1
+ ALIAS(6, COMP.VCC) // V+
+NETLIST_END()
diff --git a/src/lib/netlist/macro/modules/nlmod_NE556_DIP.cpp b/src/lib/netlist/macro/modules/nlmod_NE556_DIP.cpp
new file mode 100644
index 00000000000..7f278a18b6d
--- /dev/null
+++ b/src/lib/netlist/macro/modules/nlmod_NE556_DIP.cpp
@@ -0,0 +1,24 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+//
+
+#include "devices/net_lib.h"
+
+NETLIST_START(NE556_DIP)
+ NE555(A)
+ NE555(B)
+
+ NET_C(A.GND, B.GND)
+ NET_C(A.VCC, B.VCC)
+
+ DIPPINS( /* +--------------+ */
+ A.DISCH, /* 1DISCH |1 ++ 14| VCC */ A.VCC,
+ A.THRESH, /* 1THRES |2 13| 2DISCH */ B.DISCH,
+ A.CONT, /* 1CONT |3 12| 2THRES */ B.THRESH,
+ A.RESET, /* 1RESET |4 NE556 11| 2CONT */ B.CONT,
+ A.OUT, /* 1OUT |5 10| 2RESET */ B.RESET,
+ A.TRIG, /* 1TRIG |6 9| 2OUT */ B.OUT,
+ A.GND, /* GND |7 8| 2TRIG */ B.TRIG
+ /* +--------------+ */
+ )
+NETLIST_END()
diff --git a/src/lib/netlist/macro/nlm_base_lib.cpp b/src/lib/netlist/macro/nlm_base_lib.cpp
index c5f4c7c695b..b9c4165a46b 100644
--- a/src/lib/netlist/macro/nlm_base_lib.cpp
+++ b/src/lib/netlist/macro/nlm_base_lib.cpp
@@ -13,6 +13,7 @@ static NETLIST_START(diode_models)
// FIXME: 1N916 currently only a copy of 1N914!
NET_MODEL("1N916 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
NET_MODEL("1N4001 D(Is=14.11n N=1.984 Rs=33.89m Ikf=94.81 Xti=3 Eg=1.11 Cjo=25.89p M=.44 Vj=.3245 Fc=.5 Bv=75 Ibv=10u Tt=5.7u Iave=1 Vpk=50 mfg=GI type=silicon)")
+ NET_MODEL("1N4002 D(IS=65.4p RS=42.2m BV=100 IBV=5.00u CJO=14.8p M=0.333 N=1.36 TT=2.88u)")
NET_MODEL("1N4148 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
NET_MODEL("1N4154 D(Is=0.1n Rs=4 N=1.67 Cjo=2p M=.333 tt=3n Iave=150m Vpk=35 Bv=60 Ibv=0.1p mfg=Vishay type=silicon)")
NET_MODEL("1N4454 D(Is=168.1e-21 Rs=.1 N=1 Cjo=2p M=.333 tt=5.771n Iave=400m Vpk=35 Bv=75 Ibv=100u mfg=OnSemi type=silicon)")
@@ -25,6 +26,15 @@ static NETLIST_START(diode_models)
NET_MODEL("LedBlue D(IS=93.2p RS=42M N=7.47 BV=5 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=5 type=LED)")
NET_MODEL("LedWhite D(Is=0.27n Rs=5.65 N=6.79 Cjo=42p Iave=30m Vpk=5 type=LED)")
+ // Zdiodes ...
+
+ // not really found anywhere, just took the 5239 and changed the
+ // breakdown voltage to 5.1 according to the datasheet
+ NET_MODEL("1N5231 D(BV=5.1 IBV=0.020 NBV=1)")
+ NET_MODEL("1N5236B D(BV=7.5 IS=27.5p RS=33.8 N=1.10 CJO=58.2p VJ=0.750 M=0.330 TT=50.1n)")
+ NET_MODEL("1N5240 D(BV=10 IS=14.4p RS=32.0 N=1.10 CJO=24.1p VJ=0.750 M=0.330 TT=50.1n)")
+ NET_MODEL("1N5240B D(BV=10 IS=14.4p RS=32.0 N=1.10 CJO=24.1p VJ=0.750 M=0.330 TT=50.1n)")
+
NETLIST_END()
/* ----------------------------------------------------------------------------
@@ -58,13 +68,24 @@ static NETLIST_START(bjt_models)
NET_MODEL("2N3644 PNP(IS=650.6E-18 ISE=54.81E-15 ISC=0 XTI=3 BF=231.7 BR=3.563 IKF=1.079 IKR=0 XTB=1.5 VAF=115.7 VAR=35 VJE=0.65 VJC=0.65 RE=0.15 RC=0.715 RB=10 CJE=19.82E-12 CJC=14.76E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.829 NC=2 MJE=0.3357 MJC=0.5383 TF=603.7E-12 TR=111.3E-9 ITF=0.65 VTF=5 XTF=1.7 EG=1.11 KF=0 AF=1 VCEO=60 ICRATING=500m MFG=NSC)")
NET_MODEL("2N3702 PNP(Is=650.6E-18 Xti=3 Eg=1.11 Vaf=115.7 Bf=133.8 Ne=1.832 Ise=97.16f Ikf=1.081 Xtb=1.5 Br=3.73 Nc=2 Isc=0 Ikr=0 Rc=.715 Cjc=14.76p Mjc=.5383 Vjc=.75 Fc=.5 Cje=19.82p Mje=.3357 Vje=.75 Tr=114.1n Tf=761.3p Itf=.65 Vtf=5 Xtf=1.7 Rb=10 mfg=National)")
NET_MODEL("2N3704 NPN(IS=26.03f VAF=90.7 Bf=736.1K IKF=.1983 XTB=1.5 BR=1.024 CJC=11.01p CJE=24.07p RB=10 RC=.5 RE=.5 TR=233.8n TF=1.03n ITF=0 VTF=0 XTF=0 mfg=Motorola)")
+ // SPICE model parameters taken from Fairchild Semiconductor datasheet
NET_MODEL("2N3904 NPN(IS=1E-14 VAF=100 Bf=300 IKF=0.4 XTB=1.5 BR=4 CJC=4E-12 CJE=8E-12 RB=20 RC=0.1 RE=0.1 TR=250E-9 TF=350E-12 ITF=1 VTF=2 XTF=3 Vceo=40 Icrating=200m mfg=Philips)")
+ // SPICE model parameters taken from Fairchild Semiconductor datasheet
+ NET_MODEL("2N3906 PNP(Is=1.41f Xti=3 Eg=1.11 Vaf=18.7 Bf=180.7 Ne=1.5 Ise=0 Ikf=80m Xtb=1.5 Br=4.977 Nc=2 Isc=0 Ikr=0 Rc=2.5 Cjc=9.728p Mjc=.5776 Vjc=.75 Fc=.5 Cje=8.063p Mje=.3677 Vje=.75 Tr=33.42n Tf=179.3p Itf=.4 Vtf=4 Xtf=6 Rb=10)")
// 2N5190 = BC817-25
NET_MODEL("2N5190 NPN(IS=9.198E-14 NF=1.003 ISE=4.468E-16 NE=1.65 BF=338.8 IKF=0.4913 VAF=107.9 NR=1.002 ISC=5.109E-15 NC=1.071 BR=29.48 IKR=0.193 VAR=25 RB=1 IRB=1000 RBM=1 RE=0.2126 RC=0.143 XTB=0 EG=1.11 XTI=3 CJE=3.825E-11 VJE=0.7004 MJE=0.364 TF=5.229E-10 XTF=219.7 VTF=3.502 ITF=7.257 PTF=0 CJC=1.27E-11 VJC=0.4431 MJC=0.3983 XCJC=0.4555 TR=7E-11 CJS=0 VJS=0.75 MJS=0.333 FC=0.905 Vceo=45 Icrating=500m mfg=Philips)")
NET_MODEL("2N4401 NPN(IS=26.03f XTI=3 EG=1.11 VAF=90.7 BF=4.292K NE=1.244 ISE=26.03f IKF=0.2061 XTB=1.5 BR=1.01 NC=2 ISC=0 IKR=0 RC=0.5 CJC=11.01p MJC=0.3763 VJC=0.75 FC=0.5 CJE=24.07p MJE=0.3641 VJE=0.75 TR=233.7n TF=466.5p ITF=0 VTF=0 XTF=0 RB=10 VCEO=40)")
+ NET_MODEL("2N4403 PNP(Is=650.6E-18 Xti=3 Eg=1.11 Vaf=115.7 Bf=216.2 Ne=1.829 Ise=58.72f Ikf=1.079 Xtb=1.5 Br=3.578 Nc=2 Isc=0 Ikr=0 Rc=.715 Cjc=14.76p Mjc=.5383 Vjc=.75 Fc=.5 Cje=19.82p Mje=.3357 Vje=.75 Tr=111.6n Tf=603.7p Itf=.65 Vtf=5 Xtf=1.7 Rb=10)")
NET_MODEL("2N4124 NPN(IS=6.734f XTI=3 EG=1.11 VAF=74.03 BF=495 NE=1.28 ISE=6.734f IKF=69.35m XTB=1.5 BR=0.7214 NC=2 ISC=0 IKR=0 RC=1 CJC=3.638p MJC=0.3085 VJC=0.75 FC=0.5 CJE=4.493p MJE=0.2593 VJE=0.75 TR=238.3n TF=301.3p ITF=.4 VTF=4 XTF=2 RB=10 VCEO=25)")
NET_MODEL("2N4126 PNP(IS=1.41f XTI=3 EG=1.11 VAF=18.7 BF=203.7 NE=1.5 ISE=0 IKF=80m XTB=1.5 BR=4.924 NC=2 ISC=0 IKR=0 RC=2.5 CJC=9.728p MJC=0.5776 VJC=0.75 FC=0.5 CJE=8.063p MJE=0.3677 VJE=0.75 TR=33.23n TF=179.3p ITF=.4 VTF=4 XTF=6 RB=10 VCEO=25)")
+ // SPICE model parameters taken from http://ltwiki.org/files/LTspiceIV/Vendor%20List/Fairchild/2N/index.html
+ NET_MODEL("2N5210 NPN(Is=5.911f Xti=3 Eg=1.11 Vaf=62.37 Bf=809.9 Ne=1.358 Ise=5.911f Ikf=14.26m Xtb=1.5 Br=1.287 Nc=2 Isc=0 Ikr=0 Rc=1.61 Cjc=4.017p Mjc=.3174 Vjc=.75 Fc=.5 Cje=4.973p Mje=.4146 Vje=.75 Tr=4.68n Tf=820.9p Itf=.35 Vtf=4 Xtf=7 Rb=10)")
+ // SPICE model parameters taken from https://www.onsemi.com/support/design-resources/models?rpn=2N6107
+ NET_MODEL("2N6107 PNP(IS=7.62308e-14 BF=6692.56 NF=0.85 VAF=10 IKF=0.032192 ISE=2.07832e-13 NE=2.41828 BR=15.6629 NR=1.5 VAR=1.44572 IKR=0.32192 ISC=4.75e-16 NC=3.9375 RB=7.19824 IRB=0.1 RBM=0.1 RE=0.0001 RC=0.355458 XTB=0.1 XTI=2.97595 EG=1.206 CJE=1.84157e-10 VJE=0.99 MJE=0.347177 TF=6.63757e-09 XTF=1.50003 VTF=1.0001 ITF=1 CJC=1.06717e-10 VJC=0.942679 MJC=0.245405 XCJC=0.8 FC=0.533334 CJS=0 VJS=0.75 MJS=0.5 TR=1.32755e-07 PTF=0 KF=0 AF=1)")
+ // SPICE model parameters taken from https://www.onsemi.com/support/design-resources/models?rpn=2N6292
+ NET_MODEL("2N6292 NPN(IS=9.3092e-13 BF=2021.8 NF=0.85 VAF=63.2399 IKF=1 ISE=1.92869e-13 NE=1.97024 BR=40.0703 NR=1.5 VAR=0.89955 IKR=10 ISC=4.92338e-16 NC=3.9992 RB=6.98677 IRB=0.1 RBM=0.1 RE=0.0001 RC=0.326141 XTB=0.1 XTI=2.86739 EG=1.206 CJE=1.84157e-10 VJE=0.99 MJE=0.347174 TF=6.73756e-09 XTF=1.49917 VTF=0.997395 ITF=0.998426 CJC=1.06717e-10 VJC=0.942694 MJC=0.245406 XCJC=0.8 FC=0.533405 CJS=0 VJS=0.75 MJS=0.5 TR=6.0671e-08 PTF=0 KF=0 AF=1)")
+
NET_MODEL("2SC945 NPN(IS=3.577E-14 BF=2.382E+02 NF=1.01 VAF=1.206E+02 IKF=3.332E-01 ISE=3.038E-16 NE=1.205 BR=1.289E+01 NR=1.015 VAR=1.533E+01 IKR=2.037E-01 ISC=3.972E-14 NC=1.115 RB=3.680E+01 IRB=1.004E-04 RBM=1 RE=8.338E-01 RC=1.557E+00 CJE=1.877E-11 VJE=7.211E-01 MJE=3.486E-01 TF=4.149E-10 XTF=1.000E+02 VTF=9.956 ITF=5.118E-01 PTF=0 CJC=6.876p VJC=3.645E-01 MJC=3.074E-01 TR=5.145E-08 XTB=1.5 EG=1.11 XTI=3 FC=0.5 Vceo=50 Icrating=100m MFG=NEC)")
NET_MODEL("BC237B NPN(IS=1.8E-14 ISE=5.0E-14 ISC=1.72E-13 XTI=3 BF=400 BR=35.5 IKF=0.14 IKR=0.03 XTB=1.5 VAF=80 VAR=12.5 VJE=0.58 VJC=0.54 RE=0.6 RC=0.25 RB=0.56 CJE=13E-12 CJC=4E-12 XCJC=0.75 FC=0.5 NF=0.9955 NR=1.005 NE=1.46 NC=1.27 MJE=0.33 MJC=0.33 TF=0.64E-9 TR=50.72E-9 EG=1.11 KF=0 AF=1 VCEO=45 ICRATING=100M MFG=ZETEX)")
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index a4510fe5765..d0a0e707aaf 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -16,10 +16,10 @@
#include "nl_errstr.h"
-#include "devices/net_lib.h"
-
#include <limits>
+NETLIST_EXTERNAL(base_lib)
+
namespace netlist
{
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 32a5c542a16..3e7ff32e804 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -561,4 +561,26 @@ pstring parser_t::stringify_expression(token_t &tok)
return ret;
}
+// ----------------------------------------------------------------------------------------
+// source_token_t
+// ----------------------------------------------------------------------------------------
+
+bool source_token_t::parse(nlparse_t &setup, const pstring &name)
+{
+ if (name == m_name)
+ {
+ auto ret = setup.parse_tokens(m_store, name);
+ return ret;
+ }
+
+ return false;
+}
+
+plib::istream_uptr source_token_t::stream(const pstring &name)
+{
+ plib::unused_var(name);
+ return plib::istream_uptr();
+}
+
+
} // namespace netlist
diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h
index 077f1b10792..cbc757307d5 100644
--- a/src/lib/netlist/nl_parser.h
+++ b/src/lib/netlist/nl_parser.h
@@ -9,6 +9,7 @@
#define NL_PARSER_H_
#include "nltypes.h" // for setup_t
+#include "core/setup.h"
#include "plib/ptokenizer.h"
#include <unordered_map>
@@ -89,7 +90,27 @@ namespace netlist
std::unordered_map<pstring, token_store> m_local;
token_store *m_cur_local;
-};
+ };
+
+ class source_token_t : public source_netlist_t
+ {
+ public:
+ source_token_t(const pstring &name, const parser_t::token_store &store)
+ : m_store(store)
+ , m_name(name)
+ {
+ }
+
+ bool parse(nlparse_t &setup, const pstring &name) override;
+
+ protected:
+ plib::istream_uptr stream(const pstring &name) override;
+
+ private:
+ parser_t::token_store m_store;
+ pstring m_name;
+ };
+
} // namespace netlist
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index b2ade9d48ce..9af1ec92d51 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -352,7 +352,7 @@ namespace netlist
return false;
}
- bool nlparse_t::parse_tokens(const parser_t::token_store &tokens, const pstring &name)
+ bool nlparse_t::parse_tokens(const plib::detail::token_store &tokens, const pstring &name)
{
parser_t parser(*this);
return parser.parse(tokens, name);
@@ -1282,7 +1282,10 @@ void models_t::model_parse(const pstring &model_in, map_t &map)
key = plib::ucase(model);
auto i = m_models.find(key);
if (i == m_models.end())
- throw nl_exception(MF_MODEL_NOT_FOUND("xx" + model));
+ {
+ throw nl_exception(MF_MODEL_NOT_FOUND(pstring("xx") + model));
+ }
+
model = i->second;
}
pstring xmodel = plib::left(model, pos);
@@ -1759,22 +1762,5 @@ plib::istream_uptr source_proc_t::stream(const pstring &name)
return plib::istream_uptr();
}
-bool source_token_t::parse(nlparse_t &setup, const pstring &name)
-{
- if (name == m_name)
- {
- auto ret = setup.parse_tokens(m_store, name);
- return ret;
- }
-
- return false;
-}
-
-plib::istream_uptr source_token_t::stream(const pstring &name)
-{
- plib::unused_var(name);
- return plib::istream_uptr();
-}
-
} // namespace netlist
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 7f6988f2951..fd9cb11afab 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -14,7 +14,6 @@
#include "plib/pstring.h"
#include "nl_config.h"
-#include "nl_parser.h"
#include "nltypes.h"
#include <initializer_list>
@@ -229,7 +228,7 @@ namespace netlist
// FIXME: used by source_t - need a different approach at some time
bool parse_stream(plib::istream_uptr &&istrm, const pstring &name);
- bool parse_tokens(const parser_t::token_store &tokens, const pstring &name);
+ bool parse_tokens(const plib::detail::token_store &tokens, const pstring &name);
template <typename S, typename... Args>
void add_include(Args&&... args)
diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h
index 422a9ddfac4..5781619af1a 100644
--- a/src/lib/netlist/nltypes.h
+++ b/src/lib/netlist/nltypes.h
@@ -22,22 +22,6 @@
#include <memory>
-// FIXME: Move to ptypes
-namespace plib
-{
- // FORWARD declarations
- template <typename BASEARENA, std::size_t MINALIGN>
- class mempool_arena;
-
- struct aligned_arena;
- class dynlib_base;
-
- template<bool debug_enabled>
- class plog_base;
-
- struct plog_level;
-} // namespace plib
-
namespace netlist
{
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h
index 2023fb91c38..709f8810b83 100644
--- a/src/lib/netlist/plib/pexception.h
+++ b/src/lib/netlist/plib/pexception.h
@@ -40,10 +40,10 @@ namespace plib {
explicit pexception(const pstring &text);
const pstring &text() const noexcept { return m_text; }
- const char* what() const noexcept override { return putf8string(m_text).c_str(); }
+ const char* what() const noexcept override { return m_text.c_str(); }
private:
- pstring m_text;
+ putf8string m_text;
};
class file_e : public plib::pexception
diff --git a/src/lib/netlist/plib/ptokenizer.h b/src/lib/netlist/plib/ptokenizer.h
index 717d3fcd550..9a194a542d5 100644
--- a/src/lib/netlist/plib/ptokenizer.h
+++ b/src/lib/netlist/plib/ptokenizer.h
@@ -19,22 +19,7 @@
namespace plib {
- class ptokenizer
- {
- public:
- explicit ptokenizer() // NOLINT(misc-forwarding-reference-overload, bugprone-forwarding-reference-overload)
- : m_strm(nullptr)
- , m_unget(0)
- , m_string('"')
- , m_support_line_markers(true) // FIXME
- , m_token_queue(nullptr)
- {
- clear();
- }
-
- PCOPYASSIGNMOVE(ptokenizer, delete)
-
- virtual ~ptokenizer() = default;
+ namespace detail {
PENUM(token_type,
IDENTIFIER,
@@ -109,7 +94,34 @@ namespace plib {
pstring m_token;
};
- using token_store = std::vector<token_t>;
+ class token_store : public std::vector<token_t>
+ {
+ using std::vector<token_t>::vector;
+ };
+
+ } // namespace detail
+
+ class ptokenizer
+ {
+ public:
+ explicit ptokenizer() // NOLINT(misc-forwarding-reference-overload, bugprone-forwarding-reference-overload)
+ : m_strm(nullptr)
+ , m_unget(0)
+ , m_string('"')
+ , m_support_line_markers(true) // FIXME
+ , m_token_queue(nullptr)
+ {
+ clear();
+ }
+
+ PCOPYASSIGNMOVE(ptokenizer, delete)
+
+ virtual ~ptokenizer() = default;
+
+ using token_type = detail::token_type;
+ using token_id_t = detail::token_id_t;
+ using token_t = detail::token_t;
+ using token_store = detail::token_store;
// tokenizer stuff follows ...
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index 5c5cb37695a..544b8ab0eff 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -39,6 +39,30 @@
#undef EMSCRIPTEN
#endif
+// -----------------------------------------------------------------------------
+// forward definitions
+// -----------------------------------------------------------------------------
+
+namespace plib
+{
+ template <typename BASEARENA, std::size_t MINALIGN>
+ class mempool_arena;
+
+ struct aligned_arena;
+ class dynlib_base;
+
+ template<bool debug_enabled>
+ class plog_base;
+
+ struct plog_level;
+
+ namespace detail
+ {
+ class token_store;
+ } // namespace detail
+
+} // namespace plib
+
namespace plib
{
//============================================================
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 27aa5b293c3..44b96bf0d6d 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -694,18 +694,22 @@ void tool_app_t::static_compile()
throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(opt_out()));
sout << "#include \"plib/pdynlib.h\"\n\n";
+ sout << "#if !defined(__EMSCRIPTEN__)\n\n";
for (auto &e : map)
{
sout << "// " << putf8string(e.second.m_module) << "\n";
sout << putf8string(e.second.m_code);
}
+ sout << "#endif\n\n";
sout << "extern const plib::dynlib_static_sym nl_static_solver_syms[];\n";
sout << "const plib::dynlib_static_sym nl_static_solver_syms[] = {\n";
+ sout << "#if !defined(__EMSCRIPTEN__)\n\n";
for (auto &e : map)
{
sout << "// " << putf8string(e.second.m_module) << "\n";
sout << "\t{\"" << putf8string(e.first) << "\", reinterpret_cast<void *>(&" << putf8string(e.first) << ")},\n";
}
+ sout << "#endif\n\n";
sout << "{\"\", nullptr}\n";
sout << "};\n";
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 92a4af61399..9ea31925b98 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -227,6 +227,7 @@ namespace devices
std::size_t net_count = nets.size();
switch (net_count)
{
+#if !defined(__EMSCRIPTEN__)
case 1:
return plib::make_unique<solver::matrix_solver_direct1_t<FT>, device_arena>(*this, sname, nets, params);
case 2:
@@ -243,6 +244,7 @@ namespace devices
return create_solver<FT, 7>(7, sname, params, nets);
case 8:
return create_solver<FT, 8>(8, sname, params, nets);
+#endif
default:
log().info(MI_NO_SPECIFIC_SOLVER(net_count));
if (net_count <= 16)