/*
 * Electric(tm) VLSI Design System
 *
 * File: tecmocmos.c
 * MOSIS CMOS technology description
 * Written by: Steven M. Rubin, Static Free Software
 * Specified by: Dick Lyon and Carver Mead
 *
 * Copyright (c) 2000 Static Free Software.
 *
 * Electric(tm) is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Electric(tm) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Electric(tm); see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, Mass 02111-1307, USA.
 *
 * Static Free Software
 * 4119 Alpine Road
 * Portola Valley, California 94028
 * info@staticfreesoft.com
 */

#include "config.h"
#if TECMOCMOS

#include "global.h"
#include "egraphics.h"
#include "tech.h"
#include "tecmocmos.h"
#include "efunction.h"

/* prototypes for local routines */
void mocmos_setpseudo(void);

/*
 * this technology has six important layers to draw:
 *     metal-1, metal-2, poly, active, select, and well
 * Since three bitplanes are used by the system, not all of these layers
 * can have their own bitplanes.  For example, with 8-bit color maps, only
 * five of these can have their own bitplanes.
 * Therefore, the layers are ordered in the following importance:
 *    metal-1, poly, active	always in their own bitplane (6-bits or more)
 *    metal-2                   for 7-bits
 *    well                      for 8-bits
 *    select                    for 9-bits
 * When a layer cannot have its own bitplane, it is drawn with stipple patterns.
 * On certain displays (notably VAX frame buffers) this cannot be done.
 * Therefore, use "technology tell mocmos outline-layers"
 *
 * By default, this technology assumes the General CMOS process, where CIF
 * layers CSG and CWG are used for select and well.  It can also handle the
 * Either CMOS process, where CIF layers CSP and CWP are used for P-type
 * select/well and CSN and CWN are used for N-type select/well.  The Either
 * mode, set with "technology tell mocmos either-process", causes both P and
 * N layers to be written for all components so that either process can be
 * selected after design is complete.
 *
 * This technology can also switch from P-well (the default) to N-well with
 * "technology tell mocmos n-well".  This switching works properly regardless
 * of the General/Either process selection.
 */

/* the options table */
static KEYWORD mocmosopt[] =
{
	{"p-well",                     0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"n-well",                     0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"general-process",            0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"either-process",             0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"stipple-layers",             0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"outline-layers",             0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"convert-old-format-library", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	TERMKEY
};
COMCOMP mocmos_parse = {mocmosopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, 0, " \t", M_("MOSIS CMOS option"), M_("show current options")};

#define	EITHER    1		/* set for either, cleared for general */
#define	OUTLINE   2		/* set to outline layers, clear for stipple */
#define	NWELL     4		/* set for n-well, clear for p-well */
static INTSML mocmos_state = 0;
static TECHNOLOGY *mocmos_tech;
static char *mocmos_stipplelayers = "Select and Passivation";

/******************** LAYERS ********************/

#define	MAXLAYERS 26		/* total layers below         */
#define	LMETAL1    0		/* metal layer 1              */
#define	LMETAL2    1		/* metal layer 2              */
#define	LPOLY      2		/* polysilicon                */
#define	LSACT      3		/* S active (diffusion)       */
#define	LDACT      4		/* D active (diffusion)       */
#define	LSELECTP   5		/* P-type select              */
#define	LSELECTN   6		/* N-type select              */
#define	LWELLP     7		/* P-type well                */
#define	LWELLN     8		/* N-type well                */
#define	LCUT       9		/* contact cut                */
#define	LVIA      10		/* metal-to-metal via         */
#define	LPASS     11		/* passivation (overglass)    */
#define	LTRANS    12		/* transistor                 */
#define	LPOLYCUT  13		/* poly contact cut           */
#define	LACTCUT   14		/* active contact cut         */
#define	LSACTWELL 15		/* S active in well           */
#define	LMET1P    16		/* pseudo metal 1             */
#define	LMET2P    17		/* pseudo metal 2             */
#define	LPOLYP    18		/* pseudo polysilicon         */
#define	LSACTP    19		/* pseudo S active            */
#define	LDACTP    20		/* pseudo D active            */
#define	LSELECTPP 21		/* pseudo P-type select       */
#define	LSELECTNP 22		/* pseudo N-type select       */
#define	LWELLPP   23		/* pseudo P-type well         */
#define	LWELLNP   24		/* pseudo N-type well         */
#define	LFRAME    25		/* pad frame boundary         */

static GRAPHICS mocmos_m1_lay = {LAYERT1,COLORT1, SOLIDC, PATTERNED,
/* metal-1 layer */		{0x2222, /*   X   X   X   X  */
						0x0000,  /*                  */
						0x8888,  /* X   X   X   X    */
						0x0000,  /*                  */
						0x2222,  /*   X   X   X   X  */
						0x0000,  /*                  */
						0x8888,  /* X   X   X   X    */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_m2_lay = {LAYERT4,COLORT4, SOLIDC, PATTERNED,
/* metal-2 layer */		{0x1010, /*    X       X     */
						0x2020,  /*   X       X      */
						0x4040,  /*  X       X       */
						0x8080,  /* X       X        */
						0x0101,  /*        X       X */
						0x0202,  /*       X       X  */
						0x0404,  /*      X       X   */
						0x0808}, /*     X       X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_p_lay = {LAYERT2,COLORT2, SOLIDC, PATTERNED,
/* poly layer */		{0x0808, /*     X       X    */
						0x0404,  /*      X       X   */
						0x0202,  /*       X       X  */
						0x0101,  /*        X       X */
						0x8080,  /* X       X        */
						0x4040,  /*  X       X       */
						0x2020,  /*   X       X      */
						0x1010}, /*    X       X     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_sa_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* S active layer */	{0x0000, /*                  */
						0x0303,  /*       XX      XX */
						0x4848,  /*  X  X    X  X    */
						0x0303,  /*       XX      XX */
						0x0000,  /*                  */
						0x3030,  /*   XX      XX     */
						0x8484,  /* X    X  X    X   */
						0x3030}, /*   XX      XX     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_da_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* D active layer */	{0x0000, /*                  */
						0x0303,  /*       XX      XX */
						0x4848,  /*  X  X    X  X    */
						0x0303,  /*       XX      XX */
						0x0000,  /*                  */
						0x3030,  /*   XX      XX     */
						0x8484,  /* X    X  X    X   */
						0x3030}, /*   XX      XX     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_ssp_lay = {LAYERO,YELLOW, PATTERNED, PATTERNED,
/* P Select layer */	{0x1010, /*    X       X     */
						0x2020,  /*   X       X      */
						0x4040,  /*  X       X       */
						0x8080,  /* X       X        */
						0x0101,  /*        X       X */
						0x0202,  /*       X       X  */
						0x0404,  /*      X       X   */
						0x0808}, /*     X       X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_ssn_lay = {LAYERN,YELLOW, PATTERNED, PATTERNED,
/* N Select layer */	{0x1010, /*    X       X     */
						0x2020,  /*   X       X      */
						0x4040,  /*  X       X       */
						0x8080,  /* X       X        */
						0x0101,  /*        X       X */
						0x0202,  /*       X       X  */
						0x0404,  /*      X       X   */
						0x0808}, /*     X       X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_wp_lay = {LAYERT5,COLORT5, SOLIDC, PATTERNED,
/* P Well implant */	{0x1000, /*    X             */
						0x0020,  /*           X      */
						0x0000,  /*                  */
						0x0000,  /*                  */
						0x0001,  /*                X */
						0x0200,  /*       X          */
						0x0000,  /*                  */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_wn_lay = {LAYERN,COLORT5, SOLIDC, PATTERNED,
/* N Well implant */	{0x1000, /*    X             */
						0x0020,  /*           X      */
						0x0000,  /*                  */
						0x0000,  /*                  */
						0x0001,  /*                X */
						0x0200,  /*       X          */
						0x0000,  /*                  */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_c_lay = {LAYERO,BLACK, SOLIDC, SOLIDC,
/* cut layer */		{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_v_lay = {LAYERO,BLACK, SOLIDC, SOLIDC,
/* via layer */		{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_ovs_lay = {LAYERO,DGRAY, PATTERNED, PATTERNED,
/* passivation layer */	{0x1C1C, /*    XXX     XXX   */
						0x3E3E,  /*   XXXXX   XXXXX  */
						0x3636,  /*   XX XX   XX XX  */
						0x3E3E,  /*   XXXXX   XXXXX  */
						0x1C1C,  /*    XXX     XXX   */
						0x0000,  /*                  */
						0x0000,  /*                  */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_tr_lay = {LAYERN,ALLOFF, SOLIDC, SOLIDC,
/* transistor layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_pc_lay = {LAYERO,BLACK, SOLIDC, SOLIDC,
/* poly cut layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_ac_lay = {LAYERO,BLACK, SOLIDC, SOLIDC,
/* active cut layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_saw_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* S act well layer */	{0x0000, /*                  */
						0x0303,  /*       XX      XX */
						0x4848,  /*  X  X    X  X    */
						0x0303,  /*       XX      XX */
						0x0000,  /*                  */
						0x3030,  /*   XX      XX     */
						0x8484,  /* X    X  X    X   */
						0x3030}, /*   XX      XX     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pm1_lay ={LAYERT1,COLORT1, SOLIDC, PATTERNED,
/* pseudo metal 1 */	{0x2222, /*   X   X   X   X  */
						0x0000,  /*                  */
						0x8888,  /* X   X   X   X    */
						0x0000,  /*                  */
						0x2222,  /*   X   X   X   X  */
						0x0000,  /*                  */
						0x8888,  /* X   X   X   X    */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pm2_lay = {LAYERT4,COLORT4, SOLIDC, PATTERNED,
/* pseudo metal-2 */	{0x1010, /*    X       X     */
						0x2020,  /*   X       X      */
						0x4040,  /*  X       X       */
						0x8080,  /* X       X        */
						0x0101,  /*        X       X */
						0x0202,  /*       X       X  */
						0x0404,  /*      X       X   */
						0x0808}, /*     X       X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pp_lay = {LAYERT2,COLORT2, SOLIDC, PATTERNED,
/* pseudo poly layer */	{0x0808, /*     X       X    */
						0x0404,  /*      X       X   */
						0x0202,  /*       X       X  */
						0x0101,  /*        X       X */
						0x8080,  /* X       X        */
						0x4040,  /*  X       X       */
						0x2020,  /*   X       X      */
						0x1010}, /*    X       X     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_psa_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* pseudo S active */	{0x0000, /*                  */
						0x0303,  /*       XX      XX */
						0x4848,  /*  X  X    X  X    */
						0x0303,  /*       XX      XX */
						0x0000,  /*                  */
						0x3030,  /*   XX      XX     */
						0x8484,  /* X    X  X    X   */
						0x3030}, /*   XX      XX     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pda_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* pseudo D active */	{0x0000, /*                  */
						0x0303,  /*       XX      XX */
						0x4848,  /*  X  X    X  X    */
						0x0303,  /*       XX      XX */
						0x0000,  /*                  */
						0x3030,  /*   XX      XX     */
						0x8484,  /* X    X  X    X   */
						0x3030}, /*   XX      XX     */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pssp_lay = {LAYERO,YELLOW,PATTERNED, PATTERNED,
/* pseudo P Select */	{0x1010, /*    X       X     */
						0x2020,  /*   X       X      */
						0x4040,  /*  X       X       */
						0x8080,  /* X       X        */
						0x0101,  /*        X       X */
						0x0202,  /*       X       X  */
						0x0404,  /*      X       X   */
						0x0808}, /*     X       X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pssn_lay = {LAYERN,YELLOW,PATTERNED, PATTERNED,
/* pseudo N Select */	{0x1010, /*    X       X     */
						0x2020,  /*   X       X      */
						0x4040,  /*  X       X       */
						0x8080,  /* X       X        */
						0x0101,  /*        X       X */
						0x0202,  /*       X       X  */
						0x0404,  /*      X       X   */
						0x0808}, /*     X       X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pwp_lay = {LAYERT5,COLORT5, SOLIDC, PATTERNED,
/* pseudo P Well */		{0x1000, /*    X             */
						0x0020,  /*           X      */
						0x0000,  /*                  */
						0x0000,  /*                  */
						0x0001,  /*                X */
						0x0200,  /*       X          */
						0x0000,  /*                  */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pwn_lay = {LAYERN,COLORT5, SOLIDC, PATTERNED,
/* pseudo N Well */		{0x1000, /*    X             */
						0x0020,  /*           X      */
						0x0000,  /*                  */
						0x0000,  /*                  */
						0x0001,  /*                X */
						0x0200,  /*       X          */
						0x0000,  /*                  */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pf_lay = {LAYERO, RED, SOLIDC, PATTERNED,
/* pad frame */		{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};

/* these tables must be updated together */
GRAPHICS *mocmos_layers[MAXLAYERS+1] = {&mocmos_m1_lay, &mocmos_m2_lay,
	&mocmos_p_lay, &mocmos_sa_lay, &mocmos_da_lay, &mocmos_ssp_lay,
	&mocmos_ssn_lay, &mocmos_wp_lay, &mocmos_wn_lay, &mocmos_c_lay,
	&mocmos_v_lay, &mocmos_ovs_lay, &mocmos_tr_lay, &mocmos_pc_lay,
	&mocmos_ac_lay, &mocmos_saw_lay, &mocmos_pm1_lay, &mocmos_pm2_lay,
	&mocmos_pp_lay, &mocmos_psa_lay, &mocmos_pda_lay, &mocmos_pssp_lay,
	&mocmos_pssn_lay, &mocmos_pwp_lay, &mocmos_pwn_lay, &mocmos_pf_lay, NOGRAPHICS};
static char *mocmos_layer_names[MAXLAYERS] = {"Metal-1", "Metal-2",
	"Polysilicon", "S-Active", "D-Active", "P-Select", "N-Select", "P-Well",
	"N-Well", "Contact-Cut", "Via", "Passivation", "Transistor", "Poly-Cut",
	"Active-Cut", "S-Active-Well", "Pseudo-Metal-1", "Pseudo-Metal-2",
	"Pseudo-Polysilicon", "Pseudo-S-Active", "Pseudo-D-Active",
	"Pseudo-P-Select", "Pseudo-N-Select", "Pseudo-P-Well", "Pseudo-N-Well",
	"Pad-Frame"};
static INTBIG mocmos_layer_function[MAXLAYERS] = {LFMETAL1|LFTRANS1,
	LFMETAL2|LFTRANS4, LFPOLY1|LFTRANS2, LFDIFF|LFPTYPE|LFTRANS3,
	LFDIFF|LFNTYPE|LFTRANS3, LFIMPLANT|LFPTYPE, LFIMPLANT|LFNTYPE,
	LFWELL|LFPTYPE|LFTRANS5, LFWELL|LFNTYPE|LFTRANS5, LFCONTACT1,
	LFCONTACT2|LFCONMETAL, LFOVERGLASS, LFTRANSISTOR|LFPSEUDO,
	LFCONTACT1|LFCONPOLY, LFCONTACT1|LFCONDIFF,
	LFDIFF|LFPTYPE|LFTRANS3, LFMETAL1|LFPSEUDO|LFTRANS1,
	LFMETAL2|LFPSEUDO|LFTRANS4, LFPOLY1|LFPSEUDO|LFTRANS2,
	LFDIFF|LFPTYPE|LFPSEUDO|LFTRANS3, LFDIFF|LFNTYPE|LFPSEUDO|LFTRANS3,
	LFIMPLANT|LFPTYPE|LFPSEUDO, LFIMPLANT|LFNTYPE|LFPSEUDO,
	LFWELL|LFPTYPE|LFPSEUDO|LFTRANS5, LFWELL|LFNTYPE|LFPSEUDO|LFTRANS5,
	LFART};
static char *mocmos_cif_layers[MAXLAYERS] = {"CMF", "CMS", "CPG", "CAA", "CAA",
	"CSG", "CSG", "CWG", "CWG", "CC", "CVA", "COG", "", "CCP", "CCA", "CAA", "",
	"", "", "", "", "", "", "", "", "CX"};
static INTBIG mocmos_gds_layers[MAXLAYERS] = {10, 19, 12, 2, 2, 8, 7, 1, 1, 9,
	18, 11, -1, 9, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
static char *mocmos_layer_letters[MAXLAYERS] = {"m", "h", "p", "s", "d", "e",
	"f", "w", "n", "c", "v", "o", "t", "a", "A", "x", "M", "H", "P", "S", "D",
	"E", "F", "W", "N", "b"};

/*
 * tables for converting between stipples and outlines
 */
static GRAPHICS *mocmos_layerstipple[] =
{
	&mocmos_ssn_lay,
	&mocmos_ssp_lay,
	&mocmos_ovs_lay,
	&mocmos_pssn_lay,
	&mocmos_pssp_lay,
	&mocmos_wp_lay,
	&mocmos_wn_lay,
	&mocmos_pwp_lay,
	&mocmos_pwn_lay,
	&mocmos_m2_lay,
	&mocmos_pm2_lay
};
static INTSML mocmos_layerstipplesize = 5;

/* The low 5 bits map Metal-1, Poly, Active, Metal-2}, and well */
static TECH_COLORMAP mocmos_colmap[32] =
{                  /*     well metal2 active poly metal1 */
	{200,200,200}, /* 0:                                 */
	{ 96,209,255}, /* 1:                          metal1 */
	{255,155,192}, /* 2:                     poly        */
	{ 96,127,192}, /* 3:                     poly+metal1 */
	{107,226, 96}, /* 4:              active             */
	{ 40,186, 96}, /* 5:              active+     metal1 */
	{107,137, 72}, /* 6:              active+poly        */
	{ 40,113, 72}, /* 7:              active+poly+metal1 */
	{224, 95,255}, /* 8:       metal2                    */
	{ 85, 78,255}, /* 9:       metal2+            metal1 */
	{224, 57,192}, /* 10:      metal2+       poly        */
	{ 85, 47,192}, /* 11:      metal2+       poly+metal1 */
	{ 94, 84, 96}, /* 12:      metal2+active             */
	{ 36, 69, 96}, /* 13:      metal2+active+     metal1 */
	{ 94, 51, 72}, /* 14:      metal2+active+poly        */
	{ 36, 42, 72}, /* 15:      metal2+active+poly+metal1 */
	{240,221,181}, /* 16: well                           */
	{ 91,182,181}, /* 17: well+                   metal1 */
	{240,134,136}, /* 18: well+              poly        */
	{ 91,111,136}, /* 19: well+              poly+metal1 */
	{101,196, 68}, /* 20: well+       active             */
	{ 38,161, 68}, /* 21: well+       active+     metal1 */
	{101,119, 51}, /* 22: well+       active+poly        */
	{ 38, 98, 51}, /* 23: well+       active+poly+metal1 */
	{211, 82,181}, /* 24: well+metal2                    */
	{ 80, 68,181}, /* 25: well+metal2+            metal1 */
	{211, 50,136}, /* 26: well+metal2+       poly        */
	{ 80, 41,136}, /* 27: well+metal2+       poly+metal1 */
	{ 89, 73, 68}, /* 28: well+metal2+active             */
	{ 33, 60, 68}, /* 29: well+metal2+active+     metal1 */
	{ 89, 44, 51}, /* 30: well+metal2+active+poly        */
	{ 33, 36, 51}  /* 31: well+metal2+active+poly+metal1 */
};

/******************** DESIGN RULES ********************/

#define	X	XX
#define	A	K1
#define	B	K2
#define	C	K3
#define	D	K4
#define	E	K5

/* layers that can connect to other layers when electrically disconnected */
static INTBIG mocmos_unconnectedtable[] = {
/*          M M P S D S S W W C V P T P A S M M P S D S S W W P */
/*          e e o A A e e e e u i a r o c a e e o A A e e e e a */
/*          t t l c c l l l l t a s a l t c t t l c c l l l l d */
/*          1 2 y t t P N l l     s n y C t 1 2 y t t P N P N F */
/*                        P N       s C   W P P P P P P P P P r */
/* Met1  */ C,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Met2  */   D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Poly  */     B,A,A,X,X,X,X,X,B,X,X,D,X,X,X,X,X,X,X,X,X,X,X,X,
/* SAct  */       C,C,X,X,D,X,X,B,X,X,X,E,X,X,X,X,X,X,X,X,X,X,X,
/* DAct  */         C,X,X,X,X,X,B,X,X,X,E,X,X,X,X,X,X,X,X,X,X,X,
/* SelP  */           X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* SelN  */             X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* WellP */               X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* WellN */                 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Cut   */                   B,B,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Via   */                     B,X,B,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Pass  */                       X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Trans */                         X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* PolyC */                           X,X,X,X,X,X,X,X,X,X,X,X,X,
/* ActC  */                             X,X,X,X,X,X,X,X,X,X,X,X,
/* SactW */                               X,X,X,X,X,X,X,X,X,X,X,
/* Met1P */                                 X,X,X,X,X,X,X,X,X,X,
/* Met2P */                                   X,X,X,X,X,X,X,X,X,
/* PolyP */                                     X,X,X,X,X,X,X,X,
/* SActP */                                       X,X,X,X,X,X,X,
/* DActP */                                         X,X,X,X,X,X,
/* SelPP */                                           X,X,X,X,X,
/* SelNP */                                             X,X,X,X,
/* WelPP */                                               X,X,X,
/* WelNP */                                                 X,X,
/* PadFr */                                                   X,
};

/* layers that can connect to other layers when electrically connected */
static INTBIG mocmos_connectedtable[] = {
/*          M M P S D S S W W C V P T P A S M M P S D S S W W P */
/*          e e o A A e e e e u i a r o c a e e o A A e e e e a */
/*          t t l c c l l l l t a s a l t c t t l c c l l l l d */
/*          1 2 y t t P N l l     s n y C t 1 2 y t t P N P N F */
/*                        P N       s C   W P P P P P P P P P r */
/* Met1  */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Met2  */   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Poly  */     X,A,A,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* SAct  */       X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* DAct  */         X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* SelP  */           X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* SelN  */             X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* WellP */               X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* WellN */                 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Cut   */                   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Via   */                     B,X,X,B,B,X,X,X,X,X,X,X,X,X,X,X,
/* Pass  */                       X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Trans */                         X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* PolyC */                           B,X,X,X,X,X,X,X,X,X,X,X,X,
/* ActC  */                             B,X,X,X,X,X,X,X,X,X,X,X,
/* SactW */                               X,X,X,X,X,X,X,X,X,X,X,
/* Met1P */                                 X,X,X,X,X,X,X,X,X,X,
/* Met2P */                                   X,X,X,X,X,X,X,X,X,
/* PolyP */                                     X,X,X,X,X,X,X,X,
/* SActP */                                       X,X,X,X,X,X,X,
/* DActP */                                         X,X,X,X,X,X,
/* SelPP */                                           X,X,X,X,X,
/* SelNP */                                             X,X,X,X,
/* WelPP */                                               X,X,X,
/* WelNP */                                                 X,X,
/* PadFr */                                                   X,
};

/******************** ARCS ********************/

#define	ARCPROTOCOUNT  6
#define	AMETAL1        0	/* metal-1                   */
#define	AMETAL2        1	/* metal-2                   */
#define	APOLY          2	/* polysilicon               */
#define	ASACT          3	/* S-active                  */
#define	ADACT          4	/* D-active                  */
#define	AACT           5	/* General active            */

/* metal 1 arc */
static TECH_ARCLAY mocmos_al_m1[] = {{LMETAL1,0,FILLED }};
static TECH_ARCS mocmos_a_m1 = {
	"Metal-1",K3,AMETAL1,											/* name */
	1,mocmos_al_m1,													/* layers */
	(APMETAL1<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* metal 2 arc */
static TECH_ARCLAY mocmos_al_m2[] = {{LMETAL2,0,FILLED }};
static TECH_ARCS mocmos_a_m2 = {
	"Metal-2",K3,AMETAL2,											/* name */
	1,mocmos_al_m2,													/* layers */
	(APMETAL2<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* polysilicon arc */
static TECH_ARCLAY mocmos_al_p[] = {{LPOLY,0,FILLED }};
static TECH_ARCS mocmos_a_po = {
	"Polysilicon",K2,APOLY,											/* name */
	1,mocmos_al_p,													/* layers */
	(APPOLY1<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* S-active arc */
static TECH_ARCLAY mocmos_al_pa[] = {{LSACT,K8,FILLED}, {LWELLNP,0,FILLED},
	{LSELECTP,K4,FILLED}};
static TECH_ARCS mocmos_a_pa = {
	"S-Active",K10,ASACT,											/* name */
	3,mocmos_al_pa,													/* layers */
	(APDIFFP<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* D-active arc */
static TECH_ARCLAY mocmos_al_na[] = {{LDACT,K8,FILLED}, {LWELLP,0,FILLED},
	{LSELECTNP,K4,FILLED}};
static TECH_ARCS mocmos_a_na = {
	"D-Active",K10,ADACT,											/* name */
	3,mocmos_al_na,													/* layers */
	(APDIFFN<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* General active arc */
static TECH_ARCLAY mocmos_al_a[] = {{LDACT,0,FILLED}, {LSACT,0,FILLED}};
static TECH_ARCS mocmos_a_a = {
	"Active",K2,AACT,												/* name */
	2,mocmos_al_a,													/* layers */
	(APDIFF<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

TECH_ARCS *mocmos_arcprotos[ARCPROTOCOUNT+1] = {
	&mocmos_a_m1, &mocmos_a_m2, &mocmos_a_po, &mocmos_a_pa, &mocmos_a_na,
	&mocmos_a_a, ((TECH_ARCS *)-1)};

static INTBIG mocmos_arc_widoff[ARCPROTOCOUNT] = {0,0,0,K8,K8,0};

/*
 * tables for converting between stipples and outlines
 */
struct
{
	TECH_ARCLAY *str;
	INTSML        layer;
} mocmos_arcstipple[] =
{
	{mocmos_al_pa, 2},		/* select-p */
	{mocmos_al_na, 2},		/* select-n */
	{mocmos_al_pa, 1},		/* well-n */
	{mocmos_al_na, 1},		/* well-p */
	{mocmos_al_m2, 0}		/* metal-2 */
};
static INTSML mocmos_arcstipplesize = 2;

/******************** PORTINST CONNECTIONS ********************/

static INTBIG mocmos_pc_m1[]   = {-1, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_m1a[]  = {-1, AMETAL1, AACT, ALLGEN, -1};
static INTBIG mocmos_pc_m2[]   = {-1, AMETAL2, ALLGEN, -1};
static INTBIG mocmos_pc_p[]    = {-1, APOLY, ALLGEN, -1};
static INTBIG mocmos_pc_pa[]   = {-1, ASACT, ALLGEN, -1};
static INTBIG mocmos_pc_a[]    = {-1, AACT, ASACT, ADACT, ALLGEN,-1};
static INTBIG mocmos_pc_na[]   = {-1, ADACT, ALLGEN, -1};
static INTBIG mocmos_pc_pam1[] = {-1, ASACT, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_nam1[] = {-1, ADACT, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_pm1[]  = {-1, APOLY, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_mm[]   = {-1, AMETAL1, AMETAL2, ALLGEN, -1};
static INTBIG mocmos_pc_null[] = {-1, ALLGEN, -1};

/******************** NODES ********************/

#define	NODEPROTOCOUNT 29
#define	NMETAL1P        1	/* metal-1 pin */
#define	NMETAL2P        2	/* metal-2 pin */
#define	NPOLYP          3	/* polysilicon pin */
#define	NSACTP          4	/* S-active pin */
#define	NDACTP          5	/* D-active pin */
#define	NACTP           6	/* General active pin */
#define	NMETSACTC       7	/* metal-1-S-active contact */
#define	NMETDACTC       8	/* metal-1-D-active contact */
#define	NMETPOLYC       9	/* metal-1-polysilicon contact */
#define	NSTRANS        10	/* S-transistor */
#define	NDTRANS        11	/* D-transistor */
#define	NVIA           12	/* metal-1-metal-2 contact */
#define	NWBUT          13	/* metal-1-Well contact */
#define	NSBUT          14	/* metal-1-Substrate contact */
#define	NMETAL1N       15	/* metal-1 node */
#define	NMETAL2N       16	/* metal-2 node */
#define	NPOLYN         17	/* polysilicon node */
#define	NACTIVEN       18	/* active node */
#define	NDACTIVEN      19	/* D-active node */
/* Why no S-Active Node??? */
#define	NSELECTPN      20	/* P-select node */
#define	NSELECTNN      21	/* N-select node */
#define	NCUTN          22	/* cut node */
#define	NPCUTN         23	/* poly cut node */
#define	NACUTN         24	/* active cut node */
#define	NVIAN          25	/* via node */
#define	NWELLPN        26	/* P-well node */
#define	NWELLNN        27	/* N-well node */
#define	NPASSN         28	/* passivation node */
#define	NPADFRN        29	/* pad frame node */

/* for geometry */
static INTBIG mocmos_cutbox[8]  = {LEFTIN1,  BOTIN1,   LEFTIN3,   BOTIN3};/*adjust*/
static INTBIG mocmos_fullbox[8] = {LEFTEDGE, BOTEDGE,  RIGHTEDGE, TOPEDGE};
static INTBIG mocmos_min1box[16]= {LEFTIN1,  BOTIN1,   RIGHTIN1,  TOPIN1,
								  CENTERL2, CENTERD2, CENTERR2,  CENTERU2};
static INTBIG mocmos_in2box[8]  = {LEFTIN2,  BOTIN2,   RIGHTIN2,  TOPIN2};
static INTBIG mocmos_in4box[8]  = {LEFTIN4,  BOTIN4,   RIGHTIN4,  TOPIN4};
static INTBIG mocmos_in5box[8]  = {LEFTIN5,  BOTIN5,   RIGHTIN5,  TOPIN5};
static INTBIG mocmos_min5box[16]= {LEFTIN5,  BOTIN5,   RIGHTIN5,  TOPIN5,
								  CENTERL2, CENTERD2, CENTERR2,  CENTERU2};
static INTBIG mocmos_trdabox[8] = {LEFTIN4,  BOTIN4,   RIGHTIN4,  TOPIN4};
static INTBIG mocmos_trdpbox[8] = {LEFTIN2,  BOTIN6,   RIGHTIN2,  TOPIN6};
static INTBIG mocmos_trd1box[8] = {LEFTIN4,  BOTIN6,   RIGHTIN4,  TOPIN6};
static INTBIG mocmos_trd2box[8] = {LEFTIN4,  TOPIN5,   RIGHTIN4,  TOPIN4};
static INTBIG mocmos_trd3box[8] = {LEFTIN4,  BOTIN4,   RIGHTIN4,  BOTIN5};

/* metal-1-pin */
static TECH_PORTS mocmos_pm1_p[] = {				/* ports */
	{mocmos_pc_m1, "metal-1", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pm1_l[] = {				/* layers */
	{LMET1P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pm1 = {
	"Metal-1-Pin",NMETAL1P,NONODEPROTO,				/* name */
	K4,K4,											/* size */
	1,mocmos_pm1_p,									/* ports */
	1,mocmos_pm1_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* metal-2-pin */
static TECH_PORTS mocmos_pm2_p[] = {				/* ports */
	{mocmos_pc_m2, "metal-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pm2_l[] = {				/* layers */
	{LMET2P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pm2 = {
	"Metal-2-Pin",NMETAL2P,NONODEPROTO,				/* name */
	K4,K4,											/* size */
	1,mocmos_pm2_p,									/* ports */
	1,mocmos_pm2_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* polysilicon-pin */
static TECH_PORTS mocmos_pp_p[] = {					/* ports */
	{mocmos_pc_p, "polysilicon", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_pp_l[] = {				/* layers */
	{LPOLYP, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pp = {
	"Polysilicon-Pin",NPOLYP,NONODEPROTO,			/* name */
	K2,K2,											/* size */
	1,mocmos_pp_p,									/* ports */
	1,mocmos_pp_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* S-active-pin */
static TECH_PORTS mocmos_psa_p[] = {				/* ports */
	{mocmos_pc_pa, "s-active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN5, BOTIN5, RIGHTIN5, TOPIN5}};
static TECH_POLYGON mocmos_psa_l[] = {				/* layers */
	{LWELLNP,  -1, 4, CROSSED, BOX, mocmos_fullbox},
	{LSACTP,    0, 4, CROSSED, BOX, mocmos_in4box},
	{LSELECTPP,-1, 4, CROSSED, BOX, mocmos_in2box}};
static TECH_NODES mocmos_psa = {
	"S-Active-Pin",NSACTP,NONODEPROTO,				/* name */
	K10,K10,										/* size */
	1,mocmos_psa_p,									/* ports */
	3,mocmos_psa_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* D-active-pin */
static TECH_PORTS mocmos_pda_p[] = {				/* ports */
	{mocmos_pc_na, "d-active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN5, BOTIN5, RIGHTIN5, TOPIN5}};
static TECH_POLYGON mocmos_pda_l[] = {				/* layers */
	{LWELLPP,  -1, 4, CROSSED, BOX, mocmos_fullbox},
	{LDACTP,    0, 4, CROSSED, BOX, mocmos_in4box},
	{LSELECTNP,-1, 4, CROSSED, BOX, mocmos_in2box}};
static TECH_NODES mocmos_pda = {
	"D-Active-Pin",NDACTP,NONODEPROTO,				/* name */
	K10,K10,										/* size */
	1,mocmos_pda_p,									/* ports */
	3,mocmos_pda_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* General active-pin */
static TECH_PORTS mocmos_pa_p[] = {					/* ports */
	{mocmos_pc_a, "active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}}	;
static TECH_POLYGON mocmos_pa_l[] = {				/* layers */
	{LDACTP, 0, 4, CROSSED, BOX, mocmos_fullbox},
	{LSACTP, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pa = {
	"Active-Pin",NACTP,NONODEPROTO,					/* name */
	K2,K2,											/* size */
	1,mocmos_pa_p,									/* ports */
	2,mocmos_pa_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* metal-1-S-active-contact */
static TECH_PORTS mocmos_mpa_p[] = {				/* ports */
	{mocmos_pc_pam1, "metal-1-s-act", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN5, BOTIN5, RIGHTIN5, TOPIN5}};
static TECH_POLYGON mocmos_mpa_l[] = {				/* layers */
	{LMETAL1,  0, 4, FILLEDRECT, MINBOX, mocmos_min5box},
	{LSACT,    0, 4, FILLEDRECT, BOX,    mocmos_in4box},
	{LWELLNP, -1, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LSELECTP,-1, 4, FILLEDRECT, BOX,    mocmos_in2box},
	{LACTCUT,  0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_mpa = {
	"Metal-1-S-Active-Con",NMETSACTC,NONODEPROTO,	/* name */
	K14,K14,										/* size */
	1,mocmos_mpa_p,									/* ports */
	5,mocmos_mpa_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K2,K2,0,0,0,0};					/* characteristics */

/* metal-1-D-active-contact */
static TECH_PORTS mocmos_mna_p[] = {				/* ports */
	{mocmos_pc_nam1, "metal-1-d-act", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN5, BOTIN5, RIGHTIN5, TOPIN5}};
static TECH_POLYGON mocmos_mna_l[] = {				/* layers */
	{LMETAL1,   0, 4, FILLEDRECT, MINBOX, mocmos_min5box},
	{LDACT,     0, 4, FILLEDRECT, BOX,    mocmos_in4box},
	{LWELLP,   -1, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LSELECTNP,-1, 4, FILLEDRECT, BOX,    mocmos_in2box},
	{LACTCUT,   0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_mna = {
	"Metal-1-D-Active-Con",NMETDACTC,NONODEPROTO,	/* name */
	K14,K14,										/* size */
	1,mocmos_mna_p,									/* ports */
	5,mocmos_mna_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K2,K2,0,0,0,0};					/* characteristics */

/* metal-1-polysilicon-contact */
static TECH_PORTS mocmos_mp_p[] = {					/* ports */
	{mocmos_pc_pm1, "metal-1-polysilicon", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_mp_l[] = {				/* layers */
	{LMETAL1,  0, 4, FILLEDRECT, MINBOX, mocmos_min1box},
	{LPOLY,    0, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LPOLYCUT, 0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_mp = {
	"Metal-1-Polysilicon-Con",NMETPOLYC,NONODEPROTO,/* name */
	K6,K6,											/* size */
	1,mocmos_mp_p,									/* ports */
	3,mocmos_mp_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K2,K2,0,0,0,0};					/* characteristics */

/* S-transistor */
static TECH_PORTS mocmos_tpa_p[] = {				/* ports */
	{mocmos_pc_p,  "s-trans-poly-left",  NOPORTPROTO, (180<<PORTANGLESH)|
		(90<<PORTARANGESH),                LEFTIN2,  BOTIN7, LEFTIN3,   TOPIN7},
	{mocmos_pc_pa, "s-trans-diff-top",   NOPORTPROTO, (90<<PORTANGLESH)|
		(90<<PORTARANGESH)|(1<<PORTNETSH), LEFTIN5,  TOPIN5, RIGHTIN5,  TOPIN4},
	{mocmos_pc_p,  "s-trans-poly-right", NOPORTPROTO, (0<<PORTANGLESH)|
		(90<<PORTARANGESH),                RIGHTIN3, BOTIN7, RIGHTIN2,  TOPIN7},
	{mocmos_pc_pa, "s-trans-diff-bottom",NOPORTPROTO, (270<<PORTANGLESH)|
		(90<<PORTARANGESH)|(2<<PORTNETSH), LEFTIN5,  BOTIN4, RIGHTIN5,  BOTIN5}};
static TECH_SERPENT mocmos_tpa_l[] = {				/* graphical layers */
	{{LSACT,    1, 4, FILLEDRECT, BOX,    mocmos_trdabox}, K3, K3,  0},
	{{LPOLY,    0, 4, FILLEDRECT, BOX,    mocmos_trdpbox}, K1, K1, K2},
	{{LWELLNP, -1, 4, FILLEDRECT, BOX,    mocmos_fullbox}, K7, K7, K4},
	{{LSELECTP,-1, 4, FILLEDRECT, BOX,    mocmos_in2box},  K5, K5, K2},
	{{LTRANS,  -1, 4, FILLEDRECT, BOX,    mocmos_trd1box}, K1, K1,  0}};
static TECH_SERPENT mocmos_tpaE_l[] = {				/* electric layers */
	{{LSACT,    1, 4, FILLEDRECT, BOX,    mocmos_trd2box}, K3,  0,  0},
	{{LSACT,    3, 4, FILLEDRECT, BOX,    mocmos_trd3box},  0, K3,  0},
	{{LPOLY,    0, 4, FILLEDRECT, BOX,    mocmos_trdpbox}, K1, K1, K2},
	{{LWELLNP, -1, 4, FILLEDRECT, BOX,    mocmos_fullbox}, K7, K7, K4},
	{{LSELECTP,-1, 4, FILLEDRECT, BOX,    mocmos_in2box},  K5, K5, K2},
	{{LTRANS,  -1, 4, FILLEDRECT, BOX,    mocmos_trd1box}, K1, K1,  0}};
static TECH_NODES mocmos_tpa = {
	"S-Transistor",NSTRANS,NONODEPROTO,				/* name */
	K10,K14,										/* size */
	4,mocmos_tpa_p,									/* ports */
	5,(TECH_POLYGON *)0,							/* layers */
	NODESHRINK|(NPTRAPMOS<<NFUNCTIONSH)|HOLDSTRACE,	/* userbits */
	SERPTRANS,6,K1,K1,K2,K1,K1,mocmos_tpa_l,mocmos_tpaE_l};/* characteristics */

/* D-transistor */
static TECH_PORTS mocmos_tna_p[] = {				/* ports */
	{mocmos_pc_p,  "d-trans-poly-left", NOPORTPROTO, (180<<PORTANGLESH)|
		(90<<PORTARANGESH),                LEFTIN2,  BOTIN7, LEFTIN3,  TOPIN7},
	{mocmos_pc_na, "d-trans-diff-top",  NOPORTPROTO, (90<<PORTANGLESH)|
		(90<<PORTARANGESH)|(1<<PORTNETSH), LEFTIN5,  TOPIN5, RIGHTIN5, TOPIN4},
	{mocmos_pc_p,  "d-trans-poly-right",NOPORTPROTO, (0<<PORTANGLESH)|
		(90<<PORTARANGESH),                RIGHTIN3, BOTIN7, RIGHTIN2, TOPIN7},
	{mocmos_pc_na, "d-trans-diff-bot",  NOPORTPROTO, (270<<PORTANGLESH)|
		(90<<PORTARANGESH)|(2<<PORTNETSH), LEFTIN5,  BOTIN4, RIGHTIN5, BOTIN5}};
static TECH_SERPENT mocmos_tna_l[] = {				/* graphical layers */
	{{LDACT,     1, 4, FILLEDRECT, BOX,    mocmos_trdabox}, K3, K3,  0},
	{{LPOLY,     0, 4, FILLEDRECT, BOX,    mocmos_trdpbox}, K1, K1, K2},
	{{LWELLP,   -1, 4, FILLEDRECT, BOX,    mocmos_fullbox}, K7, K7, K4},
	{{LSELECTNP,-1, 4, FILLEDRECT, BOX,    mocmos_in2box},  K5, K5, K2},
	{{LTRANS,   -1, 4, FILLEDRECT, BOX,    mocmos_trd1box}, K1, K1,  0}};
static TECH_SERPENT mocmos_tnaE_l[] = {				/* electric layers */
	{{LDACT,     1, 4, FILLEDRECT, BOX,    mocmos_trd2box}, K3,  0,  0},
	{{LDACT,     3, 4, FILLEDRECT, BOX,    mocmos_trd3box},  0, K3,  0},
	{{LPOLY,     0, 4, FILLEDRECT, BOX,    mocmos_trdpbox}, K1, K1, K2},
	{{LWELLP,   -1, 4, FILLEDRECT, BOX,    mocmos_fullbox}, K7, K7, K4},
	{{LSELECTNP,-1, 4, FILLEDRECT, BOX,    mocmos_in2box},  K5, K5, K2},
	{{LTRANS,   -1, 4, FILLEDRECT, BOX,    mocmos_trd1box}, K1, K1,  0}};
static TECH_NODES mocmos_tna = {
	"D-Transistor",NDTRANS,NONODEPROTO,				/* name */
	K10,K14,										/* size */
	4,mocmos_tna_p,									/* ports */
	5,(TECH_POLYGON *)0,							/* layers */
	NODESHRINK|(NPTRANMOS<<NFUNCTIONSH)|HOLDSTRACE,	/* userbits */
	SERPTRANS,6,K1,K1,K2,K1,K1,mocmos_tna_l,mocmos_tnaE_l};/* characteristics */

/* metal-1-metal-2-contact */
static TECH_PORTS mocmos_mm_p[] = {					/* ports */
	{mocmos_pc_mm, "metal-1-metal-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_mm_l[] = {				/* layers */
	{LMETAL1, 0, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LMETAL2, 0, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LVIA,    0, 4, CLOSEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_mm = {
	"Metal-1-Metal-2-Con",NVIA,NONODEPROTO,			/* name */
	K4,K4,											/* size */
	1,mocmos_mm_p,									/* ports */
	3,mocmos_mm_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K1,K3,0,0,0,0};					/* characteristics */

/* Metal-1-Well Contact */
static TECH_PORTS mocmos_psub_p[] = {				/* ports */
	{mocmos_pc_m1a, "metal-1-well", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN5H, BOTIN5H, RIGHTIN5H, TOPIN5H}};
static TECH_POLYGON mocmos_psub_l[] = {				/* layers */
	{LMETAL1,   0, 4, FILLEDRECT, MINBOX, mocmos_min5box},
	{LSACTWELL,-1, 4, FILLEDRECT, BOX,    mocmos_in4box},
	{LWELLP,   -1, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LSELECTP,  0, 4, FILLEDRECT, MINBOX, mocmos_min5box},
	{LACTCUT,   0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_psub = {
	"Metal-1-Well-Con",NWBUT,NONODEPROTO,			/* name */
	K14,K14,										/* size */
	1,mocmos_psub_p,								/* ports */
	5,mocmos_psub_l,								/* layers */
	(NPWELL<<NFUNCTIONSH),							/* userbits */
	MULTICUT,K2,K2,K2,K2,0,0,0,0};					/* characteristics */

/* Metal-1-Substrate Contact */
static TECH_PORTS mocmos_nsub_p[] = {				/* ports */
	{mocmos_pc_m1a, "metal-1-substrate", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN5H, BOTIN5H, RIGHTIN5H, TOPIN5H}};
static TECH_POLYGON mocmos_nsub_l[] = {				/* layers */
	{LMETAL1,   0, 4, FILLEDRECT, MINBOX, mocmos_min5box},
	{LDACT,     0, 4, FILLEDRECT, BOX,    mocmos_in4box},
	{LWELLNP,  -1, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LSELECTNP, 0, 4, FILLEDRECT, BOX,    mocmos_in5box},
	{LACTCUT,   0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_nsub = {
	"Metal-1-Substrate-Con",NSBUT,NONODEPROTO,		/* name */
	K14,K14,										/* size */
	1,mocmos_nsub_p,								/* ports */
	5,mocmos_nsub_l,								/* layers */
	(NPSUBSTRATE<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K2,K2,0,0,0,0};					/* characteristics */

/* Metal-1-Node */
static TECH_PORTS mocmos_m1_p[] = {					/* ports */
	{mocmos_pc_m1, "metal-1", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m1_l[] = {				/* layers */
	{LMETAL1, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_m1 = {
	"Metal-1-Node",NMETAL1N,NONODEPROTO,			/* name */
	K4,K4,											/* size */
	1,mocmos_m1_p,									/* ports */
	1,mocmos_m1_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Metal-2-Node */
static TECH_PORTS mocmos_m2_p[] = {					/* ports */
	{mocmos_pc_m2, "metal-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m2_l[] = {				/* layers */
	{LMETAL2, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_m2 = {
	"Metal-2-Node",NMETAL2N,NONODEPROTO,			/* name */
	K4,K4,											/* size */
	1,mocmos_m2_p,									/* ports */
	1,mocmos_m2_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Polysilicon-Node */
static TECH_PORTS mocmos_p_p[] = {					/* ports */
	{mocmos_pc_p, "polysilicon", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_p_l[] = {				/* layers */
	{LPOLY, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_p = {
	"Polysilicon-Node",NPOLYN,NONODEPROTO,			/* name */
	K4,K4,											/* size */
	1,mocmos_p_p,									/* ports */
	1,mocmos_p_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Active-Node */
static TECH_PORTS mocmos_a_p[] = {					/* ports */
	{mocmos_pc_a, "active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_a_l[] = {				/* layers */
	{LSACT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_a = {
	"Active-Node",NACTIVEN,NONODEPROTO,				/* name */
	K4,K4,											/* size */
	1,mocmos_a_p,									/* ports */
	1,mocmos_a_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* D-Active-Node */
static TECH_PORTS mocmos_da_p[] = {					/* ports */
	{mocmos_pc_a, "active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_da_l[] = {				/* layers */
	{LDACT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_da = {
	"D-Active-Node",NDACTIVEN,NONODEPROTO,			/* name */
	K4,K4,											/* size */
	1,mocmos_da_p,									/* ports */
	1,mocmos_da_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* P-Select-Node */
static TECH_PORTS mocmos_sp_p[] = {					/* ports */
	{mocmos_pc_null, "select", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_sp_l[] = {				/* layers */
	{LSELECTP, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_sp = {
	"P-Select-Node",NSELECTPN,NONODEPROTO,			/* name */
	K6,K6,											/* size */
	1,mocmos_sp_p,									/* ports */
	1,mocmos_sp_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* N-Select-Node */
static TECH_PORTS mocmos_sn_p[] = {					/* ports */
	{mocmos_pc_null, "select", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_sn_l[] = {				/* layers */
	{LSELECTNP, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_sn = {
	"N-Select-Node",NSELECTNN,NONODEPROTO,			/* name */
	K6,K6,											/* size */
	1,mocmos_sn_p,									/* ports */
	1,mocmos_sn_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Cut-Node */
static TECH_PORTS mocmos_c_p[] = {					/* ports */
	{mocmos_pc_null, "cut", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_c_l[] = {				/* layers */
	{LCUT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_c = {
	"Cut-Node",NCUTN,NONODEPROTO,					/* name */
	K2,K2,											/* size */
	1,mocmos_c_p,									/* ports */
	1,mocmos_c_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* PolyCut-Node */
static TECH_PORTS mocmos_gc_p[] = {					/* ports */
	{mocmos_pc_null, "polycut", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_gc_l[] = {				/* layers */
	{LPOLYCUT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_gc = {
	"Poly-Cut-Node",NPCUTN,NONODEPROTO,				/* name */
	K2,K2,											/* size */
	1,mocmos_gc_p,									/* ports */
	1,mocmos_gc_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* ActiveCut-Node */
static TECH_PORTS mocmos_ac_p[] = {					/* ports */
	{mocmos_pc_null, "activecut", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_ac_l[] = {				/* layers */
	{LACTCUT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_ac = {
	"Active-Cut-Node",NACUTN,NONODEPROTO,			/* name */
	K2,K2,											/* size */
	1,mocmos_ac_p,									/* ports */
	1,mocmos_ac_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Via-Node */
static TECH_PORTS mocmos_v_p[] = {					/* ports */
	{mocmos_pc_null, "via", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_v_l[] = {				/* layers */
	{LVIA, 0, 4, CLOSEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_v = {
	"Via-Node",NVIAN,NONODEPROTO,					/* name */
	K2,K2,											/* size */
	1,mocmos_v_p,									/* ports */
	1,mocmos_v_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* P-Well-Node */
static TECH_PORTS mocmos_wp_p[] = {					/* ports */
	{mocmos_pc_pa, "well", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN3, BOTIN3, RIGHTIN3, TOPIN3}};
static TECH_POLYGON mocmos_wp_l[] = {				/* layers */
	{LWELLP, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_wp = {
	"P-Well-Node",NWELLPN,NONODEPROTO,				/* name */
	K6,K6,											/* size */
	1,mocmos_wp_p,									/* ports */
	1,mocmos_wp_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* N-Well-Node */
static TECH_PORTS mocmos_wn_p[] = {					/* ports */
	{mocmos_pc_pa, "well", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN3, BOTIN3, RIGHTIN3, TOPIN3}};
static TECH_POLYGON mocmos_wn_l[] = {				/* layers */
	{LWELLNP, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_wn = {
	"N-Well-Node",NWELLNN,NONODEPROTO,				/* name */
	K6,K6,											/* size */
	1,mocmos_wn_p,									/* ports */
	1,mocmos_wn_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Passivation-node */
static TECH_PORTS mocmos_o_p[] = {					/* ports */
	{mocmos_pc_null, "passivation", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_o_l[] = {				/* layers */
	{LPASS, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_o = {
	"Passivation-Node",NPASSN,NONODEPROTO,			/* name */
	K8,K8,											/* size */
	1,mocmos_o_p,									/* ports */
	1,mocmos_o_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Pad-Frame-node */
static TECH_PORTS mocmos_pf_p[] = {					/* ports */
	{mocmos_pc_null, "pad-frame", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_pf_l[] = {				/* layers */
	{LFRAME, 0, 4, CLOSEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pf = {
	"Pad-Frame-Node",NPADFRN,NONODEPROTO,			/* name */
	K8,K8,											/* size */
	1,mocmos_pf_p,									/* ports */
	1,mocmos_pf_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

TECH_NODES *mocmos_nodeprotos[NODEPROTOCOUNT+1] = {
	&mocmos_pm1, &mocmos_pm2, &mocmos_pp, &mocmos_psa, &mocmos_pda,
	&mocmos_pa,
	&mocmos_mpa, &mocmos_mna, &mocmos_mp,
	&mocmos_tpa, &mocmos_tna,
	&mocmos_mm,
	&mocmos_psub, &mocmos_nsub,
	&mocmos_m1, &mocmos_m2, &mocmos_p, &mocmos_a, &mocmos_da, &mocmos_sp,
	&mocmos_sn, &mocmos_c, &mocmos_gc, &mocmos_ac,
	&mocmos_v, &mocmos_wp, &mocmos_wn, &mocmos_o, &mocmos_pf, ((TECH_NODES *)-1)};

/* this table must correspond with the above table */
static INTBIG mocmos_node_widoff[NODEPROTOCOUNT*4] = {
	0,0,0,0, 0,0,0,0, 0,0,0,0, K4,K4,K4,K4, K4,K4,K4,K4,		/* pins */
	0,0,0,0,
	K4,K4,K4,K4, K4,K4,K4,K4, 0,0,0,0,							/* contacts */
	K4,K4,K6,K6, K4,K4,K6,K6,									/* trans. */
	0,0,0,0,													/* vias */
	K4,K4,K4,K4, K4,K4,K4,K4,									/* buttons */
	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,		/* nodes */
	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
	0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};

/*
 * tables for converting between stipples and outlines
 */
struct
{
	TECH_POLYGON *str;
	INTSML         layer;
} mocmos_nodepstipple[] =
{
	{mocmos_mpa_l, 3},	/* select-p */
	{mocmos_mna_l, 3},	/* select-n */
	{mocmos_psub_l, 3},	/* select-p */
	{mocmos_nsub_l, 3},	/* select-n */
	{mocmos_sp_l, 0},	/* select-p */
	{mocmos_sn_l, 0},	/* select-n */
	{mocmos_o_l, 0},	/* passivation */
	{mocmos_mpa_l, 2},	/* well-n */
	{mocmos_mna_l, 2},	/* well-p */
	{mocmos_psub_l, 2},	/* well-p */
	{mocmos_nsub_l, 2},	/* well-n */
	{mocmos_wp_l, 2},	/* well-p */
	{mocmos_wn_l, 2},	/* well-n */
	{mocmos_mm_l, 1},	/* metal-2 */
	{mocmos_m2_l, 0}	/* metal-2 */
};
static INTSML mocmos_nodepstipplesize = 7;
struct
{
	TECH_SERPENT *str;
	INTSML         layer;
} mocmos_nodesstipple[] =
{
	{mocmos_tpa_l, 3},	/* select-p */
	{mocmos_tna_l, 3},	/* select-n */
	{mocmos_tpa_l, 2},	/* well-n */
	{mocmos_tna_l, 2},	/* well-p */
};
static INTSML mocmos_nodesstipplesize = 2;

/******************** SIMULATION VARIABLES ********************/

/* for SPICE simulation */
#define	MOCMOS_MIN_RESIST	50.0f	/* minimum resistance consider */
#define	MOCMOS_MIN_CAPAC	0.04f	/* minimum capacitance consider */
float mocmos_sim_spice_resistance[MAXLAYERS] = {  /* per square micron */
	0.03f /* METAL1 */,    0.03f /* METAL2 */,    50.0f /* POLY */,
	10.0f /* SACT */,      10.0f /* DACT */,
	0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
	0.0, 0.0, 0.0, 0.0};
float mocmos_sim_spice_capacitance[MAXLAYERS] = { /* per square micron */
	0.03f /* METAL1 */,    0.03f /* METAL2 */,    0.04f /* POLY */,
	0.1f /* SACT */,       0.1f /* DACT */,
	0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
	0.0, 0.0, 0.0, 0.0};
char *mocmos_sim_spice_header_level1[] = {
	"*CMOS/BULK-NWELL (PRELIMINARY PARAMETERS)",
	".OPTIONS NOMOD DEFL=3UM DEFW=3UM DEFAD=70P DEFAS=70P LIMPTS=1000",
	"+ITL4=1000 ITL5=0 RELTOL=0.01 ABSTOL=500PA VNTOL=500UV LVLTIM=2",
	"+LVLCOD=1",
	".MODEL N NMOS LEVEL=1",
	"+KP=60E-6 VTO=0.7 GAMMA=0.3 LAMBDA=0.05 PHI=0.6",
	"+LD=0.4E-6 TOX=40E-9 CGSO=2.0E-10 CGDO=2.0E-10 CJ=.2MF/M^2",
	".MODEL P PMOS LEVEL=1",
	"+KP=20E-6 VTO=0.7 GAMMA=0.4 LAMBDA=0.05 PHI=0.6",
	"+LD=0.6E-6 TOX=40E-9 CGSO=3.0E-10 CGDO=3.0E-10 CJ=.2MF/M^2",
	".MODEL DIFFCAP D CJO=.2MF/M^2",
	NOSTRING};
char *mocmos_sim_spice_header_level2[] = {
	"* MOSIS 3u CMOS PARAMS",
	".OPTIONS NOMOD DEFL=2UM DEFW=6UM DEFAD=100P DEFAS=100P",
	"+LIMPTS=1000 ITL4=1000 ITL5=0 ABSTOL=500PA VNTOL=500UV",
	"* Note that ITL5=0 sets ITL5 to infinity",
	".MODEL N NMOS LEVEL=2 LD=0.3943U TOX=502E-10",
	"+NSUB=1.22416E+16 VTO=0.756 KP=4.224E-05 GAMMA=0.9241",
	"+PHI=0.6 UO=623.661 UEXP=8.328627E-02 UCRIT=54015.0",
	"+DELTA=5.218409E-03 VMAX=50072.2 XJ=0.4U LAMBDA=2.975321E-02",
	"+NFS=4.909947E+12 NEFF=1.001E-02 NSS=0.0 TPG=1.0",
	"+RSH=20.37 CGDO=3.1E-10 CGSO=3.1E-10",
	"+CJ=3.205E-04 MJ=0.4579 CJSW=4.62E-10 MJSW=0.2955 PB=0.7",
	".MODEL P PMOS LEVEL=2 LD=0.2875U TOX=502E-10",
	"+NSUB=1.715148E+15 VTO=-0.7045 KP=1.686E-05 GAMMA=0.3459",
	"+PHI=0.6 UO=248.933 UEXP=1.02652 UCRIT=182055.0",
	"+DELTA=1.0E-06 VMAX=100000.0 XJ=0.4U LAMBDA=1.25919E-02",
	"+NFS=1.0E+12 NEFF=1.001E-02 NSS=0.0 TPG=-1.0",
	"+RSH=79.10 CGDO=2.89E-10 CGSO=2.89E-10",
	"+CJ=1.319E-04 MJ=0.4125 CJSW=3.421E-10 MJSW=0.198 PB=0.66",
	".TEMP 25.0",
	NOSTRING};

/******************** ECAD DRC VARIABLES ********************/

/*
 * this ECAD design-rule file was written by Rick Schediwy at SPAR
 * the two lines that read " PRIMARY =" and " INDISK =" are modified
 * to include the file name with the CIF.  This design-rule set assumes
 * that the CIF layer called "DRC" is a cloak (generated by the DRC-Node
 * in the Generic technology) which causes layout under it to be ignored.
 * Errors are returned on layer "CX".  In order to do this, there must be
 * a "CIF-REF-FILE" in the specified location.  This file contains the
 * single line:
 *     .CIF 20 CX
 */
char *mocmos_drc_ecad_deck[] = {
	"; MOSIS REV 6 'EITHER' CMOS DESIGN RULE FILE",
	"; THIS COMMAND FILE CONSISTS OF COMMANDS FOR BOTH PWELL PROCESS AND NWELL PROCESS.",
	"; Last modified:  7-Jul-90  KSS",
	"*DESCRIPTION",
	" MODE = EXEC NOW",
	" SYSTEM = CIF",
	" SCALE = 0.01 MIC",
	" RESOLUTION = 0.25 MIC     ;ECADs internal resolution",
	" FLAGNON45 = NO",
	" PRINTFILE = ECADTST",
	" PRIMARY =",			/* this has a name added to it */
	" INDISK =",			/* this has a name added to it */
	" OUTDISK = errors.cif      ;name of cif errors file to be created",
	" CIF-REF-FILE = CIFREF",
	" KEEPDATA = NO             ;YES if you want .DAT files etc for LAYDE",
	" CNAMES-CSEN = YES         ;ECAD is now case sensitive",
	" CHECK-MODE = FLAT         ;HIER or FLAT (must be FLAT if layout flat)",
	" STATUS-COMMAND = \"time\"   ; comment this out in VM/CS",
	"*END",
	"*INPUT-LAYER",
	" ACTIVA  =  CAA     ;CAA",
	" POLYA   =  CPG     ;CPG",
	" PLYCNT  =  CCP     ;CCP",
	" ACTCNT  =  CCA     ;CCA",
	" GENCNT  =  CC      ;CC",
	" MT1     =  CMF     ;CMF",
	" VIA     =  CVA     ;CVA",
	" MT2     =  CMS     ;CMS",
	" VAP     =  COG     ;COG",
	" CLOAK   =  DRC     ;ERROR CLOAKING LAYER",
	";   PWELL PROCESS",
	" PWELL    =  CWP     ;CWP",
	" PSELECT  =  CSP     ;CSP",
	";   NWELL PROCESS",
	" NWELL   =  CWN     ;CWN",
	" NSELECT =  CSN     ;CSN",
	" SUBSTRATE = BULK 60",
	"*END",
	"*OPERATION",
	"; ** SORT OUT CONTACTS **",
	" AND  ACTIVA GENCNT  TMPACT     ;FIND ALL CONTACTS TO ACTIVE",
	" OR   TMPACT ACTCNT  ACTCT",
	" AND  POLYA  GENCNT  TMPPLY     ;FIND ALL CONTACTS TO POLY",
	" OR   TMPPLY PLYCNT PLYCT",
	" OR   PLYCNT ACTCNT  TMPCNT     ;FIND ALL CONTACTS",
	" OR   TMPCNT GENCNT  CNTACT",
	"; ** MAKE SURE CONTACTS ARE 2X2 **",
	"  WIDTH CNTACT  LT 2.0                OUT G000 20 ;CONTACT SIZE EXACTLY",
	"  AREA  CNTACT  RANGE 4 40000   BGCNT OUT G010 20",
	"; ** SOME LAYER DEFINITIONS **",
	";   (DETERMINATION OF ACTIVE AND WELL TYPES DEPENDS ON PROCESS)",
	";    SAME FOR EITHER PROCESS",
	" AND  POLY   ACTIVE  GATE      ;GATE REGIONS",
	" NOT  POLYA  GATE    POLYNG    ;NON GATE POLY",
	" OR   POLYNG ACTIVA  CONLYR    ;VALID LAYERS TO CONTACTS",
	"; ** BLOAT 4X4 CONTACT STRUCTURES **",
	" SIZE  CNTACT  BY 1.0  SZCNT   ;POLY STRUCTURES",
	" AND   SZCNT   POLYA   POLYB",
	" SIZE  POLYB   BY 0.5  POLYC",
	" OR    POLYA   POLYC   POLY    ; Bloated Poly",
	" AND   SZCNT   ACTIVA  ACTIVB  ;ACTIVE STRUCTURES",
	" SIZE  ACTIVB  BY 0.5  ACTIVC",
	" OR    ACTIVA  ACTIVC  ACTIVE  ; Bloated active",
	";    P-WELL PROCESS",
	" AND  ACTIVA PSELECT PPLUSP    ;P+ ACTIVE",
	" NOT  ACTIVA PSELECT NPLUSP    ;N+ ACTIVE",
	" AND  BULK   PWELL   PWEL      ;P-WELL",
	" NOT  BULK   PWELL   NSUB      ;N-SUBSTRATE",
	" NOT  PPLUSP GATE    PTMPP     ",
	" AND  PTMPP  NSUB    PSDP      ;PTRANS SOURCES & DRAINS",
	" AND  PPLUSP PWEL    PCLMPP    ;WELL CLAMPS",
	" NOT  NPLUSP GATE    NTMPP",
	" AND  NTMPP  PWEL    NSDP      ;NTRANS SOURCES & DRAINS",
	" AND  NPLUSP NSUB    NCLMPP    ;SUBSTRATE CLAMPS",
	";    N-WELL PROCESS",
	" AND  ACTIVA NSELECT NPLUSN    ;N+ ACTIVE",
	" NOT  ACTIVA NSELECT PPLUSN    ;P+ ACTIVE",
	" AND  BULK   NWELL   NWEL      ;N-WELL",
	" NOT  BULK   NWELL   PSUB      ;P-SUBSTRATE",
	" NOT  PPLUSN GATE    PTMPN     ",
	" AND  PTMPN  NWEL    PSDN      ;PTRANS SOURCES & DRAINS",
	" AND  PPLUSN PSUB    PCLMPN    ;SUBSTRATE CLAMPS",
	" NOT  NPLUSN GATE    NTMPN",
	" AND  NTMPN  PSUB    NSDN      ;NTRANS SOURCES & DRAINS",
	" AND  NPLUSN NWEL    NCLMPN    ;WELL CLAMPS",
	"*BREAK BRK1",
	"; ** GENERIC CONTACT CHECK **",
	" ENC[TO] CNTACT    CONLYR LT 1.0   OUT G020 20 ;POLY OR ACT OVERLAP OF CONT",
	" EXT     CNTACT    LT 3.0          OUT G030 20 ;SPACING TO OTHER CNTACT",
	" EXT[TO] ACTCT     PLYCT  LT 4.0   OUT G035 20 ;POLY CON TO ACT CON SPACE",
	" EXT[TO] CNTACT    GATE   LT 2.0   OUT G040 20 ;SPACING TO GATE",
	" NOT     CNTACT    CONLYR  ERRCN1  OUT G050 20 ;MAKE SURE THERE IS POLY OR ACT SURROUND",
	";    N-WELL PROCESS",
	" EXT[TO]  ACTCT    NSELECT LT 1.0  OUT N055 20 ;SPACING TO NSELECT",
	" ENC      ACTCT    NSELECT LT 1.0  OUT N056 20 ;NSELECT SURROUND OF CONTACT",
	";    P-WELL PROCESS",
	" EXT[TO]  ACTCT   PSELECT LT 1.0  OUT P055 20 ;SPACING TO PSELECT",
	" ENC      ACTCT   PSELECT LT 1.0  OUT P056 20 ;PSELECT SURROUND OF CONTACT",
	"; ** WELL CHECK **",
	";    P-WELL PROCESS",
	" WIDTH   PWELL  LT 10.0 OUT P057 20",
	" EXT     PWELL  LT 6.0  OUT P058 20     ;ASSUMES WELLS ALWAYS AT SAME POTENTIAL",
	";    N-WELL PROCESS",
	" WIDTH   NWELL  LT 10.0 OUT N057 20",
	" EXT     NWELL  LT 6.0  OUT N058 20     ;ASSUMES WELLS ALWAYS AT SAME POTENTIAL",
	"; ** ACTIVE CHECK  **",
	";    SAME FOR EITHER PROCESS",
	" WIDTH    ACTIVE LT 3.0       OUT G060 20    ;ACTIVE WIDTH",
	" EXT      ACTIVE LT 3.0       OUT G070 20    ;ACTIVE SPACING",
	" EXT[R]   GATE   LT 3.0       SMGSP          ;GENERATE GATE-GATE SPACING LAYER FOR LATER USE IN SRC/DRAIN CHECKS",
	";    P-WELL PROCESS",
	" ENC[T]  NPLUSP PWEL   LT 5.0   OUT P080 20    ;SOURCE/DRAIN ACTIVE TO WELL",
	" ENC[T]  PCLMPP PWEL   LT 3.0   OUT P085 20    ;WELL CLAMP TO WELL",
	" ENC[T]  PPLUSP NSUB   LT 5.0   OUT P090 20    ;SOURCE/DRAIN ACTIVE TO WELL",
	" ENC[T]  NCLMPP NSUB   LT 3.0   OUT P095 20    ;SUBSTRATE CLAMP TO WELL",
	" WIDTH[R] PSDP      LT 3.0      SMPSDP         ;ALL P SRC/DRAINS WIDTH < 3",
	" NOT      SMPSDP    SMGSP       POSPERP        ;WHICH ARE NOT BETWEEN GATES ",
	" WIDTH    POSPERP   LT 3.0      OUT P100 20    ;ARE ERRORS",
	" WIDTH[R] NSDP      LT 3.0      SMNSDP         ;ALL N SRC/DRAINS WIDTH < 3",
	" NOT      SMNSDP    SMGSP       POSNERP        ;WHICH ARE NOT BETWEEN GATES",
	" WIDTH    POSNERP   LT 3.0      OUT P110 20    ;ARE ERRORS",
	";    N-WELL PROCESS",
	" ENC[T]  PPLUSN NWEL   LT 5.0   OUT N080 20    ;SOURCE/DRAIN ACTIVE TO WELL",
	" ENC[T]  NCLMPN NWEL   LT 3.0   OUT N085 20    ;WELL CLAMP TO WELL",
	" ENC[T]  NPLUSN PSUB   LT 5.0   OUT N090 20    ;SOURCE/DRAIN ACTIVE TO WELL",
	" ENC[T]  PCLMPN PSUB   LT 3.0   OUT N095 20    ;SUBSTRATE CLAMP TO WELL",
	" WIDTH[R] PSDN      LT 3.0      SMPSDN         ;ALL P SRC/DRAINS WIDTH < 3",
	" NOT      SMPSDN    SMGSP       POSPERN        ;WHICH ARE NOT BETWEEN GATES ",
	" WIDTH    POSPERN   LT 3.0      OUT N100 20    ;ARE ERRORS",
	" WIDTH[R] NSDN      LT 3.0      SMNSDN         ;ALL N SRC/DRAINS WIDTH < 3",
	" NOT      SMNSDN    SMGSP       POSNERN        ;WHICH ARE NOT BETWEEN GATES",
	" WIDTH    POSNERN   LT 3.0      OUT N110 20    ;ARE ERRORS",
	"; ** GATE CHECK **",
	";    SAME FOR EITHER PROCESS",
	" WIDTH[P]  GATE  LT 2.0           OUT G120 20 ;MIN XTOR WIDTH",
	" ENC[T]    GATE  ACTIVE   LT 0.001 &",
	" ENC[TO]   GATE  POLY     LT 2.0  OUT G160 20 ;GATE OVERLAP OF ACTIVE",
	" EXT[TOC]  GATE  PSELECT  LT 3.0  OUT P150 20 ;PSELECT AWAY FROM GATES",
	" EXT[TOC]  GATE  NSELECT  LT 3.0  OUT N150 20 ;NSELECT AWAY FROM GATES",
	";    P-WELL PROCESS",
	" EXT[TP]   GATE  PSDP     LT 0.001 &    ;CHECK PSELECT SURROUND OF PTRANS GATES",
	" ENC[TOCP] GATE  PSELECT  LT 3.0  OUT P130 20",
	";    N-WELL PROCESS",
	" EXT[TP]   GATE  NSDN     LT 0.001 &    ;CHECK NSELECT SURROUND OF PTRANS GATES",
	" ENC[TOCP] GATE  NSELECT  LT 3.0  OUT N130 20",
	"; **  SELECT  CHECKS",
	";     P-WELL PROCESS",
	" ENC     PSDP    PSELECT  LT 2.0  OUT P200 20 ;PSELECT OVERLAP OF ACTIVE ",
	" EXT     NSDP    PSELECT  LT 2.0  OUT P210 20 ;PSELECT SPACE TO ACTIVE",
	";     N-WELL PROCESS",
	" ENC     NSDN    NSELECT  LT 2.0  OUT N200 20 ;NSELECT OVERLAP OF ACTIVE",
	" EXT     PSDN    NSELECT  LT 2.0  OUT N210 20 ;NSELECT SPACE TO ACTIVE",
	"; **  POLY CHECK  **",
	" WIDTH   POLY   LT 2.0          OUT G170 20   ;WIDTH",
	" EXT     POLY   LT 2.0          OUT G180 20   ;SPACING",
	" EXT[T]  POLYA  ACTIVA  LT  1.0 OUT G190 20   ;POLY - ACTIVE SPACING",
	" NOT     POLY   CLOAK      CLPOLY             ;FIELD POLY TO ACTIVE",
	" NOT     ACTIVE CLOAK      CLACT              ;USER CAN CLOAK ERRORS",
	" EXT[T]  CLPOLY CLACT   LT  1.0 OUT G195 20",
	"; ** METAL1 CHECK **",
	" WIDTH   MT1     LT 3.0         OUT G230 20 ;WIDTH",
	" EXT     MT1     LT 3.0         OUT G240 20 ;SPACING",
	" NOT     CNTACT  MT1  ERRCN2    OUT G250 20 ;METAL OVER CONTACT ?",
	" ENC[TO] CNTACT  MT1    LT 1.0  OUT G260 20 ;OVERLAP OF CONTACT",
	"; ** METAL2 CHECK **",
	" WIDTH   MT2     LT 3.0         OUT G350 20  ;WIDTH",
	" EXT     MT2     LT 4.0         OUT G360 20  ;SPACE",
	" ENC[TO] VIA     MT2    LT 1.0  OUT G370 20  ;OVERLAP OF VIA",
	"; **  VIA CHECK **",
	" WIDTH   VIA     LT 2.0                 OUT G270 20  ;VIA SIZE EXACTLY",
	" AREA    VIA     RANGE 4 40000   BGVIA  OUT G280 20",
	"; WIDTH   VIA     SELGT  2.0 BGCNTV          ;THIS FAILS SINCE WILL PASS",
	"; AND     BGCNTV  BULK   ERRCV  OUT D280 20  ;ONLY IF ALL DIMENSIONS GT 2.0",
	" EXT     VIA     LT 3.0         OUT G290 20  ;SEPARATION TO VIA",
	" ENC[TO] VIA     MT1    LT 1.0  OUT G300 20  ;OVERLAP BY METAL1",
	" EXT[T]  VIA     POLY   LT 2.0  OUT G310 20  ;SPACE TO POLY",
	" ENC     VIA     POLY   LT 2.0  OUT G315 20  ;POLY OVERLAP",
	" EXT[T]  VIA     ACTIVE LT 2.0  OUT G320 20  ;SPACE TO ACTIVE",
	" ENC     VIA     ACTIVE LT 2.0  OUT G335 20  ;ACTIVE OVERLAP",
	" EXT[T]  VIA     CNTACT LT 2.0  OUT G330 20  ;SPACING TO CONTACT",
	" AND     VIA     CNTACT ERRVP   OUT G340 20  ;VIA STACKED OVER CONTACT",
	"; **  OVERGLASS CHECK **",
	"; FLATTEN VAP     FVAP",
	"; WIDTH   FVAP    LT 75.0        OUT G380 20  ;BONDING PAD WIDTH",
	"; SIZE    VAP  BY 6.0    SVAP",
	"; AND     SVAP    MT2    MT2VAP",
	"; FLATTEN MT2VAP  FMT2V",
	"; ENC[T]  FVAP    FMT2V  LT 6.0  OUT G390 20  ;PAD OVERLAP OF GLASS",
	"; NOT     VAP     MT2    VAPERR  OUT G400 20  ;METAL2 UNDER GLASS",
	"*END",
	NOSTRING};

/******************** VARIABLE AGGREGATION ********************/

TECH_VARIABLES mocmos_variables[] =
{
	/* set general information about the technology */
	{"TECH_layer_names", (char *)mocmos_layer_names, 0.0,
		VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
	{"TECH_layer_function", (char *)mocmos_layer_function, 0.0,
		VINTEGER|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
	{"TECH_arc_width_offset", (char *)mocmos_arc_widoff, 0.0,
		VFRACT|VDONTSAVE|VISARRAY|(ARCPROTOCOUNT<<VLENGTHSH)},
	{"TECH_node_width_offset", (char *)mocmos_node_widoff, 0.0,
		VFRACT|VDONTSAVE|VISARRAY|((NODEPROTOCOUNT*4)<<VLENGTHSH)},

	/* set information for the USER aid */
	{"USER_color_map", (char *)mocmos_colmap, 0.0,
		VCHAR|VDONTSAVE|VISARRAY|((sizeof mocmos_colmap)<<VLENGTHSH)},
	{"USER_layer_letters", (char *)mocmos_layer_letters, 0.0,
		VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},

	/* set information for the I/O aid */
	{"IO_cif_layer_names", (char *)mocmos_cif_layers, 0.0,
		VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
	{"IO_gds_layer_numbers", (char *)mocmos_gds_layers, 0.0,
		VINTEGER|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},

	/* set information for the DRC aid */
	{"DRC_min_unconnected_distances", (char *)mocmos_unconnectedtable, 0.0,
		VFRACT|VDONTSAVE|VISARRAY|
			(((sizeof mocmos_unconnectedtable)/SIZEOFINTBIG)<<VLENGTHSH)},
	{"DRC_min_connected_distances", (char *)mocmos_connectedtable, 0.0,
		VFRACT|VDONTSAVE|VISARRAY|
			(((sizeof mocmos_connectedtable)/SIZEOFINTBIG)<<VLENGTHSH)},
	{"DRC_ecad_deck", (char *)mocmos_drc_ecad_deck, 0.0,
		VSTRING|VDONTSAVE|VISARRAY},

	/* set information for the SIM aid (SPICE) */
	{"SIM_spice_min_resistance", 0, MOCMOS_MIN_RESIST, VFLOAT|VDONTSAVE},
	{"SIM_spice_min_capacitance", 0, MOCMOS_MIN_CAPAC, VFLOAT|VDONTSAVE},
	{"SIM_spice_resistance", (char *)mocmos_sim_spice_resistance, 0.0,
		VFLOAT|VISARRAY|(MAXLAYERS<<VLENGTHSH)|VDONTSAVE},
	{"SIM_spice_capacitance", (char *)mocmos_sim_spice_capacitance, 0.0,
		VFLOAT|VISARRAY|(MAXLAYERS<<VLENGTHSH)|VDONTSAVE},
	{"SIM_spice_header_level1", (char *)mocmos_sim_spice_header_level1, 0.0,
		VSTRING|VDONTSAVE|VISARRAY},
	{"SIM_spice_header_level2", (char *)mocmos_sim_spice_header_level2, 0.0,
		VSTRING|VDONTSAVE|VISARRAY},
	{NULL, NULL, 0.0, 0}
};

/******************** ROUTINES ********************/

INTSML mocmos_initprocess(TECHNOLOGY *tech, INTSML pass)
{
	/* initialize the technology variable */
	if (pass == 0) mocmos_tech = tech;
	return(0);
}

void mocmos_setmode(INTSML count, char *par[])
{
	REGISTER INTSML l, i, aindex;
	REGISTER char *pp;
	REGISTER ARCPROTO *ap;
	REGISTER VARIABLE *var;
	extern COMCOMP us_noyesp;

	if (count == 0)
	{
		if ((mocmos_state&NWELL) == 0) ttyputmsg(_("Technology currently set for p-well")); else
			ttyputmsg(_("Technology currently set for n-well"));
		if ((mocmos_state&EITHER) == 0)
			ttyputmsg(_("CIF output uses general (p/n-well switchable) layers")); else
				ttyputmsg(_("CIF output runs in either p-well or n-well"));
		if ((mocmos_state&OUTLINE) == 0)
			ttyputmsg(_("%s layers use stipple patterns"), mocmos_stipplelayers); else
				ttyputmsg(_("%s layers use outlines"), mocmos_stipplelayers);
		return;
	}

	l = strlen(pp = par[0]);

	if (namesamen(pp, "convert-old-format-library", l) == 0)
	{
		ttyputmsg(_("This operation will irreversibly alter the current library"));
		count = ttygetparam(_("Proceed? [n] "), &us_noyesp, MAXPARS, par);
		if (count <= 0 || namesamen(par[0], "yes", strlen(par[0])) != 0)
			ttyputmsg(_("No changes made")); else
				tech_convertmocmoslib(el_curlib);
		return;
	}

	if (namesamen(pp, "stipple-layers", l) == 0)
	{
		/* change the descriptions of the layers */
		for(i=0; i<mocmos_layerstipplesize; i++)
			mocmos_layerstipple[i]->colstyle = PATTERNED;

		/* change the style of arcs that use these layers */
		for(i=0; i<mocmos_arcstipplesize; i++)
		{
			aindex = mocmos_arcstipple[i].layer;
			mocmos_arcstipple[i].str[aindex].style = FILLED;
		}

		/* change the style of nodes that use these layers */
		for(i=0; i<mocmos_nodepstipplesize; i++)
		{
			aindex = mocmos_nodepstipple[i].layer;
			mocmos_nodepstipple[i].str[aindex].style = FILLEDRECT;
		}
		for(i=0; i<mocmos_nodesstipplesize; i++)
		{
			aindex = mocmos_nodesstipple[i].layer;
			mocmos_nodesstipple[i].str[aindex].basics.style = FILLEDRECT;
		}

		mocmos_state &= ~OUTLINE;
		ttyputmsg(_("%s layers will use stipple patterns"), mocmos_stipplelayers);
		return;
	}

	if (namesamen(pp, "outline-layers", l) == 0)
	{
		/* change the descriptions of the layers */
		for(i=0; i<mocmos_layerstipplesize; i++)
			mocmos_layerstipple[i]->colstyle = SOLIDC;

		/* change the style of arcs that use these layers */
		for(i=0; i<mocmos_arcstipplesize; i++)
		{
			aindex = mocmos_arcstipple[i].layer;
			mocmos_arcstipple[i].str[aindex].style = CLOSED;
		}

		/* change the style of nodes that use these layers */
		for(i=0; i<mocmos_nodepstipplesize; i++)
		{
			aindex = mocmos_nodepstipple[i].layer;
			mocmos_nodepstipple[i].str[aindex].style = CLOSEDRECT;
		}
		for(i=0; i<mocmos_nodesstipplesize; i++)
		{
			aindex = mocmos_nodesstipple[i].layer;
			mocmos_nodesstipple[i].str[aindex].basics.style = CLOSEDRECT;
		}

		mocmos_state |= OUTLINE;
		ttyputmsg(_("%s layers will use outlines"), mocmos_stipplelayers);
		return;
	}

	if (namesamen(pp, "general-process", l) == 0)
	{
		mocmos_cif_layers[LSELECTP] = "CSG";
		mocmos_cif_layers[LSELECTN] = "CSG";
		mocmos_cif_layers[LWELLP] = "CWG";
		mocmos_cif_layers[LWELLN] = "CWG";
		mocmos_cif_layers[LSELECTPP] = "";
		mocmos_cif_layers[LSELECTNP] = "";
		mocmos_cif_layers[LWELLPP] = "";
		mocmos_cif_layers[LWELLNP] = "";
		mocmos_setpseudo();
		(void)setval((INTBIG)mocmos_tech, VTECHNOLOGY, "IO_cif_layer_names",
			(INTBIG)mocmos_cif_layers, VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH));
		mocmos_state &= ~EITHER;
		ttyputverbose(_("CIF output will use general (p/n-well switchable) layers"));
		return;
	}

	if (namesamen(pp, "either-process", l) == 0)
	{
		mocmos_cif_layers[LSELECTP] = "CSP";
		mocmos_cif_layers[LSELECTN] = "CSN";
		mocmos_cif_layers[LWELLP] = "CWP";
		mocmos_cif_layers[LWELLN] = "CWN";
		mocmos_cif_layers[LSELECTPP] = "CSP";
		mocmos_cif_layers[LSELECTNP] = "CSN";
		mocmos_cif_layers[LWELLPP] = "CWP";
		mocmos_cif_layers[LWELLNP] = "CWN";
		mocmos_setpseudo();
		(void)setval((INTBIG)mocmos_tech, VTECHNOLOGY, "IO_cif_layer_names",
			(INTBIG)mocmos_cif_layers, VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH));
		mocmos_state |= EITHER;
		ttyputverbose(_("CIF output will be able to run in p-well or n-well"));
		return;
	}

	if (namesamen(pp, "p-well", l) == 0)
	{
		/* set the D-transistor to be NMOS */
		mocmos_tna.creation->userbits &= ~NFUNCTION;
		mocmos_tna.creation->userbits |= (NPTRANMOS<<NFUNCTIONSH);

		/* set the S-transistor to be PMOS */
		mocmos_tpa.creation->userbits &= ~NFUNCTION;
		mocmos_tpa.creation->userbits |= (NPTRAPMOS<<NFUNCTIONSH);

		/* set the Metal-1-Well-Contact to be of type WELL */
		mocmos_psub.creation->userbits &= ~NFUNCTION;
		mocmos_psub.creation->userbits |= (NPWELL<<NFUNCTIONSH);

		/* set the Metal-1-Substrate-Contact to be of type SUBSTRATE */
		mocmos_nsub.creation->userbits &= ~NFUNCTION;
		mocmos_nsub.creation->userbits |= (NPSUBSTRATE<<NFUNCTIONSH);

		/* set the D-active arc to N-well and S-active arc to P-well */
		ap = mocmos_tech->firstarcproto;	/* metal-1 */
		ap = ap->nextarcproto;			/* metal-2 */
		ap = ap->nextarcproto;			/* polysilicon */
		ap = ap->nextarcproto;			/* S-active */
		ap->userbits &= ~AFUNCTION;
		ap->userbits |= (APDIFFP << AFUNCTIONSH);
		ap = ap->nextarcproto;			/* D-active */
		ap->userbits &= ~AFUNCTION;
		ap->userbits |= (APDIFFN << AFUNCTIONSH);

		/* change the layer functions */
		var = getval((INTBIG)mocmos_tech, VTECHNOLOGY, VINTEGER|VISARRAY, "TECH_layer_function");
		if (var != NOVARIABLE)
		{
			/* change layers */
			((INTBIG *)var->addr)[3] = LFDIFF|LFPTYPE|LFTRANS3;	/* S-active */
			((INTBIG *)var->addr)[4] = LFDIFF|LFNTYPE|LFTRANS3;	/* D-active */
			((INTBIG *)var->addr)[15] = LFDIFF|LFPTYPE|LFTRANS3; /*S-active-well*/

			/* change pseudo-layers */
			((INTBIG *)var->addr)[19] = LFDIFF|LFPTYPE|LFPSEUDO|LFTRANS3; /*sact*/
			((INTBIG *)var->addr)[20] = LFDIFF|LFNTYPE|LFPSEUDO|LFTRANS3; /*dact*/
		}

		/* change the layer visibility */
		mocmos_wp_lay.bits = LAYERT5;
		mocmos_pwp_lay.bits = LAYERT5;
		mocmos_ssp_lay.bits = LAYERO;
		mocmos_pssp_lay.bits = LAYERO;
		mocmos_wn_lay.bits = LAYERN;
		mocmos_pwn_lay.bits = LAYERN;
		mocmos_ssn_lay.bits = LAYERN;
		mocmos_pssn_lay.bits = LAYERN;

		mocmos_setpseudo();

		/* change the technology description */
		mocmos_tech->techdescript = _("Complementary MOS (from MOSIS, P-Well, double metal)");

		mocmos_state &= ~NWELL;
		ttyputverbose(_("MOSIS CMOS technology is P-well"));
		return;
	}

	if (namesamen(pp, "n-well", l) == 0)
	{
		/* set the D-transistor to be PMOS */
		mocmos_tna.creation->userbits &= ~NFUNCTION;
		mocmos_tna.creation->userbits |= (NPTRAPMOS<<NFUNCTIONSH);

		/* set the S-transistor to be NMOS */
		mocmos_tpa.creation->userbits &= ~NFUNCTION;
		mocmos_tpa.creation->userbits |= (NPTRANMOS<<NFUNCTIONSH);

		/* set the Metal-1-Well-Contact to be of type SUBSTRATE */
		mocmos_psub.creation->userbits &= ~NFUNCTION;
		mocmos_psub.creation->userbits |= (NPSUBSTRATE<<NFUNCTIONSH);

		/* set the Metal-1-Substrate-Contact to be of type WELL */
		mocmos_nsub.creation->userbits &= ~NFUNCTION;
		mocmos_nsub.creation->userbits |= (NPWELL<<NFUNCTIONSH);

		/* set the D-active arc to P-well and S-active arc to N-well */
		ap = mocmos_tech->firstarcproto;	/* metal-1 */
		ap = ap->nextarcproto;			/* metal-2 */
		ap = ap->nextarcproto;			/* polysilicon */
		ap = ap->nextarcproto;			/* S-active */
		ap->userbits &= ~AFUNCTION;
		ap->userbits |= (APDIFFN << AFUNCTIONSH);
		ap = ap->nextarcproto;			/* D-active */
		ap->userbits &= ~AFUNCTION;
		ap->userbits |= (APDIFFP << AFUNCTIONSH);

		/* change the layer functions */
		var = getval((INTBIG)mocmos_tech, VTECHNOLOGY, VINTEGER|VISARRAY, "TECH_layer_function");
		if (var != NOVARIABLE)
		{
			/* change layers */
			((INTBIG *)var->addr)[3] = LFDIFF|LFNTYPE|LFTRANS3;	/* S-active */
			((INTBIG *)var->addr)[4] = LFDIFF|LFPTYPE|LFTRANS3;	/* D-active */
			((INTBIG *)var->addr)[15] = LFSUBSTRATE|LFNTYPE|LFTRANS3;/*Sact-well*/

			/* change pseudo-layers */
			((INTBIG *)var->addr)[19] = LFDIFF|LFNTYPE|LFPSEUDO|LFTRANS3; /*sact*/
			((INTBIG *)var->addr)[20] = LFDIFF|LFPTYPE|LFPSEUDO|LFTRANS3; /*dact*/
		}

		/* change the layer visibility */
		mocmos_wp_lay.bits = LAYERN;
		mocmos_pwp_lay.bits = LAYERN;
		mocmos_ssp_lay.bits = LAYERN;
		mocmos_pssp_lay.bits = LAYERN;
		mocmos_wn_lay.bits = LAYERT5;
		mocmos_pwn_lay.bits = LAYERT5;
		mocmos_ssn_lay.bits = LAYERO;
		mocmos_pssn_lay.bits = LAYERO;

		mocmos_setpseudo();

		/* change the technology description */
		mocmos_tech->techdescript = _("Complementary MOS (from MOSIS, N-Well, double metal)");

		mocmos_state |= NWELL;
		ttyputverbose(_("MOSIS CMOS technology is N-well"));
		return;
	}
	ttyputbadusage("technology tell mocmos");
}

void mocmos_setpseudo(void)
{
	/* set normal use of N-select */
	mocmos_al_na[2].lay = LSELECTN;
	mocmos_mna_l[3].layernum = LSELECTN;
	mocmos_tna_l[3].basics.layernum = LSELECTN;
	mocmos_tnaE_l[5].basics.layernum = LSELECTN;
	mocmos_nsub_l[3].layernum = LSELECTN;
	mocmos_sn_l[0].layernum = LSELECTN;

	/* set normal use of P-select */
	mocmos_al_pa[2].lay = LSELECTP;
	mocmos_mpa_l[3].layernum = LSELECTP;
	mocmos_tpa_l[3].basics.layernum = LSELECTP;
	mocmos_tpaE_l[5].basics.layernum = LSELECTP;
	mocmos_psub_l[3].layernum = LSELECTP;
	mocmos_sp_l[0].layernum = LSELECTP;

	/* set normal use of N-Well */
	mocmos_al_pa[1].lay = LWELLN;
	mocmos_mpa_l[2].layernum = LWELLN;
	mocmos_tpa_l[2].basics.layernum = LWELLN;
	mocmos_tpaE_l[4].basics.layernum = LWELLN;
	mocmos_nsub_l[2].layernum = LWELLN;
	mocmos_wn_l[0].layernum = LWELLN;

	/* set normal use of P-Well */
	mocmos_al_na[1].lay = LWELLP;
	mocmos_mna_l[2].layernum = LWELLP;
	mocmos_tna_l[2].basics.layernum = LWELLP;
	mocmos_tnaE_l[4].basics.layernum = LWELLP;
	mocmos_psub_l[2].layernum = LWELLP;
	mocmos_wp_l[0].layernum = LWELLP;

	/* in general processes, "pseudo" the layer not being used */
	if ((mocmos_state&EITHER) == 0)
	{
		/* switch all uses of N-select */
		if (mocmos_ssn_lay.bits == LAYERN)
		{
			mocmos_al_na[2].lay = LSELECTNP;
			mocmos_mna_l[3].layernum = LSELECTNP;
			mocmos_tna_l[3].basics.layernum = LSELECTNP;
			mocmos_tnaE_l[5].basics.layernum = LSELECTNP;
			mocmos_nsub_l[3].layernum = LSELECTNP;
			mocmos_sn_l[0].layernum = LSELECTNP;
		}

		/* switch all uses of P-select */
		if (mocmos_ssp_lay.bits == LAYERN)
		{
			mocmos_al_pa[2].lay = LSELECTPP;
			mocmos_mpa_l[3].layernum = LSELECTPP;
			mocmos_tpa_l[3].basics.layernum = LSELECTPP;
			mocmos_tpaE_l[5].basics.layernum = LSELECTPP;
			mocmos_psub_l[3].layernum = LSELECTPP;
			mocmos_sp_l[0].layernum = LSELECTPP;
		}

		/* switch all uses of N-well */
		if (mocmos_wn_lay.bits == LAYERN)
		{
			mocmos_al_pa[1].lay = LWELLNP;
			mocmos_mpa_l[2].layernum = LWELLNP;
			mocmos_tpa_l[2].basics.layernum = LWELLNP;
			mocmos_tpaE_l[4].basics.layernum = LWELLNP;
			mocmos_nsub_l[2].layernum = LWELLNP;
			mocmos_wn_l[0].layernum = LWELLNP;
		}

		/* switch all uses of P-well */
		if (mocmos_wp_lay.bits == LAYERN)
		{
			mocmos_al_na[1].lay = LWELLPP;
			mocmos_mna_l[2].layernum = LWELLPP;
			mocmos_tna_l[2].basics.layernum = LWELLPP;
			mocmos_tnaE_l[4].basics.layernum = LWELLPP;
			mocmos_psub_l[2].layernum = LWELLPP;
			mocmos_wp_l[0].layernum = LWELLPP;
		}
	}
}

static VARIABLE *mocmos_shrinkvar;

INTBIG mocmos_arcpolys(ARCINST *ai)
{
	REGISTER INTBIG total;
	static INTBIG arc_shrinkback = 0;

	if (arc_shrinkback == 0) arc_shrinkback = makekey("ARC_shrinkback");
	mocmos_shrinkvar = getvalkey((INTBIG)ai, VARCINST, VINTEGER, arc_shrinkback);

	if ((ai->userbits&ISNEGATED) != 0) tech_resetnegated(ai);
	total = mocmos_arcprotos[ai->proto->arcindex]->laycount;
	if ((ai->userbits&ISDIRECTIONAL) != 0) total++;

	/* add in displayable variables */
	tech_realpolys = total;
	total += tech_displayableavars(ai);
	return(total);
}

void mocmos_shapearcpoly(ARCINST *ai, INTBIG box, POLYGON *poly)
{
	REGISTER INTSML aindex, i;
	REGISTER INTBIG shrinkback, len, oldbits, thisend, lambda;
	REGISTER TECH_ARCLAY *thista;
	INTBIG oldx[2], oldy[2];

	/* handle displayable variables */
	if (box >= tech_realpolys)
	{
		(void)tech_filldisplayableavar(ai, poly);
		return;
	}

	aindex = ai->proto->arcindex;
	if (box >= mocmos_arcprotos[aindex]->laycount) tech_makearrow(ai, poly); else
	{
		thista = &mocmos_arcprotos[aindex]->list[box];
		lambda = lambdaofarc(ai);

		if (mocmos_shrinkvar != NOVARIABLE)
		{
			/* shrink arc if connected to export */
			shrinkback = mocmos_shrinkvar->addr * lambda;
			len = ai->length;
			oldbits = ai->userbits;
			ai->userbits |= (NOEXTEND|NOTEND0|NOTEND1);
			for(i=0; i<2; i++)
			{
				if (i == 0) thisend = NOTEND0; else thisend = NOTEND1;

				oldx[i] = ai->end[i].xpos;   oldy[i] = ai->end[i].ypos;
				if (ai->end[i].nodeinst->proto->primindex != 0)
				{
					if ((oldbits&(NOEXTEND|thisend)) == NOEXTEND) ai->userbits &= ~thisend;
					continue;
				}

				/* quit if this end cannot be shrunk any more */
				if (len <= shrinkback) continue;

				/* shrink this end */
				len -= shrinkback;
				ai->userbits &= ~thisend;
				if (ai->end[0].xpos == ai->end[1].xpos)
				{
					/* vertical arc */
					if (ai->end[i].ypos < ai->end[1-i].ypos)
						ai->end[i].ypos += shrinkback; else
							ai->end[i].ypos -= shrinkback;
				} else
				{
					/* horizontal arc */
					if (ai->end[i].xpos < ai->end[1-i].xpos)
						ai->end[i].xpos += shrinkback; else
							ai->end[i].xpos -= shrinkback;
				}
			}
			makearcpoly(ai->length, ai->width-thista->off*lambda/WHOLE, ai, poly,
				thista->style);

			/* restore end co-ordinates */
			for(i=0; i<2; i++)
			{
				ai->end[i].xpos = oldx[i];   ai->end[i].ypos = oldy[i];
			}
			ai->userbits = oldbits;
		} else
		{
			makearcpoly(ai->length, ai->width-thista->off*lambda/WHOLE, ai, poly,
				thista->style);
		}
		poly->layer = thista->lay;
		poly->desc = mocmos_layers[poly->layer];
	}
}

#endif  /* TECMOCOS - at top */
