mirror of
https://github.com/holub/mame
synced 2025-06-05 12:26:35 +03:00
Converted netlist into a library. Moved most code from nl_convert.h to
nl_convert.c. Targets using netlist must now specify this explicitly with MACHINES["NETLIST"] = true Added subtarget "nl" which only contains games with netlist elements. (nw)
This commit is contained in:
parent
7500669a19
commit
872ca80ac5
@ -266,8 +266,6 @@ files {
|
|||||||
MAME_DIR .. "src/emu/machine/laserdsc.h",
|
MAME_DIR .. "src/emu/machine/laserdsc.h",
|
||||||
MAME_DIR .. "src/emu/machine/latch.c",
|
MAME_DIR .. "src/emu/machine/latch.c",
|
||||||
MAME_DIR .. "src/emu/machine/latch.h",
|
MAME_DIR .. "src/emu/machine/latch.h",
|
||||||
MAME_DIR .. "src/emu/machine/netlist.c",
|
|
||||||
MAME_DIR .. "src/emu/machine/netlist.h",
|
|
||||||
MAME_DIR .. "src/emu/machine/nvram.c",
|
MAME_DIR .. "src/emu/machine/nvram.c",
|
||||||
MAME_DIR .. "src/emu/machine/nvram.h",
|
MAME_DIR .. "src/emu/machine/nvram.h",
|
||||||
MAME_DIR .. "src/emu/machine/ram.c",
|
MAME_DIR .. "src/emu/machine/ram.c",
|
||||||
@ -389,12 +387,13 @@ function emuProject(_target, _subtarget)
|
|||||||
|
|
||||||
dofile(path.join("src", "sound.lua"))
|
dofile(path.join("src", "sound.lua"))
|
||||||
|
|
||||||
dofile(path.join("src", "netlist.lua"))
|
|
||||||
|
|
||||||
dofile(path.join("src", "video.lua"))
|
dofile(path.join("src", "video.lua"))
|
||||||
|
|
||||||
dofile(path.join("src", "machine.lua"))
|
dofile(path.join("src", "machine.lua"))
|
||||||
|
|
||||||
|
-- netlist now defines a project
|
||||||
|
dofile(path.join("src", "netlist.lua"))
|
||||||
|
|
||||||
project ("bus")
|
project ("bus")
|
||||||
uuid ("5d782c89-cf7e-4cfe-8f9f-0d4bfc16c91d")
|
uuid ("5d782c89-cf7e-4cfe-8f9f-0d4bfc16c91d")
|
||||||
|
@ -2662,3 +2662,14 @@ if (MACHINES["PCI9050"]~=null) then
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------
|
||||||
|
--
|
||||||
|
--@src/emu/machine/netlist.h,MACHINES += NETLIST
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
if (MACHINES["NETLIST"]~=null) then
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "src/emu/machine/netlist.c",
|
||||||
|
MAME_DIR .. "src/emu/machine/netlist.h",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
@ -87,6 +87,7 @@ function mainProject(_target, _subtarget)
|
|||||||
links {
|
links {
|
||||||
"osd_" .. _OPTIONS["osd"],
|
"osd_" .. _OPTIONS["osd"],
|
||||||
"bus",
|
"bus",
|
||||||
|
"netlist",
|
||||||
"optional",
|
"optional",
|
||||||
"emu",
|
"emu",
|
||||||
"dasm",
|
"dasm",
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
-- license:BSD-3-Clause
|
-- license:BSD-3-Clause
|
||||||
-- copyright-holders:MAMEdev Team
|
-- copyright-holders:MAMEdev Team
|
||||||
|
|
||||||
files {
|
project "netlist"
|
||||||
|
targetsubdir(_OPTIONS["target"] .."_" .. _OPTIONS["subtarget"])
|
||||||
|
uuid "665ef8ac-2a4c-4c3e-a05f-fd1e5db11de9"
|
||||||
|
kind (LIBTYPE)
|
||||||
|
|
||||||
|
options {
|
||||||
|
"ForceCPP",
|
||||||
|
}
|
||||||
|
|
||||||
|
includedirs {
|
||||||
|
MAME_DIR .. "src/emu/netlist",
|
||||||
|
MAME_DIR .. "src/osd",
|
||||||
|
MAME_DIR .. "src/lib/util",
|
||||||
|
}
|
||||||
|
-- if _OPTIONS["with-bundled-expat"] then
|
||||||
|
-- includedirs {
|
||||||
|
-- MAME_DIR .. "3rdparty/expat/lib",
|
||||||
|
-- }
|
||||||
|
--end
|
||||||
|
|
||||||
|
|
||||||
|
files {
|
||||||
MAME_DIR .. "src/emu/netlist/nl_config.h",
|
MAME_DIR .. "src/emu/netlist/nl_config.h",
|
||||||
MAME_DIR .. "src/emu/netlist/nl_dice_compat.h",
|
MAME_DIR .. "src/emu/netlist/nl_dice_compat.h",
|
||||||
MAME_DIR .. "src/emu/netlist/nl_lists.h",
|
MAME_DIR .. "src/emu/netlist/nl_lists.h",
|
||||||
@ -26,6 +47,10 @@ files {
|
|||||||
MAME_DIR .. "src/emu/netlist/plib/pstate.h",
|
MAME_DIR .. "src/emu/netlist/plib/pstate.h",
|
||||||
MAME_DIR .. "src/emu/netlist/plib/pstring.c",
|
MAME_DIR .. "src/emu/netlist/plib/pstring.c",
|
||||||
MAME_DIR .. "src/emu/netlist/plib/pstring.h",
|
MAME_DIR .. "src/emu/netlist/plib/pstring.h",
|
||||||
|
MAME_DIR .. "src/emu/netlist/plib/pstring.c",
|
||||||
|
MAME_DIR .. "src/emu/netlist/plib/pstring.h",
|
||||||
|
MAME_DIR .. "src/emu/netlist/tools/nl_convert.c",
|
||||||
|
MAME_DIR .. "src/emu/netlist/tools/nl_convert.h",
|
||||||
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.c",
|
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.c",
|
||||||
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.h",
|
MAME_DIR .. "src/emu/netlist/analog/nld_bjt.h",
|
||||||
MAME_DIR .. "src/emu/netlist/analog/nld_fourterm.c",
|
MAME_DIR .. "src/emu/netlist/analog/nld_fourterm.c",
|
||||||
|
@ -443,6 +443,7 @@ links {
|
|||||||
"flac",
|
"flac",
|
||||||
"7z",
|
"7z",
|
||||||
"ocore_" .. _OPTIONS["osd"],
|
"ocore_" .. _OPTIONS["osd"],
|
||||||
|
"netlist",
|
||||||
}
|
}
|
||||||
|
|
||||||
includedirs {
|
includedirs {
|
||||||
@ -455,8 +456,6 @@ files {
|
|||||||
MAME_DIR .. "src/tools/nltool.c",
|
MAME_DIR .. "src/tools/nltool.c",
|
||||||
}
|
}
|
||||||
|
|
||||||
dofile("netlist.lua")
|
|
||||||
|
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
-- castool
|
-- castool
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
@ -470,6 +470,7 @@ MACHINES["MSM6242"] = true
|
|||||||
--MACHINES["NCR5380N"] = true
|
--MACHINES["NCR5380N"] = true
|
||||||
--MACHINES["NCR5390"] = true
|
--MACHINES["NCR5390"] = true
|
||||||
MACHINES["NCR539x"] = true
|
MACHINES["NCR539x"] = true
|
||||||
|
MACHINES["NETLIST"] = true
|
||||||
--MACHINES["NCR53C7XX"] = true
|
--MACHINES["NCR53C7XX"] = true
|
||||||
MACHINES["NMC9306"] = true
|
MACHINES["NMC9306"] = true
|
||||||
--MACHINES["NSC810"] = true
|
--MACHINES["NSC810"] = true
|
||||||
|
@ -471,6 +471,7 @@ MACHINES["NCR5380N"] = true
|
|||||||
MACHINES["NCR5390"] = true
|
MACHINES["NCR5390"] = true
|
||||||
MACHINES["NCR539x"] = true
|
MACHINES["NCR539x"] = true
|
||||||
MACHINES["NCR53C7XX"] = true
|
MACHINES["NCR53C7XX"] = true
|
||||||
|
MACHINES["NETLIST"] = true
|
||||||
MACHINES["NMC9306"] = true
|
MACHINES["NMC9306"] = true
|
||||||
MACHINES["NSC810"] = true
|
MACHINES["NSC810"] = true
|
||||||
MACHINES["NSCSI"] = true
|
MACHINES["NSCSI"] = true
|
||||||
|
121
scripts/target/mame/nl.lua
Normal file
121
scripts/target/mame/nl.lua
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
-- license:BSD-3-Clause
|
||||||
|
-- copyright-holders:MAMEdev Team
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- nl.lua
|
||||||
|
--
|
||||||
|
-- Compiles all drivers using netlist code
|
||||||
|
-- Use make SUBTARGET=nl to build
|
||||||
|
--
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- Specify all the CPU cores necessary for the
|
||||||
|
-- drivers referenced in nl.lst.
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
CPUS["Z80"] = true
|
||||||
|
--CPUS["M6502"] = true
|
||||||
|
--CPUS["MCS48"] = true
|
||||||
|
--CPUS["MCS51"] = true
|
||||||
|
--CPUS["M6800"] = true
|
||||||
|
--CPUS["M6809"] = true
|
||||||
|
--CPUS["M680X0"] = true
|
||||||
|
--CPUS["TMS9900"] = true
|
||||||
|
--CPUS["COP400"] = true
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- Specify all the sound cores necessary for the
|
||||||
|
-- drivers referenced in nl.lst.
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
--SOUNDS["SAMPLES"] = true
|
||||||
|
SOUNDS["DAC"] = true
|
||||||
|
--SOUNDS["DISCRETE"] = true
|
||||||
|
SOUNDS["AY8910"] = true
|
||||||
|
--SOUNDS["YM2151"] = true
|
||||||
|
--SOUNDS["ASTROCADE"] = true
|
||||||
|
--SOUNDS["TMS5220"] = true
|
||||||
|
--SOUNDS["OKIM6295"] = true
|
||||||
|
--SOUNDS["HC55516"] = true
|
||||||
|
--SOUNDS["YM3812"] = true
|
||||||
|
--SOUNDS["CEM3394"] = true
|
||||||
|
--SOUNDS["VOTRAX"] = true
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- specify available video cores
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
VIDEOS["FIXFREQ"] = true
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- specify available machine cores
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
MACHINES["NETLIST"] = true
|
||||||
|
--MACHINES["6821PIA"] = true
|
||||||
|
--MACHINES["TTL74148"] = true
|
||||||
|
--MACHINES["TTL74153"] = true
|
||||||
|
--MACHINES["TTL7474"] = true
|
||||||
|
--MACHINES["RIOT6532"] = true
|
||||||
|
--MACHINES["PIT8253"] = true
|
||||||
|
--MACHINES["Z80CTC"] = true
|
||||||
|
--MACHINES["68681"] = true
|
||||||
|
--MACHINES["BANKDEV"] = true
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- specify available bus cores
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
-- not needed by nl.lua but build system wants at least one bus
|
||||||
|
BUSES["CENTRONICS"] = true
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- This is the list of files that are necessary
|
||||||
|
-- for building all of the drivers referenced
|
||||||
|
-- in tiny.lst
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
function createProjects_mame_nl(_target, _subtarget)
|
||||||
|
project ("mame_netlist")
|
||||||
|
targetsubdir(_target .."_" .. _subtarget)
|
||||||
|
kind (LIBTYPE)
|
||||||
|
uuid (os.uuid("drv-mame-nl"))
|
||||||
|
|
||||||
|
options {
|
||||||
|
"ForceCPP",
|
||||||
|
}
|
||||||
|
|
||||||
|
includedirs {
|
||||||
|
MAME_DIR .. "src/osd",
|
||||||
|
MAME_DIR .. "src/emu",
|
||||||
|
MAME_DIR .. "src/mame",
|
||||||
|
MAME_DIR .. "src/lib",
|
||||||
|
MAME_DIR .. "src/lib/util",
|
||||||
|
MAME_DIR .. "3rdparty",
|
||||||
|
MAME_DIR .. "3rdparty/zlib",
|
||||||
|
GEN_DIR .. "mame/layout",
|
||||||
|
}
|
||||||
|
|
||||||
|
files{
|
||||||
|
MAME_DIR .. "src/mame/drivers/pong.c",
|
||||||
|
MAME_DIR .. "src/mame/drivers/nl_pong.c",
|
||||||
|
MAME_DIR .. "src/mame/drivers/nl_pongd.c",
|
||||||
|
MAME_DIR .. "src/mame/drivers/nl_breakout.c",
|
||||||
|
|
||||||
|
MAME_DIR .. "src/mame/drivers/1942.c",
|
||||||
|
MAME_DIR .. "src/mame/video/1942.c",
|
||||||
|
MAME_DIR .. "src/mame/drivers/popeye.c",
|
||||||
|
MAME_DIR .. "src/mame/video/popeye.c",
|
||||||
|
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function linkProjects_mame_nl(_target, _subtarget)
|
||||||
|
links {
|
||||||
|
"mame_netlist",
|
||||||
|
}
|
||||||
|
end
|
@ -42,6 +42,15 @@ private:
|
|||||||
// nld_Q
|
// nld_Q
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NETLIB_NAME(Q)::NETLIB_NAME(Q)(const family_t afamily)
|
||||||
|
: netlist_device_t(afamily)
|
||||||
|
, m_qtype(BJT_NPN) { }
|
||||||
|
|
||||||
|
NETLIB_NAME(Q)::~NETLIB_NAME(Q)()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NETLIB_START(Q)
|
NETLIB_START(Q)
|
||||||
{
|
{
|
||||||
register_param("model", m_model, "");
|
register_param("model", m_model, "");
|
||||||
|
@ -38,9 +38,8 @@ public:
|
|||||||
BJT_PNP
|
BJT_PNP
|
||||||
};
|
};
|
||||||
|
|
||||||
ATTR_COLD NETLIB_NAME(Q)(const family_t afamily)
|
NETLIB_NAME(Q)(const family_t afamily);
|
||||||
: netlist_device_t(afamily)
|
virtual ~NETLIB_NAME(Q)();
|
||||||
, m_qtype(BJT_NPN) { }
|
|
||||||
|
|
||||||
inline q_type qtype() const { return m_qtype; }
|
inline q_type qtype() const { return m_qtype; }
|
||||||
inline bool is_qtype(q_type atype) const { return m_qtype == atype; }
|
inline bool is_qtype(q_type atype) const { return m_qtype == atype; }
|
||||||
@ -59,9 +58,11 @@ class NETLIB_NAME(QBJT) : public NETLIB_NAME(Q)
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ATTR_COLD NETLIB_NAME(QBJT)(const family_t afamily)
|
NETLIB_NAME(QBJT)(const family_t afamily)
|
||||||
: NETLIB_NAME(Q)(afamily) { }
|
: NETLIB_NAME(Q)(afamily) { }
|
||||||
|
|
||||||
|
virtual ~NETLIB_NAME(QBJT)() { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -173,7 +173,7 @@ class netlist_core_device_t;
|
|||||||
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
||||||
typedef void (netlist_core_device_t::*net_update_delegate)();
|
typedef void (netlist_core_device_t::*net_update_delegate)();
|
||||||
#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
|
#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
|
||||||
typedef /*__thiscall */ void (*net_update_delegate)(netlist_core_device_t *);
|
typedef MEMBER_ABI void (*net_update_delegate)(netlist_core_device_t *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
|
@ -50,7 +50,8 @@
|
|||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
/* does not work in versions over 4.7.x of 32bit MINGW */
|
/* does not work in versions over 4.7.x of 32bit MINGW */
|
||||||
#if defined(__MINGW32__) && !defined(__x86_64) && defined(__i386__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
|
#if defined(__MINGW32__) && !defined(__x86_64) && defined(__i386__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
|
||||||
#define PHAS_PMF_INTERNAL 0
|
#define PHAS_PMF_INTERNAL 1
|
||||||
|
#define MEMBER_ABI __thiscall
|
||||||
#elif defined(EMSCRIPTEN)
|
#elif defined(EMSCRIPTEN)
|
||||||
#define PHAS_PMF_INTERNAL 0
|
#define PHAS_PMF_INTERNAL 0
|
||||||
#elif defined(__arm__) || defined(__ARMEL__)
|
#elif defined(__arm__) || defined(__ARMEL__)
|
||||||
@ -62,6 +63,9 @@
|
|||||||
#define USE_DELEGATE_TYPE PHAS_PMF_INTERNAL 0
|
#define USE_DELEGATE_TYPE PHAS_PMF_INTERNAL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MEMBER_ABI
|
||||||
|
#define MEMBER_ABI
|
||||||
|
#endif
|
||||||
|
|
||||||
/* not supported in GCC prior to 4.4.x */
|
/* not supported in GCC prior to 4.4.x */
|
||||||
/* ATTR_HOT and ATTR_COLD cause performance degration in 5.1 */
|
/* ATTR_HOT and ATTR_COLD cause performance degration in 5.1 */
|
||||||
@ -134,7 +138,7 @@ typedef int64_t INT64;
|
|||||||
* It derives a pointer to a member function.
|
* It derives a pointer to a member function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 1 || (PHAS_PMF_INTERNAL)
|
#if (PHAS_PMF_INTERNAL)
|
||||||
class pmfp
|
class pmfp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
413
src/emu/netlist/tools/nl_convert.c
Normal file
413
src/emu/netlist/tools/nl_convert.c
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
// license:GPL-2.0+
|
||||||
|
// copyright-holders:Couriersud
|
||||||
|
/*
|
||||||
|
* nl_convert.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nl_convert.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
#include "plib/pstring.h"
|
||||||
|
#include "plib/plists.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
convert - convert a spice netlist
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
void nl_convert_base_t::out(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
m_buf += pstring(format).vprintf(ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
|
||||||
|
{
|
||||||
|
m_pins.add(palloc(sp_pin_alias_t, devname + "." + name, devname + "." + alias), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nl_convert_base_t::add_ext_alias(const pstring &alias)
|
||||||
|
{
|
||||||
|
m_ext_alias.add(alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
|
||||||
|
{
|
||||||
|
devs.add(palloc(sp_dev_t, atype, aname, amodel), false);
|
||||||
|
}
|
||||||
|
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval)
|
||||||
|
{
|
||||||
|
devs.add(palloc(sp_dev_t, atype, aname, aval), false);
|
||||||
|
}
|
||||||
|
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
|
||||||
|
{
|
||||||
|
devs.add(palloc(sp_dev_t, atype, aname), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nl_convert_base_t::add_term(pstring netname, pstring termname)
|
||||||
|
{
|
||||||
|
sp_net_t * net = m_nets.find_by_name(netname);
|
||||||
|
if (net == NULL)
|
||||||
|
{
|
||||||
|
net = palloc(sp_net_t, netname);
|
||||||
|
m_nets.add(net, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is a pin alias, translate ... */
|
||||||
|
sp_pin_alias_t *alias = m_pins.find_by_name(termname);
|
||||||
|
|
||||||
|
if (alias != NULL)
|
||||||
|
net->terminals().add(alias->alias());
|
||||||
|
else
|
||||||
|
net->terminals().add(termname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nl_convert_base_t::dump_nl()
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_ext_alias.size(); i++)
|
||||||
|
{
|
||||||
|
sp_net_t *net = m_nets.find_by_name(m_ext_alias[i]);
|
||||||
|
// use the first terminal ...
|
||||||
|
out("ALIAS(%s, %s)\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr());
|
||||||
|
// if the aliased net only has this one terminal connected ==> don't dump
|
||||||
|
if (net->terminals().size() == 1)
|
||||||
|
net->set_no_export();
|
||||||
|
}
|
||||||
|
for (int i=0; i<devs.size(); i++)
|
||||||
|
{
|
||||||
|
if (devs[i]->has_value())
|
||||||
|
out("%s(%s, %s)\n", devs[i]->type().cstr(),
|
||||||
|
devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr());
|
||||||
|
else if (devs[i]->has_model())
|
||||||
|
out("%s(%s, \"%s\")\n", devs[i]->type().cstr(),
|
||||||
|
devs[i]->name().cstr(), devs[i]->model().cstr());
|
||||||
|
else
|
||||||
|
out("%s(%s)\n", devs[i]->type().cstr(),
|
||||||
|
devs[i]->name().cstr());
|
||||||
|
}
|
||||||
|
// print nets
|
||||||
|
for (int i=0; i<m_nets.size(); i++)
|
||||||
|
{
|
||||||
|
sp_net_t * net = m_nets[i];
|
||||||
|
if (!net->is_no_export())
|
||||||
|
{
|
||||||
|
//printf("Net %s\n", net->name().cstr());
|
||||||
|
out("NET_C(%s", net->terminals()[0].cstr() );
|
||||||
|
for (int j=1; j<net->terminals().size(); j++)
|
||||||
|
{
|
||||||
|
out(", %s", net->terminals()[j].cstr() );
|
||||||
|
}
|
||||||
|
out(")\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
devs.clear_and_free();
|
||||||
|
m_nets.clear_and_free();
|
||||||
|
m_pins.clear_and_free();
|
||||||
|
m_ext_alias.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pstring nl_convert_base_t::get_nl_val(const double val)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (m_sp_units[i].sp_unit != "-" )
|
||||||
|
{
|
||||||
|
if (m_sp_units[i].mult <= nl_math::abs(val))
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return pstring::sprintf(m_sp_units[i].nl_func.cstr(), val / m_sp_units[i].mult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double nl_convert_base_t::get_sp_unit(const pstring &unit)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (m_sp_units[i].sp_unit != "-")
|
||||||
|
{
|
||||||
|
if (m_sp_units[i].sp_unit == unit)
|
||||||
|
return m_sp_units[i].mult;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Unit %s unknown\n", unit.cstr());
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double nl_convert_base_t::get_sp_val(const pstring &sin)
|
||||||
|
{
|
||||||
|
int p = sin.len() - 1;
|
||||||
|
while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9"))
|
||||||
|
p--;
|
||||||
|
pstring val = sin.substr(0,p + 1);
|
||||||
|
pstring unit = sin.substr(p + 1);
|
||||||
|
|
||||||
|
double ret = get_sp_unit(unit) * val.as_double();
|
||||||
|
//printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
nl_convert_base_t::sp_unit nl_convert_base_t::m_sp_units[] = {
|
||||||
|
{"T", "", 1.0e12 },
|
||||||
|
{"G", "", 1.0e9 },
|
||||||
|
{"MEG", "RES_M(%g)", 1.0e6 },
|
||||||
|
{"k", "RES_K(%g)", 1.0e3 }, /* eagle */
|
||||||
|
{"K", "RES_K(%g)", 1.0e3 },
|
||||||
|
{"", "%g", 1.0e0 },
|
||||||
|
{"M", "CAP_M(%g)", 1.0e-3 },
|
||||||
|
{"u", "CAP_U(%g)", 1.0e-6 }, /* eagle */
|
||||||
|
{"U", "CAP_U(%g)", 1.0e-6 },
|
||||||
|
{"µ", "CAP_U(%g)", 1.0e-6 },
|
||||||
|
{"N", "CAP_N(%g)", 1.0e-9 },
|
||||||
|
{"P", "CAP_P(%g)", 1.0e-12},
|
||||||
|
{"F", "%ge-15", 1.0e-15},
|
||||||
|
|
||||||
|
{"MIL", "%e", 25.4e-6},
|
||||||
|
|
||||||
|
{"-", "%g", 1.0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void nl_convert_spice_t::convert(const pstring &contents)
|
||||||
|
{
|
||||||
|
pstring_list_t spnl(contents, "\n");
|
||||||
|
|
||||||
|
// Add gnd net
|
||||||
|
|
||||||
|
// FIXME: Parameter
|
||||||
|
out("NETLIST_START(dummy)\n");
|
||||||
|
add_term("0", "GND");
|
||||||
|
|
||||||
|
pstring line = "";
|
||||||
|
|
||||||
|
for (std::size_t i=0; i < spnl.size(); i++)
|
||||||
|
{
|
||||||
|
// Basic preprocessing
|
||||||
|
pstring inl = spnl[i].trim().ucase();
|
||||||
|
if (inl.startsWith("+"))
|
||||||
|
line = line + inl.substr(1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
process_line(line);
|
||||||
|
line = inl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process_line(line);
|
||||||
|
dump_nl();
|
||||||
|
// FIXME: Parameter
|
||||||
|
out("NETLIST_END()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void nl_convert_spice_t::process_line(const pstring &line)
|
||||||
|
{
|
||||||
|
if (line != "")
|
||||||
|
{
|
||||||
|
pstring_list_t tt(line, " ", true);
|
||||||
|
double val = 0.0;
|
||||||
|
switch (tt[0].cstr()[0])
|
||||||
|
{
|
||||||
|
case ';':
|
||||||
|
out("// %s\n", line.substr(1).cstr());
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
out("// %s\n", line.substr(1).cstr());
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
if (tt[0].equals(".SUBCKT"))
|
||||||
|
{
|
||||||
|
out("NETLIST_START(%s)\n", tt[1].cstr());
|
||||||
|
for (int i=2; i<tt.size(); i++)
|
||||||
|
add_ext_alias(tt[i]);
|
||||||
|
}
|
||||||
|
else if (tt[0].equals(".ENDS"))
|
||||||
|
{
|
||||||
|
dump_nl();
|
||||||
|
out("NETLIST_END()\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out("// %s\n", line.cstr());
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
{
|
||||||
|
bool cerr = false;
|
||||||
|
/* check for fourth terminal ... should be numeric net
|
||||||
|
* including "0" or start with "N" (ltspice)
|
||||||
|
*/
|
||||||
|
// FIXME: we need a is_long method ..
|
||||||
|
ATTR_UNUSED int nval =tt[4].as_long(&cerr);
|
||||||
|
if ((!cerr || tt[4].startsWith("N")) && tt.size() > 5)
|
||||||
|
add_device("QBJT", tt[0], tt[5]);
|
||||||
|
else
|
||||||
|
add_device("QBJT", tt[0], tt[4]);
|
||||||
|
add_term(tt[1], tt[0] + ".C");
|
||||||
|
add_term(tt[2], tt[0] + ".B");
|
||||||
|
add_term(tt[3], tt[0] + ".E");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
val = get_sp_val(tt[3]);
|
||||||
|
add_device("RES", tt[0], val);
|
||||||
|
add_term(tt[1], tt[0] + ".1");
|
||||||
|
add_term(tt[2], tt[0] + ".2");
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
val = get_sp_val(tt[3]);
|
||||||
|
add_device("CAP", tt[0], val);
|
||||||
|
add_term(tt[1], tt[0] + ".1");
|
||||||
|
add_term(tt[2], tt[0] + ".2");
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
// just simple Voltage sources ....
|
||||||
|
if (tt[2].equals("0"))
|
||||||
|
{
|
||||||
|
val = get_sp_val(tt[3]);
|
||||||
|
add_device("ANALOG_INPUT", tt[0], val);
|
||||||
|
add_term(tt[1], tt[0] + ".Q");
|
||||||
|
//add_term(tt[2], tt[0] + ".2");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].cstr());
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
// FIXME: Rewrite resistor value
|
||||||
|
add_device("DIODE", tt[0], tt[3]);
|
||||||
|
add_term(tt[1], tt[0] + ".A");
|
||||||
|
add_term(tt[2], tt[0] + ".K");
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
case 'X':
|
||||||
|
{
|
||||||
|
// FIXME: specific code for KICAD exports
|
||||||
|
// last element is component type
|
||||||
|
// FIXME: Parameter
|
||||||
|
|
||||||
|
pstring xname = tt[0].replace(".", "_");
|
||||||
|
pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP";
|
||||||
|
add_device(tname, xname);
|
||||||
|
for (int i=1; i < tt.size() - 1; i++)
|
||||||
|
{
|
||||||
|
pstring term = pstring::sprintf("%s.%d", xname.cstr(), i);
|
||||||
|
add_term(tt[i], term);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
out("// IGNORED %s: %s\n", tt[0].cstr(), line.cstr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nl_convert_eagle_t::convert(const pstring &contents)
|
||||||
|
{
|
||||||
|
eagle_tokenizer tok(*this);
|
||||||
|
tok.reset(contents.cstr());
|
||||||
|
|
||||||
|
out("NETLIST_START(dummy)\n");
|
||||||
|
add_term("GND", "GND");
|
||||||
|
add_term("VCC", "VCC");
|
||||||
|
eagle_tokenizer::token_t token = tok.get_token();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (token.is_type(eagle_tokenizer::ENDOFFILE))
|
||||||
|
{
|
||||||
|
dump_nl();
|
||||||
|
// FIXME: Parameter
|
||||||
|
out("NETLIST_END()\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (token.is(tok.m_tok_SEMICOLON))
|
||||||
|
{
|
||||||
|
/* ignore empty statements */
|
||||||
|
token = tok.get_token();
|
||||||
|
}
|
||||||
|
else if (token.is(tok.m_tok_ADD))
|
||||||
|
{
|
||||||
|
pstring name = tok.get_string();
|
||||||
|
/* skip to semicolon */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
token = tok.get_token();
|
||||||
|
} while (!token.is(tok.m_tok_SEMICOLON));
|
||||||
|
token = tok.get_token();
|
||||||
|
pstring sval = "";
|
||||||
|
if (token.is(tok.m_tok_VALUE))
|
||||||
|
{
|
||||||
|
pstring vname = tok.get_string();
|
||||||
|
sval = tok.get_string();
|
||||||
|
tok.require_token(tok.m_tok_SEMICOLON);
|
||||||
|
token = tok.get_token();
|
||||||
|
}
|
||||||
|
switch (name.cstr()[0])
|
||||||
|
{
|
||||||
|
case 'Q':
|
||||||
|
{
|
||||||
|
add_device("QBJT", name, sval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
{
|
||||||
|
double val = get_sp_val(sval);
|
||||||
|
add_device("RES", name, val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
{
|
||||||
|
double val = get_sp_val(sval);
|
||||||
|
add_device("CAP", name, val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
if (sval.ucase() == "HIGH")
|
||||||
|
add_device("TTL_INPUT", name, 1);
|
||||||
|
else if (sval.ucase() == "LOW")
|
||||||
|
add_device("TTL_INPUT", name, 0);
|
||||||
|
else
|
||||||
|
add_device("ANALOG_INPUT", name, sval.as_double());
|
||||||
|
add_pin_alias(name, "1", "Q");
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
/* Pin 1 = Anode, Pin 2 = Cathode */
|
||||||
|
add_device("DIODE", name, sval);
|
||||||
|
add_pin_alias(name, "1", "A");
|
||||||
|
add_pin_alias(name, "2", "K");
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
case 'X':
|
||||||
|
{
|
||||||
|
pstring tname = "TTL_" + sval + "_DIP";
|
||||||
|
add_device(tname, name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
tok.error("// IGNORED %s\n", name.cstr());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (token.is(tok.m_tok_SIGNAL))
|
||||||
|
{
|
||||||
|
pstring netname = tok.get_string();
|
||||||
|
token = tok.get_token();
|
||||||
|
while (!token.is(tok.m_tok_SEMICOLON))
|
||||||
|
{
|
||||||
|
/* fixme: should check for string */
|
||||||
|
pstring devname = token.str();
|
||||||
|
pstring pin = tok.get_string();
|
||||||
|
add_term(netname, devname + "." + pin);
|
||||||
|
token = tok.get_token(); }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out("Unexpected %s\n", token.str().cstr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "plib/pstring.h"
|
#include "plib/pstring.h"
|
||||||
#include "plib/plists.h"
|
#include "plib/plists.h"
|
||||||
|
#include "plib/pparser.h"
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
convert - convert a spice netlist
|
convert - convert a spice netlist
|
||||||
@ -37,137 +38,23 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void out(const char *format, ...) ATTR_PRINTF(2,3)
|
void out(const char *format, ...) ATTR_PRINTF(2,3);
|
||||||
{
|
void add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias);
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
m_buf += pstring(format).vprintf(ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
|
void add_ext_alias(const pstring &alias);
|
||||||
{
|
|
||||||
m_pins.add(palloc(sp_pin_alias_t, devname + "." + name, devname + "." + alias), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_ext_alias(const pstring &alias)
|
void add_device(const pstring &atype, const pstring &aname, const pstring &amodel);
|
||||||
{
|
void add_device(const pstring &atype, const pstring &aname, double aval);
|
||||||
m_ext_alias.add(alias);
|
void add_device(const pstring &atype, const pstring &aname);
|
||||||
}
|
|
||||||
|
|
||||||
void add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
|
void add_term(pstring netname, pstring termname);
|
||||||
{
|
|
||||||
devs.add(palloc(sp_dev_t, atype, aname, amodel), false);
|
|
||||||
}
|
|
||||||
void add_device(const pstring &atype, const pstring &aname, double aval)
|
|
||||||
{
|
|
||||||
devs.add(palloc(sp_dev_t, atype, aname, aval), false);
|
|
||||||
}
|
|
||||||
void add_device(const pstring &atype, const pstring &aname)
|
|
||||||
{
|
|
||||||
devs.add(palloc(sp_dev_t, atype, aname), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_term(pstring netname, pstring termname)
|
void dump_nl();
|
||||||
{
|
|
||||||
sp_net_t * net = m_nets.find_by_name(netname);
|
|
||||||
if (net == NULL)
|
|
||||||
{
|
|
||||||
net = palloc(sp_net_t, netname);
|
|
||||||
m_nets.add(net, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if there is a pin alias, translate ... */
|
const pstring get_nl_val(const double val);
|
||||||
sp_pin_alias_t *alias = m_pins.find_by_name(termname);
|
double get_sp_unit(const pstring &unit);
|
||||||
|
|
||||||
if (alias != NULL)
|
double get_sp_val(const pstring &sin);
|
||||||
net->terminals().add(alias->alias());
|
|
||||||
else
|
|
||||||
net->terminals().add(termname);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_nl()
|
|
||||||
{
|
|
||||||
for (int i=0; i<m_ext_alias.size(); i++)
|
|
||||||
{
|
|
||||||
sp_net_t *net = m_nets.find_by_name(m_ext_alias[i]);
|
|
||||||
// use the first terminal ...
|
|
||||||
out("ALIAS(%s, %s)\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr());
|
|
||||||
// if the aliased net only has this one terminal connected ==> don't dump
|
|
||||||
if (net->terminals().size() == 1)
|
|
||||||
net->set_no_export();
|
|
||||||
}
|
|
||||||
for (int i=0; i<devs.size(); i++)
|
|
||||||
{
|
|
||||||
if (devs[i]->has_value())
|
|
||||||
out("%s(%s, %s)\n", devs[i]->type().cstr(),
|
|
||||||
devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr());
|
|
||||||
else if (devs[i]->has_model())
|
|
||||||
out("%s(%s, \"%s\")\n", devs[i]->type().cstr(),
|
|
||||||
devs[i]->name().cstr(), devs[i]->model().cstr());
|
|
||||||
else
|
|
||||||
out("%s(%s)\n", devs[i]->type().cstr(),
|
|
||||||
devs[i]->name().cstr());
|
|
||||||
}
|
|
||||||
// print nets
|
|
||||||
for (int i=0; i<m_nets.size(); i++)
|
|
||||||
{
|
|
||||||
sp_net_t * net = m_nets[i];
|
|
||||||
if (!net->is_no_export())
|
|
||||||
{
|
|
||||||
//printf("Net %s\n", net->name().cstr());
|
|
||||||
out("NET_C(%s", net->terminals()[0].cstr() );
|
|
||||||
for (int j=1; j<net->terminals().size(); j++)
|
|
||||||
{
|
|
||||||
out(", %s", net->terminals()[j].cstr() );
|
|
||||||
}
|
|
||||||
out(")\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
devs.clear_and_free();
|
|
||||||
m_nets.clear_and_free();
|
|
||||||
m_pins.clear_and_free();
|
|
||||||
m_ext_alias.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
const pstring get_nl_val(const double val)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
while (m_sp_units[i].sp_unit != "-" )
|
|
||||||
{
|
|
||||||
if (m_sp_units[i].mult <= nl_math::abs(val))
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return pstring::sprintf(m_sp_units[i].nl_func.cstr(), val / m_sp_units[i].mult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double get_sp_unit(const pstring &unit)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
while (m_sp_units[i].sp_unit != "-")
|
|
||||||
{
|
|
||||||
if (m_sp_units[i].sp_unit == unit)
|
|
||||||
return m_sp_units[i].mult;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "Unit %s unknown\n", unit.cstr());
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_sp_val(const pstring &sin)
|
|
||||||
{
|
|
||||||
int p = sin.len() - 1;
|
|
||||||
while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9"))
|
|
||||||
p--;
|
|
||||||
pstring val = sin.substr(0,p + 1);
|
|
||||||
pstring unit = sin.substr(p + 1);
|
|
||||||
|
|
||||||
double ret = get_sp_unit(unit) * val.as_double();
|
|
||||||
//printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct sp_net_t
|
struct sp_net_t
|
||||||
@ -253,26 +140,6 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nl_convert_base_t::sp_unit nl_convert_base_t::m_sp_units[] = {
|
|
||||||
{"T", "", 1.0e12 },
|
|
||||||
{"G", "", 1.0e9 },
|
|
||||||
{"MEG", "RES_M(%g)", 1.0e6 },
|
|
||||||
{"k", "RES_K(%g)", 1.0e3 }, /* eagle */
|
|
||||||
{"K", "RES_K(%g)", 1.0e3 },
|
|
||||||
{"", "%g", 1.0e0 },
|
|
||||||
{"M", "CAP_M(%g)", 1.0e-3 },
|
|
||||||
{"u", "CAP_U(%g)", 1.0e-6 }, /* eagle */
|
|
||||||
{"U", "CAP_U(%g)", 1.0e-6 },
|
|
||||||
{"µ", "CAP_U(%g)", 1.0e-6 },
|
|
||||||
{"N", "CAP_N(%g)", 1.0e-9 },
|
|
||||||
{"P", "CAP_P(%g)", 1.0e-12},
|
|
||||||
{"F", "%ge-15", 1.0e-15},
|
|
||||||
|
|
||||||
{"MIL", "%e", 25.4e-6},
|
|
||||||
|
|
||||||
{"-", "%g", 1.0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
class nl_convert_spice_t : public nl_convert_base_t
|
class nl_convert_spice_t : public nl_convert_base_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -282,136 +149,11 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(const pstring &contents)
|
void convert(const pstring &contents);
|
||||||
{
|
|
||||||
pstring_list_t spnl(contents, "\n");
|
|
||||||
|
|
||||||
// Add gnd net
|
|
||||||
|
|
||||||
// FIXME: Parameter
|
|
||||||
out("NETLIST_START(dummy)\n");
|
|
||||||
add_term("0", "GND");
|
|
||||||
|
|
||||||
pstring line = "";
|
|
||||||
|
|
||||||
for (std::size_t i=0; i < spnl.size(); i++)
|
|
||||||
{
|
|
||||||
// Basic preprocessing
|
|
||||||
pstring inl = spnl[i].trim().ucase();
|
|
||||||
if (inl.startsWith("+"))
|
|
||||||
line = line + inl.substr(1);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
process_line(line);
|
|
||||||
line = inl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
process_line(line);
|
|
||||||
dump_nl();
|
|
||||||
// FIXME: Parameter
|
|
||||||
out("NETLIST_END()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void process_line(const pstring &line)
|
void process_line(const pstring &line);
|
||||||
{
|
|
||||||
if (line != "")
|
|
||||||
{
|
|
||||||
pstring_list_t tt(line, " ", true);
|
|
||||||
double val = 0.0;
|
|
||||||
switch (tt[0].cstr()[0])
|
|
||||||
{
|
|
||||||
case ';':
|
|
||||||
out("// %s\n", line.substr(1).cstr());
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
out("// %s\n", line.substr(1).cstr());
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
if (tt[0].equals(".SUBCKT"))
|
|
||||||
{
|
|
||||||
out("NETLIST_START(%s)\n", tt[1].cstr());
|
|
||||||
for (int i=2; i<tt.size(); i++)
|
|
||||||
add_ext_alias(tt[i]);
|
|
||||||
}
|
|
||||||
else if (tt[0].equals(".ENDS"))
|
|
||||||
{
|
|
||||||
dump_nl();
|
|
||||||
out("NETLIST_END()\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out("// %s\n", line.cstr());
|
|
||||||
break;
|
|
||||||
case 'Q':
|
|
||||||
{
|
|
||||||
bool cerr = false;
|
|
||||||
/* check for fourth terminal ... should be numeric net
|
|
||||||
* including "0" or start with "N" (ltspice)
|
|
||||||
*/
|
|
||||||
// FIXME: we need a is_long method ..
|
|
||||||
ATTR_UNUSED int nval =tt[4].as_long(&cerr);
|
|
||||||
if ((!cerr || tt[4].startsWith("N")) && tt.size() > 5)
|
|
||||||
add_device("QBJT", tt[0], tt[5]);
|
|
||||||
else
|
|
||||||
add_device("QBJT", tt[0], tt[4]);
|
|
||||||
add_term(tt[1], tt[0] + ".C");
|
|
||||||
add_term(tt[2], tt[0] + ".B");
|
|
||||||
add_term(tt[3], tt[0] + ".E");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
val = get_sp_val(tt[3]);
|
|
||||||
add_device("RES", tt[0], val);
|
|
||||||
add_term(tt[1], tt[0] + ".1");
|
|
||||||
add_term(tt[2], tt[0] + ".2");
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
val = get_sp_val(tt[3]);
|
|
||||||
add_device("CAP", tt[0], val);
|
|
||||||
add_term(tt[1], tt[0] + ".1");
|
|
||||||
add_term(tt[2], tt[0] + ".2");
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
// just simple Voltage sources ....
|
|
||||||
if (tt[2].equals("0"))
|
|
||||||
{
|
|
||||||
val = get_sp_val(tt[3]);
|
|
||||||
add_device("ANALOG_INPUT", tt[0], val);
|
|
||||||
add_term(tt[1], tt[0] + ".Q");
|
|
||||||
//add_term(tt[2], tt[0] + ".2");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].cstr());
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
// FIXME: Rewrite resistor value
|
|
||||||
add_device("DIODE", tt[0], tt[3]);
|
|
||||||
add_term(tt[1], tt[0] + ".A");
|
|
||||||
add_term(tt[2], tt[0] + ".K");
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
case 'X':
|
|
||||||
{
|
|
||||||
// FIXME: specific code for KICAD exports
|
|
||||||
// last element is component type
|
|
||||||
// FIXME: Parameter
|
|
||||||
|
|
||||||
pstring xname = tt[0].replace(".", "_");
|
|
||||||
pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP";
|
|
||||||
add_device(tname, xname);
|
|
||||||
for (int i=1; i < tt.size() - 1; i++)
|
|
||||||
{
|
|
||||||
pstring term = pstring::sprintf("%s.%d", xname.cstr(), i);
|
|
||||||
add_term(tt[i], term);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
out("// IGNORED %s: %s\n", tt[0].cstr(), line.cstr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -471,112 +213,7 @@ public:
|
|||||||
nl_convert_eagle_t &m_convert;
|
nl_convert_eagle_t &m_convert;
|
||||||
};
|
};
|
||||||
|
|
||||||
void convert(const pstring &contents)
|
void convert(const pstring &contents);
|
||||||
{
|
|
||||||
eagle_tokenizer tok(*this);
|
|
||||||
tok.reset(contents.cstr());
|
|
||||||
|
|
||||||
out("NETLIST_START(dummy)\n");
|
|
||||||
add_term("GND", "GND");
|
|
||||||
add_term("VCC", "VCC");
|
|
||||||
eagle_tokenizer::token_t token = tok.get_token();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (token.is_type(eagle_tokenizer::ENDOFFILE))
|
|
||||||
{
|
|
||||||
dump_nl();
|
|
||||||
// FIXME: Parameter
|
|
||||||
out("NETLIST_END()\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (token.is(tok.m_tok_SEMICOLON))
|
|
||||||
{
|
|
||||||
/* ignore empty statements */
|
|
||||||
token = tok.get_token();
|
|
||||||
}
|
|
||||||
else if (token.is(tok.m_tok_ADD))
|
|
||||||
{
|
|
||||||
pstring name = tok.get_string();
|
|
||||||
/* skip to semicolon */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
token = tok.get_token();
|
|
||||||
} while (!token.is(tok.m_tok_SEMICOLON));
|
|
||||||
token = tok.get_token();
|
|
||||||
pstring sval = "";
|
|
||||||
if (token.is(tok.m_tok_VALUE))
|
|
||||||
{
|
|
||||||
pstring vname = tok.get_string();
|
|
||||||
sval = tok.get_string();
|
|
||||||
tok.require_token(tok.m_tok_SEMICOLON);
|
|
||||||
token = tok.get_token();
|
|
||||||
}
|
|
||||||
switch (name.cstr()[0])
|
|
||||||
{
|
|
||||||
case 'Q':
|
|
||||||
{
|
|
||||||
add_device("QBJT", name, sval);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
{
|
|
||||||
double val = get_sp_val(sval);
|
|
||||||
add_device("RES", name, val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
{
|
|
||||||
double val = get_sp_val(sval);
|
|
||||||
add_device("CAP", name, val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
if (sval.ucase() == "HIGH")
|
|
||||||
add_device("TTL_INPUT", name, 1);
|
|
||||||
else if (sval.ucase() == "LOW")
|
|
||||||
add_device("TTL_INPUT", name, 0);
|
|
||||||
else
|
|
||||||
add_device("ANALOG_INPUT", name, sval.as_double());
|
|
||||||
add_pin_alias(name, "1", "Q");
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
/* Pin 1 = Anode, Pin 2 = Cathode */
|
|
||||||
add_device("DIODE", name, sval);
|
|
||||||
add_pin_alias(name, "1", "A");
|
|
||||||
add_pin_alias(name, "2", "K");
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
case 'X':
|
|
||||||
{
|
|
||||||
pstring tname = "TTL_" + sval + "_DIP";
|
|
||||||
add_device(tname, name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
tok.error("// IGNORED %s\n", name.cstr());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (token.is(tok.m_tok_SIGNAL))
|
|
||||||
{
|
|
||||||
pstring netname = tok.get_string();
|
|
||||||
token = tok.get_token();
|
|
||||||
while (!token.is(tok.m_tok_SEMICOLON))
|
|
||||||
{
|
|
||||||
/* fixme: should check for string */
|
|
||||||
pstring devname = token.str();
|
|
||||||
pstring pin = tok.get_string();
|
|
||||||
add_term(netname, devname + "." + pin);
|
|
||||||
token = tok.get_token(); }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
out("Unexpected %s\n", token.str().cstr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
32
src/mame/nl.lst
Normal file
32
src/mame/nl.lst
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
nl.lst
|
||||||
|
|
||||||
|
List of all drivers using netlist code. This file is parsed by then
|
||||||
|
genie build system.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
1942 // 12/1984 (c) 1984
|
||||||
|
1942a // 12/1984 (c) 1984
|
||||||
|
1942abl // bootleg
|
||||||
|
1942b // 12/1984 (c) 1984
|
||||||
|
1942w // 12/1984 (c) 1984 + Williams Electronics license (c) 1985
|
||||||
|
1942p // prototype
|
||||||
|
1942h // hack (Two Bit Score?)
|
||||||
|
popeye // (c) 1982
|
||||||
|
popeyeu // (c) 1982
|
||||||
|
popeyef // (c) 1982
|
||||||
|
popeyebl // bootleg
|
||||||
|
|
||||||
|
// mario
|
||||||
|
|
||||||
|
|
||||||
|
// Atari 100% TTL
|
||||||
|
pong // (c) 1972 Atari
|
||||||
|
pongd // (c) 1975 Atari
|
||||||
|
pongf // (c) 1972 Atari
|
||||||
|
breakout // (c) 1976 Atari
|
||||||
|
|
Loading…
Reference in New Issue
Block a user