static char *SccsId = "@(#)proc_mc.c 4.5 (TU-Delft) 12/10/91";
/**********************************************************

Name/Version      : cldm/4.5

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : J. Annevelink
Creation date     : 18-May-1983
Modified by       : S. de Graaf, Paul Stravers [ps]
Modification date : 06-Apr-1987
Modification date : 22-Apr-1988
Modification date : 20-May-1988
Modification date : 10-Dec-1991 (4.5)
Modification date : 22-Mar-1993 [ps]


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1987-1988, All rights reserved
**********************************************************/
#include "extern.h"

proc_mc (inst, mir, rot)
int     inst,
        mir,
        rot;
{
    IMPCELL * ic;
    DM_PROJECT * proj;
    DM_CELL * mc_key;
    DM_STREAM * fp_mc_info;
    long    b_xl,
            b_xr,
            b_yb,
            b_yt,
            tmp;
    register long   a,
                    b,
                    c,
                    d;

    if (!check_tree (mc_name, mod_tree)) {
	pr_exit (014, 10, mc_name);/* not found */
	return;
    }
    if (tree_ptr -> errflag == 1) {
	pr_exit (014, 52, mc_name);/* model def. error */
	return;
    }

    ic = tree_ptr -> impcell;

    if (tree_ptr -> bbox) {
	b_xl = tree_ptr -> bbox -> xl;
	b_xr = tree_ptr -> bbox -> xr;
	b_yb = tree_ptr -> bbox -> yb;
	b_yt = tree_ptr -> bbox -> yt;
    }
    else {
	if (ic) {
	    proj = dmOpenProject (ic -> dmpath, PROJ_READ);
	    mc_key = dmCheckOut (proj, ic -> cellname,
		    ACTUAL, DONTCARE, LAYOUT, READONLY);
	}
	else {
	    mc_key = dmCheckOut (dmproject, mc_name,
		    ACTUAL, DONTCARE, LAYOUT, READONLY);
	}

	fp_mc_info = dmOpenStream (mc_key, "info", "r");

	if (dmGetDesignData (fp_mc_info, GEO_INFO) <= 0)
	    pr_exit (0137, 28, mc_name);

	ALLOC (tree_ptr -> bbox, mod_bbox);
	tree_ptr -> bbox -> xl = b_xl = ginfo.bxl;
	tree_ptr -> bbox -> xr = b_xr = ginfo.bxr;
	tree_ptr -> bbox -> yb = b_yb = ginfo.byb;
	tree_ptr -> bbox -> yt = b_yt = ginfo.byt;

	dmCloseStream (fp_mc_info, COMPLETE);
	dmCheckIn (mc_key, COMPLETE);
    }

    if (ic) {
	gmc.imported = IMPORTED;
    }
    else {
	gmc.imported = LOCAL;
    }

    if (!inst)
	strcpy (instance, ".");

    a = b = c = d = 0;

    switch (rot) {		/* rotate (degrees) */
	case 0: 
	    ++a;
	    ++d;
	    break;
	case 90: 
	    --b;
	    ++c;
	    break;
	case 180: 
	    --a;
	    --d;
	    break;
	case 270: 
	    ++b;
	    --c;
	    break;
    }

    switch (mir) {		/* mirror */
	case 1: 
	    b = -b;
	    d = -d;
	    break;
	case 2: 
	    a = -a;
	    c = -c;
	    break;
    }

    if (sfx > 1) { b_xl *= sfx; b_xr *= sfx; }
    if (sfy > 1) { b_yb *= sfy; b_yt *= sfy; }

    tmp = b_xl;
    b_xl = a * tmp + b * b_yb;
    b_yb = c * tmp + d * b_yb;
    tmp = b_xr;
    b_xr = a * tmp + b * b_yt;
    b_yt = c * tmp + d * b_yt;
    if (b_xl > b_xr) {
	tmp = b_xl;
	b_xl = b_xr;
	b_xr = tmp;
    }
    if (b_yb > b_yt) {
	tmp = b_yb;
	b_yb = b_yt;
	b_yt = tmp;
    }

 /* translate and copy r_box */
 /* this version normally uses a modified modelcall def */

    if (o_mode == 0) {
	tx -= b_xl;
	ty -= b_yb;
    }

    b_xl += tx + (dx < 0 ? (dx * nx) : 0);
    b_xr += tx + (dx > 0 ? (dx * nx) : 0);
    b_yb += ty + (dy < 0 ? (dy * ny) : 0);
    b_yt += ty + (dy > 0 ? (dy * ny) : 0);

    strcpy (gmc.cell_name, mc_name);
    strcpy (gmc.inst_name, instance);

    gmc.mtx[0] = sfx * a;
    gmc.mtx[1] = sfy * b;
    gmc.mtx[2] = tx;
    gmc.mtx[3] = sfx * c;
    gmc.mtx[4] = sfy * d;
    gmc.mtx[5] = ty;
    gmc.bxl = b_xl;
    gmc.bxr = b_xr;
    gmc.byb = b_yb;
    gmc.byt = b_yt;
    gmc.dx = dx;
    gmc.nx = nx;
    gmc.dy = dy;
    gmc.ny = ny;

    dmPutDesignData (fp_mc, GEO_MC);

    if (ini_mcbbox) {		/* update modelcall bounding box */
	ini_mcbbox = 0;
	mcbb_xl = b_xl;
	mcbb_xr = b_xr;
	mcbb_yb = b_yb;
	mcbb_yt = b_yt;
	/* additional sea-of-gates hack: bbx of all MC's except the IMAGE [ps]
	 */
	if ( strcmp(instance,"IMAGE") != 0)
	{
	   mcNoImage_xl = b_xl;
	   mcNoImage_xr = b_xr;
	   mcNoImage_yb = b_yb;
	   mcNoImage_yt = b_yt;
	}
    }
    else {
	if (mcbb_xl > b_xl) mcbb_xl = b_xl;
	if (mcbb_xr < b_xr) mcbb_xr = b_xr;
	if (mcbb_yb > b_yb) mcbb_yb = b_yb;
	if (mcbb_yt < b_yt) mcbb_yt = b_yt;
	if ( strcmp(instance,"IMAGE") != 0)
	{
	   if (mcNoImage_xl > b_xl) mcNoImage_xl = b_xl;
	   if (mcNoImage_xr < b_xr) mcNoImage_xr = b_xr;
	   if (mcNoImage_yb > b_yb) mcNoImage_yb = b_yb;
	   if (mcNoImage_yt < b_yt) mcNoImage_yt = b_yt;
	}
    }
}

proc_cif_mc (inst, x0, x1, x2, y0, y1, y2)
int     inst,
        x0,
        x1,
        x2,
        y0,
        y1,
        y2;
{
    IMPCELL * ic;
    DM_PROJECT * proj;
    DM_CELL * mc_key;
    DM_STREAM * fp_mc_info;
    long    b_xl,
            b_xr,
            b_yb,
            b_yt,
            tmp;
    long    a,
            b,
            c,
            d;

    a = x0;
    b = y0;
    c = x1;
    d = y1;
    tx = x2;
    ty = y2;

    if (!check_tree (mc_name, mod_tree)) {
	pr_exit (014, 10, mc_name);/* not found */
	return;
    }
    if (tree_ptr -> errflag == 1) {
	pr_exit (014, 52, mc_name);/* model def. error */
	return;
    }

    ic = tree_ptr -> impcell;

    if (tree_ptr -> bbox) {
	b_xl = tree_ptr -> bbox -> xl;
	b_xr = tree_ptr -> bbox -> xr;
	b_yb = tree_ptr -> bbox -> yb;
	b_yt = tree_ptr -> bbox -> yt;
    }
    else {
	if (ic) {
	    proj = dmOpenProject (ic -> dmpath, PROJ_READ);
	    mc_key = dmCheckOut (proj, ic -> cellname,
		    ACTUAL, DONTCARE, LAYOUT, READONLY);
	}
	else {
	    mc_key = dmCheckOut (dmproject, mc_name,
		    ACTUAL, DONTCARE, LAYOUT, READONLY);
	}

	fp_mc_info = dmOpenStream (mc_key, "info", "r");

	if (dmGetDesignData (fp_mc_info, GEO_INFO) <= 0)
	    pr_exit (0137, 28, mc_name);

	ALLOC (tree_ptr -> bbox, mod_bbox);
	tree_ptr -> bbox -> xl = b_xl = ginfo.bxl;
	tree_ptr -> bbox -> xr = b_xr = ginfo.bxr;
	tree_ptr -> bbox -> yb = b_yb = ginfo.byb;
	tree_ptr -> bbox -> yt = b_yt = ginfo.byt;

	dmCloseStream (fp_mc_info, COMPLETE);
	dmCheckIn (mc_key, COMPLETE);
    }

    if (ic) {
	gmc.imported = IMPORTED;
    }
    else {
	gmc.imported = LOCAL;
    }

    if (!inst)
	strcpy (instance, ".");

    tmp = b_xl;
    b_xl = a * tmp + b * b_yb;
    b_yb = c * tmp + d * b_yb;
    tmp = b_xr;
    b_xr = a * tmp + b * b_yt;
    b_yt = c * tmp + d * b_yt;
    if (b_xl > b_xr) {
	tmp = b_xl;
	b_xl = b_xr;
	b_xr = tmp;
    }
    if (b_yb > b_yt) {
	tmp = b_yb;
	b_yb = b_yt;
	b_yt = tmp;
    }

 /* translate and copy r_box */
 /* this version normally uses a modified modelcall def */

    if (o_mode != 0) { /* inverse of ldm */
	tx -= b_xl;
	ty -= b_yb;
    }

    b_xl += tx + (dx < 0 ? (dx * nx) : 0);
    b_xr += tx + (dx > 0 ? (dx * nx) : 0);
    b_yb += ty + (dy < 0 ? (dy * ny) : 0);
    b_yt += ty + (dy > 0 ? (dy * ny) : 0);

    strcpy (gmc.cell_name, mc_name);
    strcpy (gmc.inst_name, instance);

    gmc.mtx[0] = a;
    gmc.mtx[1] = b;
    gmc.mtx[2] = tx;
    gmc.mtx[3] = c;
    gmc.mtx[4] = d;
    gmc.mtx[5] = ty;
    gmc.bxl = b_xl;
    gmc.bxr = b_xr;
    gmc.byb = b_yb;
    gmc.byt = b_yt;
    gmc.dx = dx;
    gmc.nx = nx;
    gmc.dy = dy;
    gmc.ny = ny;

    dmPutDesignData (fp_mc, GEO_MC);

    if (ini_mcbbox) {		/* update modelcall bounding box */
	ini_mcbbox = 0;
	mcbb_xl = b_xl;
	mcbb_xr = b_xr;
	mcbb_yb = b_yb;
	mcbb_yt = b_yt;
	/* additional sea-of-gates hack: bbx of all MC's except the IMAGE [ps]
	 */
	if ( strcmp(instance,"IMAGE") != 0)
	{
	   mcNoImage_xl = b_xl;
	   mcNoImage_xr = b_xr;
	   mcNoImage_yb = b_yb;
	   mcNoImage_yt = b_yt;
	}
    }
    else {
	if (mcbb_xl > b_xl) mcbb_xl = b_xl;
	if (mcbb_xr < b_xr) mcbb_xr = b_xr;
	if (mcbb_yb > b_yb) mcbb_yb = b_yb;
	if (mcbb_yt < b_yt) mcbb_yt = b_yt;
	if ( strcmp(instance,"IMAGE") != 0)
	{
	   if (mcNoImage_xl > b_xl) mcNoImage_xl = b_xl;
	   if (mcNoImage_xr < b_xr) mcNoImage_xr = b_xr;
	   if (mcNoImage_yb > b_yb) mcNoImage_yb = b_yb;
	   if (mcNoImage_yt < b_yt) mcNoImage_yt = b_yt;
	}
    }
}
