

#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/lists.h"
#include "exec/ports.h"
#include "exec/libraries.h"
#include "exec/devices.h"
#include "exec/io.h"
#include "devices/serial.h"
#include "lattice/stdio.h"

struct IOExtSer *IORser;
struct MsgPort *port;
char buffer[200];
extern struct MsgPort *CreatePort();
extern struct IORequest *CreateExtIO();
UBYTE *bdtop,*fatrec;              /* pointer to layer information */
int random,rdmuse,xcfac,ycfac,res,shearing,camrdy,tofile;
int xcept1,xcept2,xcept3,xcept4;
int fillmem[4];
UBYTE xname[20],bdname[80],fname[80],tname[80],choice[20],outfile[80];
UBYTE plotype;
FILE *outfp;

main()
   {
   int error;
   unsigned long rbl,brk,baud,rwl,wwl,sf,t0,t1;

      printf("\033[42m\033[33m                                  \033[0m\n");
      printf("\033[42m\033[33m \033[41m SoftCircuits, Inc -- PLOT v1.3 \033[42m \033[0m\n");
      printf("\033[42m\033[33m                                  \033[0m\n");

      xcfac=0;
      ycfac=0;
      random=1;
      res=0;
      xcept1=99;
      xcept2=99;
      xcept3=99;
      xcept4=99;

retry:
      printf("\nEnter board name: ");
      gets(&fname[0]);
      if (strlen(&fname[0]) == 0)
         {
            printf("Illegal filename\n");
            exit(10);
         }

      printf("\nSelect plot Options; Enter a numeral\n");
      printf("         [ 0 ]   Plot TOP layer\n");
      printf("         [ 1 ]   Plot BOTTOM layer\n");
      printf("         [ 2 ]   Plot PADs only\n");
      printf("         [ 3 ]   Plot TOP layer -- NO PADS\n");
      printf("         [ 4 ]   Plot BOTTOM layer -- NO PADS\n");
      printf("         [ 5 ]   Plot SILKSCREEN only\n");
      printf("Select; ");
      gets(&choice[0]);

      switch(choice[0])
         {
            case '0':
               {
                  strcpy(&xname[0],".layer1");
                  break;
               }
            case '1':
               {
                  strcpy(&xname[0],".layer2");
                  break;
               }
            case '2':
               {
                  strcpy(&xname[0],".layer1");
                  break;
               }
            case '3':
               {
                  strcpy(&xname[0],".layer1");
                  break;
               }
            case '4':
               {
                  strcpy(&xname[0],".layer2");
                  break;
               }
            case '5':
               {
                  strcpy(&xname[0],".silk");
                  break;
               }
            default:
               {
                  printf("Illegal choice\n");
                  exit(20);
               }
         }

      plotype=choice[0];
      shearing=0;
      if (plotype == '5') goto skipshear;

      printf("\nPlot shear lines?\n");
      printf("(Y or N): ");
      gets(&choice[0]);
      switch(choice[0])
         {
            case 'y':
            case 'Y':
               {
                  shearing=1;
                  break;
               }
            case 'n':
            case 'N':
               {
                  shearing=0;
                  break;
               }
            default:
               {
                  printf("Illegal choice\n");
                  exit(20);
               }
         }

skipshear:

      printf("\nSelect plot quality\n");
      printf("        [ 0 ]    Camera ready\n");
      printf("        [ 1 ]    Check plot\n");
      printf("Select: ");
      gets(&choice[0]);
      switch(choice[0])
         {
            case '0':
               {
                  camrdy='1';
                  break;
               }
            case '1':
               {
                  camrdy='0';
                  break;
               }
            default:
               {
                  printf("Illegal choice\n");
                  exit(20);
               }
         }

      res=2;
      if (camrdy == '1') goto nolores;

      printf("\nSelect plot size option:\n");
      printf("        [ 2 ]    2:1 plotting\n");
      printf("        [ 1 ]    1:1 plotting\n");
      printf("Select: ");
      gets(&choice[0]);

      switch(choice[0])
         {
            case '1':
               {
                  res=1;
                  break;
               }
            case '2':
               {
                  res=2;
                  break;
               }
            default:
               {
                  printf("Illegal choice\n");
                  exit(20);
               }
         }

nolores:

      printf("Select output target:\n");
      printf("        [ 0 ]    Output to Plotter\n");
      printf("        [ 1 ]    Output to File\n");
      printf("Select: ");
      gets(&choice[0]);
      switch(choice[0])
         {
            case '0':
               {
                  tofile=0;
                  break;
               }
            case '1':
               {
                  tofile=1;
                  printf("Enter file name: ");
                  gets(&outfile[0]);
                  break;
               }
            default:
               {
                  printf("Illegal choice;\n");
                  exit(20);
               }
         }

      printf("\nconfiguration is as follows -- is this correct?\n\n");
      printf("File to plot = '\033[1m\033[33m%s\033[0m'\n",&fname[0]);
      printf("Shear lines  = \033[1m\033[33m");
      if (shearing == 0)
         {
            printf(" not");
         }
      printf(" plotted\033[0m\n");
      printf("Resolved at  =  \033[1m\033[33m");
      switch(res)
         {
            case 1:
               {
                  printf("1:1\n");
                  break;
               }
            case 2:
               {
                  printf("2:1\n");
                  break;
               }
         }
      printf("\033[0mQuality      =  \033[1m\033[33m");
      switch(camrdy)
         {
            case '0':
               {
                  printf("Check plot\n");
                  break;
               }
            case '1':
               {
                  printf("Camera ready\n");
                  break;
               }
         }


      printf("\033[0mItem to plot =  \033[1m\033[33m");
      switch(plotype)
         {
            case '0':
               {
                  printf("the TOP layer.\n");
                  break;
               }
            case '1':
               {
                  printf("the BOTTOM layer.\n");
                  break;
               }
            case '2':
               {
                  printf("the PADs only. (No trace information)\n");
                  break;
               }
            case '3':
               {
                  printf("the TOP layer; NO PADS\n");
                  break;
               }
            case '4':
               {
                  printf("the BOTTOM layer; NO PADS\n");
                  break;
               }
            case '5':
               {
                  printf("the SILKSCREEN\n");
               }
         }

      printf("\033[0mPlot output  =  \033[1m\033[33m");
      switch(tofile)
         {
            case 0:
               {
                  printf("the Plotter\n");
                  break;
               }
            case 1:
               {
                  printf("the file: \033[0m'\033[1m\033[33m");
                  printf(&outfile[0]);
                  printf("\033[0m'\n");
                  break;
               }
         }

what:
      printf("\033[0m\nEnter 'Y' or 'N': ");
      gets(&choice[0]);
      switch(choice[0])
         {
            case 'y':
            case 'Y':
               {
                  break;
               }
            case 'n':
            case 'N':
               {
                  goto retry;
               }
            default:
               {
                  goto what;
               }
         }

      if ((bdtop=(UBYTE*)calloc(65536,1))==NULL)
         {
            printf("layer memory allocation failed -- Not Enough Memory");
            exit(0);
         }
      if ((fatrec=(UBYTE*)calloc(65536,1))==NULL)
         {
            printf("working memory allocation failed -- Not Enough Memory");
            exit(20);
         }

      if (tofile==1) goto skipserial;

      port = CreatePort(SERIALNAME,0);
      if (port == NULL)
         {
            printf("\nProblems during CreatePort\n");
            exit(100);
         }
      IORser = (struct IOExtSer*)CreateExtIO(port,sizeof(struct IOExtSer));
      if (IORser == NULL)
         {
            printf("Problems during CreateExtIO\n");
            goto cleanup1;
         }
open:
      if ((error=OpenDevice(SERIALNAME,0,IORser,0)) != 0)
         {
            printf("Serial device did not open\n");
            goto cleanup1;
         }
      rbl=4096;
      rwl=0x08;
      wwl=0x08;
      brk=75000;
      baud=9600;
      sf=0x00;
      t0=0x51040303;
      t1=0x03030303;

      if ((error=SetParams(IORser,rbl,rwl,wwl,brk,baud,sf,t0,t1)) != 0)
         {
            printf("SetParams returned an error\n");
            goto cleanup2;
         }

skipserial:
      if (tofile==1)
         {
            if (outfp=fopen(&outfile[0],"w"))
               {
                  printf("Plot output file opened successfully\n");
               }
            else
               {
                  printf("file open failed on plot write!\n");
                  exit(20);
               }
         }
      if (loadbd()==0)
         {
            goto cleanup2;
         }
      if (plotype != '5')
         {
            printf("Processing requested file; --Stand by--\n");
            flipfn();
            justfn();
         }

      if (tofile==0)
         {
            printf("Output to plotter beginning now\n");
         }
      else
         {
            printf("Output to file beginning now\n");
         }
      if (plotype != '5')
         {
            plotfn();
         }
      else
         {
            silkfn();
         }
      printf("Output stream completed\n");

cleanup2:
      if (tofile==0) CloseDevice(IORser);
cleanup1:
      if (tofile==0) DeletePort(port);
      if (tofile==1) fclose(outfp);
      exit(0);
   }

flipfn()
   {
   int xpos,ypos,ypod;
   UBYTE temp;
      for (xpos=0; xpos<256; xpos++)
         {
            ypod=255;
            for (ypos=0; ypos<128; ypos++)
               {
                  temp=(UBYTE)vtxlate(bdtop[xpos+(ypos*256)]);
                  bdtop[xpos+(256*ypos)]=(UBYTE)vtxlate(bdtop[xpos+(256*ypod)]);
                  bdtop[xpos+(256*ypod)]=(UBYTE)temp;
                  ypod--;
               }
         }
   }

justfn()
   {
   int limits,xlow,ylow;
      limits=vcheck(bdtop);
      xlow =(limits >> 24) & 255;
      ylow =(limits >>  8) & 255;
      txmove(xlow);
      tymove(ylow);
   }

txmove(xlow)
   int xlow;
   {
   int xsrc,xdst,ypos;
      for (ypos=0; ypos<256; ypos++)
         {
            xdst=0;
            xsrc=xlow;
            while(xsrc < 256)
               {
                  bdtop[xdst+(ypos*256)]=bdtop[xsrc+(256*ypos)];
                  xsrc++;
                  xdst++;
               }
            while(xdst < 256)
               {
                  bdtop[xdst+(256+ypos)]=0;
                  xdst++;
               }
         }
   }

tymove(ylow)
   int ylow;
   {
   int xpos,ydst,ysrc;
      for (xpos=0; xpos<256; xpos++)
         {
            ysrc=ylow;
            ydst=0;
            while(ysrc < 256)
               {
                  bdtop[xpos+(256*ydst)]=bdtop[xpos+(256*ysrc)];
                  ysrc++;
                  ydst++;
               }
            while(ydst < 256)
               {
                  bdtop[xpos+(256*ydst)]=0;
                  ydst++;
               }
         }
   }

churfn(xpos,ypos,data)
   int xpos,ypos,data;
   {
   UBYTE tbuff[80];
   int tmp;
      if (xpos < 0)
         {
            return(0);
         }
      if (ypos < 0)
         {
            return(0);
         }
      if (data == 0)
         {
            return(0);
         }
      if (data > 31)
         {
            xcfac=0;
            ycfac=0;
            move(xpos,ypos);
            strcpy(&tbuff[0],"S11 ");
            tmp=strlen(&tbuff[0]);
            tbuff[tmp]=(UBYTE)data;
            tbuff[tmp+1]=(UBYTE)'_';
            tbuff[tmp+2]=(UBYTE)' ';
            tbuff[tmp+3]=0;
            spurt(&tbuff[0]);
            return(0);
         }
      linedraw(xpos,ypos,data);
   }

linedraw(xpos,ypos,data)
   int xpos,ypos,data;
   {
      xcfac=0;
      ycfac=0;
      spurt("U A ");
      move(xpos,ypos);
      switch(data)
         {
            case 26: /* vert line  */
               {
                  spurt("R 0,-10 D 0,20 U A ");
                  break;
               }
            case 27: /* horz line */
               {
                  spurt("R -10,0 D 20,0 U A ");
                  break;
               }
            case 28: /* bot left */
               {
                  spurt("R 0,10 D 0,-10 10,0 U A "); /*tl*/
                  break;
               }
            case 29: /* bot right */
               {
                  spurt("R -10,0 D 10,0 0,10 U A "); /*tr*/
                  break;
               }
            case 30: /* top left */
               {
                  spurt("R 0,-10 D 0,10 10,0 U A "); /*bl*/
                  break;
               }
            case 31: /* top right */
               {
                  spurt("R 0,-10 D 0,10 -10,0 U A"); /*br*/
                  break;
               }
         }
   }

fxmin()
   {
   int xpos,ypos;
      for (xpos=0; xpos<256; xpos++)
         {
            for (ypos=0; ypos<256; ypos++)
               {
                  if (chread(xpos,ypos,bdtop) != 0)
                     {
                        return(xpos);
                     }
               }
         }
      return(-1);
   }

fymax()
   {
   int xpos,ypos;
      for (ypos=255; ypos>=0; ypos--)
         {
            for (xpos=0; xpos<256; xpos++)
               {
                  if (chread(xpos,ypos,bdtop) != 0)
                     {
                        return(ypos);
                     }
               }
         }
      return(-1);
   }

silkfn()
   {
   int xpos,ypos,ymax,xmin;
      ymax=fymax();
      xmin=fxmin();
      if (xmin == -1)
         {
            printf("No Silkscreen data found\n");
            return(0);
         }
      if (ymax == -1)
         {
            printf("No Silkscreen data found\n");
            return(0);
         }
      spurt(";:");
      if (res==1)
         {
            spurt("ECx "); /* 1:1 plot... (IOLINE type plotter only) */
         }
      else
         {
            spurt("EC5 "); /* 2:1 plot... */
         }
      spurt("V8 A 100,100 S12 SoftCircuits, Inc --- Plot of: ");
      spurt(&fname[0]);
      spurt(&xname[0]);
      spurt("_ U");
      for (xpos=0; xpos<256; xpos++)
         {
            for (ypos=0; ypos<256; ypos++)
               {
                  churfn(xpos-xmin,ypos-(255-ymax),chread(xpos,(255-ypos),bdtop));
               }
         }
   }

plotfn()
   {
      spurt(";:");
      if (res==1)
         {
            spurt("ECx "); /* 1:1 plot... */
         }
      else
         {
            spurt("EC5 "); /* 2:1 plot... */
         }
      spurt("V8 A 100,100 S12 SoftCircuits, Inc --- Plot of: ");
      spurt(&fname[0]);
      spurt(&xname[0]);
      spurt("_ U");
      if (shearing == 1)
         {
            doshear();
         }
      if (plotype < '3')
         {
            doholes();
         }
      if (plotype != '2')
         {
            dostrat();
            doang();
            dotease();
            dofat();
            dosinglefat();
            dofill();
            dotrimpads();
         }
   }

dosinglefat()
   {
   int xpos,ypos;
      spurt("V3 ");
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  if (bdtop[(256*ypos)+xpos] == 1)
                     {
                        if (fatrec[(256*ypos)+xpos] == 0)
                           {
                              fatrec[(256*ypos)+xpos] = 1;
                              doafat(xpos,ypos);
                           }
                     }
               }
         }
   }

dotease()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  tdraw(xpos,ypos,bdtop[(ypos*256)+xpos]);
               }
         }
   }

tdraw(xpos,ypos,data)
   int xpos,ypos,data;
   {
      if ( (data < 10) || (data > 13) )
         {
            return(0);
         }
      xcfac=0;
      ycfac=0;
      move(xpos,ypos);
      if (data == 10) /* top t */
         {
            spurt("R D 0,-9 A U ");
         }
      if (data == 11) /* bot t */
         {
            spurt("R D 0,9 A U ");
         }
      if (data == 12) /* left t */
         {
            spurt("R D -9,0 A U ");
         }
      if (data == 13) /* rite t */
         {
            spurt("R D 9,0 A U ");
         }
   }

doang()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  angpuke(xpos,ypos,bdtop[(ypos*256)+xpos]);
               }
         }
   }

angpuke(xpos,ypos,data)
   int xpos,ypos,data;
   {
      if (data > 5)
         {
            if (data < 10)
               {
                  angpump(xpos,ypos,data);
                  return(0);
               }
         }
      if (data == 2) /* dual: te/bw */
         {
            angpump(xpos,ypos,9);
            angpump(xpos,ypos,8);
            return(0);
         }
      if (data == 3) /* dual: tw/be */
         {
            angpump(xpos,ypos,6);
            angpump(xpos,ypos,7);
            return(0);
         }
   }

rdrd(xpos,ypos)
   int xpos,ypos;
   {
      if (xpos < 0) return(0);
      if (ypos < 0) return(0);
      if (xpos > 255) return(0);
      if (ypos > 255) return(0);
      return((int)bdtop[xpos+(ypos*256)]);
   }

angpump(xpos,ypos,data)
   int xpos,ypos,data;
   {
      xcfac=0;
      ycfac=-10;
      spurt("U ");
      move(xpos,ypos);
      spurt("R ");
      ycfac=0;
      switch(data)
         {
            case 6: /* NW */
               {
                  if (rdrd(xpos,ypos-1) == 1)
                     {
                        spurt("D 0,-3 0,3 ");
                     }
                  spurt("D -10,10 ");
                  if (rdrd(xpos-1,ypos) == 1)
                     {
                        spurt("-3,0 ");
                     }
                  break;
               }
            case 7: /* SE */
               {
                  spurt("10,10 D ");
                  if (rdrd(xpos+1,ypos) == 1)
                     {
                        spurt("3,0 -3,0 ");
                     }
                  spurt("-10,10 ");
                  if (rdrd(xpos,ypos+1) == 1)
                     {
                        spurt("0,3 ");
                     }
                  break;
               }
            case 8: /* SW */
               {
                  spurt("-10,10 D ");
                  if (rdrd(xpos-1,ypos) == 1)
                     {
                        spurt("-3,0 3,0 ");
                     }
                  spurt("10,10 ");
                  if (rdrd(xpos,ypos+1) == 1)
                     {
                        spurt("0,3 ");
                     }
                  break;
               }
            case 9: /* NE */
               {
                  if (rdrd(xpos,ypos-1) == 1)
                     {
                        spurt("D 0,-3 0,3 ");
                     }
                  spurt("D 10,10 ");
                  if (rdrd(xpos+1,ypos) == 1)
                     {
                        spurt("3,0 ");
                     }
                  break;
               }
         }
      spurt("U A ");
   }

dofill()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  fillcell(xpos,ypos);
               }
         }
   }

fillcell(xpos,ypos)
   int xpos,ypos;
   {
      if (rdrd(xpos,ypos) != 1)
         {
            trfill(xpos,ypos);
            brfill(xpos,ypos);
            tlfill(xpos,ypos);
            blfill(xpos,ypos);
            xcfac=0;
            ycfac=0;
         }
   }

dtrfill(xpos,ypos)
   int xpos,ypos;
   {
      xcfac=10;
      ycfac=-10;
      move(xpos,ypos);
      spurt("D R 0,10 -10,-10, 10,0 -3,3 0,3 -3,-3 3,0 A U ");
   }

dbrfill(xpos,ypos)
   int xpos,ypos;
   {
      xcfac=10;
      ycfac=10;
      move(xpos,ypos);
      spurt("D R 0,-10 -10,10 10,0 3,-3 0,3 -3,3 3,0 A U ");
   }

dtlfill(xpos,ypos)
   int xpos,ypos;
   {
      xcfac=-10;
      ycfac=-10;
      move(xpos,ypos);
      spurt("D R 10,0 -10,10 0,-10 3,3 3,0 -3,3 0,-3 A U ");
   }

dblfill(xpos,ypos)
   int xpos,ypos;
   {
      xcfac=-10;
      ycfac=10;
      move(xpos,ypos);
      spurt("D R 0,-10 10,10 -10,0 3,-3 0,-3 3,3 -3,0 A U ");
   }

okck(xpos,ypos)
   int xpos,ypos;
   {
      if (rdrd(xpos,ypos) == 1) return(1);
      if (rdrd(xpos,ypos) > 14)
         {
            if (rdrd(xpos,ypos) != 17)
               {
                  return(1);
               }
         }
      return(0);
   }

trfill(xpos,ypos)
   int xpos,ypos;
   {
      if (okck(xpos+1,ypos) == 1)
         {
            if (okck(xpos+1,ypos-1) == 1)
               {
                  if (okck(xpos,ypos-1) == 1)
                     {
                        dtrfill(xpos,ypos);
                     }
               }
         }
   }

brfill(xpos,ypos)
   int xpos,ypos;
   {
      if (okck(xpos+1,ypos) == 1)
         {
            if (okck(xpos+1,ypos+1) == 1)
               {
                  if (okck(xpos,ypos+1) == 1)
                     {
                        dbrfill(xpos,ypos);
                     }
               }
         }
   }

tlfill(xpos,ypos)
   int xpos,ypos;
   {
      if (okck(xpos-1,ypos) == 1)
         {
            if (okck(xpos-1,ypos-1) == 1)
               {
                  if (okck(xpos,ypos-1) == 1)
                     {
                        dtlfill(xpos,ypos);
                     }
               }
         }
   }

blfill(xpos,ypos)
   int xpos,ypos;
   {
      if (okck(xpos-1,ypos) == 1)
         {
            if (okck(xpos-1,ypos+1) == 1)
               {
                  if (okck(xpos,ypos+1) == 1)
                     {
                        dblfill(xpos,ypos);
                     }
               }
         }
   }

dostrat()
   {
   int xpos,ypos;
   spurt("L0 ");
      ycfac=-10;
      xcept1=12;
      xcept2=13;
      xcept3=14;
      for (xpos=0; xpos<=255; xpos++)
         {
            drawvsh(xpos,4,1);
         }
      ycfac=0;
      xcfac=-10;
      xcept1=10;
      xcept2=11;
      xcept3=14;
      for (ypos=0; ypos<=255; ypos++)
         {
            drawhsh(ypos,5,1);
         }
      xcfac=0;
      xcept1=99;
      xcept2=99;
      xcept3=99;
   }

doshear()
   {
   int xpos,ypos;
      spurt("L7 ");
      ycfac=-10;
      for (xpos=0; xpos<=255; xpos++)
         {
            drawvsh(xpos,17,0);
         }
      ycfac=0;
      xcfac=-10;
      for (ypos=0; ypos<=255; ypos++)
         {
            drawhsh(ypos,17,0);
         }
      xcfac=0;
      spurt("L0 ");
   }

drawhsh(stroke,type,resval)
   int stroke,type,resval;
   {
   int now,later,online,count;
      now=0;
      count=resval;
      later=0;
      online=0;
hsh1:
      if ((bdtop[(stroke*256)+now] == type)
           ||
          (bdtop[(stroke*256)+now] == xcept1)
           ||
          (bdtop[(stroke*256)+now] == xcept2)
           ||
          (bdtop[(stroke*256)+now] == xcept3)  )
         {
            if (online != 1)
               {
                  count=resval;
                  online=1;
                  later=now;
               }
            else
               {
                  count++;
               }
         }
      else
         {
            if (online == 1)
               {
                  if (count != 0)
                     {
                        spurt("U ");
                        move(later,stroke);
                        spurt("D ");
                        move(now,stroke);
                     }
                  online=0;
               }
            count=resval;
         }
      if (++now < 256) goto hsh1;
   }

drawvsh(stroke,type,resval)
   int stroke,type,resval;
   {
   int now,later,online,count;
      now=0;
      count=resval;
      later=0;
      online=0;
vsh1:
      if ((bdtop[(now*256)+stroke] == type)
           ||
          (bdtop[(now*256)+stroke] == xcept1)
           ||
          (bdtop[(now*256)+stroke] == xcept2)
           ||
          (bdtop[(now*256)+stroke] == xcept3)  )
         {
            if (online != 1)
               {
                  count=resval;
                  online=1;
                  later=now;
               }
            else
               {
                  count++;
               }
         }
      else
         {
            if (online == 1)
               {
                  if (count != 0)
                     {
                        spurt("U ");
                        move(stroke,later);
                        spurt("D ");
                        move(stroke,now);
                     }
                  online=0;
               }
            count=resval;
         }
      if (++now < 256) goto vsh1;
   }

dotrimpads()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  exfortrim(xpos,ypos);
               }
         }
   }

exfortrim(xpos,ypos)
   int xpos,ypos;
   {
      switch(bdtop[(ypos*256)+xpos])
         {
            case 15:
            case 16:
            case 19:
               {
                  if (xpos > 0) /* look to the left for fatcell */
                     {
                        if (bdtop[(ypos*256)+(xpos-1)]==1)
                           {
                              move(xpos,ypos);
                              spurt("R -5,-5 D -5,-5 U A ");
                              move(xpos,ypos);
                              spurt("R -5,5 D -5,5 U A ");
                           }
                     }
                  if (xpos < 255) /* look to the right for a fatcell */
                     {
                        if (bdtop[(ypos*256)+(xpos+1)]==1)
                           {
                              move(xpos,ypos);
                              spurt("R 5,-5 D 5,-5 U A ");
                              move(xpos,ypos);
                              spurt("R 5,5 D 5,5 U A ");
                           }
                     }
                  if (ypos > 0) /* look to the top for a fatcell */
                     {
                        if (bdtop[((ypos-1)*256)+xpos]==1)
                           {
                              move(xpos,ypos);
                              spurt("R -5,-5 D -5,-5 U A ");
                              move(xpos,ypos);
                              spurt("R 5,-5 D 5,-5 U A ");
                           }
                     }
                  if (ypos < 255) /* look to the bottom for a fatcell */
                     {
                        if (bdtop[((ypos+1)*256)+xpos]==1)
                           {
                              move(xpos,ypos);
                              spurt("R -5,5 D -5,5 U A ");
                              move(xpos,ypos);
                              spurt("R 5,5 D 5,5 U A ");
                           }
                     }
               }
         }
   }

doholes()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos=xpos+2)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  if (bdtop[(ypos*256)+xpos] > 14)
                     {
                        drawhole(xpos,ypos,bdtop[(256*ypos)+xpos]);
                     }
               }
            for (ypos=255; ypos>=0; ypos--)
               {
                  if (bdtop[(ypos*256)+xpos+1] > 14)
                     {
                        drawhole(xpos+1,ypos,bdtop[(256*ypos)+xpos+1]);
                     }
               }
         }
   }

drawhole(xpos,ypos,data)
   int xpos,ypos,data;
   {
      if (camrdy == '1')
         {
            drawhcam(xpos,ypos,data);
         }
      else
         {
            drawhchk(xpos,ypos,data);
         }
   }

/* camera-ready vias */
dnvhole(xpos,ypos)
   int xpos,ypos;
   {
      spurt("CC ");
      xmove(xpos,ypos);
      spurt(",9 ");
      spurt("CC ");
      xmove(xpos,ypos);
      spurt(",6 ");
   }

/* camera-ready pads */
dnhole(xpos,ypos)
   int xpos,ypos;
   {
      spurt("CC ");
      xmove(xpos,ypos);
      spurt(",10 ");
      spurt("CC ");
      xmove(xpos,ypos);
      spurt(",6 ");
   }

/* camera-ready pin-ones */
dnonehole(xpos,ypos)
   int xpos,ypos;
   {
      spurt("CC ");
      xmove(xpos,ypos);
      spurt(",10 ");
      spurt("CC ");
      xmove(xpos,ypos);
      spurt(",6 ");
   }

drawhcam(xpos,ypos,data)
   int xpos,ypos,data;
   {
       if (data == 15) /* normal pad */
         {
            dnhole(xpos,ypos);
         }
      if (data == 16) /* feedthru */
         {
            dnvhole(xpos,ypos);
         }
      if (data == 18) /* drill hole marker */
         {
            spurt("CC ");
            xmove(xpos,ypos);
            spurt(",3 ");
            spurt("R D -10,-10 20,20 U -20,0 D 20,-20 U A ");
         }
      if (data == 19) /* pin one */
         {
            dnonehole(xpos,ypos);
         }
   }

drawhchk(xpos,ypos,data)
   int xpos,ypos,data;
   {
       if (data == 15) /* normal pad */
         {
            spurt("CC ");
            xmove(xpos,ypos);
            spurt(",10 ");
         }
      if (data == 16) /* feedthru */
         {
            spurt("CC ");
            xmove(xpos,ypos);
            spurt(",10 ");
         }
      if (data == 18) /* drill hole marker */
         {
            spurt("CC ");
            xmove(xpos,ypos);
            spurt(",3 ");
            spurt("R D -10,-10 20,20 U -20,0 D 20,-20 U A ");
         }
      if (data == 19) /* pin one */
         {
            spurt("CC ");
            xmove(xpos,ypos);
            spurt(",10 ");
            spurt("CC ");
            xmove(xpos,ypos);
            spurt(",5 ");

/*            move(xpos,ypos);
            spurt("R -10,-10 D 20,0 0,20 -20,0 0,-20 U A ");*/
         }
   }

nfy()
   {
   int i;
      for (i=0; i<125000; i++);
   }

nfx()
   {
   int i;
      for (i=0; i<64000; i++);
   }

scale(value,cfac)
   int value,cfac;
   {
      value=(20*value)+300+cfac;
      return(value);
   }

move(xpos,ypos) /* send "x,y " */
   int xpos,ypos;
   {
      xmove(xpos,ypos);
      spurt(" ");
   }

xmove(xpos,ypos) /* send "x,y" */
   int xpos,ypos;
   {
   UBYTE xtxt[20],ytxt[20];
      stci_d(&xtxt[0],scale(xpos,xcfac),19);
      stci_d(&ytxt[0],scale(ypos,ycfac),19);
      spurt(&xtxt[0]);
      spurt(",");
      spurt(&ytxt[0]);
   }

spurt(ptr)
   UBYTE *ptr;
   {
      if (tofile==0)
         {
            WriteSer(IORser,ptr,-1);
         }
      else
         {
            sendfile(ptr);
         }
   }

sendfile(ptr)
   UBYTE *ptr;
   {
   UBYTE plotcell;
notdone:
      plotcell=*ptr++;
      if (plotcell==0)
         {
            return(0);
         }
      if (fwrite(&plotcell,1,1,outfp) != 1)
         {
            fclose(outfp);
            printf("Write to plotter output file failed!\n");
            exit(20);
         }
      goto notdone;
   }

WriteSer(io,data,length)
   struct IOExtSer *io;
   char *data;
   int length;
   {
   int error;
      io->IOSer.io_Data=(APTR*)data;
      io->IOSer.io_Length=length;
      io->IOSer.io_Command=CMD_WRITE;
      if ((error=DoIO(io)) != 0)
         {
            printf("serial device write error %ld\n",error);
         }
      return(error);
   }

SetParams(io,rbuf_len,rlen,wlen,brk,baud,sf,ta0,ta1)
   struct IOExtSer *io;
   unsigned long rbuf_len,brk,baud,ta0,ta1;
   unsigned char rlen,wlen,sf;
   {
   int error;
      io->io_CtlChar              = 0x11130000;
      io->io_ReadLen              = rlen;
      io->io_BrkTime              = brk;
      io->io_Baud                 = baud;
      io->io_WriteLen             = wlen;
      io->io_StopBits             = 0x01;
      io->io_RBufLen              = rbuf_len;
      io->io_SerFlags             = sf;
      io->IOSer.io_Command        = SDCMD_SETPARAMS;
      io->io_TermArray.TermArray0 = ta0;
      io->io_TermArray.TermArray1 = ta1;

      if ((error=DoIO(io)) != 0)
         {
            printf("serial device SetParams error %ld \n",error);
         }
      return(error);
   }


/*
 * board  load
 */

loadbd()
   {
   FILE *fp;

      strcpy(&tname[0],"boardlib/");
      strcat(&tname[0],&fname[0]);
      strcat(&tname[0],&xname[0]);

      if (fp = fopen(&tname[0],"r"))
         {
            printf("Please wait -- loading '%s'\n",&tname[0]);
            if (plotype != '5')
               {
                  fread(&rdmuse,4,1,fp);                  /* get file encryptor */
                  if (fread(bdtop,65536,1,fp) != 1)
                     {
                        printf("file error - entire file not loaded\n");
                        return(0);
                     }
               }
            else
               {
                  if (fread(bdtop,4,1,fp) != 1)
                     {
                        printf("file error - entire file not loaded\n");
                        return(0);
                     }
                  if (fread(bdtop,49152,1,fp) != 1)
                     {
                        printf("file error - entire file not loaded\n");
                        return(0);
                     }
               }
            fclose(fp);
            if (plotype != '5')
               {
                  encode(rdmuse,bdtop);
               }
            return(1);
         }
      else
         {
            printf("'%s' file not found\n",&tname[0]);
            return(0);
         }
   }



permute()
   {
      random=random+random+random+random+random;
   }

remute()
   {
   int tmp,indux;
      tmp=((random >> 8) & 0xFF)+157;
      for (indux=0; indux<tmp; indux++)
         {
            permute();
         }
      rdmuse=random;
   }

dofat()
   {
   int xpos,ypos;
      spurt("L0 ");
      for (xpos=0; xpos<=255; xpos++)
         {
            drawvfat(xpos,1,0);
         }
      for (ypos=0; ypos<=255; ypos++)
         {
            drawhfat(ypos,1,0);
         }
   }

drawhfat(stroke,type,resval)
   int stroke,type,resval;
   {
   int asub,aadd,now,later,online,count;
      now=0;
      count=resval;
      later=0;
      online=0;
hfat1:
      if ((bdtop[(stroke*256)+now] == type))
         {
            if (online != 1)
               {
                  count=resval;
                  online=1;
                  later=now;
               }
            else
               {
                  count++;
               }
         }
      else
         {
            if (online == 1)
               {
                  if (count > 2)
                     {
                        asub=2;
                        aadd=1;
                        if (bdread(now,stroke) > 14)      asub=1;
                        if (bdread(later-1,stroke) > 14)  aadd=0;
                        hstreamfat(stroke,now-asub,later+aadd);
                     }
                  online=0;
               }
            count=resval;
         }
      if (++now < 256) goto hfat1;
   }

drawvfat(stroke,type,resval)
   int stroke,type,resval;
   {
   int asub,aadd,now,later,online,count;
      now=0;
      count=resval;
      later=0;
      online=0;
vfat1:
      if ((bdtop[(now*256)+stroke] == type))
         {
            if (online != 1)
               {
                  count=resval;
                  online=1;
                  later=now;
               }
            else
               {
                  count++;
               }
         }
      else
         {
            if (online == 1)
               {
                  if (count > 2)
                     {
                        asub=2;
                        aadd=1;
                        if (bdread(stroke,now) > 14)       asub=1;
                        if (bdread(stroke,later-1) > 14)   aadd=0;
                        vstreamfat(stroke,now-asub,later+aadd);
                     }
                  online=0;
               }
            count=resval;
         }
      if (++now < 256) goto vfat1;
   }

bdread(xpos,ypos)
   int xpos,ypos;
   {
   int data;
      data=(UBYTE)bdtop[xpos+(ypos*256)];
      return(data);
   }

vstreamfat(xpos,ypostart,yposend)
   int xpos,ypostart,yposend;
   {
   int j;
   UBYTE yvector[20],xvector[20];
      for (j=yposend; j<=ypostart; j++)
         {
            fatrec[xpos+(j*256)]=1;
         }
      xcfac=-10;
      ycfac=-10;
      move(xpos,yposend);
      spurt("R ");
      stci_d(&yvector[0],((ypostart-yposend)*20)+23,18);
      stci_d(&xvector[0],0,18);
         for (j=0; j<6; j++)
            {
               spurt("D 0,");
               spurt(&yvector[0]);
               spurt(" U 4,-");
               spurt(&yvector[0]);
               spurt(" ");
            }
      spurt("A ");
      xcfac=0;
      ycfac=0;
   }

doafat(xpos,ypos)
   int xpos,ypos;
   {
      int i;
      ycfac=-10;    /*(10)*/
      xcfac=0;
      move(xpos,ypos);
      spurt("R D");
/* draw central diamond: */
      spurt("10,10 ");
      spurt("-10,10 ");
      spurt("-10,-10 ");
      spurt("10,-10 ");
      spurt("0,5 ");
      spurt("5,5 ");
      spurt("-5,5 ");
      spurt("-5,-5 ");
      spurt("5,-5 ");
      spurt("0,6 U ");

/* draw up to four sets of corners: */
      for (i=0; i<4; i++)
         {
            fillmem[i]=0;
         }
      xcfac=-10;
      if (  (bdread(xpos+1,ypos) == 1)
         || (bdread(xpos+1,ypos) >= 15)  )
         {
            filltr(xpos,ypos);
            fillbr(xpos,ypos);
         }
      if (  (bdread(xpos-1,ypos) == 1)
         || (bdread(xpos-1,ypos) >= 15)  )
         {
            filltl(xpos,ypos);
            fillbl(xpos,ypos);
         }
      if (  (bdread(xpos,ypos+1) == 1)
         || (bdread(xpos,ypos+1) >= 15)  )
         {
            fillbl(xpos,ypos);
            fillbr(xpos,ypos);
         }
      if (  (bdread(xpos,ypos-1) == 1)
         || (bdread(xpos,ypos-1) >= 15)  )
         {
            filltl(xpos,ypos);
            filltr(xpos,ypos);
         }
/* terminate fatcell draw mode */
      spurt("U A ");
      xcfac=0;
      ycfac=0;
   }

filltl(xpos,ypos)
   int xpos,ypos;
   {
      if (fillmem[0] != 0) return(0);
      spurt("A U");
      move(xpos,ypos);
      spurt("R ");
      spurt("D ");
      spurt("7,0 -7,7 0,-7 4,4 "); /*(7)*/
      spurt("4,0 -4,4 0,-4 ");
      fillmem[0]=1;
   }

filltr(xpos,ypos)
   int xpos,ypos;
   {
      if (fillmem[1] != 0) return(0);
      spurt("A U ");
      move(xpos,ypos);
      spurt("R 13,0 "); /*(8)*/
      spurt("D ");
      spurt("7,0 0,7 -7,-7 4,4 "); /*(3,4)*/
      spurt("0,4 -4,-4 4,0 ");

      fillmem[1]=1;
   }

fillbr(xpos,ypos)
   int xpos,ypos;
   {
      if (fillmem[2] != 0) return(0);
      spurt("A U ");
      move(xpos,ypos);
      spurt("R 20,20 ");/*(15,15)*/
      spurt("D ");
      spurt("0,-7 -7,7 7,0 -4,-4 ");
      spurt("0,-4  -4,4 4,0 ");
      fillmem[2]=1;
   }

fillbl(xpos,ypos)
   int xpos,ypos;
   {
      if (fillmem[3] != 0) return(0);
      spurt("A U ");
      move(xpos,ypos);
      spurt("R 0,20 ");/*(15)*/
      spurt("D ");
      spurt("7,0 -7,-7 0,7 4,-4 ");
      spurt("4,0 -4,-4 0,4 ");
      fillmem[3]=1;
   }



hstreamfat(ypos,xpostart,xposend)
   int ypos,xpostart,xposend;
   {
   int j;
   UBYTE yvector[20],xvector[20];
      for (j=xposend; j<=xpostart; j++)
         {
            fatrec[j+(ypos*256)]=1;
         }
      xcfac=-10;
      ycfac=-10;
      move(xposend,ypos);
      spurt("R ");
      stci_d(&xvector[0],((xpostart-xposend)*20)+23,18);
      stci_d(&yvector[0],0,18);
         for (j=0; j<6; j++)
            {
               spurt("D ");
               spurt(&xvector[0]);
               spurt(",0 U -");
               spurt(&xvector[0]);
               spurt(",4 ");
            }
      spurt("A ");
      xcfac=0;
      ycfac=0;
   }

