/*********************************************************************`

   Modified: 2/21/86 by Richie Bielak
      Fixed to space 8/72 of an inch, when printing
      graphics. 
      
*********************************************************************/
#include  "exec/types.h"
#include  "exec/nodes.h"
#include  "exec/lists.h"
#include  "exec/memory.h"
/**#include  "devices/printer.h"    */
#include  "devices/prtbase.h"
/*#include  "lattice/stdio.h"      */

extern struct PrinterData *PD;
extern struct PrinterExtendedData *PED;

/* for the C.Itoh 1570    */

long Render(ct, x, y, status)
UBYTE ct;      /* null for b/w printers */
UWORD x,y;      /* the x & y co-ordinates */
            /* or the pc & pr print values, or special */
UBYTE status;   /* print status (0-init, 1-enter pixel, 2-dump) */
{
   static UWORD ROWSIZE;
   static UWORD COLORSIZE;
   static UBYTE dirty[4];
   static BYTE thou,huns,tens,ones; /* used to program buffer size */
   static UWORD colors[4];
   static unsigned long BUFSIZE,bufptr;
   WORD ym, y_save, i;      /* misc. var */
   LONG xm,il,bufptx;
   BYTE err;      /* the error # */
   char null = 0;
   static char startup[] = "\x1b$\x1bf\x1bN\x1bm2\x1bA\x1bC0";
                        /*  0   12   34   56   789   01   23   */
   static char startup2[] = "\x1bCP71244447\x1bT32\r\n";
                        /*   0   12345678901   2345 6     */
/*   UBYTE temp[5];      */

   switch(status) {

      case 0 :   /* alloc memory for printer buffer */
/*         i = (center) ? ((PED->ped_MaxXDots - x) / 2) : 0;
              /* get # of centering pixels */
         ROWSIZE=x;   /* # of dot columns */
         thou = ROWSIZE/1000;
         huns = (ROWSIZE-thou*1000)/100;
         tens = (ROWSIZE-thou*1000-huns*100)/10;
         ones = (ROWSIZE-thou*1000-huns*100-tens*10);
         COLORSIZE = (PED->ped_NumRows == 24) ? (ROWSIZE*3+10) : (ROWSIZE+10);
         BUFSIZE=(COLORSIZE*4); /* buffer size required for 1570 */
         colors[0] = 9; /* black */
         colors[1] = COLORSIZE+9;  /* yellow */
         colors[2] = COLORSIZE*2+9;    /* magenta */
         colors[3] = COLORSIZE*3+9;  /* cyan */
         PD->pd_PrintBuf = (UBYTE *) AllocMem(BUFSIZE*2,MEMF_PUBLIC);
         if (err=(PD->pd_PrintBuf == 0)) return((long *)err);
         if (PED->ped_NumRows == 24)
             {startup[8] = '2';
              startup2[13] = '4';
              startup2[14] = '8';}
         else
             {startup[8] = '1';
              startup2[13] = '3';
              startup2[14] = '2';}
         (*PD->pd_PWrite)(&startup,14);
         (*PD->pd_PWrite)(&startup2,17);
    /* reset printer to power-up state */
         if (err=PWait(1,0)) return(err);
         bufptr = 0;
         return(0L); /* flag all ok */
         break;

      case 1 :   /* put pixel in buffer */
         if (PED->ped_NumRows == 24)
            {
             y_save = y & 0x7fff;
             ym = y_save/24;
/*             (*PD->pd_PWrite)(" ym=",4);
             temp[0] = ym/1000;
             temp[1] = (ym-temp[0]*1000)/100;
             temp[2] = (ym-temp[0]*1000-temp[1]*100)/10;
             temp[3] = ym-temp[0]*1000-temp[1]*100-temp[2]*10+'0';
             temp[0] = temp[0]+'0';
             temp[1] = temp[1]+'0';
             temp[2] = temp[2]+'0';
             (*PD->pd_PWrite)(&temp,4);       */
             ym = y_save-ym*24;
/*             (*PD->pd_PWrite)(" ym=",4);
             temp[0] = ym/1000;
             temp[1] = (ym-temp[0]*1000)/100;
             temp[2] = (ym-temp[0]*1000-temp[1]*100)/10;
             temp[3] = ym-temp[0]*1000-temp[1]*100-temp[2]*10+'0';
             temp[0] = temp[0]+'0';
             temp[1] = temp[1]+'0';
             temp[2] = temp[2]+'0';
             (*PD->pd_PWrite)(&temp,4); */
             xm = x*24;
             il = bufptr+colors[ct]+(xm+ym)/8; /* calc which byte to use */
             PD->pd_PrintBuf[il] = PD->pd_PrintBuf[il] | (1 << (ym&7)); /* fill print buffer */
            }
         else
            {ym = y & 7;
             i = bufptr+colors[ct]+x; /* calc which byte to use */
             PD->pd_PrintBuf[i] = PD->pd_PrintBuf[i] | (1 << ym); /* fill print buffer */
            }

/*       (*PD->pd_PWrite)(" i=",3);
         ym = i;
         temp[0] = ym/10000;
         temp[1] = (ym-temp[0]*10000)/1000;
         temp[2] = (ym-temp[0]*10000-temp[1]*1000)/100;
         temp[3] = (ym-temp[0]*10000-temp[1]*1000-temp[2]*100)/10;
         temp[4] = ym-temp[0]*10000-temp[1]*1000-temp[2]*100-temp[3]*10+'0';
         temp[0] = temp[0]+'0';
         temp[1] = temp[1]+'0';
         temp[2] = temp[2]+'0';
         temp[3] = temp[3]+'0';
         (*PD->pd_PWrite)(&temp,5);       */

         dirty[ct] = 1;
         return(0L); /* flag all ok */
         break;

      case 2 : /* dump buffer to printer */
         bufptx = bufptr;
         for (i=0; i<4; i++)
             {if (dirty[i])
                   (*PD->pd_PWrite)(&(PD->pd_PrintBuf[bufptx]), COLORSIZE);
              bufptx += COLORSIZE;}
         (*PD->pd_PWrite)("\n", 1);
         bufptr = BUFSIZE-bufptr;
         return(0); /* flag all ok */
         break;

      case 3 : /* clear and init buffer */
/*         for (il=bufptr; il<bufptr+BUFSIZE; il++)
              PD->pd_PrintBuf[il] = 0; /* clear buffer */
         setmem(&PD->pd_PrintBuf[bufptr],BUFSIZE,null);
         bufptx = bufptr;
         for (i='0'; i<'4'; i++)
            {PD->pd_PrintBuf[bufptx] = 0x1b;
             PD->pd_PrintBuf[bufptx+1] = 'C';
             PD->pd_PrintBuf[bufptx+2] = i;
             PD->pd_PrintBuf[bufptx+3] = 0x1b;
             PD->pd_PrintBuf[bufptx+4] = (PED->ped_NumRows == 24) ?
                  'G' : 'S';
             PD->pd_PrintBuf[bufptx+5] = thou + '0';
             PD->pd_PrintBuf[bufptx+6] = huns + '0';
             PD->pd_PrintBuf[bufptx+7] = tens + '0';
             PD->pd_PrintBuf[bufptx+8] = ones + '0';
             PD->pd_PrintBuf[bufptx+COLORSIZE-1] = '\r';
             bufptx += COLORSIZE;}
         for (i=0; i<4;i++) dirty[i] = 0;
         return(0); /* flag all ok */
         break;

      case 4 :
             /*  reset printer to power-up state */
         startup[8] = (PED->ped_NumRows == 24) ? '2' : '1';
         (*PD->pd_PWrite)(&startup,14);
            /*   wait for both buffers to empty
         err = (*(PD->pd_PBothReady))();
            /* free the print buffer memory */
         FreeMem(PD->pd_PrintBuf,BUFSIZE*2);
         return(err);   /* return status */
         break;

/*      case 5: /* io_special flags call */
/*           center = x & SPECIAL_CENTER;   /* set center flag */
/*           return(0);
           break;   */
      default: 
         return(0);
        }

}
