
/* "WOL", an integrated circuit layout tool,
   Copyright (C) 1983, 1990 California Institute of Technology.
   Author: Massimo Sivilotti
   Thanks to: Glenn Gribble, Marty Sirkin, Sylvie Rychebusch
	      Maryann Mayer, Carver Mead, Rick Koshi, Torre Lande
   Maintainer: John Lazzaro
   Maintainers's address: lazzaro@hobiecat.cs.caltech.edu;
                          CB 425/ CU Boulder/Boulder CO 91125. 
			  Send questions, bug fixes, to this address.

This program 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 (Version 1, 1989).

This program 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 this program; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* Output from p2c, the Pascal-to-C translator */
/* p2c: wolopt.text, line 9: Note: Range checking is OFF [216] */
/* p2c: wolopt.text, line 10: Note: Stack checking is OFF [217] */
/* p2c: wolopt.text, line 16: Note: Range checking is ON [216] */
/* From input file "ext_defs.text" */


/* Change these for testing */


/* Definitions for an extract program */

#include "global.h"


#define EXT_DEFS_G
#include "ext_defs.h"


const layer_namet layer_names = {   /***/
  "poly", "diff", "metal", "well", "cutp", "cuta", "glass", "metal2",
  "select", "via", "poly2", "cut2", "l_d", "l_ds", "l_dw", "l_dsw", "l_dp",
  "l_dp2", "l_dps", "l_dpw", "l_dpsw", "l_dp2s", "l_dp2w", "l_dp2sw",
  "l_dpp2", "l_dpp2s", "l_dpp2w", "l_dpp2sw"
};


/*extern void asm_newbytes_(void **p, long z);*/


void ext_init_mem(void)
{
  /* Call this only once!! */
  ext_marker = NULL;
  core_box_kind = core_add(sizeof(box_rec), "boxes");
  core_con_kind = core_add(sizeof(hcon_rec), "conns");
  if (core_box_kind < 0 || core_con_kind < 0) {
    printf("\007ext_defs: init_mem: core_add failed\n");
    /* Re-compile with more core kinds */
    _Escape(-1);
  }
  binx = -1;
  biny = -1;
  binwidth = -1;
  binheight = -1;
}


void xtr_free_mem(void)
{
  if (ext_marker == NULL)
    return;
  core_release((core_rec **)(&ext_marker));
  ext_marker = NULL;
  nodenumbers = NULL;
  ptran = NULL;
  ntran = NULL;
  ptran2 = NULL;   /***/
  ntran2 = NULL;   /***/
  binx = -1;
  biny = -1;
  binwidth = -1;
  binheight = -1;
}


void re_init_mem(void)
{

    int si;

  core_mark((core_rec **)(&ext_marker));
  asm_newbytes((void **)(&nodenumbers), sizeof(nodenumtype));
  asm_newbytes((void **)(&ptran), sizeof(tran_arr));
  memset(ptran, 0, sizeof(tran_arr));
  asm_newbytes((void **)(&ntran), sizeof(tran_arr));
  memset(ntran, 0, sizeof(tran_arr));
  asm_newbytes((void **)(&ptran2), sizeof(tran_arr));
  memset(ptran2, 0, sizeof(tran_arr));   /***/
  asm_newbytes((void **)(&ntran2), sizeof(tran_arr));
  memset(ntran2, 0, sizeof(tran_arr));   /***/

  /*for i:=min_node to max_node do nodenumbers^[i] := -1;*/
  na_fillword((long *)nodenumbers, -1, max_node - min_node + 1);

  nodenum = min_node;
  maxnode = min_node;
  lastmax = min_node + node_thresh;

  /* Add VDD and GROUND */
  nodenumbers[GROUND - min_node] = GROUND;
  nodenumbers[VDD - min_node] = VDD;

  boxes_added = 0;
  boxes_checked = 0;
  boxes_clipped = 0;
  edges_clipped = 0;
  boxes_swallow = 0;
  strcpy(src_name, "(wol-interactive)");

  xtrtime = 0;
  trantime = 0;
  woltoxtrtime = 0;

  if (binx <= 0 || biny <= 0 || binwidth <= 0 || binheight <= 0) {
    printf("\007Danger!  Danger!  Will Robinson, bin sizes screwed up.\n");
    _Escape(10);
  }

  printf("Re_init_mem:       Memory left = %ld\n", asm_memavail());
  si = 2 * binx * biny * sizeof(bin_rec);
  printf(" Creating %d bytes memory-block for bins\n", si);
  asm_newbytes((void **)(&bins), si);
  printf("  Bins allocated.  Memory left = %ld\n", asm_memavail());
  memset(bins, 0, si);
  binmax = binx * biny - 1;
  /*$if false$
   for i:=0 to binmax do with bins^[i] do
      for j:=min_layer to max_layer do
         layers[j].boxes := NIL;
$end$*/
}


long nextnodenum(void)
{
  long Result, tmp;

  while ((nodenum <= max_node)&&(nodenumbers[nodenum - min_node] != -1))
     nodenum++;   /*write(#141's'#136);*/
  if (nodenum > max_node)
    printf("Nodelist corruption, %i\n", nodenumbers[nodenum - min_node]);
  nodenumbers[nodenum - min_node] = nodenum;
  Result = nodenum;
  if (maxnode >= nodenum)
    return Result;
  maxnode = nodenum;
  if (maxnode <= lastmax)
    return Result;
  tmp = nodenum;
  mashnodes();
  nodenumbers[tmp - min_node] = tmp;   /* Restore node information */
  return Result;
}


void freenodenum(long node_)
{
  nodenumbers[node_ - min_node] = -1;
  if (node_ < nodenum)
    nodenum = node_;
}


box_rec *new_box()
{
     box_rec *b;
     b = (box_rec *)malloc(sizeof(box_rec));
     b->next = NULL;
     return b;

}


hcon_rec *new_hcon()
{
     hcon_rec *h;
     h = (hcon_rec *)malloc(sizeof(hcon_rec));
     h->next = NULL;   /* just to make sure -- MAS */
     return h;

}


vcon_rec *new_vcon()
{
     vcon_rec *v;

     v = (vcon_rec *)malloc(sizeof(vcon_rec));
     v->next = NULL;
     return v;

}


void equiv(long n1, long n2)
{
  long a1, a2;

  /*   if global_debug then
        writeln('equiv(',n1:1,',',n2:1,');');  */
  a1 = nodenumbers[n1 - min_node];
  a2 = nodenumbers[n2 - min_node];
  while (a1 != a2) {
    if (a2 < a1) {
      nodenumbers[n1 - min_node] = a2;
      n1 = a1;
      a1 = nodenumbers[a1 - min_node];
    } else {
      nodenumbers[n2 - min_node] = a1;
      n2 = a2;
      a2 = nodenumbers[a2 - min_node];
    }
  }
}


void equivforce(void)
{
  long n, t;

  n = min_node;
  while (n <= maxnode) {
    t = nodenumbers[n - min_node];
    if (t >= min_node)
      nodenumbers[n - min_node] = nodenumbers[t - min_node];
    n++;
  }
}


void mashnodes(void)
{
  long b, l, n, freed;
  box_rec *bp;
  hcon_rec *hp;
  vcon_rec *vp;
  boolean used[max_node - min_node + 1];
  long FORLIM;
  layer_rec *WITH;

  equivforce();
  if (xtr_debug)
    return;
  FORLIM = maxnode;
  for (b = min_node; b <= FORLIM; b++)
    used[b - min_node] = false;
  used[GROUND - min_node] = true;
  used[VDD - min_node] = true;

  FORLIM = binmax;
  for (b = 0; b <= FORLIM; b++) {
    for (l = min_layer; l <= max_layer; l++) {
      WITH = &bins[b].layers[l - min_layer];
      bp = WITH->boxes;
      while (bp != NULL) {
	n = nodenumbers[bp->node_ - min_node];
	used[n - min_node] = true;
	bp->node_ = n;
	bp = bp->next;
      }
      hp = WITH->south;
      while (hp != NULL) {
	n = nodenumbers[hp->node_ - min_node];
	used[n - min_node] = true;
	hp->node_ = n;
	hp = hp->next;
      }
      vp = WITH->west;
      while (vp != NULL) {
	n = nodenumbers[vp->node_ - min_node];
	used[n - min_node] = true;
	vp->node_ = n;
	vp = vp->next;
      }
    }
  }
  freed = 0;
  for (b = maxnode; b >= min_node; b--) {
    if (!used[b - min_node]) {
      nodenumbers[b - min_node] = -1;
      nodenum = b;
      freed++;
    }
  }
  lastmax = maxnode + node_thresh;
  /*writeln(freed:1,' free nodes out of ',maxnode:1,' allocated, min=',nodenum:1);*/
}


/* module ext_defs */




/* End. */
