/*
 * Electric(tm) VLSI Design System
 *
 * File: tecmocmos.c
 * MOSIS CMOS technology description
 * Written by: Steven M. Rubin, Static Free Software
 * The MOSIS 6-metal, 2-poly submicron rules, with SCMOS and DEEP options
 *
 * 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"
#include "drc.h"

/* the options table */
static KEYWORD mocmosopt[] =
{
	{"2-metal-rules",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"3-metal-rules",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"4-metal-rules",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"5-metal-rules",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"6-metal-rules",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"one-polysilicon",            0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"two-polysilicon",            0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"scmos-rules",                0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"submicron-rules",            0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"deep-rules",                 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"full-graphics",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"alternate-active-poly",      0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"standard-active-poly",       0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"allow-stacked-vias",         0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"disallow-stacked-vias",      0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"stick-display",              0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	{"switch-n-and-p",             0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
	TERMKEY
};
COMCOMP mocmos_parse = {mocmosopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
	NOBACKUP, 0, " \t", M_("MOSIS CMOS Submicron option"), 0};

typedef struct
{
	NODEPROTO *np[2];
	PORTPROTO *pp[2][4];
	INTBIG     portcount;
} PRIMSWAP;

static PRIMSWAP    mocmos_primswap[7];

static INTBIG      mocmos_state;			/* settings */
       TECHNOLOGY *mocmos_tech;
static INTBIG      mocmos_arrowbox;
       NODEPROTO  *mocmos_metal1poly2prim;
       NODEPROTO  *mocmos_metal1poly12prim;
       NODEPROTO  *mocmos_metal1metal2prim;
       NODEPROTO  *mocmos_metal4metal5prim;
       NODEPROTO  *mocmos_metal5metal6prim;
       NODEPROTO  *mocmos_ptransistorprim;
       NODEPROTO  *mocmos_ntransistorprim;
       NODEPROTO  *mocmos_metal1pwellprim;
       NODEPROTO  *mocmos_metal1nwellprim;

/* prototypes for local routines */
static void    mocmos_setstate(INTBIG newstate);
static void    mocmos_switchnp(void);
static void    mocmos_nodesizeoffset(NODEINST *ni, INTBIG *lx, INTBIG *ly, INTBIG *hx, INTBIG *hy);
static INTBIG  mocmos_arcwidthoffset(ARCINST *ai);
static void    mocmos_setupprimswap(INTBIG index1, INTBIG index2, PRIMSWAP *swap);
static void    mocmos_setlayerminwidth(char *layername, INTBIG minwidth);
static void    mocmos_setdefnodesize(TECH_NODES *nty, INTBIG index, INTBIG wid, INTBIG hei);
static void    mocmos_setlayersurroundvia(TECH_NODES *nty, INTBIG layer, INTBIG surround);
static void    mocmos_setlayersurroundlayer(TECH_NODES *nty, INTBIG outerlayer, INTBIG innerlayer, INTBIG surround);
static void    mocmos_settransistoractiveoverhang(INTBIG overhang);
static void    mocmos_settransistorpolyoverhang(INTBIG overhang);
static void    mocmos_settransistorwellsurround(INTBIG overhang);
static INTBIG  mocmos_nodepolys(NODEINST *ni, INTBIG *reasonable, WINDOWPART *win);
static void    mocmos_shapenodepoly(NODEINST *ni, INTBIG box, POLYGON *poly);
static INTBIG  mocmos_arcpolys(ARCINST *ai, WINDOWPART *win);
static void    mocmos_shapearcpoly(ARCINST *ai, INTBIG box, POLYGON *poly);
static BOOLEAN mocmos_loadDRCtables(void);
static char   *mocmos_describestate(INTBIG state);

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

#define MAXLAYERS   40		/* total layers below         */
#define LMETAL1      0		/* metal layer 1              */
#define LMETAL2      1		/* metal layer 2              */
#define LMETAL3      2		/* metal layer 3              */
#define LMETAL4      3		/* metal layer 4              */
#define LMETAL5      4		/* metal layer 5              */
#define LMETAL6      5		/* metal layer 6              */
#define LPOLY1       6		/* polysilicon                */
#define LPOLY2       7		/* polysilicon 2 (electrode)  */
#define LPACT        8		/* P active                   */
#define LNACT        9		/* N active                   */
#define LSELECTP    10		/* P-type select              */
#define LSELECTN    11		/* N-type select              */
#define LWELLP      12		/* P-type well                */
#define LWELLN      13		/* N-type well                */
#define LPOLYCUT    14		/* poly contact cut           */
#define LACTCUT     15		/* active contact cut         */
#define LVIA1       16		/* metal1-to-metal2 via       */
#define LVIA2       17		/* metal2-to-metal3 via       */
#define LVIA3       18		/* metal3-to-metal4 via       */
#define LVIA4       19		/* metal4-to-metal5 via       */
#define LVIA5       20		/* metal5-to-metal6 via       */
#define LPASS       21		/* passivation (overglass)    */
#define LTRANS      22		/* transistor polysilicon     */
#define LPOLYCAP    23		/* polysilicon capacitor      */
#define LPACTWELL   24		/* P active in well           */
#define LMET1P      25		/* pseudo metal 1             */
#define LMET2P      26		/* pseudo metal 2             */
#define LMET3P      27		/* pseudo metal 3             */
#define LMET4P      28		/* pseudo metal 4             */
#define LMET5P      29		/* pseudo metal 5             */
#define LMET6P      30		/* pseudo metal 6             */
#define LPOLY1P     31		/* pseudo polysilicon 1       */
#define LPOLY2P     32		/* pseudo polysilicon 2       */
#define LPACTP      33		/* pseudo P active            */
#define LNACTP      34		/* pseudo N active            */
#define LSELECTPP   35		/* pseudo P-type select       */
#define LSELECTNP   36		/* pseudo N-type select       */
#define LWELLPP     37		/* pseudo P-type well         */
#define LWELLNP     38		/* pseudo N-type well         */
#define LFRAME      39		/* 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_m3_lay = {LAYERT5,COLORT5, SOLIDC, PATTERNED,
/* metal-3 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_m4_lay = {LAYERO,LBLUE, PATTERNED, PATTERNED,
/* metal-4 layer */		{0xCCCC, /* XX  XX  XX  XX   */
						0xCCCC,  /* XX  XX  XX  XX   */
						0x3333,  /*   XX  XX  XX  XX */
						0x3333,  /*   XX  XX  XX  XX */
						0xCCCC,  /* XX  XX  XX  XX   */
						0xCCCC,  /* XX  XX  XX  XX   */
						0x3333,  /*   XX  XX  XX  XX */
						0x3333}, /*   XX  XX  XX  XX */
						NOVARIABLE, 0};
static GRAPHICS mocmos_m5_lay = {LAYERO,LRED, PATTERNED, PATTERNED,
/* metal-5 layer */		{0xFCFC, /* XXXXXX  XXXXXX   */
						0x8080,  /* X       X        */
						0x8080,  /* X       X        */
						0xF8F8,  /* XXXXX   XXXXX    */
						0x0404,  /*      X       X   */
						0x0404,  /*      X       X   */
						0xF8F8,  /* XXXXX   XXXXX    */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_m6_lay = {LAYERO,CYAN, PATTERNED, PATTERNED,
/* metal-6 layer */		{0x1818, /*    XX      XX    */
						0x6060,  /*  XX      XX      */
						0x8080,  /* X       X        */
						0xF8F8,  /* XXXXX   XXXXX    */
						0x8484,  /* X    X  X    X   */
						0x8484,  /* X    X  X    X   */
						0x7878,  /*  XXXX    XXXX    */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_p1_lay = {LAYERT2,COLORT2, SOLIDC, PATTERNED,
/* poly layer */		{0x1111, /*    X   X   X   X */
						0xFFFF,  /* XXXXXXXXXXXXXXXX */
						0x1111,  /*    X   X   X   X */
						0x5555,  /*  X X X X X X X X */
						0x1111,  /*    X   X   X   X */
						0xFFFF,  /* XXXXXXXXXXXXXXXX */
						0x1111,  /*    X   X   X   X */
						0x5555}, /*  X X X X X X X X */
						NOVARIABLE, 0};
static GRAPHICS mocmos_p2_lay = {LAYERO,ORANGE, PATTERNED, PATTERNED,
/* poly2 layer */		{0xAFAF, /* X X XXXXX X XXXX */
						0x8888,  /* X   X   X   X    */
						0xFAFA,  /* XXXXX X XXXXX X  */
						0x8888,  /* X   X   X   X    */
						0xAFAF,  /* X X XXXXX X XXXX */
						0x8888,  /* X   X   X   X    */
						0xFAFA,  /* XXXXX X XXXXX X  */
						0x8888}, /* X   X   X   X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pa_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* P 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_na_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* N 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 = {LAYERO,YELLOW, PATTERNED, PATTERNED,
/* N Select layer */	{0x0101, /*        X       X */
						0x0000,  /*                  */
						0x1010,  /*    X       X     */
						0x0000,  /*                  */
						0x0101,  /*        X       X */
						0x0000,  /*                  */
						0x1010,  /*    X       X     */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_wp_lay = {LAYERO,BROWN, PATTERNED, PATTERNED,
/* P Well layer */		{0x0202, /*       X       X  */
						0x0101,  /*        X       X */
						0x8080,  /* X       X        */
						0x4040,  /*  X       X       */
						0x2020,  /*   X       X      */
						0x1010,  /*    X       X     */
						0x0808,  /*     X       X    */
						0x0404}, /*      X       X   */
						NOVARIABLE, 0};
static GRAPHICS mocmos_wn_lay = {LAYERO,BROWN, PATTERNED, PATTERNED,
/* N Well implant */	{0x0202, /*       X       X  */
						0x0000,  /*                  */
						0x2020,  /*   X       X      */
						0x0000,  /*                  */
						0x0202,  /*       X       X  */
						0x0000,  /*                  */
						0x2020,  /*   X       X      */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pc_lay = {LAYERO,DGRAY, SOLIDC, SOLIDC,
/* poly cut layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_ac_lay = {LAYERO,DGRAY, SOLIDC, SOLIDC,
/* active cut layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_v1_lay = {LAYERO,GRAY, SOLIDC, SOLIDC,
/* via1 layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_v2_lay = {LAYERO,GRAY, SOLIDC, SOLIDC,
/* via2 layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_v3_lay = {LAYERO,GRAY, SOLIDC, SOLIDC,
/* via3 layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_v4_lay = {LAYERO,GRAY, SOLIDC, SOLIDC,
/* via4 layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_v5_lay = {LAYERO,GRAY, SOLIDC, SOLIDC,
/* via5 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 = {LAYERT2,COLORT2, SOLIDC, PATTERNED,
/* poly/trans layer */	{0x1111, /*    X   X   X   X */
						0xFFFF,  /* XXXXXXXXXXXXXXXX */
						0x1111,  /*    X   X   X   X */
						0x5555,  /*  X X X X X X X X */
						0x1111,  /*    X   X   X   X */
						0xFFFF,  /* XXXXXXXXXXXXXXXX */
						0x1111,  /*    X   X   X   X */
						0x5555}, /*  X X X X X X X X */
						NOVARIABLE, 0};
static GRAPHICS mocmos_cp_lay = {LAYERO,BLACK, SOLIDC, SOLIDC,
/* poly cap layer */	{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};
static GRAPHICS mocmos_paw_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* P 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_pm3_lay = {LAYERT5,COLORT5, SOLIDC, PATTERNED,
/* pseudo metal-3 */	{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_pm4_lay = {LAYERO,LBLUE, PATTERNED, PATTERNED,
/* pseudo metal-4 */	{0xCCCC, /* XX  XX  XX  XX   */
						0xCCCC,  /* XX  XX  XX  XX   */
						0x3333,  /*   XX  XX  XX  XX */
						0x3333,  /*   XX  XX  XX  XX */
						0xCCCC,  /* XX  XX  XX  XX   */
						0xCCCC,  /* XX  XX  XX  XX   */
						0x3333,  /*   XX  XX  XX  XX */
						0x3333}, /*   XX  XX  XX  XX */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pm5_lay = {LAYERO,LRED, PATTERNED, PATTERNED,
/* pseudo metal-5 */	{0xFCFC, /* XXXXXX  XXXXXX   */
						0x8080,  /* X       X        */
						0x8080,  /* X       X        */
						0xF8F8,  /* XXXXX   XXXXX    */
						0x0404,  /*      X       X   */
						0x0404,  /*      X       X   */
						0xF8F8,  /* XXXXX   XXXXX    */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pm6_lay = {LAYERO,CYAN, PATTERNED, PATTERNED,
/* pseudo metal-6 */	{0x1818, /*    XX      XX    */
						0x6060,  /*  XX      XX      */
						0x8080,  /* X       X        */
						0xF8F8,  /* XXXXX   XXXXX    */
						0x8484,  /* X    X  X    X   */
						0x8484,  /* X    X  X    X   */
						0x7878,  /*  XXXX    XXXX    */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pp1_lay = {LAYERT2,COLORT2, SOLIDC, PATTERNED,
/* pseudo poly layer */	{0x1111, /*    X   X   X   X */
						0xFFFF,  /* XXXXXXXXXXXXXXXX */
						0x1111,  /*    X   X   X   X */
						0x5555,  /*  X X X X X X X X */
						0x1111,  /*    X   X   X   X */
						0xFFFF,  /* XXXXXXXXXXXXXXXX */
						0x1111,  /*    X   X   X   X */
						0x5555}, /*  X X X X X X X X */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pp2_lay = {LAYERO,ORANGE, PATTERNED, PATTERNED,
/* pseudo poly2 layer */{0xAFAF, /* X X XXXXX X XXXX */
						0x8888,  /* X   X   X   X    */
						0xFAFA,  /* XXXXX X XXXXX X  */
						0x8888,  /* X   X   X   X    */
						0xAFAF,  /* X X XXXXX X XXXX */
						0x8888,  /* X   X   X   X    */
						0xFAFA,  /* XXXXX X XXXXX X  */
						0x8888}, /* X   X   X   X    */
						NOVARIABLE, 0};
static GRAPHICS mocmos_ppa_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* pseudo P 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_pna_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
/* pseudo N 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 = {LAYERO,YELLOW,PATTERNED, PATTERNED,
/* pseudo N Select */	{0x0101, /*        X       X */
						0x0000,  /*                  */
						0x1010,  /*    X       X     */
						0x0000,  /*                  */
						0x0101,  /*        X       X */
						0x0000,  /*                  */
						0x1010,  /*    X       X     */
						0x0000}, /*                  */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pwp_lay = {LAYERO,BROWN, PATTERNED, PATTERNED,
/* pseudo P Well */		{0x0202, /*       X       X  */
						0x0101,  /*        X       X */
						0x8080,  /* X       X        */
						0x4040,  /*  X       X       */
						0x2020,  /*   X       X      */
						0x1010,  /*    X       X     */
						0x0808,  /*     X       X    */
						0x0404}, /*      X       X   */
						NOVARIABLE, 0};
static GRAPHICS mocmos_pwn_lay = {LAYERO,BROWN, PATTERNED, PATTERNED,
/* pseudo N Well */		{0x0202, /*       X       X  */
						0x0000,  /*                  */
						0x2020,  /*   X       X      */
						0x0000,  /*                  */
						0x0202,  /*       X       X  */
						0x0000,  /*                  */
						0x2020,  /*   X       X      */
						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_m3_lay,				/* metal 1/2/3 */
	&mocmos_m4_lay, &mocmos_m5_lay, &mocmos_m6_lay,				/* metal 4/5/6 */
	&mocmos_p1_lay, &mocmos_p2_lay,								/* poly 1/2 */
	&mocmos_pa_lay, &mocmos_na_lay,								/* P/N active */
	&mocmos_ssp_lay, &mocmos_ssn_lay,							/* P/N select */
	&mocmos_wp_lay, &mocmos_wn_lay,								/* P/N well */
	&mocmos_pc_lay, &mocmos_ac_lay,								/* poly/act cut */
	&mocmos_v1_lay, &mocmos_v2_lay, &mocmos_v3_lay,				/* via 1/2/3 */
	&mocmos_v4_lay, &mocmos_v5_lay,								/* via 4/5 */
	&mocmos_ovs_lay,											/* overglass */
	&mocmos_tr_lay,												/* transistor poly */
	&mocmos_cp_lay,												/* poly cap */
	&mocmos_paw_lay,											/* P active well */
	&mocmos_pm1_lay, &mocmos_pm2_lay,							/* pseudo metal 1/2 */
	&mocmos_pm3_lay, &mocmos_pm4_lay,							/* pseudo metal 3/4 */
	&mocmos_pm5_lay, &mocmos_pm6_lay,							/* pseudo metal 5/6 */
	&mocmos_pp1_lay, &mocmos_pp2_lay,							/* pseudo poly 1/2 */
	&mocmos_ppa_lay, &mocmos_pna_lay,							/* pseudo P/N active */
	&mocmos_pssp_lay, &mocmos_pssn_lay,							/* pseudo P/N select */
	&mocmos_pwp_lay, &mocmos_pwn_lay,							/* pseudo P/N well */
	&mocmos_pf_lay, NOGRAPHICS};								/* pad frame */
static char *mocmos_layer_names[MAXLAYERS] = {
	"Metal-1", "Metal-2", "Metal-3",							/* metal 1/2/3 */
	"Metal-4", "Metal-5", "Metal-6",							/* metal 4/5/6 */
	"Polysilicon-1", "Polysilicon-2",							/* poly 1/2 */
	"P-Active", "N-Active",										/* P/N active */
	"P-Select", "N-Select",										/* P/N select */
	"P-Well", "N-Well",											/* P/N well */
	"Poly-Cut", "Active-Cut",									/* poly/act cut */
	"Via1", "Via2", "Via3",										/* via 1/2/3 */
	"Via4", "Via5",												/* via 4/5 */
	"Passivation",												/* overglass */
	"Transistor-Poly",											/* transistor poly */
	"Poly-Cap",													/* poly cap */
	"P-Active-Well",											/* P active well */
	"Pseudo-Metal-1", "Pseudo-Metal-2",							/* pseudo metal 1/2 */
	"Pseudo-Metal-3", "Pseudo-Metal-4",							/* pseudo metal 3/4 */
	"Pseudo-Metal-5", "Pseudo-Metal-6",							/* pseudo metal 5/6 */
	"Pseudo-Polysilicon", "Pseudo-Electrode",					/* pseudo poly 1/2 */
	"Pseudo-P-Active", "Pseudo-N-Active",						/* pseudo P/N active */
	"Pseudo-P-Select", "Pseudo-N-Select",						/* pseudo P/N select */
	"Pseudo-P-Well", "Pseudo-N-Well",							/* pseudo P/N well */
	"Pad-Frame"};												/* pad frame */
static INTBIG mocmos_layer_function[MAXLAYERS] = {
	LFMETAL1|LFTRANS1, LFMETAL2|LFTRANS4, LFMETAL3|LFTRANS5,	/* metal 1/2/3 */
	LFMETAL4, LFMETAL5, LFMETAL6,								/* metal 4/5/6 */
	LFPOLY1|LFTRANS2, LFPOLY2,									/* poly 1/2 */
	LFDIFF|LFPTYPE|LFTRANS3, LFDIFF|LFNTYPE|LFTRANS3,			/* P/N active */
	LFIMPLANT|LFPTYPE, LFIMPLANT|LFNTYPE,						/* P/N select */
	LFWELL|LFPTYPE, LFWELL|LFNTYPE,								/* P/N well */
	LFCONTACT1|LFCONPOLY, LFCONTACT1|LFCONDIFF,					/* poly/act cut */
	LFCONTACT2|LFCONMETAL, LFCONTACT3|LFCONMETAL, LFCONTACT4|LFCONMETAL,	/* via 1/2/3 */
	LFCONTACT5|LFCONMETAL, LFCONTACT6|LFCONMETAL,				/* via 4/5 */
	LFOVERGLASS,												/* overglass */
	LFPOLY1|LFINTRANS|LFTRANS2,									/* transistor poly */
	LFCAP,														/* poly cap */
	LFDIFF|LFPTYPE|LFTRANS3,									/* P active well */
	LFMETAL1|LFPSEUDO|LFTRANS1,LFMETAL2|LFPSEUDO|LFTRANS4,		/* pseudo metal 1/2 */
	LFMETAL3|LFPSEUDO|LFTRANS5, LFMETAL4|LFPSEUDO,				/* pseudo metal 3/4 */
	LFMETAL5|LFPSEUDO, LFMETAL6|LFPSEUDO,						/* pseudo metal 5/6 */
	LFPOLY1|LFPSEUDO|LFTRANS2, LFPOLY2|LFPSEUDO,				/* pseudo poly 1/2 */
	LFDIFF|LFPTYPE|LFPSEUDO|LFTRANS3,							/* pseudo P/N active */
		LFDIFF|LFNTYPE|LFPSEUDO|LFTRANS3,
	LFIMPLANT|LFPTYPE|LFPSEUDO, LFIMPLANT|LFNTYPE|LFPSEUDO,		/* pseudo P/N select */
	LFWELL|LFPTYPE|LFPSEUDO, LFWELL|LFNTYPE|LFPSEUDO,			/* pseudo P/N well */
	LFART};														/* pad frame */
static char *mocmos_cif_layers[MAXLAYERS] = {
	"CMF", "CMS", "CMT", "CMQ", "CMP", "CM6",					/* metal 1/2/3/4/5/6 */
	"CPG", "CEL",												/* poly 1/2 */
	"CAA", "CAA",												/* P/N active */
	"CSP", "CSN",												/* P/N select */
	"CWP", "CWN",												/* P/N well */
	"CCC", "CCC",												/* poly/act cut */
	"CVA", "CVS", "CVT", "CVQ", "CV5",							/* via 1/2/3/4/5 */
	"COG",														/* overglass */
	"CPG",														/* transistor poly */
	"CPC",														/* poly cap */
	"CAA",														/* P active well */
	"", "", "", "", "", "",										/* pseudo metal 1/2/3/4/5/6 */
	"", "",														/* pseudo poly 1/2 */
	"", "",														/* pseudo P/N active */
	"CSP", "CSN",												/* pseudo P/N select */
	"CWP", "CWN",												/* pseudo P/N well */
	"CX"};														/* pad frame */
static INTBIG mocmos_gds_layers[MAXLAYERS] = {
	49, 51, 62, 31, 33, 38,										/* metal 1/2/3/4/5/6 */
	46, 56,														/* poly 1/2 */
	43, 43,														/* P/N active */
	44, 45,														/* P/N select */
	41, 42,														/* P/N well */
	25, 25,														/* poly/act cut */
	50, 61, 30, 32, 39,											/* via 1/2/3/4/5 */
	52,															/* overglass */
	46,															/* transistor poly */
	28,															/* poly cap */
	43,															/* P active well */
	-1, -1, -1, -1, -1, -1,										/* pseudo metal 1/2/3/4/5/6 */
	-1, -1,														/* pseudo poly 1/2 */
	-1, -1,														/* pseudo P/N active */
	-1, -1,														/* pseudo P/N select */
	-1, -1,														/* pseudo P/N well */
	19};														/* pad frame */
static char *mocmos_skill_layers[MAXLAYERS] = {
	"metal1", "metal2", "metal3",								/* metal 1/2/3 */
	"metal4", "metal5", "metal6",								/* metal 4/5/6 */
	"poly", "",													/* poly 1/2 */
	"aa", "aa",													/* P/N active */
	"pplus", "nplus",											/* P/N select */
	"pwell", "nwell",											/* P/N well */
	"pcont", "acont",											/* poly/act cut */
	"via", "via2", "via3", "via4", "via5",						/* via 1/2/3/4/5 */
	"glasscut",													/* overglass */
	"poly",														/* transistor poly */
	"",															/* poly cap */
	"aa",														/* P active well */
	"", "", "", "", "", "",										/* pseudo metal 1/2/3/4/5/6 */
	"", "",														/* pseudo poly 1/2 */
	"", "",														/* pseudo P/N active */
	"pplus", "nplus",											/* pseudo P/N select */
	"pwell", "nwell",											/* pseudo P/N well */
	""};														/* pad frame */
static INTBIG mocmos_3dthick_layers[MAXLAYERS] = {
	0, 0, 0, 0, 0, 0,											/* metal 1/2/3/4/5/6 */
	0, 0,														/* poly 1/2 */
	0, 0,														/* P/N active */
	0, 0,														/* P/N select */
	0, 0,														/* P/N well */
	2, 4,														/* poly/act cut */
	2, 2, 2, 2, 2,												/* via 1/2/3/4/5 */
	0,															/* overglass */
	0,															/* transistor poly */
	0,															/* poly cap */
	0,															/* P active well */
	0, 0, 0, 0, 0, 0,											/* pseudo metal 1/2/3/4/5/6 */
	0, 0,														/* pseudo poly 1/2 */
	0, 0,														/* pseudo P/N active */
	0, 0,														/* pseudo P/N select */
	0, 0,														/* pseudo P/N well */
	0};															/* pad frame */
static INTBIG mocmos_3dheight_layers[MAXLAYERS] = {
	17, 19, 21, 23, 25, 27,										/* metal 1/2/3/4/5/6 */
	15, 16,														/* poly 1/2 */
	13, 13,														/* P/N active */
	12, 12,														/* P/N select */
	11, 11,														/* P/N well */
	16, 15,														/* poly/act cut */
	18, 20, 22, 24, 26,											/* via 1/2/3/4/5 */
	30,															/* overglass */
	15,															/* transistor poly */
	28,															/* poly cap */
	13,															/* P active well */
	17, 19, 21, 23, 25, 27,										/* pseudo metal 1/2/3/4/5/6 */
	12, 13,														/* pseudo poly 1/2 */
	11, 11,														/* pseudo P/N active */
	2, 2,														/* pseudo P/N select */
	0, 0,														/* pseudo P/N well */
	33};														/* pad frame */
/* there are no available letters */
static char *mocmos_layer_letters[MAXLAYERS] = {
	"m", "h", "r", "q", "a", "c",								/* metal 1/2/3/4/5/6 */
	"p", "l",													/* poly 1/2 */
	"s", "d",													/* P/N active */
	"e", "f",													/* P/N select */
	"w", "n",													/* P/N well */
	"j", "k",													/* poly/act cut */
	"v", "u", "z", "i", "y",									/* via 1/2/3/4/5 */
	"o",														/* overglass */
	"t",														/* transistor poly */
	"g",														/* poly cap */
	"x",														/* P active well */
	"M", "H", "R", "Q", "A", "C",								/* pseudo metal 1/2/3/4/5/6 */
	"P", "L",													/* pseudo poly 1/2 */
	"S", "D",													/* pseudo P/N active */
	"E", "F",													/* pseudo P/N select */
	"W", "N",													/* pseudo P/N well */
	"b"};														/* pad frame */

/* The low 5 bits map Metal-1, Poly-1, Active, Metal-2, and Metal-3 */
static TECH_COLORMAP mocmos_colmap[32] =
{                  /*     Metal-3 Metal-2 Active Polysilicon-1 Metal-1 */
	{200,200,200}, /*  0:                                              */
	{ 96,209,255}, /*  1:                                      Metal-1 */
	{255,155,192}, /*  2:                        Polysilicon-1         */
	{111,144,177}, /*  3:                        Polysilicon-1 Metal-1 */
	{107,226, 96}, /*  4:                 Active                       */
	{ 83,179,160}, /*  5:                 Active               Metal-1 */
	{161,151,126}, /*  6:                 Active Polysilicon-1         */
	{110,171,152}, /*  7:                 Active Polysilicon-1 Metal-1 */
	{224, 95,255}, /*  8:         Metal-2                              */
	{135,100,191}, /*  9:         Metal-2                      Metal-1 */
	{170, 83,170}, /* 10:         Metal-2        Polysilicon-1         */
	{152,104,175}, /* 11:         Metal-2        Polysilicon-1 Metal-1 */
	{150,124,163}, /* 12:         Metal-2 Active                       */
	{129,144,165}, /* 13:         Metal-2 Active               Metal-1 */
	{155,133,151}, /* 14:         Metal-2 Active Polysilicon-1         */
	{141,146,153}, /* 15:         Metal-2 Active Polysilicon-1 Metal-1 */
	{247,251, 20}, /* 16: Metal-3                                      */
	{154,186, 78}, /* 17: Metal-3                              Metal-1 */
	{186,163, 57}, /* 18: Metal-3                Polysilicon-1         */
	{167,164, 99}, /* 19: Metal-3                Polysilicon-1 Metal-1 */
	{156,197, 41}, /* 20: Metal-3         Active                       */
	{138,197, 83}, /* 21: Metal-3         Active               Metal-1 */
	{161,184, 69}, /* 22: Metal-3         Active Polysilicon-1         */
	{147,183, 97}, /* 23: Metal-3         Active Polysilicon-1 Metal-1 */
	{186,155, 76}, /* 24: Metal-3 Metal-2                              */
	{155,163,119}, /* 25: Metal-3 Metal-2                      Metal-1 */
	{187,142, 97}, /* 26: Metal-3 Metal-2        Polysilicon-1         */
	{165,146,126}, /* 27: Metal-3 Metal-2        Polysilicon-1 Metal-1 */
	{161,178, 82}, /* 28: Metal-3 Metal-2 Active                       */
	{139,182,111}, /* 29: Metal-3 Metal-2 Active               Metal-1 */
	{162,170, 97}, /* 30: Metal-3 Metal-2 Active Polysilicon-1         */
	{147,172,116}  /* 31: Metal-3 Metal-2 Active Polysilicon-1 Metal-1 */
};

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

#define WIDELIMIT         K10					/* wide rules apply to geometry larger than this */


/* the meaning of "when" in the DRC table */
#define M2      01		/* only applies if there are 2 metal layers in process */
#define M3      02		/* only applies if there are 3 metal layers in process */
#define M4      04		/* only applies if there are 4 metal layers in process */
#define M5     010		/* only applies if there are 5 metal layers in process */
#define M6     020		/* only applies if there are 6 metal layers in process */
#define M23     03		/* only applies if there are 2-3 metal layers in process */
#define M234    07		/* only applies if there are 2-4 metal layers in process */
#define M2345  017		/* only applies if there are 2-5 metal layers in process */
#define M456   034		/* only applies if there are 4-6 metal layers in process */
#define M56    030		/* only applies if there are 5-6 metal layers in process */
#define M3456  036		/* only applies if there are 3-6 metal layers in process */

#define AC     040		/* only applies if alternate contact rules are in effect */
#define NAC   0100		/* only applies if alternate contact rules are not in effect */
#define SV    0200		/* only applies if stacked vias are allowed */
#define NSV   0400		/* only applies if stacked vias are not allowed */
#define DE   01000		/* only applies if deep rules are in effect */
#define SU   02000		/* only applies if submicron rules are in effect */
#define SC   04000		/* only applies if scmos rules are in effect */

/* the meaning of "ruletype" in the DRC table */
#define MINWID     1		/* a minimum-width rule */
#define NODSIZ     2		/* a node size rule */
#define SURROUND   3		/* a general surround rule */
#define VIASUR     4		/* a via surround rule */
#define TRAWELL    5		/* a transistor well rule */
#define TRAPOLY    6		/* a transistor poly rule */
#define TRAACTIVE  7		/* a transistor active rule */
#define SPACING    8		/* a spacing rule */
#define SPACINGM   9		/* a multi-cut spacing rule */
#define SPACINGW  10		/* a wide spacing rule */
#define SPACINGE  11		/* an edge spacing rule */
#define CONSPA    12		/* a connected spacing rule */
#define UCONSPA   13		/* an unconnected spacing rule */
#define CUTSPA    14		/* a contact cut spacing rule */
#define CUTSIZE   15		/* a contact cut size rule */
#define CUTSUR    16		/* a contact cut surround rule */

struct
{
	char *rule;				/* the name of the rule */
	INTBIG when;			/* when the rule is used */
	INTBIG ruletype;		/* the type of the rule */
	char *layer1, *layer2;	/* two layers that are used by the rule */
	INTBIG distance;		/* the spacing of the rule */
	char *nodename;			/* the node that is used by the rule */
} mocmos_drcrules[] =
{
	{"1.1",  DE|SU,           MINWID,   "P-Well",          0,               K12, 0},
	{"1.1",  DE|SU,           MINWID,   "N-Well",          0,               K12, 0},
	{"1.1",  DE|SU,           MINWID,   "Pseudo-P-Well",   0,               K12, 0},
	{"1.1",  DE|SU,           MINWID,   "Pseudo-N-Well",   0,               K12, 0},
	{"1.1",  SC,              MINWID,   "P-Well",          0,               K10, 0},
	{"1.1",  SC,              MINWID,   "N-Well",          0,               K10, 0},
	{"1.1",  SC,              MINWID,   "Pseudo-P-Well",   0,               K10, 0},
	{"1.1",  SC,              MINWID,   "Pseudo-N-Well",   0,               K10, 0},

	{"1.2",  DE|SU,           UCONSPA,  "P-Well",         "P-Well",         K18, 0},
	{"1.2",  DE|SU,           UCONSPA,  "N-Well",         "N-Well",         K18, 0},
	{"1.2",  SC,              UCONSPA,  "P-Well",         "P-Well",         K9,  0},
	{"1.2",  SC,              UCONSPA,  "N-Well",         "N-Well",         K9,  0},

	{"1.3",  0,               CONSPA,   "P-Well",         "P-Well",         K6,  0},
	{"1.3",  0,               CONSPA,   "N-Well",         "N-Well",         K6,  0},

	{"1.4",  0,               UCONSPA,  "P-Well",         "N-Well",         0,   0},

	{"2.1",  0,               MINWID,   "P-Active",        0,               K3,  0},
	{"2.1",  0,               MINWID,   "N-Active",        0,               K3,  0},

	{"2.2",  0,               SPACING,  "P-Active",       "P-Active",       K3,  0},
	{"2.2",  0,               SPACING,  "N-Active",       "N-Active",       K3,  0},
	{"2.2",  0,               SPACING,  "P-Active-Well",  "P-Active-Well",  K3,  0},
	{"2.2",  0,               SPACING,  "P-Active",       "N-Active",       K3,  0},
	{"2.2",  0,               SPACING,  "P-Active",       "P-Active-Well",  K3,  0},
	{"2.2",  0,               SPACING,  "N-Active",       "P-Active-Well",  K3,  0},

	{"2.3",  DE|SU,           SURROUND, "N-Well",         "P-Active",       K6, "Metal-1-P-Active-Con"},
	{"2.3",  DE|SU,           SURROUND, "P-Well",         "N-Active",       K6, "Metal-1-N-Active-Con"},
	{"2.3",  DE|SU,           TRAWELL,   0,                0,               K6,  0},
	{"2.3",  SC,              SURROUND, "N-Well",         "P-Active",       K5, "Metal-1-P-Active-Con"},
	{"2.3",  SC,              SURROUND, "P-Well",         "N-Active",       K5, "Metal-1-N-Active-Con"},
	{"2.3",  SC,              TRAWELL,   0,                0,               K5,  0},

	{"3.1",  0,               MINWID,   "Polysilicon-1",   0,               K2,  0},
	{"3.1",  0,               MINWID,   "Transistor-Poly", 0,               K2,  0},

	{"3.2",  DE|SU,           SPACING,  "Polysilicon-1",  "Polysilicon-1",  K3,  0},
	{"3.2",  DE|SU,           SPACING,  "Polysilicon-1",  "Transistor-Poly",K3,  0},
	{"3.2",  SC,              SPACING,  "Polysilicon-1",  "Polysilicon-1",  K2,  0},
	{"3.2",  SC,              SPACING,  "Polysilicon-1",  "Transistor-Poly",K2,  0},

	{"3.2a", DE,              SPACING,  "Transistor-Poly","Transistor-Poly",K4,  0},
	{"3.2a", SU,              SPACING,  "Transistor-Poly","Transistor-Poly",K3,  0},
	{"3.2a", SC,              SPACING,  "Transistor-Poly","Transistor-Poly",K2,  0},

	{"3.3",  DE,              TRAPOLY,   0,                0,               H2,  0},
	{"3.3",  SU|SC,           TRAPOLY,   0,                0,               K2,  0},

	{"3.4",  DE,              TRAACTIVE, 0,                0,               K4,  0},
	{"3.4",  SU|SC,           TRAACTIVE, 0,                0,               K3,  0},

	{"3.5",  0,               SPACING,  "Polysilicon-1",  "P-Active",       K1,  0},
	{"3.5",  0,               SPACING,  "Transistor-Poly","P-Active",       K1,  0},
	{"3.5",  0,               SPACING,  "Polysilicon-1",  "N-Active",       K1,  0},
	{"3.5",  0,               SPACING,  "Transistor-Poly","N-Active",       K1,  0},
	{"3.5",  0,               SPACING,  "Polysilicon-1",  "P-Active-Well",  K1,  0},
	{"3.5",  0,               SPACING,  "Transistor-Poly","P-Active-Well",  K1,  0},

	{"4.4",  DE,              MINWID,   "P-Select",        0,               K4,  0},
	{"4.4",  DE,              MINWID,   "N-Select",        0,               K4,  0},
	{"4.4",  DE,              MINWID,   "Pseudo-P-Select", 0,               K4,  0},
	{"4.4",  DE,              MINWID,   "Pseudo-N-Select", 0,               K4,  0},
	{"4.4",  DE,              SPACING,  "P-Select",       "P-Select",       K4,  0},
	{"4.4",  DE,              SPACING,  "N-Select",       "N-Select",       K4,  0},
	{"4.4",  SU|SC,           MINWID,   "P-Select",        0,               K2,  0},
	{"4.4",  SU|SC,           MINWID,   "N-Select",        0,               K2,  0},
	{"4.4",  SU|SC,           MINWID,   "Pseudo-P-Select", 0,               K2,  0},
	{"4.4",  SU|SC,           MINWID,   "Pseudo-N-Select", 0,               K2,  0},
	{"4.4",  SU|SC,           SPACING,  "P-Select",       "P-Select",       K2,  0},
	{"4.4",  SU|SC,           SPACING,  "N-Select",       "N-Select",       K2,  0},
	{"4.4",  0,               SPACING,  "P-Select",       "N-Select",       0,   0},

	{"5.1",  0,               MINWID,   "Poly-Cut",        0,               K2,  0},

	{"5.2",        NAC,       NODSIZ,    0,                0,               K5, "Metal-1-Polysilicon-1-Con"},
	{"5.2",        NAC,       SURROUND, "Polysilicon-1",  "Metal-1",        H0, "Metal-1-Polysilicon-1-Con"},
#if	1
	{"5.2",        NAC,       CUTSUR,    0,                0,               H1, "Metal-1-Polysilicon-1-Con"},
#endif
	{"5.2b",       AC,        NODSIZ,    0,                0,               K4, "Metal-1-Polysilicon-1-Con"},
	{"5.2b",       AC,        SURROUND, "Polysilicon-1",  "Metal-1",        0,  "Metal-1-Polysilicon-1-Con"},
#if	1
	{"5.2b",       AC,        CUTSUR,    0,                0,               K1, "Metal-1-Polysilicon-1-Con"},
#endif

	{"5.3",     DE,           CUTSPA,    0,                0,               K4, "Metal-1-Polysilicon-1-Con"},
	{"5.3",     DE,           SPACING,  "Poly-Cut",       "Poly-Cut",       K4,  0},
	{"5.3,6.3", DE|NAC,       SPACING,  "Active-Cut",     "Poly-Cut",       K4,  0},
	{"5.3",     SU,           CUTSPA,    0,                0,               K3, "Metal-1-Polysilicon-1-Con"},
	{"5.3",     SU,           SPACING,  "Poly-Cut",       "Poly-Cut",       K3,  0},
	{"5.3,6.3", SU|NAC,       SPACING,  "Active-Cut",     "Poly-Cut",       K3,  0},
	{"5.3",     SC,           CUTSPA,    0,                0,               K2, "Metal-1-Polysilicon-1-Con"},
	{"5.3",     SC,           SPACING,  "Poly-Cut",       "Poly-Cut",       K2,  0},
	{"5.3,6.3", SC|NAC,       SPACING,  "Active-Cut",     "Poly-Cut",       K2,  0},

	{"5.4",  0,               SPACING,  "Poly-Cut",       "P-Active",       K2,  0},
	{"5.4",  0,               SPACING,  "Poly-Cut",       "N-Active",       K2,  0},

	{"5.5b", DE|SU|AC,        UCONSPA,  "Poly-Cut",       "Polysilicon-1",  K5,  0},
	{"5.5b", DE|SU|AC,        UCONSPA,  "Poly-Cut",       "Transistor-Poly",K5,  0},
	{"5.5b", SC|   AC,        UCONSPA,  "Poly-Cut",       "Polysilicon-1",  K4,  0},
	{"5.5b", SC|   AC,        UCONSPA,  "Poly-Cut",       "Transistor-Poly",K4,  0},

	{"5.6b",       AC,        SPACING,  "Poly-Cut",       "P-Active",       K2,  0},
	{"5.6b",       AC,        SPACING,  "Poly-Cut",       "N-Active",       K2,  0},

	{"5.7b",       AC,        SPACINGM, "Poly-Cut",       "P-Active",       K3,  0},
	{"5.7b",       AC,        SPACINGM, "Poly-Cut",       "N-Active",       K3,  0},

	{"6.1",  0,               MINWID,   "Active-Cut",      0,               K2,  0},

	{"6.2",        NAC,       NODSIZ,    0,                0,               K5, "Metal-1-P-Active-Con"},
	{"6.2",        NAC,       SURROUND, "P-Active",       "Metal-1",        H0, "Metal-1-P-Active-Con"},
	{"6.2",        NAC,       SURROUND, "P-Select",       "P-Active",       K2, "Metal-1-P-Active-Con"},
	{"6.2",        NAC,       SURROUND, "N-Well",         "P-Active",       K6, "Metal-1-P-Active-Con"},
#if	1
	{"6.2",        NAC,       CUTSUR,    0,                0,               H1, "Metal-1-P-Active-Con"},
#endif
	{"6.2b",       AC,        NODSIZ,    0,                0,               K4, "Metal-1-P-Active-Con"},
	{"6.2b",       AC,        SURROUND, "P-Active",       "Metal-1",        0,  "Metal-1-P-Active-Con"},
	{"6.2b",       AC,        SURROUND, "P-Select",       "P-Active",       K2, "Metal-1-P-Active-Con"},
	{"6.2b",       AC,        SURROUND, "N-Well",         "P-Active",       K6, "Metal-1-P-Active-Con"},
#if	1
	{"6.2b",       AC,        CUTSUR,    0,                0,               K1, "Metal-1-P-Active-Con"},
#endif

	{"6.2",        NAC,       NODSIZ,    0,                0,               K5, "Metal-1-N-Active-Con"},
	{"6.2",        NAC,       SURROUND, "N-Active",       "Metal-1",        H0, "Metal-1-N-Active-Con"},
	{"6.2",        NAC,       SURROUND, "N-Select",       "N-Active",       K2, "Metal-1-N-Active-Con"},
	{"6.2",        NAC,       SURROUND, "P-Well",         "N-Active",       K6, "Metal-1-N-Active-Con"},
#if	1
	{"6.2",        NAC,       CUTSUR,    0,                0,               H1, "Metal-1-N-Active-Con"},
#endif
	{"6.2b",       AC,        NODSIZ,    0,                0,               K4, "Metal-1-N-Active-Con"},
	{"6.2b",       AC,        SURROUND, "N-Active",       "Metal-1",        0,  "Metal-1-N-Active-Con"},
	{"6.2b",       AC,        SURROUND, "N-Select",       "N-Active",       K2, "Metal-1-N-Active-Con"},
	{"6.2b",       AC,        SURROUND, "P-Well",         "N-Active",       K6, "Metal-1-N-Active-Con"},
#if	1
	{"6.2b",       AC,        CUTSUR,    0,                0,               K1, "Metal-1-N-Active-Con"},
#endif

	{"6.2",        NAC,       NODSIZ,    0,                0,               K5, "Metal-1-P-Well-Con"},
	{"6.2",        NAC,       SURROUND, "P-Active-Well",  "Metal-1",        H0, "Metal-1-P-Well-Con"},
	{"6.2",        NAC,       SURROUND, "P-Select",       "P-Active-Well",  K2, "Metal-1-P-Well-Con"},
	{"6.2",        NAC,       SURROUND, "P-Well",         "P-Active-Well",  K6, "Metal-1-P-Well-Con"},
#if	1
	{"6.2",        NAC,       CUTSUR,    0,                0,               H1, "Metal-1-P-Well-Con"},
#endif
	{"6.2b",       AC,        NODSIZ,    0,                0,               K4, "Metal-1-P-Well-Con"},
	{"6.2b",       AC,        SURROUND, "P-Active-Well",  "Metal-1",        0,  "Metal-1-P-Well-Con"},
	{"6.2b",       AC,        SURROUND, "P-Select",       "P-Active-Well",  K2, "Metal-1-P-Well-Con"},
	{"6.2b",       AC,        SURROUND, "P-Well",         "P-Active-Well",  K6, "Metal-1-P-Well-Con"},
#if	1
	{"6.2b",       AC,        CUTSUR,    0,                0,               K1, "Metal-1-P-Well-Con"},
#endif

	{"6.2",        NAC,       NODSIZ,    0,                0,               K5, "Metal-1-N-Well-Con"},
	{"6.2",        NAC,       SURROUND, "N-Active",       "Metal-1",        H0, "Metal-1-N-Well-Con"},
	{"6.2",        NAC,       SURROUND, "N-Select",       "N-Active",       K2, "Metal-1-N-Well-Con"},
	{"6.2",        NAC,       SURROUND, "N-Well",         "N-Active",       K6, "Metal-1-N-Well-Con"},
#if	1
	{"6.2",        NAC,       CUTSUR,    0,                0,               H1, "Metal-1-N-Well-Con"},
#endif
	{"6.2b",       AC,        NODSIZ,    0,                0,               K4, "Metal-1-N-Well-Con"},
	{"6.2b",       AC,        SURROUND, "N-Active",       "Metal-1",        0,  "Metal-1-N-Well-Con"},
	{"6.2b",       AC,        SURROUND, "N-Select",       "N-Active",       K2, "Metal-1-N-Well-Con"},
	{"6.2b",       AC,        SURROUND, "N-Well",         "N-Active",       K6, "Metal-1-N-Well-Con"},
#if	1
	{"6.2b",       AC,        CUTSUR,    0,                0,               K1, "Metal-1-N-Well-Con"},
#endif

	{"6.3",  DE,              CUTSPA,    0,                0,               K4, "Metal-1-P-Active-Con"},
	{"6.3",  DE,              CUTSPA,    0,                0,               K4, "Metal-1-N-Active-Con"},
	{"6.3",  DE,              SPACING,  "Active-Cut",     "Active-Cut",     K4,  0},
	{"6.3",  SU,              CUTSPA,    0,                0,               K3, "Metal-1-P-Active-Con"},
	{"6.3",  SU,              CUTSPA,    0,                0,               K3, "Metal-1-N-Active-Con"},
	{"6.3",  SU,              SPACING,  "Active-Cut",     "Active-Cut",     K3,  0},
	{"6.3",  SC,              CUTSPA,    0,                0,               K2, "Metal-1-P-Active-Con"},
	{"6.3",  SC,              CUTSPA,    0,                0,               K2, "Metal-1-N-Active-Con"},
	{"6.3",  SC,              SPACING,  "Active-Cut",     "Active-Cut",     K2,  0},

	{"6.4",  0,               SPACING,  "Active-Cut",     "Transistor-Poly",K2,  0},

	{"6.5b",       AC,        UCONSPA,  "Active-Cut",     "P-Active",       K5,  0},
	{"6.5b",       AC,        UCONSPA,  "Active-Cut",     "N-Active",       K5,  0},

	{"6.6b",       AC,        SPACING,  "Active-Cut",     "Polysilicon-1",  K2,  0},

	{"6.7b",       AC,        SPACINGM, "Active-Cut",     "Polysilicon-1",  K3,  0},

	{"6.8b",       AC,        SPACING,  "Active-Cut",     "Poly-Cut",       K4,  0},

	{"7.1",  0,               MINWID,   "Metal-1",         0,               K3,  0},

	{"7.2",  DE|SU,           SPACING,  "Metal-1",        "Metal-1",        K3,  0},
	{"7.2",  SC,              SPACING,  "Metal-1",        "Metal-1",        K2,  0},

	{"7.4",  DE|SU,           SPACINGW, "Metal-1",        "Metal-1",        K6,  0},
	{"7.4",  SC,              SPACINGW, "Metal-1",        "Metal-1",        K4,  0},

	{"8.1",  DE,              CUTSIZE,   0,                0,               K3, "Metal-1-Metal-2-Con"},
	{"8.1",  DE,              NODSIZ,    0,                0,               K5, "Metal-1-Metal-2-Con"},
	{"8.1",  SU|SC,           CUTSIZE,   0,                0,               K2, "Metal-1-Metal-2-Con"},
	{"8.1",  SU|SC,           NODSIZ,    0,                0,               K4, "Metal-1-Metal-2-Con"},

	{"8.2",  0,               SPACING,  "Via1",           "Via1",           K3,  0},

	{"8.3",  0,               VIASUR,   "Metal-1",         0,               K1, "Metal-1-Metal-2-Con"},

	{"8.4",        NSV,       SPACING,  "Poly-Cut",       "Via1",           K2,  0},
	{"8.4",        NSV,       SPACING,  "Active-Cut",     "Via1",           K2,  0},

	{"8.5",        NSV,       SPACINGE, "Via1",           "Polysilicon-1",  K2,  0},
	{"8.5",        NSV,       SPACINGE, "Via1",           "Transistor-Poly",K2,  0},
	{"8.5",        NSV,       SPACINGE, "Via1",           "Polysilicon-2",  K2,  0},
	{"8.5",        NSV,       SPACINGE, "Via1",           "P-Active",       K2,  0},
	{"8.5",        NSV,       SPACINGE, "Via1",           "N-Active",       K2,  0},

	{"9.1",  0,               MINWID,   "Metal-2",         0,               K3,  0},

	{"9.2",  DE,              SPACING,  "Metal-2",        "Metal-2",        K4,  0},
	{"9.2",  SU|SC,           SPACING,  "Metal-2",        "Metal-2",        K3,  0},

	{"9.3",  0,               VIASUR,   "Metal-2",         0,               K1, "Metal-1-Metal-2-Con"},

	{"9.4",  DE,              SPACINGW, "Metal-2",        "Metal-2",        K8,  0},
	{"9.4",  SU|SC,           SPACINGW, "Metal-2",        "Metal-2",        K6,  0},

	{"11.1", SU,              MINWID,   "Polysilicon-2",   0,               K7,  0},
	{"11.1", SC,              MINWID,   "Polysilicon-2",   0,               K3,  0},

	{"11.2", 0,               SPACING,  "Polysilicon-2",  "Polysilicon-2",  K3,  0},

	{"11.3", SU,              SURROUND, "Polysilicon-2",  "Polysilicon-1",  K5, "Metal-1-Polysilicon-1-2-Con"},
	{"11.3", SU,              NODSIZ,    0,                0,               K15,"Metal-1-Polysilicon-1-2-Con"},
	{"11.3", SU,              CUTSUR,    0,                0,               H6, "Metal-1-Polysilicon-1-2-Con"},
	{"11.3", SC,              SURROUND, "Polysilicon-2",  "Polysilicon-1",  K2, "Metal-1-Polysilicon-1-2-Con"},
	{"11.3", SC,              NODSIZ,    0,                0,               K9, "Metal-1-Polysilicon-1-2-Con"},
	{"11.3", SC,              CUTSUR,    0,                0,               H3, "Metal-1-Polysilicon-1-2-Con"},

	{"14.1", DE,              CUTSIZE,   0,                0,               K3, "Metal-2-Metal-3-Con"},
	{"14.1", DE,              MINWID,   "Via2",            0,               K3,  0},
	{"14.1", DE,              NODSIZ,    0,                0,               K5, "Metal-2-Metal-3-Con"},
	{"14.1", SU|SC,           CUTSIZE,   0,                0,               K2, "Metal-2-Metal-3-Con"},
	{"14.1", SU|SC,           MINWID,   "Via2",            0,               K2,  0},
	{"14.1", SU|SC|    M23,   NODSIZ,    0,                0,               K6, "Metal-2-Metal-3-Con"},
	{"14.1", SU|SC|    M456,  NODSIZ,    0,                0,               K4, "Metal-2-Metal-3-Con"},

	{"14.2", 0,               SPACING,  "Via2",           "Via2",           K3,  0},

	{"14.3", 0,               VIASUR,   "Metal-2",         0,               K1, "Metal-2-Metal-3-Con"},

	{"14.4", SU|SC|NSV,       SPACING,  "Via1",           "Via2",           K2,  0},

	{"15.1", SC|       M3,    MINWID,   "Metal-3",         0,               K6,  0},
	{"15.1", SU|       M3,    MINWID,   "Metal-3",         0,               K5,  0},
	{"15.1", SC|       M456,  MINWID,   "Metal-3",         0,               K3,  0},
	{"15.1", SU|       M456,  MINWID,   "Metal-3",         0,               K3,  0},
	{"15.1", DE,              MINWID,   "Metal-3",         0,               K3,  0},

	{"15.2", DE,              SPACING,  "Metal-3",        "Metal-3",        K4,  0},
	{"15.2", SU,              SPACING,  "Metal-3",        "Metal-3",        K3,  0},
	{"15.2", SC|       M3,    SPACING,  "Metal-3",        "Metal-3",        K4,  0},
	{"15.2", SC|       M456,  SPACING,  "Metal-3",        "Metal-3",        K3,  0},

	{"15.3", DE,              VIASUR,   "Metal-3",         0,               K1, "Metal-2-Metal-3-Con"},
	{"15.3", SU|SC|    M3,    VIASUR,   "Metal-3",         0,               K2, "Metal-2-Metal-3-Con"},
	{"15.3", SU|SC|    M456,  VIASUR,   "Metal-3",         0,               K1, "Metal-2-Metal-3-Con"},

	{"15.4", DE,              SPACINGW, "Metal-3",        "Metal-3",        K8,  0},
	{"15.4", SU,              SPACINGW, "Metal-3",        "Metal-3",        K6,  0},
	{"15.4", SC|       M3,    SPACINGW, "Metal-3",        "Metal-3",        K8,  0},
	{"15.4", SC|       M456,  SPACINGW, "Metal-3",        "Metal-3",        K6,  0},

	{"21.1", DE,              CUTSIZE,   0,                0,               K3, "Metal-3-Metal-4-Con"},
	{"21.1", DE,              MINWID,   "Via3",            0,               K3,  0},
	{"21.1", DE,              NODSIZ,    0,                0,               K5, "Metal-3-Metal-4-Con"},
	{"21.1", SU|SC,           CUTSIZE,   0,                0,               K2, "Metal-3-Metal-4-Con"},
	{"21.1", SU|SC,           MINWID,   "Via3",            0,               K2,  0},
	{"21.1", SU|       M4,    NODSIZ,    0,                0,               K6, "Metal-3-Metal-4-Con"},
	{"21.1", SU|       M56,   NODSIZ,    0,                0,               K4, "Metal-3-Metal-4-Con"},
	{"21.1", SC,              NODSIZ,    0,                0,               K6, "Metal-3-Metal-4-Con"},

	{"21.2", 0,               SPACING,  "Via3",           "Via3",           K3,  0},

	{"21.3", 0,               VIASUR,   "Metal-3",         0,               K1, "Metal-3-Metal-4-Con"},

	{"22.1",           M4,    MINWID,   "Metal-4",         0,               K6,  0},
	{"22.1",           M56,   MINWID,   "Metal-4",         0,               K3,  0},

	{"22.2",           M4,    SPACING,  "Metal-4",        "Metal-4",        K6,  0},
	{"22.2", DE|       M56,   SPACING,  "Metal-4",        "Metal-4",        K4,  0},
	{"22.2", SU|       M56,   SPACING,  "Metal-4",        "Metal-4",        K3,  0},

	{"22.3",           M4,    VIASUR,   "Metal-4",         0,               K2, "Metal-3-Metal-4-Con"},
//	{"22.3",           M4,    CUTSUR,   0,                 0,               K2, "Metal-3-Metal-4-Con"},
	{"22.3",           M56,   VIASUR,   "Metal-4",         0,               K1, "Metal-3-Metal-4-Con"},
//	{"22.3",           M56,   CUTSUR,   0,                 0,               K1, "Metal-3-Metal-4-Con"},

	{"22.4",           M4,    SPACINGW, "Metal-4",        "Metal-4",        K12, 0},
	{"22.4", DE|       M56,   SPACINGW, "Metal-4",        "Metal-4",        K8,  0},
	{"22.4", SU|       M56,   SPACINGW, "Metal-4",        "Metal-4",        K6,  0},

	{"25.1", DE,              CUTSIZE,   0,                0,               K3, "Metal-4-Metal-5-Con"},
	{"25.1", DE,              MINWID,   "Via4",            0,               K3,  0},
	{"25.1", SU,              CUTSIZE,   0,                0,               K2, "Metal-4-Metal-5-Con"},
	{"25.1", SU,              MINWID,   "Via4",            0,               K2,  0},
#if 0
	{"25.1", DE,              NODSIZ,    0,                0,               K7, "Metal-4-Metal-5-Con"},
	{"25.1", SU,              NODSIZ,    0,                0,               K4, "Metal-4-Metal-5-Con"},
#else
	{"25.1", SU,              NODSIZ,    0,                0,               K4, "Metal-4-Metal-5-Con"},
	{"25.1", DE|       M5,    NODSIZ,    0,                0,               K7, "Metal-4-Metal-5-Con"},
	{"25.1", DE|       M6,    NODSIZ,    0,                0,               K5, "Metal-4-Metal-5-Con"},
#endif

	{"25.2", 0,               SPACINGW, "Via4",           "Via4",           K3,  0},

	{"25.3", 0,               VIASUR,   "Metal-4",         0,               K1, "Metal-4-Metal-5-Con"},

	{"26.1",           M5,    MINWID,   "Metal-5",         0,               K4,  0},
	{"26.1",           M6,    MINWID,   "Metal-5",         0,               K3,  0},

	{"26.2",           M5,    SPACING,  "Metal-5",        "Metal-5",        K4,  0},
	{"26.2", DE|       M6,    SPACING,  "Metal-5",        "Metal-5",        K4,  0},
	{"26.2", SU|       M6,    SPACING,  "Metal-5",        "Metal-5",        K3,  0},

	{"26.3", DE|       M5,    VIASUR,   "Metal-5",         0,               K2, "Metal-4-Metal-5-Con"},
	{"26.3", SU|       M5,    VIASUR,   "Metal-5",         0,               K1, "Metal-4-Metal-5-Con"},
	{"26.3",           M6,    VIASUR,   "Metal-5",         0,               K1, "Metal-4-Metal-5-Con"},

	{"26.4",           M5,    SPACINGW, "Metal-5",        "Metal-5",        K8,  0},
	{"26.4", DE|       M6,    SPACINGW, "Metal-5",        "Metal-5",        K8,  0},
	{"26.4", SU|       M6,    SPACINGW, "Metal-5",        "Metal-5",        K6,  0},

	{"29.1", DE,              CUTSIZE,   0,                0,               K4, "Metal-5-Metal-6-Con"},
	{"29.1", DE,              MINWID,   "Via5",            0,               K4,  0},
	{"29.1", DE,              NODSIZ,    0,                0,               K8, "Metal-5-Metal-6-Con"},
	{"29.1", SU,              CUTSIZE,   0,                0,               K3, "Metal-5-Metal-6-Con"},
	{"29.1", SU,              MINWID,   "Via5",            0,               K3,  0},
	{"29.1", SU,              NODSIZ,    0,                0,               K5, "Metal-5-Metal-6-Con"},

	{"29.2", 0,               SPACING,  "Via5",           "Via5",           K4,  0},

	{"29.3", 0,               VIASUR,   "Metal-5",         0,               K1, "Metal-5-Metal-6-Con"},

	{"30.1", 0,               MINWID,   "Metal-6",         0,               K4,  0},

	{"30.2", 0,               SPACING,  "Metal-6",        "Metal-6",        K4,  0},

	{"30.3", DE,              VIASUR,   "Metal-6",         0,               K2, "Metal-5-Metal-6-Con"},
	{"30.3", SU,              VIASUR,   "Metal-6",         0,               K1, "Metal-5-Metal-6-Con"},

	{"30.4", 0,               SPACINGW, "Metal-6",        "Metal-6",        K8,  0},

	{0,      0,               0,         0,                0,               0,   0}
};

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

#define ARCPROTOCOUNT 11
#define AMETAL1        0	/* metal-1                   */
#define AMETAL2        1	/* metal-2                   */
#define AMETAL3        2	/* metal-3                   */
#define AMETAL4        3	/* metal-4                   */
#define AMETAL5        4	/* metal-5                   */
#define AMETAL6        5	/* metal-6                   */
#define APOLY1         6	/* polysilicon-1             */
#define APOLY2         7	/* polysilicon-2             */
#define APACT          8	/* P-active                  */
#define ANACT          9	/* N-active                  */
#define AACT          10	/* General active            */

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

/* metal 3 arc */
static TECH_ARCLAY mocmos_al_m3[] = {{LMETAL3,0,FILLED }};
static TECH_ARCS mocmos_a_m3 = {
	"Metal-3",K3,AMETAL3,NOARCPROTO,								/* name */
	1,mocmos_al_m3,													/* layers */
	(APMETAL3<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* metal 4 arc */
static TECH_ARCLAY mocmos_al_m4[] = {{LMETAL4,0,FILLED }};
static TECH_ARCS mocmos_a_m4 = {
	"Metal-4",K3,AMETAL4,NOARCPROTO,								/* name */
	1,mocmos_al_m4,													/* layers */
	(APMETAL4<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* metal 5 arc */
static TECH_ARCLAY mocmos_al_m5[] = {{LMETAL5,0,FILLED }};
static TECH_ARCS mocmos_a_m5 = {
	"Metal-5",K3,AMETAL5,NOARCPROTO,								/* name */
	1,mocmos_al_m5,													/* layers */
	(APMETAL5<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)|ANOTUSED};	/* userbits */

/* metal 6 arc */
static TECH_ARCLAY mocmos_al_m6[] = {{LMETAL6,0,FILLED }};
static TECH_ARCS mocmos_a_m6 = {
	"Metal-6",K4,AMETAL6,NOARCPROTO,								/* name */
	1,mocmos_al_m6,													/* layers */
	(APMETAL6<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)|ANOTUSED};	/* userbits */

/* polysilicon 1 arc */
static TECH_ARCLAY mocmos_al_p1[] = {{LPOLY1,0,FILLED }};
static TECH_ARCS mocmos_a_po1 = {
	"Polysilicon-1",K2,APOLY1,NOARCPROTO,							/* name */
	1,mocmos_al_p1,													/* layers */
	(APPOLY1<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* polysilicon 2 arc */
static TECH_ARCLAY mocmos_al_p2[] = {{LPOLY2,0,FILLED }};
static TECH_ARCS mocmos_a_po2 = {
	"Polysilicon-2",K7,APOLY2,NOARCPROTO,							/* name */
	1,mocmos_al_p2,													/* layers */
	(APPOLY2<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* P-active arc */
static TECH_ARCLAY mocmos_al_pa[] = {{LPACT,K12,FILLED}, {LWELLN,0,FILLED},
	{LSELECTP,K8,FILLED}};
static TECH_ARCS mocmos_a_pa = {
	"P-Active",K15,APACT,NOARCPROTO,								/* name */
	3,mocmos_al_pa,													/* layers */
	(APDIFFP<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

/* N-active arc */
static TECH_ARCLAY mocmos_al_na[] = {{LNACT,K12,FILLED}, {LWELLP,0,FILLED},
	{LSELECTN,K8,FILLED}};
static TECH_ARCS mocmos_a_na = {
	"N-Active",K15,ANACT,NOARCPROTO,								/* name */
	3,mocmos_al_na,													/* layers */
	(APDIFFN<<AFUNCTIONSH)|WANTFIXANG|CANWIPE|(90<<AANGLEINCSH)};	/* userbits */

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

TECH_ARCS *mocmos_arcprotos[ARCPROTOCOUNT+1] = {
	&mocmos_a_m1, &mocmos_a_m2, &mocmos_a_m3,
	&mocmos_a_m4, &mocmos_a_m5, &mocmos_a_m6,
	&mocmos_a_po1, &mocmos_a_po2,
	&mocmos_a_pa, &mocmos_a_na,
	&mocmos_a_a, ((TECH_ARCS *)-1)};

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

/******************** 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_m3[]   = {-1, AMETAL3, ALLGEN, -1};
static INTBIG mocmos_pc_m4[]   = {-1, AMETAL4, ALLGEN, -1};
static INTBIG mocmos_pc_m5[]   = {-1, AMETAL5, ALLGEN, -1};
static INTBIG mocmos_pc_m6[]   = {-1, AMETAL6, ALLGEN, -1};
static INTBIG mocmos_pc_p1[]   = {-1, APOLY1, ALLGEN, -1};
static INTBIG mocmos_pc_p2[]   = {-1, APOLY2, ALLGEN, -1};
static INTBIG mocmos_pc_pa[]   = {-1, APACT, ALLGEN, -1};
static INTBIG mocmos_pc_a[]    = {-1, AACT, APACT, ANACT, ALLGEN,-1};
static INTBIG mocmos_pc_na[]   = {-1, ANACT, ALLGEN, -1};
static INTBIG mocmos_pc_pam1[] = {-1, APACT, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_nam1[] = {-1, ANACT, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_pm1[]  = {-1, APOLY1, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_pm2[]  = {-1, APOLY2, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_pm12[] = {-1, APOLY1, APOLY2, AMETAL1, ALLGEN, -1};
static INTBIG mocmos_pc_m1m2[] = {-1, AMETAL1, AMETAL2, ALLGEN, -1};
static INTBIG mocmos_pc_m2m3[] = {-1, AMETAL2, AMETAL3, ALLGEN, -1};
static INTBIG mocmos_pc_m3m4[] = {-1, AMETAL3, AMETAL4, ALLGEN, -1};
static INTBIG mocmos_pc_m4m5[] = {-1, AMETAL4, AMETAL5, ALLGEN, -1};
static INTBIG mocmos_pc_m5m6[] = {-1, AMETAL5, AMETAL6, ALLGEN, -1};
static INTBIG mocmos_pc_null[] = {-1, ALLGEN, -1};

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

#define NODEPROTOCOUNT 51
#define NMETAL1P        1	/* metal-1 pin */
#define NMETAL2P        2	/* metal-2 pin */
#define NMETAL3P        3	/* metal-3 pin */
#define NMETAL4P        4	/* metal-4 pin */
#define NMETAL5P        5	/* metal-5 pin */
#define NMETAL6P        6	/* metal-6 pin */
#define NPOLY1P         7	/* polysilicon-1 pin */
#define NPOLY2P         8	/* polysilicon-2 pin */
#define NPACTP          9	/* P-active pin */
#define NNACTP         10	/* N-active pin */
#define NACTP          11	/* General active pin */
#define NMETPACTC      12	/* metal-1-P-active contact */
#define NMETNACTC      13	/* metal-1-N-active contact */
#define NMETPOLY1C     14	/* metal-1-polysilicon-1 contact */
#define NMETPOLY2C     15	/* metal-1-polysilicon-2 contact */
#define NMETPOLY12C    16	/* metal-1-polysilicon-1-2 capacitor/contact */
#define NTRANSP        17	/* P-transistor */
#define NTRANSN        18	/* N-transistor */
#define NVIA1          19	/* metal-1-metal-2 contact */
#define NVIA2          20	/* metal-2-metal-3 contact */
#define NVIA3          21	/* metal-3-metal-4 contact */
#define NVIA4          22	/* metal-4-metal-5 contact */
#define NVIA5          23	/* metal-5-metal-6 contact */
#define NPWBUT         24	/* metal-1-P-Well contact */
#define NNWBUT         25	/* metal-1-N-Well contact */
#define NMETAL1N       26	/* metal-1 node */
#define NMETAL2N       27	/* metal-2 node */
#define NMETAL3N       28	/* metal-3 node */
#define NMETAL4N       29	/* metal-4 node */
#define NMETAL5N       30	/* metal-5 node */
#define NMETAL6N       31	/* metal-6 node */
#define NPOLY1N        32	/* polysilicon-1 node */
#define NPOLY2N        33	/* polysilicon-2 node */
#define NPACTIVEN      34	/* P-active node */
#define NNACTIVEN      35	/* N-active node */
#define NSELECTPN      36	/* P-select node */
#define NSELECTNN      37	/* N-select node */
#define NPCUTN         38	/* poly cut node */
#define NACUTN         39	/* active cut node */
#define NVIA1N         40	/* via-1 node */
#define NVIA2N         41	/* via-2 node */
#define NVIA3N         42	/* via-3 node */
#define NVIA4N         43	/* via-4 node */
#define NVIA5N         44	/* via-5 node */
#define NWELLPN        45	/* P-well node */
#define NWELLNN        46	/* N-well node */
#define NPASSN         47	/* passivation node */
#define NPADFRN        48	/* pad frame node */
#define NPOLYCAPN      49	/* polysilicon-capacitor node */
#define NPACTWELLN     50	/* P-active-Well node */
#define NTRANSPN       51	/* transistor-poly 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_in0hbox[8] = {LEFTIN0H, BOTIN0H,  RIGHTIN0H, TOPIN0H};
static INTBIG mocmos_in1box[8]  = {LEFTIN1,  BOTIN1,   RIGHTIN1,  TOPIN1};
static INTBIG mocmos_in1hbox[8] = {LEFTIN1H, BOTIN1H,  RIGHTIN1H, TOPIN1H};
static INTBIG mocmos_in2box[8]  = {LEFTIN2,  BOTIN2,   RIGHTIN2,  TOPIN2};
static INTBIG mocmos_in2hbox[8] = {LEFTIN2H, BOTIN2H,  RIGHTIN2H, TOPIN2H};
static INTBIG mocmos_in3box[8]  = {LEFTIN3,  BOTIN3,   RIGHTIN3,  TOPIN3};
static INTBIG mocmos_in4box[8]  = {LEFTIN4,  BOTIN4,   RIGHTIN4,  TOPIN4};
static INTBIG mocmos_in4hbox[8] = {LEFTIN4H, BOTIN4H,  RIGHTIN4H, TOPIN4H};
static INTBIG mocmos_in5box[8]  = {LEFTIN5,  BOTIN5,   RIGHTIN5,  TOPIN5};
static INTBIG mocmos_in5hbox[8] = {LEFTIN5H, BOTIN5H,  RIGHTIN5H, TOPIN5H};
static INTBIG mocmos_in6box[8]  = {LEFTIN6,  BOTIN6,   RIGHTIN6,  TOPIN6};
static INTBIG mocmos_in6hbox[8] = {LEFTIN6H, BOTIN6H,  RIGHTIN6H, TOPIN6H};
static INTBIG mocmos_trabox[8]  = {LEFTIN6,  BOTIN7,   RIGHTIN6,  TOPIN7};
static INTBIG mocmos_tra1box[8] = {LEFTIN6,  CENTER,   RIGHTIN6,  TOPIN7};
static INTBIG mocmos_tra2box[8] = {LEFTIN6,  BOTIN7,   RIGHTIN6,  CENTER};
static INTBIG mocmos_trwbox[8]  = {LEFTEDGE, BOTIN1,   RIGHTEDGE, TOPIN1};
static INTBIG mocmos_trsbox[8]  = {LEFTIN4,  BOTIN5,   RIGHTIN4,  TOPIN5};
static INTBIG mocmos_trpbox[8]  = {LEFTIN4,  BOTIN10,  RIGHTIN4,  TOPIN10};
static INTBIG mocmos_trtbox[8]  = {LEFTIN6,  BOTIN10,  RIGHTIN6,  TOPIN10};

/*
 * for MULTICUT:
 *   cut size is f1 x f2
 *   cut indented f3 from highlighting
 *   cuts spaced f4 apart
 *
 * for SERPTRANS:
 *   layer count is f1
 *   active port inset f2 from end of serpentine path
 *   active port is f3 from poly edge
 *   poly width is f4
 *   poly port inset f5 from poly edge
 *   poly port is f6 from active edge
 * also for SERPTRANS, the 3 extra fields of the TECH_SERPENT are:
 *   lwidth: the extension of the polygon to the left of the centerline
 *   rwidth: the extension of the polygon to the right
 *   extend: the extension of the polygon on each end of the serpentine path.
 */
#define WC 0
/* 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 */
	K3,K3,											/* 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 */
	K3,K3,											/* 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 */

/* metal-3-pin */
static TECH_PORTS mocmos_pm3_p[] = {				/* ports */
	{mocmos_pc_m3, "metal-3", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pm3_l[] = {				/* layers */
	{LMET3P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pm3 = {
	"Metal-3-Pin",NMETAL3P,NONODEPROTO,				/* name */
	K3,K3,											/* size */
	1,mocmos_pm3_p,									/* ports */
	1,mocmos_pm3_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* metal-4-pin */
static TECH_PORTS mocmos_pm4_p[] = {				/* ports */
	{mocmos_pc_m4, "metal-4", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pm4_l[] = {				/* layers */
	{LMET4P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pm4 = {
	"Metal-4-Pin",NMETAL4P,NONODEPROTO,				/* name */
	K3,K3,											/* size */
	1,mocmos_pm4_p,									/* ports */
	1,mocmos_pm4_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* metal-5-pin */
static TECH_PORTS mocmos_pm5_p[] = {				/* ports */
	{mocmos_pc_m5, "metal-5", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pm5_l[] = {				/* layers */
	{LMET5P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pm5 = {
	"Metal-5-Pin",NMETAL5P,NONODEPROTO,				/* name */
	K3,K3,											/* size */
	1,mocmos_pm5_p,									/* ports */
	1,mocmos_pm5_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK|NNOTUSED,	/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* metal-6-pin */
static TECH_PORTS mocmos_pm6_p[] = {				/* ports */
	{mocmos_pc_m6, "metal-6", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pm6_l[] = {				/* layers */
	{LMET6P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pm6 = {
	"Metal-6-Pin",NMETAL6P,NONODEPROTO,				/* name */
	K3,K3,											/* size */
	1,mocmos_pm6_p,									/* ports */
	1,mocmos_pm6_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK|NNOTUSED,	/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

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

/* polysilicon-2-pin */
static TECH_PORTS mocmos_pp2_p[] = {				/* ports */
	{mocmos_pc_p2, "polysilicon-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_pp2_l[] = {				/* layers */
	{LPOLY2P, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pp2 = {
	"Polysilicon-2-Pin",NPOLY2P,NONODEPROTO,		/* name */
	K3,K3,											/* size */
	1,mocmos_pp2_p,									/* ports */
	1,mocmos_pp2_l,									/* layers */
	(NPPIN<<NFUNCTIONSH)|ARCSWIPE|ARCSHRINK,		/* userbits */
	0,0,0,0,0,0,0,0,0};								/* characteristics */

/* P-active-pin */
static TECH_PORTS mocmos_psa_p[] = {				/* ports */
	{mocmos_pc_pa, "p-active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN7H, BOTIN7H, RIGHTIN7H, TOPIN7H}};
static TECH_POLYGON mocmos_psa_l[] = {				/* layers */
	{LPACTP,    0, 4, CROSSED, BOX, mocmos_in6box},
	{LWELLNP,  WC, 4, CROSSED, BOX, mocmos_fullbox},
	{LSELECTPP,WC, 4, CROSSED, BOX, mocmos_in4box}};
static TECH_NODES mocmos_psa = {
	"P-Active-Pin",NPACTP,NONODEPROTO,				/* name */
	K15,K15,										/* 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 */

/* N-active-pin */
static TECH_PORTS mocmos_pda_p[] = {				/* ports */
	{mocmos_pc_na, "n-active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN7H, BOTIN7H, RIGHTIN7H, TOPIN7H}};
static TECH_POLYGON mocmos_pda_l[] = {				/* layers */
	{LNACTP,    0, 4, CROSSED, BOX, mocmos_in6box},
	{LWELLPP,  WC, 4, CROSSED, BOX, mocmos_fullbox},
	{LSELECTNP,WC, 4, CROSSED, BOX, mocmos_in4box}};
static TECH_NODES mocmos_pda = {
	"N-Active-Pin",NNACTP,NONODEPROTO,				/* name */
	K15,K15,										/* 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),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}}	;
static TECH_POLYGON mocmos_pa_l[] = {				/* layers */
	{LNACTP, 0, 4, CROSSED, BOX, mocmos_fullbox},
	{LPACTP, 0, 4, CROSSED, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pa = {
	"Active-Pin",NACTP,NONODEPROTO,					/* name */
	K3,K3,											/* 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-P-active-contact */
static TECH_PORTS mocmos_mpa_p[] = {				/* ports */
	{mocmos_pc_pam1, "metal-1-p-act", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN8, BOTIN8, RIGHTIN8, TOPIN8}};
static TECH_POLYGON mocmos_mpa_l[] = {				/* layers */
	{LMETAL1,  0, 4, FILLEDRECT, BOX, mocmos_in6hbox},
	{LPACT,    0, 4, FILLEDRECT, BOX, mocmos_in6box},
	{LWELLN,  WC, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LSELECTP,WC, 4, FILLEDRECT, BOX, mocmos_in4box},
	{LACTCUT,  0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_mpa = {
	"Metal-1-P-Active-Con",NMETPACTC,NONODEPROTO,	/* name */
	K17,K17,										/* size */
	1,mocmos_mpa_p,									/* ports */
	5,mocmos_mpa_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,H1,K3,0,0,0,0};					/* characteristics */

/* metal-1-N-active-contact */
static TECH_PORTS mocmos_mna_p[] = {				/* ports */
	{mocmos_pc_nam1, "metal-1-n-act", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN8, BOTIN8, RIGHTIN8, TOPIN8}};
static TECH_POLYGON mocmos_mna_l[] = {				/* layers */
	{LMETAL1,   0, 4, FILLEDRECT, BOX, mocmos_in6hbox},
	{LNACT,     0, 4, FILLEDRECT, BOX, mocmos_in6box},
	{LWELLP,   WC, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LSELECTN, WC, 4, FILLEDRECT, BOX, mocmos_in4box},
	{LACTCUT,   0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_mna = {
	"Metal-1-N-Active-Con",NMETNACTC,NONODEPROTO,	/* name */
	K17,K17,										/* size */
	1,mocmos_mna_p,									/* ports */
	5,mocmos_mna_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,H1,K3,0,0,0,0};					/* characteristics */

/* metal-1-polysilicon-1-contact */
static TECH_PORTS mocmos_mp1_p[] = {				/* ports */
	{mocmos_pc_pm1, "metal-1-polysilicon-1", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN2, BOTIN2, RIGHTIN2, TOPIN2}};
static TECH_POLYGON mocmos_mp1_l[] = {				/* layers */
	{LMETAL1,  0, 4, FILLEDRECT, BOX, mocmos_in0hbox},
	{LPOLY1,   0, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LPOLYCUT, 0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_mp1 = {
	"Metal-1-Polysilicon-1-Con",NMETPOLY1C,NONODEPROTO,/* name */
	K5,K5,											/* size */
	1,mocmos_mp1_p,									/* ports */
	3,mocmos_mp1_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,H1,K3,0,0,0,0};					/* characteristics */

/* metal-1-polysilicon-2-contact */
static TECH_PORTS mocmos_mp2_p[] = {				/* ports */
	{mocmos_pc_pm2, "metal-1-polysilicon-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN4H, BOTIN4H, RIGHTIN4H, TOPIN4H}};
static TECH_POLYGON mocmos_mp2_l[] = {				/* layers */
	{LMETAL1,  0, 4, FILLEDRECT, BOX, mocmos_in3box},
	{LPOLY2,   0, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LPOLYCUT, 0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_mp2 = {
	"Metal-1-Polysilicon-2-Con",NMETPOLY2C,NONODEPROTO,/* name */
	K10,K10,										/* size */
	1,mocmos_mp2_p,									/* ports */
	3,mocmos_mp2_l,									/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K4,K3,0,0,0,0};					/* characteristics */

/* metal-1-polysilicon-1-2-contact */
static TECH_PORTS mocmos_mp12_p[] = {				/* ports */
	{mocmos_pc_pm12, "metal-1-polysilicon-1-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN7, BOTIN7, RIGHTIN7, TOPIN7}};
static TECH_POLYGON mocmos_mp12_l[] = {				/* layers */
	{LMETAL1,  0, 4, FILLEDRECT, BOX, mocmos_in5hbox},
	{LPOLY1,   0, 4, FILLEDRECT, BOX, mocmos_in5box},
	{LPOLY2,   0, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LPOLYCUT, 0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_mp12 = {
	"Metal-1-Polysilicon-1-2-Con",NMETPOLY12C,NONODEPROTO,/* name */
	K15,K15,										/* size */
	1,mocmos_mp12_p,								/* ports */
	4,mocmos_mp12_l,								/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,H6,K3,0,0,0,0};					/* characteristics */

/* index numbers for the transistor layers in "mocmos_tpa_l" and "mocmos_tna_l" */
#define TRANSACTLAYER      0		/* layer for active */
#define TRANSPOLYLAYER     1		/* layer for polysilicon */
#define TRANSWELLLAYER     2		/* layer for well */
#define TRANSSELECTLAYER   3		/* layer for select */

/* index numbers for the transistor electrical layers in "mocmos_tpaE_l" and "mocmos_tnaE_l" */
#define TRANSEACT1LAYER    0		/* electrical layer for part 1 of active */
#define TRANSEACT2LAYER    1		/* electrical layer for part 2 of active */
#define TRANSEPOLYLAYER    2		/* electrical layer for polysilicon */
#define TRANSEWELLLAYER    3		/* electrical layer for well */
#define TRANSESELECTLAYER  4		/* electrical layer for select */

/* P-transistor */
static TECH_PORTS mocmos_tpa_p[] = {				/* ports */
	{mocmos_pc_p1, "p-trans-poly-left",  NOPORTPROTO, (180<<PORTANGLESH)|
		(90<<PORTARANGESH),                LEFTIN4,  BOTIN11, LEFTIN4,   TOPIN11},
	{mocmos_pc_pa, "p-trans-diff-top",   NOPORTPROTO, (90<<PORTANGLESH)|
		(90<<PORTARANGESH)|(1<<PORTNETSH), LEFTIN7H,  TOPIN7H, RIGHTIN7H,  TOPIN7},
	{mocmos_pc_p1, "p-trans-poly-right", NOPORTPROTO, (0<<PORTANGLESH)|
		(90<<PORTARANGESH),                RIGHTIN4, BOTIN11, RIGHTIN4,  TOPIN11},
	{mocmos_pc_pa, "p-trans-diff-bottom",NOPORTPROTO, (270<<PORTANGLESH)|
		(90<<PORTARANGESH)|(2<<PORTNETSH), LEFTIN7H,  BOTIN7, RIGHTIN7H,  BOTIN7H}};
static TECH_SERPENT mocmos_tpa_l[] = {				/* graphical layers */
	{{LPACT,     1, 4, FILLEDRECT, BOX,    mocmos_trabox},  K4, K4,  0},
	{{LTRANS,    0, 4, FILLEDRECT, BOX,    mocmos_trpbox},  K1, K1, K2},
	{{LWELLN,   -1, 4, FILLEDRECT, BOX,    mocmos_trwbox}, K10,K10, K6},
	{{LSELECTP, -1, 4, FILLEDRECT, BOX,    mocmos_trsbox},  K6, K6, K2}};
static TECH_SERPENT mocmos_tpaE_l[] = {				/* electric layers */
	{{LPACT,     1, 4, FILLEDRECT, BOX,    mocmos_tra1box}, K4,  0,  0},
	{{LPACT,     3, 4, FILLEDRECT, BOX,    mocmos_tra2box},  0, K4,  0},
	{{LTRANS,    0, 4, FILLEDRECT, BOX,    mocmos_trpbox},  K1, K1, K2},
	{{LWELLN,   -1, 4, FILLEDRECT, BOX,    mocmos_trwbox}, K10,K10, K6},
	{{LSELECTP, -1, 4, FILLEDRECT, BOX,    mocmos_trsbox},  K6, K6, K2}};
static TECH_NODES mocmos_tpa = {
	"P-Transistor",NTRANSP,NONODEPROTO,				/* name */
	K15,K22,										/* size */
	4,mocmos_tpa_p,									/* ports */
	4,(TECH_POLYGON *)0,							/* layers */
	NODESHRINK|(NPTRAPMOS<<NFUNCTIONSH)|HOLDSTRACE,	/* userbits */
	SERPTRANS,5,H1,H2,K2,K1,K2,mocmos_tpa_l,mocmos_tpaE_l};/* characteristics */

/* N-transistor */
static TECH_PORTS mocmos_tna_p[] = {				/* ports */
	{mocmos_pc_p1, "n-trans-poly-left", NOPORTPROTO, (180<<PORTANGLESH)|
		(90<<PORTARANGESH),                LEFTIN4,  BOTIN11, LEFTIN4,   TOPIN11},
	{mocmos_pc_na, "n-trans-diff-top",  NOPORTPROTO, (90<<PORTANGLESH)|
		(90<<PORTARANGESH)|(1<<PORTNETSH), LEFTIN7H,  TOPIN7H, RIGHTIN7H,  TOPIN7},
	{mocmos_pc_p1, "n-trans-poly-right",NOPORTPROTO, (0<<PORTANGLESH)|
		(90<<PORTARANGESH),                RIGHTIN4, BOTIN11, RIGHTIN4,  TOPIN11},
	{mocmos_pc_na, "n-trans-diff-bot",  NOPORTPROTO, (270<<PORTANGLESH)|
		(90<<PORTARANGESH)|(2<<PORTNETSH), LEFTIN7H,  BOTIN7, RIGHTIN7H,  BOTIN7H}};
static TECH_SERPENT mocmos_tna_l[] = {				/* graphical layers */
	{{LNACT,     1, 4, FILLEDRECT, BOX,    mocmos_trabox},  K4, K4,  0},
	{{LTRANS,    0, 4, FILLEDRECT, BOX,    mocmos_trpbox},  K1, K1, K2},
	{{LWELLP,   -1, 4, FILLEDRECT, BOX,    mocmos_trwbox}, K10,K10, K6},
	{{LSELECTN, -1, 4, FILLEDRECT, BOX,    mocmos_trsbox},  K6, K6, K2}};
static TECH_SERPENT mocmos_tnaE_l[] = {				/* electric layers */
	{{LNACT,     1, 4, FILLEDRECT, BOX,    mocmos_tra1box}, K4,  0,  0},
	{{LNACT,     3, 4, FILLEDRECT, BOX,    mocmos_tra2box},  0, K4,  0},
	{{LTRANS,    0, 4, FILLEDRECT, BOX,    mocmos_trpbox},  K1, K1, K2},
	{{LWELLP,   -1, 4, FILLEDRECT, BOX,    mocmos_trwbox}, K10,K10, K6},
	{{LSELECTN, -1, 4, FILLEDRECT, BOX,    mocmos_trsbox},  K6, K6, K2}};
static TECH_NODES mocmos_tna = {
	"N-Transistor",NTRANSN,NONODEPROTO,				/* name */
	K15,K22,										/* size */
	4,mocmos_tna_p,									/* ports */
	4,(TECH_POLYGON *)0,							/* layers */
	NODESHRINK|(NPTRANMOS<<NFUNCTIONSH)|HOLDSTRACE,	/* userbits */
	SERPTRANS,5,H1,H2,K2,K1,K2,mocmos_tna_l,mocmos_tnaE_l};/* characteristics */

/* metal-1-metal-2-contact */
static TECH_PORTS mocmos_m1m2_p[] = {				/* ports */
	{mocmos_pc_m1m2, "metal-1-metal-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m1m2_l[] = {				/* layers */
	{LMETAL1, 0, 4, FILLEDRECT, BOX, mocmos_in0hbox},
	{LMETAL2, 0, 4, FILLEDRECT, BOX, mocmos_in0hbox},
	{LVIA1,   0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_m1m2 = {
	"Metal-1-Metal-2-Con",NVIA1,NONODEPROTO,		/* name */
	K5,K5,											/* size */
	1,mocmos_m1m2_p,								/* ports */
	3,mocmos_m1m2_l,								/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K1,K3,0,0,0,0};					/* characteristics */

/* metal-2-metal-3-contact */
static TECH_PORTS mocmos_m2m3_p[] = {				/* ports */
	{mocmos_pc_m2m3, "metal-2-metal-3", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN2H, BOTIN2H, RIGHTIN2H, TOPIN2H}};
static TECH_POLYGON mocmos_m2m3_l[] = {				/* layers */
	{LMETAL2, 0, 4, FILLEDRECT, BOX, mocmos_in1box},
	{LMETAL3, 0, 4, FILLEDRECT, BOX, mocmos_in1box},
	{LVIA2,   0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_m2m3 = {
	"Metal-2-Metal-3-Con",NVIA2,NONODEPROTO,		/* name */
	K6,K6,											/* size */
	1,mocmos_m2m3_p,								/* ports */
	3,mocmos_m2m3_l,								/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K1,K3,0,0,0,0};					/* characteristics */

/* metal-3-metal-4-contact */
static TECH_PORTS mocmos_m3m4_p[] = {				/* ports */
	{mocmos_pc_m3m4, "metal-3-metal-4", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN2H, BOTIN2H, RIGHTIN2H, TOPIN2H}};
static TECH_POLYGON mocmos_m3m4_l[] = {				/* layers */
	{LMETAL3, 0, 4, FILLEDRECT, BOX, mocmos_in1box},
	{LMETAL4, 0, 4, FILLEDRECT, BOX, mocmos_fullbox},
	{LVIA3,   0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_m3m4 = {
	"Metal-3-Metal-4-Con",NVIA3,NONODEPROTO,		/* name */
	K6,K6,											/* size */
	1,mocmos_m3m4_p,								/* ports */
	3,mocmos_m3m4_l,								/* layers */
	(NPCONTACT<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,K2,K3,0,0,0,0};					/* characteristics */

/* metal-4-metal-5-contact */
static TECH_PORTS mocmos_m4m5_p[] = {				/* ports */
	{mocmos_pc_m4m5, "metal-4-metal-5", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN2H, BOTIN2H, RIGHTIN2H, TOPIN2H}};
static TECH_POLYGON mocmos_m4m5_l[] = {				/* layers */
	{LMETAL4, 0, 4, FILLEDRECT, BOX, mocmos_in1hbox},
	{LMETAL5, 0, 4, FILLEDRECT, BOX, mocmos_in1hbox},
	{LVIA4,   0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_m4m5 = {
	"Metal-4-Metal-5-Con",NVIA4,NONODEPROTO,		/* name */
	K7,K7,											/* size */
	1,mocmos_m4m5_p,								/* ports */
	3,mocmos_m4m5_l,								/* layers */
	(NPCONTACT<<NFUNCTIONSH)|NNOTUSED,				/* userbits */
	MULTICUT,K2,K2,K1,K3,0,0,0,0};					/* characteristics */

/* metal-5-metal-6-contact */
static TECH_PORTS mocmos_m5m6_p[] = {				/* ports */
	{mocmos_pc_m5m6, "metal-5-metal-6", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN2H, BOTIN2H, RIGHTIN2H, TOPIN2H}};
static TECH_POLYGON mocmos_m5m6_l[] = {				/* layers */
	{LMETAL5, 0, 4, FILLEDRECT, BOX, mocmos_in1box},
	{LMETAL6, 0, 4, FILLEDRECT, BOX, mocmos_in1box},
	{LVIA5,   0, 4, FILLEDRECT, BOX, mocmos_cutbox}};
static TECH_NODES mocmos_m5m6 = {
	"Metal-5-Metal-6-Con",NVIA5,NONODEPROTO,		/* name */
	K8,K8,											/* size */
	1,mocmos_m5m6_p,								/* ports */
	3,mocmos_m5m6_l,								/* layers */
	(NPCONTACT<<NFUNCTIONSH)|NNOTUSED,				/* userbits */
	MULTICUT,K3,K3,K2,K4,0,0,0,0};					/* characteristics */

/* Metal-1-P-Well Contact */
static TECH_PORTS mocmos_psub_p[] = {				/* ports */
	{mocmos_pc_m1a, "metal-1-well", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN8, BOTIN8, RIGHTIN8, TOPIN8}};
static TECH_POLYGON mocmos_psub_l[] = {				/* layers */
	{LMETAL1,   0, 4, FILLEDRECT, BOX,    mocmos_in6hbox},
	{LPACTWELL, 0, 4, FILLEDRECT, BOX,    mocmos_in6box},
	{LWELLP,   WC, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LSELECTP, WC, 4, FILLEDRECT, BOX,    mocmos_in4box},
	{LACTCUT,   0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_psub = {
	"Metal-1-P-Well-Con",NPWBUT,NONODEPROTO,		/* name */
	K17,K17,										/* size */
	1,mocmos_psub_p,								/* ports */
	5,mocmos_psub_l,								/* layers */
	(NPWELL<<NFUNCTIONSH),							/* userbits */
	MULTICUT,K2,K2,H1,K3,0,0,0,0};					/* characteristics */

/* Metal-1-N-Well Contact */
static TECH_PORTS mocmos_nsub_p[] = {				/* ports */
	{mocmos_pc_m1a, "metal-1-substrate", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN8, BOTIN8, RIGHTIN8, TOPIN8}};
static TECH_POLYGON mocmos_nsub_l[] = {				/* layers */
	{LMETAL1,   0, 4, FILLEDRECT, BOX,    mocmos_in6hbox},
	{LNACT,     0, 4, FILLEDRECT, BOX,    mocmos_in6box},
	{LWELLN,   WC, 4, FILLEDRECT, BOX,    mocmos_fullbox},
	{LSELECTN, WC, 4, FILLEDRECT, BOX,    mocmos_in4box},
	{LACTCUT,   0, 4, FILLEDRECT, BOX,    mocmos_cutbox}};
static TECH_NODES mocmos_nsub = {
	"Metal-1-N-Well-Con",NNWBUT,NONODEPROTO,		/* name */
	K17,K17,										/* size */
	1,mocmos_nsub_p,								/* ports */
	5,mocmos_nsub_l,								/* layers */
	(NPSUBSTRATE<<NFUNCTIONSH),						/* userbits */
	MULTICUT,K2,K2,H1,K3,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 */
	K3,K3,											/* 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 */
	K3,K3,											/* 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 */

/* Metal-3-Node */
static TECH_PORTS mocmos_m3_p[] = {					/* ports */
	{mocmos_pc_m3, "metal-3", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m3_l[] = {				/* layers */
	{LMETAL3, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_m3 = {
	"Metal-3-Node",NMETAL3N,NONODEPROTO,			/* name */
	K3,K3,											/* size */
	1,mocmos_m3_p,									/* ports */
	1,mocmos_m3_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Metal-4-Node */
static TECH_PORTS mocmos_m4_p[] = {					/* ports */
	{mocmos_pc_m4, "metal-4", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m4_l[] = {				/* layers */
	{LMETAL4, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_m4 = {
	"Metal-4-Node",NMETAL4N,NONODEPROTO,			/* name */
	K3,K3,											/* size */
	1,mocmos_m4_p,									/* ports */
	1,mocmos_m4_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Metal-5-Node */
static TECH_PORTS mocmos_m5_p[] = {					/* ports */
	{mocmos_pc_m5, "metal-5", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m5_l[] = {				/* layers */
	{LMETAL5, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_m5 = {
	"Metal-5-Node",NMETAL5N,NONODEPROTO,			/* name */
	K3,K3,											/* size */
	1,mocmos_m5_p,									/* ports */
	1,mocmos_m5_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE|NNOTUSED,		/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Metal-6-Node */
static TECH_PORTS mocmos_m6_p[] = {					/* ports */
	{mocmos_pc_m6, "metal-6", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_m6_l[] = {				/* layers */
	{LMETAL6, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_m6 = {
	"Metal-6-Node",NMETAL6N,NONODEPROTO,			/* name */
	K3,K3,											/* size */
	1,mocmos_m6_p,									/* ports */
	1,mocmos_m6_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE|NNOTUSED,		/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Polysilicon-1-Node */
static TECH_PORTS mocmos_p1_p[] = {					/* ports */
	{mocmos_pc_p1, "polysilicon-1", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_p1_l[] = {				/* layers */
	{LPOLY1, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_p1 = {
	"Polysilicon-1-Node",NPOLY1N,NONODEPROTO,		/* name */
	K2,K2,											/* size */
	1,mocmos_p1_p,									/* ports */
	1,mocmos_p1_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Polysilicon-2-Node */
static TECH_PORTS mocmos_p2_p[] = {					/* ports */
	{mocmos_pc_p2, "polysilicon-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_p2_l[] = {				/* layers */
	{LPOLY2, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_p2 = {
	"Polysilicon-2-Node",NPOLY2N,NONODEPROTO,		/* name */
	K3,K3,											/* size */
	1,mocmos_p2_p,									/* ports */
	1,mocmos_p2_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* P-Active-Node */
static TECH_PORTS mocmos_a_p[] = {					/* ports */
	{mocmos_pc_a, "active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_a_l[] = {				/* layers */
	{LPACT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_a = {
	"P-Active-Node",NPACTIVEN,NONODEPROTO,			/* name */
	K3,K3,											/* 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 */

/* N-Active-Node */
static TECH_PORTS mocmos_da_p[] = {					/* ports */
	{mocmos_pc_a, "active", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1H, BOTIN1H, RIGHTIN1H, TOPIN1H}};
static TECH_POLYGON mocmos_da_l[] = {				/* layers */
	{LNACT, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_da = {
	"N-Active-Node",NNACTIVEN,NONODEPROTO,			/* name */
	K3,K3,											/* 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, -1, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_sp = {
	"P-Select-Node",NSELECTPN,NONODEPROTO,			/* name */
	K4,K4,											/* 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 */
	{LSELECTN,  -1, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_sn = {
	"N-Select-Node",NSELECTNN,NONODEPROTO,			/* name */
	K4,K4,											/* 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 */

/* 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-1-Node */
static TECH_PORTS mocmos_v1_p[] = {					/* ports */
	{mocmos_pc_null, "via-1", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_v1_l[] = {				/* layers */
	{LVIA1, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_v1 = {
	"Via-1-Node",NVIA1N,NONODEPROTO,				/* name */
	K2,K2,											/* size */
	1,mocmos_v1_p,									/* ports */
	1,mocmos_v1_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Via-2-Node */
static TECH_PORTS mocmos_v2_p[] = {					/* ports */
	{mocmos_pc_null, "via-2", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_v2_l[] = {				/* layers */
	{LVIA2, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_v2 = {
	"Via-2-Node",NVIA2N,NONODEPROTO,				/* name */
	K2,K2,											/* size */
	1,mocmos_v2_p,									/* ports */
	1,mocmos_v2_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Via-3-Node */
static TECH_PORTS mocmos_v3_p[] = {					/* ports */
	{mocmos_pc_null, "via-3", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_v3_l[] = {				/* layers */
	{LVIA3, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_v3 = {
	"Via-3-Node",NVIA3N,NONODEPROTO,				/* name */
	K2,K2,											/* size */
	1,mocmos_v3_p,									/* ports */
	1,mocmos_v3_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Via-4-Node */
static TECH_PORTS mocmos_v4_p[] = {					/* ports */
	{mocmos_pc_null, "via-4", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_v4_l[] = {				/* layers */
	{LVIA4, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_v4 = {
	"Via-4-Node",NVIA4N,NONODEPROTO,				/* name */
	K2,K2,											/* size */
	1,mocmos_v4_p,									/* ports */
	1,mocmos_v4_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE|NNOTUSED,		/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Via-5-Node */
static TECH_PORTS mocmos_v5_p[] = {					/* ports */
	{mocmos_pc_null, "via-5", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_v5_l[] = {				/* layers */
	{LVIA5, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_v5 = {
	"Via-5-Node",NVIA5N,NONODEPROTO,				/* name */
	K2,K2,											/* size */
	1,mocmos_v5_p,									/* ports */
	1,mocmos_v5_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE|NNOTUSED,		/* 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, -1, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_wp = {
	"P-Well-Node",NWELLPN,NONODEPROTO,				/* name */
	K12,K12,										/* 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 */
	{LWELLN,  -1, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_wn = {
	"N-Well-Node",NWELLNN,NONODEPROTO,				/* name */
	K12,K12,										/* 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 */

/* Polysilicon-Capacitor-node */
static TECH_PORTS mocmos_pc_p[] = {					/* ports */
	{mocmos_pc_null, "poly-cap", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_pc_l[] = {				/* layers */
	{LPOLYCAP, 0, 4, CLOSEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_pc = {
	"Poly-Cap-Node",NPOLYCAPN,NONODEPROTO,			/* name */
	K8,K8,											/* size */
	1,mocmos_pc_p,									/* ports */
	1,mocmos_pc_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* P-Active-Well-node */
static TECH_PORTS mocmos_paw_p[] = {				/* ports */
	{mocmos_pc_null, "p-active-well", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE}};
static TECH_POLYGON mocmos_paw_l[] = {				/* layers */
	{LPACTWELL, 0, 4, CLOSEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_paw = {
	"P-Active-Well-Node",NPACTWELLN,NONODEPROTO,	/* name */
	K8,K8,											/* size */
	1,mocmos_paw_p,									/* ports */
	1,mocmos_paw_l,									/* layers */
	(NPNODE<<NFUNCTIONSH)|HOLDSTRACE,				/* userbits */
	POLYGONAL,0,0,0,0,0,0,0,0};						/* characteristics */

/* Polysilicon-1-Transistor-Node */
static TECH_PORTS mocmos_tp1_p[] = {					/* ports */
	{mocmos_pc_p1, "trans-poly-1", NOPORTPROTO, (180<<PORTARANGESH),
		LEFTIN1, BOTIN1, RIGHTIN1, TOPIN1}};
static TECH_POLYGON mocmos_tp1_l[] = {				/* layers */
	{LTRANS, 0, 4, FILLEDRECT, BOX, mocmos_fullbox}};
static TECH_NODES mocmos_tp1 = {
	"Transistor-Poly-Node",NTRANSPN,NONODEPROTO,	/* name */
	K2,K2,											/* size */
	1,mocmos_tp1_p,									/* ports */
	1,mocmos_tp1_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_pm3,		/* metal 1/2/3 pin */
	&mocmos_pm4, &mocmos_pm5, &mocmos_pm6,		/* metal 4/5/6 pin */
	&mocmos_pp1, &mocmos_pp2,					/* polysilicon 1/2 pin */
	&mocmos_psa, &mocmos_pda,					/* P/N active pin */
	&mocmos_pa,									/* active pin */
	&mocmos_mpa, &mocmos_mna,					/* metal 1 to P/N active contact */
	&mocmos_mp1, &mocmos_mp2,					/* metal 1 to polysilicon 1/2 contact */
	&mocmos_mp12,								/* poly capacitor */
	&mocmos_tpa, &mocmos_tna,					/* P/N transistor */
	&mocmos_m1m2, &mocmos_m2m3, &mocmos_m3m4,	/* via 1/2/3 */
	&mocmos_m4m5, &mocmos_m5m6,					/* via 4/5 */
	&mocmos_psub, &mocmos_nsub,					/* p-well / n-well contact */
	&mocmos_m1, &mocmos_m2, &mocmos_m3,			/* metal 1/2/3 node */
	&mocmos_m4, &mocmos_m5, &mocmos_m6,			/* metal 4/5/6 node */
	&mocmos_p1, &mocmos_p2,						/* polysilicon 1/2 node */
	&mocmos_a, &mocmos_da,						/* active N-Active node */
	&mocmos_sp, &mocmos_sn,						/* P/N select node */
	&mocmos_gc, &mocmos_ac,						/* poly cut / active cut */
	&mocmos_v1, &mocmos_v2, &mocmos_v3,			/* via 1/2/3 node */
	&mocmos_v4, &mocmos_v5,						/* via 4/5 node */
	&mocmos_wp, &mocmos_wn,						/* P/N well node */
	&mocmos_o,									/* overglass node */
	&mocmos_pf,									/* pad frame node */
	&mocmos_pc,									/* poly-cap node */
	&mocmos_paw,								/* p-active-well node */
	&mocmos_tp1, ((TECH_NODES *)-1)};			/* transistor poly node */

/* this tables must correspond with the above table (mocmos_nodeprotos) */
static INTBIG mocmos_node_widoff[NODEPROTOCOUNT*4] = {
	0,0,0,0, 0,0,0,0, 0,0,0,0,						/* metal 1/2/3 pin */
	0,0,0,0, 0,0,0,0, 0,0,0,0,						/* metal 4/5/6 pin */
	0,0,0,0, 0,0,0,0,								/* polysilicon 1/2 pin */
	K6,K6,K6,K6, K6,K6,K6,K6,						/* P/N active pin */
	0,0,0,0,										/* active pin */
	K6,K6,K6,K6, K6,K6,K6,K6,						/* metal 1 to P/N active contact */
	0,0,0,0, 0,0,0,0,								/* metal 1 to polysilicon 1/2 contact */
	0,0,0,0,										/* poly capacitor */
	K6,K6,K10,K10, K6,K6,K10,K10,					/* P/N transistor */
	H0,H0,H0,H0, K1,K1,K1,K1, 0,0,0,0,				/* via 1/2/3 */
	H1,H1,H1,H1, K1,K1,K1,K1,						/* via 4/5 */
	K6,K6,K6,K6, K6,K6,K6,K6,						/* p-well / n-well contact */
	0,0,0,0, 0,0,0,0, 0,0,0,0,						/* metal 1/2/3 node */
	0,0,0,0, 0,0,0,0, 0,0,0,0,						/* metal 4/5/6 node */
	0,0,0,0, 0,0,0,0,								/* polysilicon 1/2 node */
	0,0,0,0, 0,0,0,0,								/* active N-Active node */
	0,0,0,0, 0,0,0,0,								/* P/N select node */
	0,0,0,0, 0,0,0,0,								/* poly cut / active cut */
	0,0,0,0, 0,0,0,0, 0,0,0,0,						/* via 1/2/3 node */
	0,0,0,0, 0,0,0,0,								/* via 4/5 node */
	0,0,0,0, 0,0,0,0,								/* P/N well node */
	0,0,0,0,										/* overglass node */
	0,0,0,0,										/* pad frame node */
	0,0,0,0,										/* poly-cap node */
	0,0,0,0,										/* p-active-well node */
	0,0,0,0};										/* transistor poly node */

/* this tables must correspond with the above table (mocmos_nodeprotos) */
static INTBIG mocmos_node_minsize[NODEPROTOCOUNT*2] = {
	XX,XX, XX,XX, XX,XX,							/* metal 1/2/3 pin */
	XX,XX, XX,XX, XX,XX,							/* metal 4/5/6 pin */
	XX,XX, XX,XX,									/* polysilicon 1/2 pin */
	XX,XX, XX,XX,									/* P/N active pin */
	XX,XX,											/* active pin */
	K17,K17, K17,K17,								/* metal 1 to P/N active contact */
	K5,K5, K10,K10,									/* metal 1 to polysilicon 1/2 contact */
	K15,K15,										/* poly capacitor */
	K15,K22, K15,K22,								/* P/N transistor */
	K5,K5, K6,K6, K6,K6,							/* via 1/2/3 */
	K7,K7, K8,K8,									/* via 4/5 */
	K17,K17, K17,K17,								/* p-well / n-well contact */
	XX,XX, XX,XX, XX,XX,							/* metal 1/2/3 node */
	XX,XX, XX,XX, XX,XX,							/* metal 4/5/6 node */
	XX,XX, XX,XX,									/* polysilicon 1/2 node */
	XX,XX, XX,XX,									/* active N-Active node */
	XX,XX, XX,XX,									/* P/N select node */
	XX,XX, XX,XX,									/* poly cut / active cut */
	XX,XX, XX,XX, XX,XX,							/* via 1/2/3 node */
	XX,XX, XX,XX,									/* via 4/5 node */
	XX,XX, XX,XX,									/* P/N well node */
	XX,XX,											/* overglass node */
	XX,XX,											/* pad frame node */
	XX,XX,											/* poly-cap node */
	XX,XX,											/* p-active-well node */
	XX,XX};											/* transistor poly node */

/* this tables must correspond with the above table (mocmos_nodeprotos) */
static char *mocmos_node_minsize_rule[NODEPROTOCOUNT] = {
	"", "", "",										/* metal 1/2/3 pin */
	"", "", "",										/* metal 4/5/6 pin */
	"", "",											/* polysilicon 1/2 pin */
	"", "",											/* P/N active pin */
	"",												/* active pin */
	"6.2, 7.3", "6.2, 7.3",							/* metal 1 to P/N active contact */
	"5.2, 7.3", "???",								/* metal 1 to polysilicon 1/2 contact */
	"???",											/* poly capacitor */
	"2.1, 3.1", "2.1, 3.1",							/* P/N transistor */
	"8.3, 9.3", "14.3, 15.3", "21.3, 22.3",			/* via 1/2/3 */
	"25.3, 26.3", "29.3, 30.3",						/* via 4/5 */
	"4.2, 6.2, 7.3", "4.2, 6.2, 7.3",				/* p-well / n-well contact */
	"", "", "",										/* metal 1/2/3 node */
	"", "", "",										/* metal 4/5/6 node */
	"", "",											/* polysilicon 1/2 node */
	"", "",											/* active N-Active node */
	"", "",											/* P/N select node */
	"", "",											/* poly cut / active cut */
	"", "", "",										/* via 1/2/3 node */
	"", "",											/* via 4/5 node */
	"", "",											/* P/N well node */
	"",												/* overglass node */
	"",												/* pad frame node */
	"",												/* poly-cap node */
	"",												/* p-active-well node */
	""};											/* transistor poly node */

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

/* for SPICE simulation */
#define mocmos_MIN_RESIST	50.0f	/* minimum resistance consider */
#define mocmos_MIN_CAPAC	     0.04f	/* minimum capacitance consider */
static float mocmos_sim_spice_resistance[MAXLAYERS] = {  /* per square micron */
	0.06f, 0.06f, 0.06f,				/* metal 1/2/3 */
	0.03f, 0.03f, 0.03f,				/* metal 4/5/6 */
	2.5f, 50.0f,						/* poly 1/2 */
	2.5f, 3.0f,							/* P/N active */
	0.0, 0.0,							/* P/N select */
	0.0, 0.0,							/* P/N well */
	2.2f, 2.5f,							/* poly/act cut */
	1.0f, 0.9f, 0.8f, 0.8f, 0.8f,		/* via 1/2/3/4/5 */
	0.0,								/* overglass */
	2.5f,								/* transistor poly */
	0.0,								/* poly cap */
	0.0,								/* P active well */
	0.0, 0.0, 0.0, 0.0, 0.0, 0.0,		/* pseudo metal 1/2/3/4/5/6 */
	0.0, 0.0,							/* pseudo poly 1/2 */
	0.0, 0.0,							/* pseudo P/N active */
	0.0, 0.0,							/* pseudo P/N select */
	0.0, 0.0,							/* pseudo P/N well */
	0.0};								/* pad frame */
static float mocmos_sim_spice_capacitance[MAXLAYERS] = { /* per square micron */
	0.07f, 0.04f, 0.04f,				/* metal 1/2/3 */
	0.04f, 0.04f, 0.04f,				/* metal 4/5/6 */
	0.09f, 1.0f,						/* poly 1/2 */
	0.9f, 0.9f,							/* P/N active */
	0.0, 0.0,							/* P/N select */
	0.0, 0.0,							/* P/N well */
	0.0, 0.0,							/* poly/act cut */
	0.0, 0.0, 0.0, 0.0, 0.0,			/* via 1/2/3/4/5 */
	0.0,								/* overglass */
	0.09f,								/* transistor poly */
	0.0,								/* poly cap */
	0.0,								/* P active well */
	0.0, 0.0, 0.0, 0.0, 0.0, 0.0,		/* pseudo metal 1/2/3/4/5/6 */
	0.0, 0.0,							/* pseudo poly 1/2 */
	0.0, 0.0,							/* pseudo P/N active */
	0.0, 0.0,							/* pseudo P/N select */
	0.0, 0.0,							/* pseudo P/N well */
	0.0};								/* pad frame */
static char *mocmos_sim_spice_header_level1[] = {
	"*CMOS/BULK-NWELL (PRELIMINARY PARAMETERS)",
	".OPTIONS NOMOD DEFL=3UM DEFW=3UM DEFAD=70P DEFAS=70P LIMPTS=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};
static char *mocmos_sim_spice_header_level2[] = {
	"* MOSIS 3u CMOS PARAMS",
	".OPTIONS NOMOD DEFL=2UM DEFW=6UM DEFAD=100P DEFAS=100P",
	"+LIMPTS=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};


/******************** 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)},
	{"TECH_layer_3dthickness", (char *)mocmos_3dthick_layers, 0.0,
		VINTEGER|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
	{"TECH_layer_3dheight", (char *)mocmos_3dheight_layers, 0.0,
		VINTEGER|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},

	/* set information for the USER tool */
	{"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 DRC tool */
	{"DRC_min_node_size", (char *)mocmos_node_minsize, 0.0,
		VFRACT|VDONTSAVE|VISARRAY|((NODEPROTOCOUNT*2)<<VLENGTHSH)},
	{"DRC_min_node_size_rule", (char *)mocmos_node_minsize_rule, 0.0,
		VSTRING|VDONTSAVE|VISARRAY|(NODEPROTOCOUNT<<VLENGTHSH)},

	/* set information for the I/O tool */
	{"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)},
	{"IO_skill_layer_names", (char *)mocmos_skill_layers, 0.0,
		VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},

	/* set information for the SIM tool (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}
};

/******************** TECHNOLOGY INTERFACE ROUTINES ********************/

BOOLEAN mocmos_initprocess(TECHNOLOGY *tech, INTBIG pass)
{
	/* initialize the technology variable */
	switch (pass)
	{
		case 0:
			mocmos_tech = tech;
			break;
		case 1:
			mocmos_metal1poly2prim = getnodeproto("mocmos:Metal-1-Polysilicon-2-Con");
			mocmos_metal1poly12prim = getnodeproto("mocmos:Metal-1-Polysilicon-1-2-Con");
			mocmos_metal1metal2prim = getnodeproto("mocmos:Metal-1-Metal-2-Con");
			mocmos_metal4metal5prim = getnodeproto("mocmos:Metal-4-Metal-5-Con");
			mocmos_metal5metal6prim = getnodeproto("mocmos:Metal-5-Metal-6-Con");
			mocmos_ptransistorprim = getnodeproto("mocmos:P-Transistor");
			mocmos_ntransistorprim = getnodeproto("mocmos:N-Transistor");
			mocmos_metal1pwellprim = getnodeproto("mocmos:Metal-1-P-Well-Con");
			mocmos_metal1nwellprim = getnodeproto("mocmos:Metal-1-N-Well-Con");
			break;
		case 2:
			/* load these DRC tables */
			nextchangequiet();
			if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_wide_limitkey,
				WIDELIMIT, VFRACT|VDONTSAVE) == NOVARIABLE) return(TRUE);
			mocmos_state = 0;
			mocmos_setstate(MOCMOSSUBMRULES|MOCMOS4METAL);
			nextchangequiet();
			setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, el_techstate_key, mocmos_state,
				VINTEGER|VDONTSAVE);
			break;
	}
	return(FALSE);
}

INTBIG mocmos_request(char *command, va_list ap)
{
	REGISTER INTBIG realstate;
	static INTBIG equivtable[3] = {LPOLY1,LTRANS, -1};

	if (namesame(command, "has-state") == 0) return(1);
	if (namesame(command, "get-state") == 0)
	{
		return(mocmos_state);
	}
	if (namesame(command, "get-layer-equivalences") == 0)
	{
		return((INTBIG)equivtable);
	}
	if (namesame(command, "set-state") == 0)
	{
		mocmos_setstate(va_arg(ap, INTBIG));
		return(0);
	}
	if (namesame(command, "describe-state") == 0)
	{
		return((INTBIG)mocmos_describestate(va_arg(ap, INTBIG)));
	}
	if (namesame(command, "switch-n-and-p") == 0)
	{
		mocmos_switchnp();
		return(0);
	}
	if (namesame(command, "factory-reset") == 0)
	{
		realstate = mocmos_state;
		mocmos_state++;
		mocmos_setstate(realstate);
		return(0);
	}
	return(0);
}

void mocmos_setmode(INTBIG count, char *par[])
{
	REGISTER INTBIG l;
	REGISTER char *pp;

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

	if (namesamen(pp, "full-graphics", l) == 0)
	{
		mocmos_setstate(mocmos_state & ~MOCMOSSTICKFIGURE);
		ttyputverbose(M_("MOSIS CMOS technology displays full graphics"));
		return;
	}
	if (namesamen(pp, "stick-display", l) == 0 && l >= 3)
	{
		mocmos_setstate(mocmos_state | MOCMOSSTICKFIGURE);
		ttyputverbose(M_("MOSIS CMOS technology displays stick figures"));
		return;
	}

	if (namesamen(pp, "alternate-active-poly", l) == 0 && l >= 3)
	{
		mocmos_setstate(mocmos_state | MOCMOSALTAPRULES);
		ttyputverbose(M_("MOSIS CMOS technology uses alternate active/poly rules"));
		return;
	}
	if (namesamen(pp, "standard-active-poly", l) == 0 && l >= 3)
	{
		mocmos_setstate(mocmos_state & ~MOCMOSALTAPRULES);
		ttyputverbose(M_("MOSIS CMOS technology uses standard active/poly rules"));
		return;
	}

	if (namesamen(pp, "disallow-stacked-vias", l) == 0 && l >= 2)
	{
		mocmos_setstate(mocmos_state | MOCMOSNOSTACKEDVIAS);
		ttyputverbose(M_("MOSIS CMOS technology disallows stacked vias"));
		return;
	}
	if (namesamen(pp, "allow-stacked-vias", l) == 0 && l >= 3)
	{
		mocmos_setstate(mocmos_state & ~MOCMOSNOSTACKEDVIAS);
		ttyputverbose(M_("MOSIS CMOS technology allows stacked vias"));
		return;
	}

	if (namesamen(pp, "scmos-rules", l) == 0 && l >= 2)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSRULESET) | MOCMOSSCMOSRULES);
		ttyputverbose(M_("MOSIS CMOS technology uses standard SCMOS rules"));
		return;
	}
	if (namesamen(pp, "submicron-rules", l) == 0 && l >= 2)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSRULESET) | MOCMOSSUBMRULES);
		ttyputverbose(M_("MOSIS CMOS technology uses submicron rules"));
		return;
	}
	if (namesamen(pp, "deep-rules", l) == 0 && l >= 2)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSRULESET) | MOCMOSDEEPRULES);
		ttyputverbose(M_("MOSIS CMOS technology uses deep submicron rules"));
		return;
	}

	if (namesamen(pp, "one-polysilicon", l) == 0)
	{
		mocmos_setstate(mocmos_state & ~MOCMOSTWOPOLY);
		ttyputverbose(M_("MOSIS CMOS technology uses 1-polysilicon rules"));
		return;
	}
	if (namesamen(pp, "two-polysilicon", l) == 0)
	{
		mocmos_setstate(mocmos_state | MOCMOSTWOPOLY);
		ttyputverbose(M_("MOSIS CMOS technology uses 2-polysilicon rules"));
		return;
	}

	if (namesamen(pp, "2-metal-rules", l) == 0)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSMETALS) | MOCMOS2METAL);
		ttyputverbose(M_("MOSIS CMOS technology uses 2-metal rules"));
		return;
	}
	if (namesamen(pp, "3-metal-rules", l) == 0)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSMETALS) | MOCMOS3METAL);
		ttyputverbose(M_("MOSIS CMOS technology uses 3-metal rules"));
		return;
	}
	if (namesamen(pp, "4-metal-rules", l) == 0)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSMETALS) | MOCMOS4METAL);
		ttyputverbose(M_("MOSIS CMOS technology uses 4-metal rules"));
		return;
	}
	if (namesamen(pp, "5-metal-rules", l) == 0)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSMETALS) | MOCMOS5METAL);
		ttyputverbose(M_("MOSIS CMOS technology uses 5-metal rules"));
		return;
	}
	if (namesamen(pp, "6-metal-rules", l) == 0)
	{
		mocmos_setstate((mocmos_state & ~MOCMOSMETALS) | MOCMOS6METAL);
		ttyputverbose(M_("MOSIS CMOS technology uses 6-metal rules"));
		return;
	}

	if (namesamen(pp, "switch-n-and-p", l) == 0 && l >= 2)
	{
		mocmos_switchnp();
	}

	ttyputbadusage("technology tell mocmos");
}

INTBIG mocmos_nodepolys(NODEINST *ni, INTBIG *reasonable, WINDOWPART *win)
{
	REGISTER INTBIG pindex, count;
	TECH_NODES *thistn;
	REGISTER NODEPROTO *np;

	/* special cases for special primitives */
	np = ni->proto;
	pindex = np->primindex;
	thistn = np->tech->nodeprotos[pindex-1];
	count = thistn->layercount;
	switch (pindex)
	{
		case NMETAL1P:
		case NMETAL2P:
		case NMETAL3P:
		case NMETAL4P:
		case NMETAL5P:
		case NMETAL6P:
		case NPOLY1P:
		case NPOLY2P:
		case NPACTP:
		case NNACTP:
		case NACTP:
			/* pins disappear with one or two wires */
			if (tech_pinusecount(ni, NOWINDOWPART)) count = 0;
			break;
		case NMETPACTC:
		case NMETNACTC:
		case NMETPOLY1C:
		case NMETPOLY2C:
		case NMETPOLY12C:
		case NVIA1:
		case NVIA2:
		case NVIA3:
		case NVIA4:
		case NVIA5:
		case NPWBUT:
		case NNWBUT:
			/* contacts draw a box the size of the port */
			count = 1;
			break;
		case NTRANSP:
		case NTRANSN:
			/* prepare for possible serpentine transistor */
			count = tech_inittrans(2, ni);
			break;
	}

	/* add in displayable variables */
	tech_realpolys = count;
	count += tech_displayablenvars(ni, tech_curwindowpart);
	if (reasonable != 0) *reasonable = count;
	return(count);
}

void mocmos_shapenodepoly(NODEINST *ni, INTBIG box, POLYGON *poly)
{
	TECH_POLYGON *lay;
	REGISTER INTBIG pindex;
	REGISTER NODEPROTO *np;
	REGISTER INTBIG lambda, cx, cy;
	REGISTER TECH_NODES *thistn;
	REGISTER TECH_PORTS *portdata;
	static GRAPHICS contactdesc = {LAYERO,BLACK, SOLIDC, SOLIDC,
		{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};

	/* handle displayable variables */
	if (box >= tech_realpolys)
	{
		(void)tech_filldisplayablenvar(ni, poly, tech_curwindowpart, 0);
		return;
	}

	np = ni->proto;
	pindex = np->primindex;
	thistn = mocmos_tech->nodeprotos[pindex-1];
	lambda = lambdaofnode(ni);
	switch (pindex)
	{
		case NMETAL1P:
		case NMETAL2P:
		case NMETAL3P:
		case NMETAL4P:
		case NMETAL5P:
		case NMETAL6P:
		case NPOLY1P:
		case NPOLY2P:
		case NPACTP:
		case NNACTP:
		case NACTP:
			/* pins disappear with one or two wires */
			poly->layer = LPOLYCUT;
			if (poly->limit < 2) (void)extendpolygon(poly, 2);
			cx = (ni->lowx + ni->highx) / 2;
			cy = (ni->lowy + ni->highy) / 2;
			poly->xv[0] = cx;   poly->yv[0] = cy;
			poly->xv[1] = cx;   poly->yv[1] = cy + lambda/2;
			poly->count = 2;
			poly->style = DISC;
			poly->desc = mocmos_tech->layers[poly->layer];
			break;
		case NMETPACTC:
		case NMETNACTC:
		case NMETPOLY1C:
		case NMETPOLY2C:
		case NMETPOLY12C:
		case NVIA1:
		case NVIA2:
		case NVIA3:
		case NVIA4:
		case NVIA5:
		case NPWBUT:
		case NNWBUT:
			/* contacts draw a box the size of the port */
			poly->layer = LPOLYCUT;
			if (poly->limit < 2) (void)extendpolygon(poly, 2);
			portdata = &thistn->portlist[0];
			subrange(ni->lowx, ni->highx, portdata->lowxmul, portdata->lowxsum,
				portdata->highxmul, portdata->highxsum, &poly->xv[0], &poly->xv[1], lambda);
			subrange(ni->lowy, ni->highy, portdata->lowymul, portdata->lowysum,
				portdata->highymul, portdata->highysum, &poly->yv[0], &poly->yv[1], lambda);
			poly->count = 2;
			poly->style = CLOSEDRECT;
			poly->desc = &contactdesc;
			switch (pindex)
			{
				case NMETPACTC:   contactdesc.bits = LAYERT1|LAYERT3;  contactdesc.col = COLORT1|COLORT3;   break;
				case NMETNACTC:   contactdesc.bits = LAYERT1|LAYERT3;  contactdesc.col = COLORT1|COLORT3;   break;
				case NMETPOLY1C:  contactdesc.bits = LAYERT1|LAYERT2;  contactdesc.col = COLORT1|COLORT2;   break;
				case NMETPOLY2C:  contactdesc.bits = LAYERO;           contactdesc.col = ORANGE;            break;
				case NMETPOLY12C: contactdesc.bits = LAYERO;           contactdesc.col = ORANGE;            break;
				case NVIA1:       contactdesc.bits = LAYERT1|LAYERT4;  contactdesc.col = COLORT1|COLORT4;   break;
				case NVIA2:       contactdesc.bits = LAYERT4|LAYERT5;  contactdesc.col = COLORT4|COLORT5;   break;
				case NVIA3:       contactdesc.bits = LAYERO;           contactdesc.col = LBLUE;             break;
				case NVIA4:       contactdesc.bits = LAYERO;           contactdesc.col = LRED;              break;
				case NVIA5:       contactdesc.bits = LAYERO;           contactdesc.col = CYAN;              break;
				case NPWBUT:      contactdesc.bits = LAYERO;           contactdesc.col = BROWN;             break;
				case NNWBUT:      contactdesc.bits = LAYERO;           contactdesc.col = YELLOW;            break;
			}
			break;
		case NTRANSP:
		case NTRANSN:
			/* prepare for possible serpentine transistor */
			lay = &thistn->gra[box].basics;
			poly->layer = lay->layernum;
			if (poly->layer == LTRANS)
			{
				ni->lowy += lambda;
				ni->highy -= lambda;
			} else
			{
				ni->lowx += lambda + lambda/2;
				ni->highx -= lambda + lambda/2;
			}
			tech_filltrans(poly, &lay, thistn->gra, ni, lambda, box, (TECH_PORTS *)0);
			if (poly->layer == LTRANS)
			{
				ni->lowy -= lambda;
				ni->highy += lambda;
			} else
			{
				ni->lowx -= lambda + lambda/2;
				ni->highx += lambda + lambda/2;
			}
			poly->desc = mocmos_tech->layers[poly->layer];
			break;
		default:
			lay = &thistn->layerlist[box];
			tech_fillpoly(poly, lay, ni, lambda, FILLED);
			poly->desc = mocmos_tech->layers[poly->layer];
			break;
	}
}

void mocmos_nodesizeoffset(NODEINST *ni, INTBIG *lx, INTBIG *ly, INTBIG *hx, INTBIG *hy)
{
	REGISTER INTBIG pindex;
	REGISTER NODEPROTO *np;
	REGISTER INTBIG lambda, cx, cy;
	INTBIG bx, by, ux, uy;
	REGISTER TECH_NODES *thistn;
	REGISTER TECH_PORTS *portdata;

	np = ni->proto;
	pindex = np->primindex;
	lambda = lambdaofnode(ni);
	switch (pindex)
	{
		case NMETAL1P:
		case NMETAL2P:
		case NMETAL3P:
		case NMETAL4P:
		case NMETAL5P:
		case NMETAL6P:
		case NPOLY1P:
		case NPOLY2P:
		case NPACTP:
		case NNACTP:
		case NACTP:
			cx = (ni->lowx + ni->highx) / 2;
			cy = (ni->lowy + ni->highy) / 2;
			*lx = (cx - lambda) - ni->lowx;
			*hx = ni->highx - (cx + lambda);
			*ly = (cy - lambda) - ni->lowy;
			*hy = ni->highy - (cy + lambda);
			break;
		case NMETPACTC:
		case NMETNACTC:
		case NMETPOLY1C:
		case NMETPOLY2C:
		case NMETPOLY12C:
		case NVIA1:
		case NVIA2:
		case NVIA3:
		case NVIA4:
		case NVIA5:
		case NPWBUT:
		case NNWBUT:
			/* contacts draw a box the size of the port */
			thistn = mocmos_tech->nodeprotos[pindex-1];
			portdata = &thistn->portlist[0];
			subrange(ni->lowx, ni->highx, portdata->lowxmul, portdata->lowxsum,
				portdata->highxmul, portdata->highxsum, &bx, &ux, lambda);
			subrange(ni->lowy, ni->highy, portdata->lowymul, portdata->lowysum,
				portdata->highymul, portdata->highysum, &by, &uy, lambda);
			*lx = bx - ni->lowx;
			*hx = ni->highx - ux;
			*ly = by - ni->lowy;
			*hy = ni->highy - uy;
			break;
		default:
			nodeprotosizeoffset(np, lx, ly, hx, hy);
			if (pindex == NTRANSP || pindex == NTRANSN)
			{
				*lx += lambda + lambda/2;
				*hx += lambda + lambda/2;
				*ly += lambda;
				*hy += lambda;
			}
			break;
	}
}

INTBIG mocmos_arcpolys(ARCINST *ai, WINDOWPART *win)
{
	REGISTER INTBIG i;

	i = 1;
	mocmos_arrowbox = -1;
	if ((ai->userbits&ISDIRECTIONAL) != 0) mocmos_arrowbox = i++;

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

void mocmos_shapearcpoly(ARCINST *ai, INTBIG box, POLYGON *poly)
{
	REGISTER INTBIG aindex;
	REGISTER INTBIG angle;
	REGISTER INTBIG x1,y1, x2,y2, i;
	REGISTER TECH_ARCLAY *thista;
	static GRAPHICS intense = {LAYERO, RED, SOLIDC, SOLIDC,
		{0,0,0,0,0,0,0,0}, NOVARIABLE, 0};

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

	/* initialize for the arc */
	aindex = ai->proto->arcindex;
	thista = &mocmos_arcprotos[aindex]->list[box];
	poly->layer = thista->lay;
	switch (ai->proto->arcindex)
	{
		case AMETAL1:
		case AMETAL2:
		case AMETAL3:
		case AMETAL4:
		case AMETAL5:
		case AMETAL6:
			intense.col = BLUE;
			break;
		case APOLY1:
		case APOLY2:
			intense.col = RED;
			break;
		case APACT:
		case ANACT:
		case AACT:
			intense.col = DGREEN;
			break;
	}
	if (mocmos_arrowbox < 0 || box == 0)
	{
		/* simple arc */
		poly->desc = mocmos_tech->layers[poly->layer];
		makearcpoly(ai->length, ai->width-ai->proto->nominalwidth, ai, poly, thista->style);
		return;
	}

	/* prepare special information for directional arcs */
	poly->desc = &intense;
	x1 = ai->end[0].xpos;   y1 = ai->end[0].ypos;
	x2 = ai->end[1].xpos;   y2 = ai->end[1].ypos;
	angle = ((ai->userbits&AANGLE) >> AANGLESH) * 10;
	if ((ai->userbits&REVERSEEND) != 0)
	{
		i = x1;   x1 = x2;   x2 = i;
		i = y1;   y1 = y2;   y2 = i;
		angle = (angle+1800) % 3600;
	}

	/* draw the directional arrow */
	poly->style = VECTORS;
	poly->layer = -1;
	if (poly->limit < 2) (void)extendpolygon(poly, 2);
	poly->count = 0;
	if ((ai->userbits&NOTEND1) == 0)
		tech_addheadarrow(poly, angle, x2, y2, lambdaofarc(ai));
}

INTBIG mocmos_arcwidthoffset(ARCINST *ai)
{
	return(ai->proto->nominalwidth);
}

/******************** SUPPORT ROUTINES ********************/

/*
 * Routine to switch N and P layers (not terribly useful)
 */
void mocmos_switchnp(void)
{
	REGISTER LIBRARY *lib;
	REGISTER NODEPROTO *np;
	REGISTER NODEINST *ni, *rni;
	REGISTER ARCINST *ai;
	REGISTER ARCPROTO *ap, *app, *apn;
	REGISTER PORTPROTO *pp, *rpp;
	REGISTER PORTARCINST *pi;
	REGISTER PORTEXPINST *pe;
	REGISTER INTBIG i, j, k;

	/* find the important node and arc prototypes */
	mocmos_setupprimswap(NPACTP, NNACTP, &mocmos_primswap[0]);
	mocmos_setupprimswap(NMETPACTC, NMETNACTC, &mocmos_primswap[1]);
	mocmos_setupprimswap(NTRANSP, NTRANSN, &mocmos_primswap[2]);
	mocmos_setupprimswap(NPWBUT, NNWBUT, &mocmos_primswap[3]);
	mocmos_setupprimswap(NPACTIVEN, NNACTIVEN, &mocmos_primswap[4]);
	mocmos_setupprimswap(NSELECTPN, NSELECTNN, &mocmos_primswap[5]);
	mocmos_setupprimswap(NWELLPN, NWELLNN, &mocmos_primswap[6]);
	app = apn = NOARCPROTO;
	for(ap = mocmos_tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
	{
		if (namesame(ap->protoname, "P-Active") == 0) app = ap;
		if (namesame(ap->protoname, "N-Active") == 0) apn = ap;
	}

	for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
	{
		for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
		{
			for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
			{
				if (ni->proto->primindex == 0) continue;
				if (ni->proto->tech != mocmos_tech) continue;
				for(i=0; i<7; i++)
				{
					for(k=0; k<2; k++)
					{
						if (ni->proto == mocmos_primswap[i].np[k])
						{
							ni->proto = mocmos_primswap[i].np[1-k];
							for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
							{
								for(j=0; j<mocmos_primswap[i].portcount; j++)
								{
									if (pi->proto == mocmos_primswap[i].pp[k][j])
									{
										pi->proto = mocmos_primswap[i].pp[1-k][j];
										break;
									}
								}
							}
							for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
							{
								for(j=0; j<mocmos_primswap[i].portcount; j++)
								{
									if (pe->proto == mocmos_primswap[i].pp[k][j])
									{
										pe->proto = mocmos_primswap[i].pp[1-k][j];
										pe->exportproto->subportproto = pe->proto;
										break;
									}
								}
							}
							break;
						}
					}
				}
			}
			for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
			{
				if (ai->proto->tech != mocmos_tech) continue;
				if (ai->proto == app)
				{
					ai->proto = apn;
				} else if (ai->proto == apn)
				{
					ai->proto = app;
				}
			}
		}
		for(np = lib->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
		{
			for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
			{
				/* find the primitive at the bottom */
				rpp = pp->subportproto;
				rni = pp->subnodeinst;
				while (rni->proto->primindex == 0)
				{
					rni = rpp->subnodeinst;
					rpp = rpp->subportproto;
				}
				pp->connects = rpp->connects;
			}
		}
	}
	for(i=0; i<7; i++)
	{
		ni = mocmos_primswap[i].np[0]->firstinst;
		mocmos_primswap[i].np[0]->firstinst = mocmos_primswap[i].np[1]->firstinst;
		mocmos_primswap[i].np[1]->firstinst = ni;
	}
}

/*
 * Helper routine for "mocmos_switchnp()".
 */
void mocmos_setupprimswap(INTBIG index1, INTBIG index2, PRIMSWAP *swap)
{
	REGISTER NODEPROTO *np;
	REGISTER PORTPROTO *pp;

	swap->np[0] = swap->np[1] = NONODEPROTO;
	for(np = mocmos_tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto)
	{
		if (np->primindex == index1) swap->np[0] = np;
		if (np->primindex == index2) swap->np[1] = np;
	}
	if (swap->np[0] == NONODEPROTO || swap->np[1] == NONODEPROTO) return;
	swap->portcount = 0;
	for(pp = swap->np[0]->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
		swap->pp[0][swap->portcount++] = pp;
	swap->portcount = 0;
	for(pp = swap->np[1]->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
		swap->pp[1][swap->portcount++] = pp;
}

/*
 * Routine to set the technology to state "newstate", which encodes the number of metal
 * layers, whether it is a deep process, and other rules.
 */
void mocmos_setstate(INTBIG newstate)
{
	extern void tech_initmaxdrcsurround(void);

	switch (newstate&MOCMOSMETALS)
	{
		/* cannot use deep rules if less than 5 layers of metal */
		case MOCMOS2METAL:
		case MOCMOS3METAL:
		case MOCMOS4METAL:
			if ((newstate&MOCMOSRULESET) == MOCMOSDEEPRULES)
				newstate = (newstate & ~MOCMOSRULESET) | MOCMOSSUBMRULES;
			break;

		/* cannot use scmos rules if more than 4 layers of metal */
		case MOCMOS5METAL:
		case MOCMOS6METAL:
			if ((newstate&MOCMOSRULESET) == MOCMOSSCMOSRULES)
				newstate = (newstate & ~MOCMOSRULESET) | MOCMOSSUBMRULES;
			break;
	}

	if (mocmos_state == newstate) return;
	mocmos_state = newstate;

	/* set stick-figure state */
	if ((mocmos_state&MOCMOSSTICKFIGURE) != 0)
	{
		/* stick figure drawing */
		mocmos_tech->nodepolys = mocmos_nodepolys;
		mocmos_tech->shapenodepoly = mocmos_shapenodepoly;
		mocmos_tech->nodesizeoffset = mocmos_nodesizeoffset;
		mocmos_tech->arcpolys = mocmos_arcpolys;
		mocmos_tech->shapearcpoly = mocmos_shapearcpoly;
		mocmos_tech->arcwidthoffset = mocmos_arcwidthoffset;
	} else
	{
		/* full figure drawing */
		mocmos_tech->nodepolys = 0;
		mocmos_tech->shapenodepoly = 0;
		mocmos_tech->nodesizeoffset = 0;
		mocmos_tech->arcpolys = 0;
		mocmos_tech->shapearcpoly = 0;
		mocmos_tech->arcwidthoffset = 0;
	}

	/* set rules */
	if (mocmos_loadDRCtables()) return;

	/* disable Metal-3/4/5/6-Pin, Metal-2/3/4/5-Metal-3/4/5/6-Con, Metal-3/4/5/6-Node, Via-2/3/4/5-Node */
	mocmos_pm3.creation->userbits |= NNOTUSED;
	mocmos_pm4.creation->userbits |= NNOTUSED;
	mocmos_pm5.creation->userbits |= NNOTUSED;
	mocmos_pm6.creation->userbits |= NNOTUSED;
	mocmos_m2m3.creation->userbits |= NNOTUSED;
	mocmos_m3m4.creation->userbits |= NNOTUSED;
	mocmos_m4m5.creation->userbits |= NNOTUSED;
	mocmos_m5m6.creation->userbits |= NNOTUSED;
	mocmos_m3.creation->userbits |= NNOTUSED;
	mocmos_m4.creation->userbits |= NNOTUSED;
	mocmos_m5.creation->userbits |= NNOTUSED;
	mocmos_m6.creation->userbits |= NNOTUSED;
	mocmos_v2.creation->userbits |= NNOTUSED;
	mocmos_v3.creation->userbits |= NNOTUSED;
	mocmos_v4.creation->userbits |= NNOTUSED;
	mocmos_v5.creation->userbits |= NNOTUSED;

	/* disable Polysilicon-2 */
	mocmos_a_po2.creation->userbits |= ANOTUSED;
	mocmos_pp2.creation->userbits |= NNOTUSED;
	mocmos_mp2.creation->userbits |= NNOTUSED;
	mocmos_mp12.creation->userbits |= NNOTUSED;
	mocmos_p2.creation->userbits |= NNOTUSED;

	/* disable metal 3-6 arcs */
	mocmos_a_m3.creation->userbits |= ANOTUSED;
	mocmos_a_m4.creation->userbits |= ANOTUSED;
	mocmos_a_m5.creation->userbits |= ANOTUSED;
	mocmos_a_m6.creation->userbits |= ANOTUSED;

	/* enable the desired nodes */
	switch (mocmos_state&MOCMOSMETALS)
	{
		case MOCMOS6METAL:
			mocmos_pm6.creation->userbits &= ~NNOTUSED;
			mocmos_m5m6.creation->userbits &= ~NNOTUSED;
			mocmos_m6.creation->userbits &= ~NNOTUSED;
			mocmos_v5.creation->userbits &= ~NNOTUSED;
			mocmos_a_m6.creation->userbits &= ~ANOTUSED;
			/* FALLTHROUGH */ 
		case MOCMOS5METAL:
			mocmos_pm5.creation->userbits &= ~NNOTUSED;
			mocmos_m4m5.creation->userbits &= ~NNOTUSED;
			mocmos_m5.creation->userbits &= ~NNOTUSED;
			mocmos_v4.creation->userbits &= ~NNOTUSED;
			mocmos_a_m5.creation->userbits &= ~ANOTUSED;
			/* FALLTHROUGH */ 
		case MOCMOS4METAL:
			mocmos_pm4.creation->userbits &= ~NNOTUSED;
			mocmos_m3m4.creation->userbits &= ~NNOTUSED;
			mocmos_m4.creation->userbits &= ~NNOTUSED;
			mocmos_v3.creation->userbits &= ~NNOTUSED;
			mocmos_a_m4.creation->userbits &= ~ANOTUSED;
			/* FALLTHROUGH */ 
		case MOCMOS3METAL:
			mocmos_pm3.creation->userbits &= ~NNOTUSED;
			mocmos_m2m3.creation->userbits &= ~NNOTUSED;
			mocmos_m3.creation->userbits &= ~NNOTUSED;
			mocmos_v2.creation->userbits &= ~NNOTUSED;
			mocmos_a_m3.creation->userbits &= ~ANOTUSED;
			break;
	}
	if ((mocmos_state&MOCMOSRULESET) != MOCMOSDEEPRULES)
	{
		if ((mocmos_state&MOCMOSTWOPOLY) != 0)
		{
			/* non-DEEP: enable Polysilicon-2 */
			mocmos_a_po2.creation->userbits &= ~ANOTUSED;
			mocmos_pp2.creation->userbits &= ~NNOTUSED;
			mocmos_mp2.creation->userbits &= ~NNOTUSED;
			mocmos_mp12.creation->userbits &= ~NNOTUSED;
			mocmos_p2.creation->userbits &= ~NNOTUSED;
		}
	}

	/* now rewrite the description */
	(void)reallocstring(&mocmos_tech->techdescript, mocmos_describestate(mocmos_state), mocmos_tech->cluster);

	/* recache design rules */
	tech_initmaxdrcsurround();
}

/*
 * Routine to remove all information in the design rule tables.
 * Returns true on error.
 */
BOOLEAN mocmos_loadDRCtables(void)
{
	REGISTER INTBIG i, tot, totarraybits, layer1, layer2, layert1, layert2, temp, index,
		distance, goodrule, when, node, pass;
	INTBIG *condist, *uncondist, *condistW, *uncondistW,
		*condistM, *uncondistM, *minsize, *edgedist;
	char **condistrules, **uncondistrules, **condistWrules, **uncondistWrules,
		**condistMrules, **uncondistMrules, **minsizerules, **edgedistrules,
		proc[20], metal[20], rule[100];
	REGISTER BOOLEAN errorfound;
	REGISTER TECH_NODES *nty;
	REGISTER NODEPROTO *np;

	/* allocate local copy of DRC tables */
	tot = (MAXLAYERS * MAXLAYERS + MAXLAYERS) / 2;
	condist = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	uncondist = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	condistW = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	uncondistW = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	condistM = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	uncondistM = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	edgedist = (INTBIG *)emalloc(tot * SIZEOFINTBIG, el_tempcluster);
	condistrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	uncondistrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	condistWrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	uncondistWrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	condistMrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	uncondistMrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	edgedistrules = (char **)emalloc(tot * (sizeof (char *)), el_tempcluster);
	minsize = (INTBIG *)emalloc(MAXLAYERS * SIZEOFINTBIG, el_tempcluster);
	minsizerules = (char **)emalloc(MAXLAYERS * (sizeof (char *)), el_tempcluster);

	/* clear all rules */
	for(i=0; i<tot; i++)
	{
		condist[i] = uncondist[i] = XX;
		condistW[i] = uncondistW[i] = XX;
		condistM[i] = uncondistM[i] = XX;
		edgedist[i] = XX;
		(void)allocstring(&condistrules[i], "", el_tempcluster);
		(void)allocstring(&uncondistrules[i], "", el_tempcluster);
		(void)allocstring(&condistWrules[i], "", el_tempcluster);
		(void)allocstring(&uncondistWrules[i], "", el_tempcluster);
		(void)allocstring(&condistMrules[i], "", el_tempcluster);
		(void)allocstring(&uncondistMrules[i], "", el_tempcluster);
		(void)allocstring(&edgedistrules[i], "", el_tempcluster);
	}
	for(i=0; i<MAXLAYERS; i++)
	{
		minsize[i] = XX;
		(void)allocstring(&minsizerules[i], "", el_tempcluster);
	}

	/* load the DRC tables from the explanation table */
	errorfound = FALSE;
	for(pass=0; pass<2; pass++)
	{
		for(i=0; mocmos_drcrules[i].rule != 0; i++)
		{
			/* see if the rule applies */
			if (pass == 0)
			{
				if (mocmos_drcrules[i].ruletype == NODSIZ) continue;
			} else
			{
				if (mocmos_drcrules[i].ruletype != NODSIZ) continue;
			}

			when = mocmos_drcrules[i].when;
			goodrule = 1;
			if ((when&(DE|SU|SC)) != 0)
			{
				switch (mocmos_state&MOCMOSRULESET)
				{
					case MOCMOSDEEPRULES:  if ((when&DE) == 0) goodrule = 0;   break;
					case MOCMOSSUBMRULES:  if ((when&SU) == 0) goodrule = 0;   break;
					case MOCMOSSCMOSRULES: if ((when&SC) == 0) goodrule = 0;   break;
				}
				if (goodrule == 0) continue;
			}
			if ((when&(M2|M3|M4|M5|M6)) != 0)
			{
				switch (mocmos_state&MOCMOSMETALS)
				{
					case MOCMOS2METAL:  if ((when&M2) == 0) goodrule = 0;   break;
					case MOCMOS3METAL:  if ((when&M3) == 0) goodrule = 0;   break;
					case MOCMOS4METAL:  if ((when&M4) == 0) goodrule = 0;   break;
					case MOCMOS5METAL:  if ((when&M5) == 0) goodrule = 0;   break;
					case MOCMOS6METAL:  if ((when&M6) == 0) goodrule = 0;   break;
				}
				if (goodrule == 0) continue;
			}
			if ((when&AC) != 0)
			{
				if ((mocmos_state&MOCMOSALTAPRULES) == 0) continue;
			}
			if ((when&NAC) != 0)
			{
				if ((mocmos_state&MOCMOSALTAPRULES) != 0) continue;
			}
			if ((when&SV) != 0)
			{
				if ((mocmos_state&MOCMOSNOSTACKEDVIAS) != 0) continue;
			}
			if ((when&NSV) != 0)
			{
				if ((mocmos_state&MOCMOSNOSTACKEDVIAS) == 0) continue;
			}

			/* find the layer names */
			if (mocmos_drcrules[i].layer1 == 0) layer1 = -1; else
			{
				for(layer1=0; layer1<mocmos_tech->layercount; layer1++)
					if (namesame(mocmos_layer_names[layer1], mocmos_drcrules[i].layer1) == 0) break;
				if (layer1 >= mocmos_tech->layercount)
				{
					ttyputerr("Warning: no layer '%s' in mocmos technology", mocmos_drcrules[i].layer1);
					errorfound = TRUE;
					break;
				}
			}
			if (mocmos_drcrules[i].layer2 == 0) layer2 = -1; else
			{
				for(layer2=0; layer2<mocmos_tech->layercount; layer2++)
					if (namesame(mocmos_layer_names[layer2], mocmos_drcrules[i].layer2) == 0) break;
				if (layer2 >= mocmos_tech->layercount)
				{
					ttyputerr("Warning: no layer '%s' in mocmos technology", mocmos_drcrules[i].layer2);
					errorfound = TRUE;
					break;
				}
			}
			if (mocmos_drcrules[i].nodename == 0) node = -1; else
			{
				for(node=0; node<mocmos_tech->nodeprotocount; node++)
				{
					nty = mocmos_tech->nodeprotos[node];
					np = nty->creation;
					if (namesame(np->primname, mocmos_drcrules[i].nodename) == 0) break;
				}
				if (node >= mocmos_tech->nodeprotocount)
				{
					ttyputerr("Warning: no node '%s' in mocmos technology", mocmos_drcrules[i].nodename);
					errorfound = TRUE;
					break;
				}
			}

			/* get more information about the rule */
			distance = mocmos_drcrules[i].distance;
			proc[0] = 0;
			if ((when&(DE|SU|SC)) != 0)
			{
				switch (mocmos_state&MOCMOSRULESET)
				{
					case MOCMOSDEEPRULES:  strcpy(proc, "DEEP");   break;
					case MOCMOSSUBMRULES:  strcpy(proc, "SUBM");   break;
					case MOCMOSSCMOSRULES: strcpy(proc, "SCMOS");  break;
				}
			}
			metal[0] = 0;
			if ((when&(M2|M3|M4|M5|M6)) != 0)
			{
				switch (mocmos_state&MOCMOSMETALS)
				{
					case MOCMOS2METAL:  strcpy(metal, "2m");   break;
					case MOCMOS3METAL:  strcpy(metal, "3m");   break;
					case MOCMOS4METAL:  strcpy(metal, "4m");   break;
					case MOCMOS5METAL:  strcpy(metal, "5m");   break;
					case MOCMOS6METAL:  strcpy(metal, "6m");   break;
				}
				if (goodrule == 0) continue;
			}
			strcpy(rule, mocmos_drcrules[i].rule);
			if (proc[0] != 0 || metal[0] != 0)
			{
				strcat(rule, ", ");
				strcat(rule, metal);
				strcat(rule, proc);
			}
			layert1 = layer1;   layert2 = layer2;
			if (layert1 > layert2) { temp = layert1; layert1 = layert2;  layert2 = temp; }
			index = (layert1+1) * (layert1/2) + (layert1&1) * ((layert1+1)/2);
			index = layert2 + mocmos_tech->layercount * layert1 - index;

			/* set the rule */
			switch (mocmos_drcrules[i].ruletype)
			{
				case MINWID:
					minsize[layer1] = distance;
					(void)reallocstring(&minsizerules[layer1], rule, el_tempcluster);
					mocmos_setlayerminwidth(mocmos_drcrules[i].layer1, distance);
					break;
				case NODSIZ:
					mocmos_setdefnodesize(nty, node, distance, distance);
					break;
				case SURROUND:
					mocmos_setlayersurroundlayer(nty, layer1, layer2, distance);
					break;
				case VIASUR:
					mocmos_setlayersurroundvia(nty, layer1, distance);
					nty->f3 = (INTSML)distance;
					break;
				case TRAWELL:
					mocmos_settransistorwellsurround(distance);
					break;
				case TRAPOLY:
					mocmos_settransistorpolyoverhang(distance);
					break;
				case TRAACTIVE:
					mocmos_settransistoractiveoverhang(distance);
					break;
				case SPACING:
					condist[index] = uncondist[index] = distance;
					(void)reallocstring(&condistrules[index], rule, el_tempcluster);
					(void)reallocstring(&uncondistrules[index], rule, el_tempcluster);
					break;
				case SPACINGM:
					condistM[index] = uncondistM[index] = distance;
					(void)reallocstring(&condistMrules[index], rule, el_tempcluster);
					(void)reallocstring(&uncondistMrules[index], rule, el_tempcluster);
					break;
				case SPACINGW:
					condistW[index] = uncondistW[index] = distance;
					(void)reallocstring(&condistWrules[index], rule, el_tempcluster);
					(void)reallocstring(&uncondistWrules[index], rule, el_tempcluster);
					break;
				case SPACINGE:
					edgedist[index] = distance;
					(void)reallocstring(&edgedistrules[index], rule, el_tempcluster);
					break;
				case CONSPA:
					condist[index] = distance;
					(void)reallocstring(&condistrules[index], rule, el_tempcluster);
					break;
				case UCONSPA:
					uncondist[index] = distance;
					(void)reallocstring(&uncondistrules[index], rule, el_tempcluster);
					break;
				case CUTSPA:
					nty->f4 = (INTSML)distance;
					break;
				case CUTSIZE:
					nty->f1 = nty->f2 = (INTSML)distance;
					break;
				case CUTSUR:
					nty->f3 = (INTSML)distance;
					break;
			}
		}
	}
	if (!errorfound)
	{
		/* clear the rules on the technology */
		changesquiet(TRUE);
		totarraybits = VDONTSAVE|VISARRAY|(tot << VLENGTHSH);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_connected_distanceskey,
			(INTBIG)condist, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_connected_distances_rulekey,
			(INTBIG)condistrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_unconnected_distanceskey,
			(INTBIG)uncondist, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_unconnected_distances_rulekey,
			(INTBIG)uncondistrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_connected_distancesWkey,
			(INTBIG)condistW, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_connected_distancesW_rulekey,
			(INTBIG)condistWrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_unconnected_distancesWkey,
			(INTBIG)uncondistW, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_unconnected_distancesW_rulekey,
			(INTBIG)uncondistWrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_connected_distancesMkey,
			(INTBIG)condistM, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_connected_distancesM_rulekey,
			(INTBIG)condistMrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_unconnected_distancesMkey,
			(INTBIG)uncondistM, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_unconnected_distancesM_rulekey,
			(INTBIG)uncondistMrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_edge_distanceskey,
			(INTBIG)edgedist, VFRACT|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_edge_distances_rulekey,
			(INTBIG)edgedistrules, VSTRING|totarraybits) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_wide_limitkey,
			WIDELIMIT, VFRACT|VDONTSAVE) == NOVARIABLE) return(TRUE);

		/* clear minimum size rules */
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_min_widthkey,
			(INTBIG)minsize, VFRACT|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)) == NOVARIABLE) return(TRUE);
		if (setvalkey((INTBIG)mocmos_tech, VTECHNOLOGY, dr_min_width_rulekey,
			(INTBIG)minsizerules, VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)) == NOVARIABLE) return(TRUE);
		changesquiet(FALSE);

		/* reset valid DRC dates */
		drcb_reset_dates();
	}

	/* free rule arrays */
	/* clear all rules */
	for(i=0; i<tot; i++)
	{
		efree((char *)condistrules[i]);
		efree((char *)uncondistrules[i]);
		efree((char *)condistWrules[i]);
		efree((char *)uncondistWrules[i]);
		efree((char *)condistMrules[i]);
		efree((char *)uncondistMrules[i]);
		efree((char *)edgedistrules[i]);
	}
	for(i=0; i<MAXLAYERS; i++)
	{
		efree((char *)minsizerules[i]);
	}
	efree((char *)condist);
	efree((char *)uncondist);
	efree((char *)condistW);
	efree((char *)uncondistW);
	efree((char *)condistM);
	efree((char *)uncondistM);
	efree((char *)edgedist);
	efree((char *)condistrules);
	efree((char *)uncondistrules);
	efree((char *)condistWrules);
	efree((char *)uncondistWrules);
	efree((char *)condistMrules);
	efree((char *)uncondistMrules);
	efree((char *)edgedistrules);
	efree((char *)minsize);
	efree((char *)minsizerules);
	return(errorfound);
}

/*
 * Routine to describe the technology when it is in state "state".
 */
char *mocmos_describestate(INTBIG state)
{
	REGISTER INTBIG nummetals, numpolys;
	REGISTER char *rules;

	(void)initinfstr();
	switch (state&MOCMOSMETALS)
	{
		case MOCMOS2METAL: nummetals = 2;   break;
		case MOCMOS3METAL: nummetals = 3;   break;
		case MOCMOS4METAL: nummetals = 4;   break;
		case MOCMOS5METAL: nummetals = 5;   break;
		case MOCMOS6METAL: nummetals = 6;   break;
	}
	switch (state&MOCMOSRULESET)
	{
		case MOCMOSSCMOSRULES:
			numpolys = 2;
			rules = _("now standard");
			break;
		case MOCMOSDEEPRULES:
			numpolys = 1;
			rules = _("now deep");
			break;
		case MOCMOSSUBMRULES:
			numpolys = 2;
			rules = _("now submicron");
			break;
	}
	(void)formatinfstr(_("Complementary MOS (from MOSIS, 2-6 metals [now %ld], 1-2 polys [now %ld], flex rules [%s]"),
		nummetals, numpolys, rules);
	if ((state&MOCMOSSTICKFIGURE) != 0) (void)addstringtoinfstr(_(", stick-figures"));
	if ((state&MOCMOSNOSTACKEDVIAS) != 0) (void)addstringtoinfstr(_(", stacked vias disallowed"));
	if ((state&MOCMOSALTAPRULES) != 0) (void)addstringtoinfstr(_(", alternate contact rules"));
	(void)addstringtoinfstr(")");
	return(returninfstr());
}

/*
 * Routine to implement rule 3.3 which specifies the amount of poly overhang
 * on a transistor.
 */
void mocmos_settransistorpolyoverhang(INTBIG overhang)
{
	/* define the poly box in terms of the central transistor box */
	mocmos_trpbox[1] = mocmos_trtbox[1] - overhang;
	mocmos_trpbox[5] = mocmos_trtbox[5] + overhang;

	/* the serpentine poly overhang */
	mocmos_tpa_l[TRANSPOLYLAYER].extend = (INTSML)overhang;
	mocmos_tpaE_l[TRANSEPOLYLAYER].extend = (INTSML)overhang;
	mocmos_tna_l[TRANSPOLYLAYER].extend = (INTSML)overhang;
	mocmos_tnaE_l[TRANSEPOLYLAYER].extend = (INTSML)overhang;
}

/*
 * Routine to implement rule 3.4 which specifies the amount of active overhang
 * on a transistor.
 */
void mocmos_settransistoractiveoverhang(INTBIG overhang)
{
	INTBIG polywidth, welloverhang;

	/* pickup extension of well about active (2.3) */
	welloverhang = mocmos_trabox[1] - mocmos_trwbox[1];

	/* define the active box in terms of the central transistor box */
	mocmos_trabox[3] = mocmos_trtbox[3] - overhang;
	mocmos_trabox[7] = mocmos_trtbox[7] + overhang;
	mocmos_tra1box[7] = mocmos_trtbox[7] + overhang;
	mocmos_tra2box[3] = mocmos_trtbox[3] - overhang;

	/* extension of well about active (2.3) */
	mocmos_trwbox[3] = mocmos_trabox[3] - welloverhang;
	mocmos_trwbox[7] = mocmos_trabox[7] + welloverhang;

	/* extension of select about active = 2 (4.2) */
	mocmos_trsbox[3] = mocmos_trabox[3] - K2;
	mocmos_trsbox[7] = mocmos_trabox[7] + K2;

	/* the serpentine active overhang */
	polywidth = mocmos_tpa.ysize/2 - mocmos_trtbox[3];
	mocmos_tpa_l[TRANSACTLAYER].lwidth = (INTSML)(polywidth + overhang);
	mocmos_tpa_l[TRANSACTLAYER].rwidth = (INTSML)(polywidth + overhang);
	mocmos_tpaE_l[TRANSEACT1LAYER].lwidth = (INTSML)(polywidth + overhang);
	mocmos_tpaE_l[TRANSEACT2LAYER].rwidth = (INTSML)(polywidth + overhang);
	mocmos_tna_l[TRANSACTLAYER].lwidth = (INTSML)(polywidth + overhang);
	mocmos_tna_l[TRANSACTLAYER].rwidth = (INTSML)(polywidth + overhang);
	mocmos_tnaE_l[TRANSEACT1LAYER].lwidth = (INTSML)(polywidth + overhang);
	mocmos_tnaE_l[TRANSEACT2LAYER].rwidth = (INTSML)(polywidth + overhang);

	/* serpentine: extension of well about active (2.3) */
	mocmos_tpa_l[TRANSWELLLAYER].lwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tpa_l[TRANSWELLLAYER].rwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tpaE_l[TRANSEWELLLAYER].lwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tpaE_l[TRANSEWELLLAYER].rwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tna_l[TRANSWELLLAYER].lwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tna_l[TRANSWELLLAYER].rwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tnaE_l[TRANSEWELLLAYER].lwidth = (INTSML)(polywidth + overhang + welloverhang);
	mocmos_tnaE_l[TRANSEWELLLAYER].rwidth = (INTSML)(polywidth + overhang + welloverhang);

	/* serpentine: extension of select about active = 2 (4.2) */
	mocmos_tpa_l[TRANSSELECTLAYER].lwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tpa_l[TRANSSELECTLAYER].rwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tpaE_l[TRANSESELECTLAYER].lwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tpaE_l[TRANSESELECTLAYER].rwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tna_l[TRANSSELECTLAYER].lwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tna_l[TRANSSELECTLAYER].rwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tnaE_l[TRANSESELECTLAYER].lwidth = (INTSML)(polywidth + overhang + K2);
	mocmos_tnaE_l[TRANSESELECTLAYER].rwidth = (INTSML)(polywidth + overhang + K2);
}

/*
 * Routine to implement rule 2.3 which specifies the amount of well surround
 * about active on a transistor.
 */
void mocmos_settransistorwellsurround(INTBIG overhang)
{
	/* define the well box in terms of the active box */
	mocmos_trwbox[1] = mocmos_trabox[1] - overhang;
	mocmos_trwbox[3] = mocmos_trabox[3] - overhang;
	mocmos_trwbox[5] = mocmos_trabox[5] + overhang;
	mocmos_trwbox[7] = mocmos_trabox[7] + overhang;

	/* the serpentine poly overhang */
	mocmos_tpa_l[TRANSWELLLAYER].extend = (INTSML)overhang;
	mocmos_tpa_l[TRANSWELLLAYER].lwidth = mocmos_tpa_l[TRANSWELLLAYER].rwidth = (INTSML)(overhang+K4);
	mocmos_tpaE_l[TRANSEWELLLAYER].extend = (INTSML)overhang;
	mocmos_tpaE_l[TRANSEWELLLAYER].lwidth = mocmos_tpaE_l[TRANSEWELLLAYER].rwidth = (INTSML)(overhang+K4);
	mocmos_tna_l[TRANSWELLLAYER].extend = (INTSML)overhang;
	mocmos_tna_l[TRANSWELLLAYER].lwidth = mocmos_tna_l[TRANSWELLLAYER].rwidth = (INTSML)(overhang+K4);
	mocmos_tnaE_l[TRANSEWELLLAYER].extend = (INTSML)overhang;
	mocmos_tnaE_l[TRANSEWELLLAYER].lwidth = mocmos_tnaE_l[TRANSEWELLLAYER].rwidth = (INTSML)(overhang+K4);
}

/*
 * Routine to change the design rules for layer "layername" layers so that
 * the layers are at least "width" wide.  Affects the default arc width
 * and the default pin size.
 */
void mocmos_setlayerminwidth(char *layername, INTBIG width)
{
	REGISTER ARCPROTO *ap;
	REGISTER INTBIG lambda, i;
	INTBIG lx, hx, ly, hy;
	REGISTER NODEPROTO *np;
	REGISTER TECH_NODES *nty;
	REGISTER TECH_PORTS *npp;
	REGISTER char *pt;

	/* next find that arc and set its default width */
	for(ap = mocmos_tech->firstarcproto; ap != NOARCPROTO; ap = ap->nextarcproto)
		if (namesame(ap->protoname, layername) == 0) break;
	if (ap == NOARCPROTO) return;
	lambda = el_curlib->lambda[mocmos_tech->techindex];
	ap->nominalwidth = (width + mocmos_arc_widoff[ap->arcindex]) * lambda / WHOLE;

	/* finally, find that arc's pin and set its size and port offset */
	(void)initinfstr();
	(void)formatinfstr("%s-Pin", layername);
	pt = returninfstr();
	for(i=0; i<mocmos_tech->nodeprotocount; i++)
	{
		nty = mocmos_tech->nodeprotos[i];
		np = nty->creation;
		if (namesame(np->primname, pt) == 0) break;
	}
	if (np != NONODEPROTO)
	{
		nodeprotosizeoffset(np, &lx, &ly, &hx, &hy);
		lambda = el_curlib->lambda[mocmos_tech->techindex];
		np->lowx = -width * lambda / WHOLE / 2 - lx;
		np->highx = width * lambda / WHOLE / 2 + hx;
		np->lowy = -width * lambda / WHOLE / 2 - ly;
		np->highy = width * lambda / WHOLE / 2 + hy;
		npp = &nty->portlist[0];
		npp->lowxsum = (INTSML)(width/2 + lx * WHOLE / lambda);
		npp->lowysum = (INTSML)(width/2 + ly * WHOLE / lambda);
		npp->highxsum = (INTSML)(-width/2 - hx * WHOLE / lambda);
		npp->highysum = (INTSML)(-width/2 - hy * WHOLE / lambda);
	}
}

static struct
{
	INTBIG   indent;
	INTBIG  *offsetbox;
} mocmos_offsetboxes[] =
{
	0,   mocmos_fullbox,
	H0,  mocmos_in0hbox,
	K1,  mocmos_in1box,
	H1,  mocmos_in1hbox,
	K2,  mocmos_in2box,
	H2,  mocmos_in2hbox,
	K3,  mocmos_in3box,
	K4,  mocmos_in4box,
	H4,  mocmos_in4hbox,
	K5,  mocmos_in5box,
	H5,  mocmos_in5hbox,
	K6,  mocmos_in6box,
	H6,  mocmos_in6hbox,
	-1, 0
};

/*
 * Routine to set the surround distance of layer "layer" from the via in node "nodename" to "surround".
 */
void mocmos_setlayersurroundvia(TECH_NODES *nty, INTBIG layer, INTBIG surround)
{
	REGISTER INTBIG i, j, viasize, layersize, indent;

	/* find the via size */
	viasize = nty->f1;
	layersize = viasize + surround*2;
	indent = (nty->xsize - layersize) / 2;
	for(i=0; mocmos_offsetboxes[i].indent >= 0; i++)
		if (mocmos_offsetboxes[i].indent == indent) break;
	if (mocmos_offsetboxes[i].indent < 0)
		ttyputerr("MOSIS CMOS Submicron technology has no box that offsets by %s", frtoa(indent)); else
	{
		for(j=0; j<nty->layercount; j++)
			if (nty->layerlist[j].layernum == layer) break;
		if (j >= nty->layercount) return;
		nty->layerlist[j].points = mocmos_offsetboxes[i].offsetbox;
	}
}

/*
 * Routine to set the surround distance of layer "outerlayer" from layer "innerlayer"
 * in node "nodename" to "surround".
 */
void mocmos_setlayersurroundlayer(TECH_NODES *nty, INTBIG outerlayer, INTBIG innerlayer, INTBIG surround)
{
	REGISTER INTBIG i, j, indent;

	/* find the inner layer */
	for(j=0; j<nty->layercount; j++)
		if (nty->layerlist[j].layernum == innerlayer) break;
	if (j >= nty->layercount) return;
	for(i=0; mocmos_offsetboxes[i].indent >= 0; i++)
		if (mocmos_offsetboxes[i].offsetbox == nty->layerlist[j].points) break;
	if (mocmos_offsetboxes[i].indent < 0)
	{
		ttyputerr("MOSIS CMOS Submicron technology cannot determine indentation of layer %ld on %s",
			innerlayer, nty->creation->primname);
		return;
	}

	indent = mocmos_offsetboxes[i].indent - surround;
	for(i=0; mocmos_offsetboxes[i].indent >= 0; i++)
		if (mocmos_offsetboxes[i].indent == indent) break;
	if (mocmos_offsetboxes[i].indent < 0)
		ttyputerr("MOSIS CMOS Submicron technology has no box that offsets by %s", frtoa(indent)); else
	{
		for(j=0; j<nty->layercount; j++)
			if (nty->layerlist[j].layernum == outerlayer) break;
		if (j >= nty->layercount) return;
		nty->layerlist[j].points = mocmos_offsetboxes[i].offsetbox;
	}
}

/*
 * Routine to set the true node size (the highlighted area) of node "nodename" to "wid" x "hei".
 */
void mocmos_setdefnodesize(TECH_NODES *nty, INTBIG index, INTBIG wid, INTBIG hei)
{
	REGISTER INTBIG xindent, yindent;
	REGISTER VARIABLE *var;

	xindent = (nty->xsize - wid) / 2;
	yindent = (nty->ysize - hei) / 2;

	var = getval((INTBIG)mocmos_tech, VTECHNOLOGY, VFRACT|VISARRAY, "TECH_node_width_offset");
	if (var != NOVARIABLE)
	{
		((INTBIG *)var->addr)[index*4] = xindent;
		((INTBIG *)var->addr)[index*4+1] = xindent;
		((INTBIG *)var->addr)[index*4+2] = yindent;
		((INTBIG *)var->addr)[index*4+3] = yindent;
	}
}

#endif  /* TECMOCMOS - at top */
