/* 11/06/86 fitted to .7 mm pen.  NCCS */

#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 "exec/memory.h"
#include "exec/interrupts.h"
#include "exec/tasks.h"
#include "exec/execbase.h"
#include "devices/parallel.h"
#include "devices/serial.h"
#include "lattice/stdio.h"

struct IOExtPar IORparallel;
struct IOExtSer *IORserial;
struct MsgPort *port;
char buffer[200];
extern struct MsgPort *CreatePort();
extern struct IORequest *CreateExtIO();
extern APTR AllocMem();

       /*    scaling factors for ROLAND DG DXY-880 plotter  */
       /* Some NOTES: 
for 2:1 plot 20 program units = .1 inch (2.54mm), 1 P.U.=.005 inch (.125mm)
for 1:1 plot 20 program units = .05inch (1.27mm), 1 P.U.=.0025inch (.0635mm)

for .7 mm pen (.0276 inch) = 5.6 Program Units, ( 11.01 P.U. / line ) */

#define XMAXPAGE "15200"             /* maximum X plotter cordinate*/
#define YMAXPAGE "10800"             /* maximum Y plotter cordinate*/

#define LOMAXPAGEX "2992"            /* x size in low res */
#define LOMAXPAGEY "2126"            /* y size in low res */
#define HIMAXPAGEX "5984"            /* x size in high res */
#define HIMAXPAGEY "4252"            /* y size in high res */

#define HICHARWIDTH ".0625"          /* char width in high res */
#define HICHARHEIGHT ".0875"         /* char heigth in high res */
#define LOCHARWIDTH ".1250"          /* char width in low res */
#define LOCHARHEIGHT ".1750"         /* char heigth in low res */

/*          pen selection variables  Roland DG DXY-880 8 pens  */

#define SILKPEN ";SP 1;"      /*  BLACK pen to color silk/shear */
#define HOLEPEN ";SP 1;"      /*  BLACK pen to color holes/pads/vias */
#define TRACEPEN ";SP 1;"     /*  BLACK pen to color lines fat/normal */
#define CHARPEN ";SP 1;"      /*  BLACK  pen to color characters */

/*                    Label Terminator Character                  */
/*           this should only be changed if the plotter doesn't   */
/*           use the standard HPGL text terminator                */

#define LABELTERM 3;

UBYTE *bdtop,*fatrec;              /* pointer to layer information */
int error,random,rdmuse,xcfac,ycfac,res,shearing,camrdy,tofile;
int xcept1,xcept2,xcept3,xcept4;
int viacntr,padcntr,drillcntr;
float xmaxsize,ymaxsize;
int fillmem[4];
UBYTE x1name[20],x2name[20],bdname[80],fname[80],tname[80],choice[20];
UBYTE outfile[80],xtxt[20],ytxt[20],dumpname[80];
UBYTE plotype,temp;
FILE *outfp;


main()
   {
     

      printf("\n\033[42m\033[33m                                     \033[0m\n");
      printf("\033[42m\033[33m \033[41m  HP-GL (RolandDG) Plot v3.5 rev C \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;

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

retry:
      printf("\n\nEnter board path/name \n<CR> to quit »  ");
      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(&x1name[0],".layer1");
                  strcpy(&x2name[0],"all1");                 
                  break;
               }
            case '1':
               {
                  strcpy(&x1name[0],".layer2");
                  strcpy(&x2name[0],"all2");
                  break;
               }
            case '2':
               {
                  strcpy(&x1name[0],".layer1");
                  strcpy(&x2name[0],"pad");
                  break;
               }
            case '3':
               {
                  strcpy(&x1name[0],".layer1");
                  strcpy(&x2name[0],"top");
                  break;
               }
            case '4':
               {
                  strcpy(&x1name[0],".layer2");
                  strcpy(&x2name[0],"bott");
                  break;
               }
            case '5':
               {
                  strcpy(&x1name[0],".silk");
                  strcpy(&x2name[0],"silk");
                  break;
               }
            default:
               {
                  printf("Illegal choice\n");
                  exit(20);
               }
         }

      plotype=choice[0];
      shearing=0;
      if (plotype != '5') 
       {
         printf("\n\n\n\n\n\nPlot shear lines?\n\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);
               }
            }
       }
     else
       {
         shearing = 0;
       }
      if(plotype <= '1')
       {
         printf("\n\n\n\nSelect plot quality\n\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);
               }
           }
        }
     else
       {
         camrdy = 0;
       }

      printf("\n\n\nSelect plot size option:\n\n\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);
               }
         }


         printf("\n\nSelect Data Output Flow Direction\n\n");
         printf("[1]  Disk File\n");
         printf("[2]  Plotter on the Parallel Port\n");
         printf("[3]  Plotter on the Serial Port\n");
         printf("Select »  ");
         gets(&choice[0]);
         switch(choice[0])
             {  
               case '1':
                 {
                  tofile = 1;
		  printf("\n\nEnter File name > ");
		  gets(&dumpname[0]);
                  strcpy(&outfile[0],&dumpname[0]);
		  strcat(&outfile[0],"_");
                  strcat(&outfile[0],&x2name[0]);
                  strcat(&outfile[0],".plot");
                  break;
                 }
               case '2':
                 {
                  tofile =2;    
                  if((error=setupar()) != 0)
                   {
                     printf(" Bad news parallel port setup error\n");
                     exit(10);
                   } 
                  break;
                 }
               case '3':
                 {
                  tofile = 3;
                  if((error=setupser()) != 0)    
                   {
                     printf(" Bad news serial port setup error\n");
                     if(error == 1) goto cleanup1;
                     if(error == 2) goto cleanup2;
                     else exit(100);
                   } 
                  break;      /* init serial port */
                 }
               default:
                 {
                   printf("Illegal Choice\n");
                   exit(20);
                 }
              }


      printf("\nconfiguration is\n");
      printf("File to plot = '\033[1m\033[33m%s\033[0m'",&fname[0]);
      
      if (plotype != '5') 
       {
          printf("\nShear lines  = \033[1m\033[33m");
          if (shearing == 0)
            {
               printf(" not");
            }
         printf(" plotted\033[0m");
       }
      printf("\nResolved at  =  \033[1m\033[33m");
      switch(res)
         {
            case 1:
               {
                  printf("1:1\n");
                  break;
               }
            case 2:
               {
                  printf("2:1\n");
                  break;
               }
         }
      if ( plotype <= '1')
         {    
          printf("\033[0mQuality      =  \033[1m\033[33m");
          switch(camrdy)
           {
            case '0':
               {
                  printf("Check plot\n");
                  break;
               }
            case '1':
               {
                  printf("Camera ready\n");
                  break;
               }
           default:
               {
                  printf("\n");
               }  
           }
         }

      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[0moutput  =  \033[1m\033[33m");
      switch(tofile)
         {
            case 3:
               {
                  printf("to the Serial Port\n");
                  break;
               } 
            case 2:
               {
                  printf("to the Parallel Port\n");
                  break;
               }
            case 1:
               {
                  printf("\033[0m'\033[1m\033[33m");
                  printf(&outfile[0]);
                  printf("\033[0m'\n");
                  break;
               }
         }

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

      printf("\n\n\n\n");

      if (tofile == 1)
           { 
            if (outfp=fopen(&outfile[0],"w"))
              {
                ;
              }
            else
               {
                  printf("file open failed on plot write!\n");

                  exit(20);
               }
           } 
      if (loadbd()==0)
         {
            printf("loading of the boardfile has failed\n");
            goto cleanup2;
         }
      if (plotype != '5')
         {
            printf("Processing requested file;\n  --PLEASE----Stand by--\n");

            flipfn();
            justfn();
            plotfn();
         }
      else
         {
            silkfn();
         }
           xmaxsize=(xmaxsize/20)*.05;
           ymaxsize=(ymaxsize/20)*.05;
      printf("Output stream completed\n");
      printf("The board has the following parameters\n");
       if (plotype <= '2' )
         {
            printf("  # of via's         %d\n",viacntr);
            printf("  # of pad's         %d\n",padcntr);
            printf("  # of drill holes   %d\n",drillcntr);
         }
      printf("  Approx size of the board is ");
      printf("%.3f by %.3f  inches\n",xmaxsize,ymaxsize);

cleanup1:
      if(tofile == 3) CloseDevice(IORserial);
      if(tofile == 2) CloseDevice(&IORparallel);
cleanup2:
      if ( free((UBYTE*)bdtop) != 0)
         {
           printf(" error freeing layer memory\n");
         }
      if ( free((UBYTE*)fatrec) != 0)
         {
           printf(" error freeing working memory\n");
         }
      if(tofile >= 2) DeletePort(port);
      if(tofile == 1) fclose(outfp);
      exit(0);
   }                /*  -------- END OF MAIN()---------  */

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;
            spurt(";PU PA "); 
            move(xpos,ypos);
            spurt(CHARPEN);
            spurt(";PU PR -5,-7.5 ");
            strcpy(&tbuff[0],"LB");
            tmp=strlen(&tbuff[0]);
            tbuff[tmp]=(UBYTE)data;
            tbuff[tmp+1] = LABELTERM;
            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(";PU PA ");
      move(xpos,ypos);
      spurt(SILKPEN);
      switch(data)
         {
            case 26: /* vert line  */
               {
                  spurt(";PR 0,-10 PD 0,20 ");
                  break;
               }
            case 27: /* horz line */
               {
                  spurt(";PR -10,0;PD 20,0 ");
                  break;
               }
            case 28: /* bot left */
               {
                  spurt(";PR 0,10;PD 0,-10, 10,0 "); /*tl*/
                  break;
               }
            case 29: /* bot right */
               {
                  spurt(";PR -10,0;PD 10,0, 0,10 "); /*tr*/
                  break;
               }
            case 30: /* top left */
               {
                  spurt(";PR 0,-10;PD 0,10, 10,0 "); /*bl*/
                  break;
               }
            case 31: /* top right */
               {
                  spurt(";PR 0,-10;PD 0,10, -10,0 "); /*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);
         }
      if (res == 2)
         {
          spurt(";IN;IP 0,0,");
          spurt(XMAXPAGE);
          spurt(",");
          spurt(YMAXPAGE);
          spurt(";SC 0,");
          spurt( LOMAXPAGEX );
          spurt(",0,");
          spurt( LOMAXPAGEY );
          spurt("; PU PA 0,0;SI ");
          spurt( LOCHARWIDTH );
          spurt(",");
          spurt( LOCHARHEIGHT );
          spurt(";");
         }
       else
         {
          spurt("IN;IP 0,0,");
          spurt(XMAXPAGE);
          spurt(",");
          spurt(YMAXPAGE);
          spurt(";SC 0,");
          spurt( HIMAXPAGEX );
          spurt(",0,");
          spurt( HIMAXPAGEY );
          spurt(";PU PA 0,0;SI ");
          spurt( HICHARWIDTH );
          spurt(",");
          spurt( HICHARHEIGHT );
          spurt(";");
         } 
       for (xpos=0; xpos<256; xpos++)
         {
            for (ypos=0; ypos<256; ypos++)
               {
                 churfn(xpos-xmin,ypos-(255-ymax),chread(xpos,(255-ypos),bdtop));
               }
         }
    spurt(" PU ");
   }

plotfn()
   {
    UBYTE tbuff[80];
    int tmp;

      if (res == 2)
          { 
           spurt(";IN;IP 0,0,");
           spurt(XMAXPAGE);
           spurt(",");
           spurt(YMAXPAGE);
           spurt(";SC 0,");
           spurt( LOMAXPAGEX );
           spurt(",0,");
           spurt( LOMAXPAGEY );
           spurt("; PU PA 0,0;SI ");
           spurt( LOCHARWIDTH );
           spurt(",");
           spurt( LOCHARHEIGHT );
           spurt(";VS 2;");
          }
        else
          {
           spurt("IN;IP 0,0,");
           spurt(XMAXPAGE);
           spurt(",");
           spurt(YMAXPAGE);
           spurt(";SC 0,");
           spurt( HIMAXPAGEX );
           spurt(",0,");
           spurt( HIMAXPAGEY );
           spurt("; PU PA 0,0;SI ");
           spurt( HICHARWIDTH );
           spurt(",");
           spurt( HICHARHEIGHT );
          }
     spurt(CHARPEN);
     strcpy(&tbuff[0],"PU; PA 20,20; LB");
     strcat(&tbuff[0],&tname[0]);
     tmp = strlen(&tbuff[0]);
     tbuff[tmp] = LABELTERM;
     tbuff[tmp+1] =';';
     tbuff[tmp+2]=0;
     spurt(&tbuff[0]); 

     if (shearing == 1)
         {
            spurt(SILKPEN);
            doshear();
         }
      if (plotype < '3')
         {
            spurt(HOLEPEN);
            doholes();
         }
      if (plotype != '2')
         {
            spurt(TRACEPEN);
            dostrat();
            doang();
            dotease();
            dofat();
            dosinglefat();
          if(camrdy == '1')
            {
              dofill();
            }
         }
    spurt(" PU ");
   }

dosinglefat()
   {
   int xpos,ypos,fatype;

      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  if (bdtop[(256*ypos)+xpos] == 1)
                     {
                        if (fatrec[(256*ypos)+xpos] == 0)
                           {
                              fatype = checkfat(xpos,ypos);
                              fatrec[(256*ypos)+xpos] = 1;
                              ycfac = -10;
                              fatype = rectcheck(xpos,ypos,fatype);
                              doafat(xpos,ypos,fatype);
                           }
                     }
               }
         }
   }

dotease()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                  tdraw(xpos,ypos,bdtop[(ypos*256)+xpos]);
               }
         }
   }
dofill()
   {
   int xpos,ypos;
      for (xpos=0; xpos<=255; xpos++)
         {
            for (ypos=0; ypos<=255; ypos++)
               {
                 if(okck(xpos,ypos) >= 1)
                  {
                   xcfac = 0;
                   ycfac = -10;
                   doafill(xpos,ypos);
                   padfill(xpos,ypos);
                 }
               }
         }
   }

tdraw(xpos,ypos,data)
   int xpos,ypos,data;
   {
/*    int j;    */

      if ( (data < 10) || (data > 13) )
         {
            return(0);
         }
      xcfac=0;
      ycfac=0;
      spurt(";PU PA ");
      move(xpos,ypos);
      if (data == 10) /* top t */
         {
            spurt(";PR PD 0,-9;PU PA ");
         }
      if (data == 11) /* bot t */
         {
            spurt(";PR PD 0,9;PU PA ");
         }
      if (data == 12) /* left t */
         {
            spurt(";PR PD -9,0; PU PA ");
         }
      if (data == 13) /* rite t */
         {
            spurt(";PR PD 9,0; PU PA ");
         }
  }

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;
   {
/*     int j;    */

      xcfac=0;
      ycfac=-10;
      spurt(";PU PA ");
      move(xpos,ypos);
      spurt(";PR ");
      ycfac=0;
      switch(data)
         {
            case 6: /* NW */
               {
		if (rdrd(xpos,ypos-1) == 1)
		   {
		     spurt(";PD 0,-3 0,3 ");
		   }
		spurt(";PD -10,10 ");
		if (rdrd(xpos-1,ypos) == 1)
		   {
		     spurt(" -3,0 ");
		   }	

               break;
               }
            case 7: /* SE */
               {
                  spurt(" 10,10;PD ");
		  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;PD ");
		  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(";PD 0,-3 0,3 ");
		   }
		spurt(";PD 10,10 ");
		if (rdrd(xpos+1,ypos) == 1)
		   {
			spurt(" 3,0 ");
		   }

                  break;
               }
           }
	spurt(";PU PA "); 
  }


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


dostrat()
   {
   int xpos,ypos;
   spurt(";PA ");
      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(";PA ");
      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(";PU PA ");
   }

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(";PU ");
                        move(later,stroke);
                        spurt(";PD ");
                        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(";PU ");
                           move(stroke,later);
                           spurt(";PD ");
                           move(stroke,now);
                   }
                  online=0;
               }
            count=resval;
         }
      if (++now < 256) goto vsh1;
   }


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(";PA ");
      xmove(xpos,ypos);
      spurt(" CI 8, 5;");
      spurt(" CI 5, 10;");
      spurt(";PU PA ");
      viacntr++;
   }

/* camera-ready pads */
dnhole(xpos,ypos)
   int xpos,ypos;
   {
      spurt(";PA ");
      xmove(xpos,ypos);
      spurt(";CI 9, 5;");
      spurt(";CI 6, 10; PU PA ");
      padcntr++;
    }

/* camera-ready pin-ones */
dnonehole(xpos,ypos)
   int xpos,ypos;
   {
      spurt(";PA ");
      xmove(xpos,ypos);
      spurt(";CI 10, 45;");
      spurt(";CI 6, 10; PU PA ");
     padcntr++;
    }

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(";PA ");
            xmove(xpos,ypos);
            spurt(";CI 10, 10; ");
            spurt(";PR PD -10,-10, 20,20 PU -20,0 PD 20,-20; PU ");

            drillcntr++;
         }
      if (data == 19) /* pin one */
         {
            dnonehole(xpos,ypos);
         }
   }

drawhchk(xpos,ypos,data)
   int xpos,ypos,data;
   {
       if (data == 15) /* normal pad */
         {
            spurt(";PA ");
            xmove(xpos,ypos);
            spurt(";CI 10, 20; PU ");
            padcntr++;
         }
      if (data == 16) /* feedthru */
         {
            spurt(";PA ");
            xmove(xpos,ypos);
            spurt(";CI 10, 20; ");
            spurt(";PR PD -10,0 20,0 PU -10,10 PD 0,-20;PU PA ");
            viacntr++;
         }
      if (data == 18) /* drill hole marker */
         {
            spurt(";PA ");
            xmove(xpos,ypos);
            spurt(";CI 6, 20; ");
            spurt(";PR PD -10,-10, 20,20 PU -20,0 PD 20,-20; PU PA ");
            drillcntr++;
         }
      if (data == 19) /* pin one */
         {
            spurt(";PA ");
            xmove(xpos,ypos);
            spurt(";PU PR -10,-10 PD 20,0, 0,20, -20,0, 0,-20;PU PA ");
            xmove(xpos,ypos);
            padcntr++;
         }
   }


scale(value,cfac)
   int value,cfac;
   {
      value=(20*value)+150+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;
   {
      stci_d(&xtxt[0],scale(xpos,xcfac),19);
      xmaxsize=max(scale(xpos,xcfac),xmaxsize);
      stci_d(&ytxt[0],scale(ypos,ycfac),19);
      ymaxsize=max(scale(ypos,ycfac),ymaxsize);
      spurt(&xtxt[0]);
      spurt(",");
      spurt(&ytxt[0]);
   }

spurt(ptr)
   UBYTE *ptr;
   {
      switch(tofile)
         {
            case 1:
              {  
                 sendfile(ptr);
                 break;
              }
             case 2:
               {
                 writepar(ptr,strlen(ptr));
                 break;
               }
             case 3:
               {
                   writeser(IORserial,ptr,-1);
                   break;
               }
            }   
            
   }

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;
   }




/*
 * board  load
 */

loadbd()
   {
   FILE *fp;

      strcpy(&tname[0],&fname[0]);
      strcat(&tname[0],&x1name[0]);

      if (fp = fopen(&tname[0],"r"))
         {
            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(";PA ");
      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;
      spurt(";PU PA ");
      move(xpos,yposend);
      spurt(";PR ");
      stci_d(&yvector[0],((ypostart-yposend)*20)+23,18);
      stci_d(&xvector[0],0,18);
      spurt(" 2,0 ");
         for (j=0; j<5; j++)
            {
               spurt(" PD 0,");
               spurt(&yvector[0]);
               spurt(" PU 4,-");
               spurt(&yvector[0]);
               spurt(" ");
            }
      spurt(";PA");
      xcfac=0;
      ycfac=0;
   }

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;
      spurt(";PU PA ");
      move(xposend,ypos);
      spurt(";PR ");
      stci_d(&xvector[0],((xpostart-xposend)*20)+23,18);
      stci_d(&yvector[0],0,18);
      spurt(" 0,2 ");
         for (j=0; j<5; j++)
            {
	       spurt("PD ");
               spurt(&xvector[0]);
               spurt(",0 PU -");
               spurt(&xvector[0]);
               spurt(",4 ");
            }
      spurt(";PA ");
      xcfac=0;
      ycfac=0;
   }
setupser()
   {
   
    unsigned long rbl,brk,baud,rwl,wwl,sf,t0,t1; 
        

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

      if ((error=SetParams(IORserial,rbl,rwl,wwl,brk,baud,sf,t0,t1)) != 0)
         {
            printf("SetParams retruned an error\n");
            return(2);
         }
    }
    
writeser(io,data,length)
   struct IOExtSer *io;
   APTR *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);
   }

struct IORequest *CreateExtIO(ioReplyPort,size)
    struct MsgPort *ioReplyPort;
    LONG size;
{
    struct IORequest *ioReq;

    if (ioReplyPort == 0)
	return ((struct IORequest   *) 0);

    ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC);

    if (ioReq == 0)
	return ((struct IORequest   *) 0);

    ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE;
    ioReq -> io_Message.mn_Node.ln_Pri = 0;

    ioReq -> io_Message.mn_ReplyPort = ioReplyPort;

    return (ioReq);
}


setupar()
{
    unsigned char pflags;
    unsigned long pt0;
    unsigned long pt1;

    if ((error = OpenDevice (PARALLELNAME, 0, &IORparallel, 0)) != 0)
     {
        printf ("bad news %ld on Open \n", error);
        exit (error);
     }

    port = CreatePort (PARALLELNAME,0);
    IORparallel.IOPar.io_Message.mn_ReplyPort = port;

    pflags = PARF_EOFMODE;
    pt0  = 0x51040303;
    pt1  = 0x03030303;

    if ((error = setparams (pflags,pt0,pt1)) != 0)
    {
        printf ("bad news %ld on setup \n", error);  
        DeletePort();
        exit (error);
    } 


}

 /* PARALLEL I/O functions */

setparams(pf,ta0,ta1)

    unsigned char pf;
    unsigned long ta0;
    unsigned long ta1;

{
    int error;

    IORparallel.io_ParFlags      = pf;
    IORparallel.IOPar.io_Command = PDCMD_SETPARAMS;
    IORparallel.io_PTermArray.PTermArray0 = ta0;
    IORparallel.io_PTermArray.PTermArray1 = ta1;

    if ((error = DoIO (&IORparallel)) != 0) {
        printf ("parallel.device setparams error %ld \n", error);
    }
    return (error);
}


writepar(data,length)
    APTR *data;
    int length;
{
    int     error;

    IORparallel.IOPar.io_Data = (APTR) data;
    IORparallel.IOPar.io_Length = length;
    IORparallel.IOPar.io_Command = CMD_WRITE;

    if ((error = DoIO (&IORparallel)) != 0)
    {
        printf ("parallel.device write error %ld \n", error);
    }
    return (error);
}
